From dad6412c0d224ec883a26ee279ac1e58feb296c6 Mon Sep 17 00:00:00 2001 From: Duc Tri Nguyen Date: Tue, 2 Apr 2024 10:24:18 -0400 Subject: [PATCH 01/68] Initial addition of sig_stfl API and dummy XMSS variant Signed-off-by: Duc Tri Nguyen --- .CMake/alg_support.cmake | 25 ++- CMakeLists.txt | 6 +- src/CMakeLists.txt | 8 + src/oqs.h | 1 + src/oqsconfig.h.cmake | 3 + src/sig_stfl/sig_stfl.c | 93 +++++++++++ src/sig_stfl/sig_stfl.h | 199 +++++++++++++++++++++++ src/sig_stfl/xmss/CMakeLists.txt | 5 + src/sig_stfl/xmss/sig_stfl_xmss.h | 23 +++ src/sig_stfl/xmss/sig_stfl_xmss_sha256.c | 43 +++++ 10 files changed, 404 insertions(+), 2 deletions(-) create mode 100644 src/sig_stfl/sig_stfl.c create mode 100644 src/sig_stfl/sig_stfl.h create mode 100644 src/sig_stfl/xmss/CMakeLists.txt create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss.h create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_sha256.c diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index 3bdb103af7..2bc0079b0d 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -495,7 +495,30 @@ if(OQS_DIST_X86_64_BUILD OR (OQS_USE_AVX2_INSTRUCTIONS)) endif() endif() -##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_ADD_ENABLE_BY_ALG_CONDITIONAL_END +##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_ADD_ENABLE_BY_ALG_END + +option(OQS_ENABLE_SIG_STFL_XMSS "Enable XMSS algorithm family" ON) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_XMSS_SHA256_H10 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) + +if((OQS_MINIMAL_BUILD STREQUAL "ON")) + message(FATAL_ERROR "OQS_MINIMAL_BUILD option ${OQS_MINIMAL_BUILD} no longer supported") +endif() + +if(NOT DEFINED OQS_ALGS_ENABLED OR OQS_ALGS_ENABLED STREQUAL "") + set(OQS_ALGS_ENABLED "All") +endif() + +if(NOT ((OQS_MINIMAL_BUILD STREQUAL "") OR (OQS_MINIMAL_BUILD STREQUAL "OFF"))) + filter_algs("${OQS_MINIMAL_BUILD}") +elseif (${OQS_ALGS_ENABLED} STREQUAL "STD") +##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_LIST_STANDARDIZED_ALGS_START + filter_algs("KEM_kyber_512;KEM_kyber_768;KEM_kyber_1024;SIG_dilithium_2;SIG_dilithium_3;SIG_dilithium_5;SIG_falcon_512;SIG_falcon_1024;SIG_sphincs_sha2_128f_simple;SIG_sphincs_sha2_128s_simple;SIG_sphincs_sha2_192f_simple;SIG_sphincs_sha2_192s_simple;SIG_sphincs_sha2_256f_simple;SIG_sphincs_sha2_256s_simple;SIG_sphincs_shake_128f_simple;SIG_sphincs_shake_128s_simple;SIG_sphincs_shake_192f_simple;SIG_sphincs_shake_192s_simple;SIG_sphincs_shake_256f_simple;SIG_sphincs_shake_256s_simple") +##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_LIST_STANDARDIZED_ALGS_END +elseif(${OQS_ALGS_ENABLED} STREQUAL "NIST_R4") + filter_algs("KEM_classic_mceliece_348864;KEM_classic_mceliece_348864f;KEM_classic_mceliece_460896;KEM_classic_mceliece_460896f;KEM_classic_mceliece_6688128;KEM_classic_mceliece_6688128f;KEM_classic_mceliece_6960119;KEM_classic_mceliece_6960119f;KEM_classic_mceliece_8192128;KEM_classic_mceliece_8192128f;KEM_hqc_128;KEM_hqc_192;KEM_hqc_256;KEM_bike_l1;KEM_bike_l3") +else() + message(STATUS "Alg enablement unchanged") +endif() # Set XKCP (Keccak) required for Sphincs AVX2 code even if OpenSSL3 SHA3 is used: if (${OQS_ENABLE_SIG_SPHINCS} OR NOT ${OQS_USE_SHA3_OPENSSL}) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0ca5543ed..f95809e9df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,7 +153,8 @@ set(PUBLIC_HEADERS ${PROJECT_SOURCE_DIR}/src/oqs.h ${PROJECT_SOURCE_DIR}/src/common/common.h ${PROJECT_SOURCE_DIR}/src/common/rand/rand.h ${PROJECT_SOURCE_DIR}/src/kem/kem.h - ${PROJECT_SOURCE_DIR}/src/sig/sig.h) + ${PROJECT_SOURCE_DIR}/src/sig/sig.h + ${PROJECT_SOURCE_DIR}/src/sig_stfl/sig_stfl.h) set(INTERNAL_HEADERS ${PROJECT_SOURCE_DIR}/src/common/aes/aes.h ${PROJECT_SOURCE_DIR}/src/common/rand/rand_nist.h @@ -195,6 +196,9 @@ endif() if(OQS_ENABLE_SIG_SPHINCS) set(PUBLIC_HEADERS ${PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/src/sig/sphincs/sig_sphincs.h) endif() +if(OQS_ENABLE_SIG_STFL_XMSS) + set(PUBLIC_HEADERS ${PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/src/sig_stfl/xmss/sig_stfl_xmss.h) +endif() ##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_INCLUDE_HEADERS_END execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/include/oqs) execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${PUBLIC_HEADERS} ${PROJECT_BINARY_DIR}/include/oqs) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d0dfb6f043..e6e6ce6f07 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,7 @@ add_subdirectory(common) # initialize KEM|SIG_OBJS for --warn-uninitialized set(KEM_OBJS "") set(SIG_OBJS "") +set(SIG_STFL_OBJS "") if(${OQS_ENABLE_KEM_BIKE}) add_subdirectory(kem/bike) @@ -56,10 +57,17 @@ if(OQS_ENABLE_SIG_SPHINCS) endif() ##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_ADD_ALG_OBJECTS_END +if(OQS_ENABLE_SIG_STFL_XMSS) + add_subdirectory(sig_stfl/xmss) + set(SIG_STFL_OBJS ${SIG_STFL_OBJS} ${XMSS_OBJS}) +endif() + add_library(oqs kem/kem.c ${KEM_OBJS} sig/sig.c ${SIG_OBJS} + sig_stfl/sig_stfl.c + ${SIG_STFL_OBJS} ${COMMON_OBJS}) # Internal library to be used only by test programs diff --git a/src/oqs.h b/src/oqs.h index 3acedd11bf..6d1923c78b 100644 --- a/src/oqs.h +++ b/src/oqs.h @@ -17,5 +17,6 @@ #include #include #include +#include #endif // OQS_H diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index f3b2e7c425..4e0ecc0875 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -190,3 +190,6 @@ #cmakedefine OQS_ENABLE_SIG_sphincs_shake_256s_simple 1 #cmakedefine OQS_ENABLE_SIG_sphincs_shake_256s_simple_avx2 1 ///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_ADD_ALG_ENABLE_DEFINES_END + +#cmakedefine OQS_ENABLE_SIG_STFL_XMSS 1 +#cmakedefine OQS_ENABLE_SIG_STFL_XMSS_SHA256_H10 1 diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c new file mode 100644 index 0000000000..f33540f8e4 --- /dev/null +++ b/src/sig_stfl/sig_stfl.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: MIT + +#include +#include +#if defined(_WIN32) +#include +#define strcasecmp _stricmp +#else +#include +#endif + +#include + +OQS_API const char *OQS_SIG_STFL_alg_identifier(size_t i) { + + const char *a[OQS_SIG_algs_length] = { + OQS_SIG_STFL_alg_xmss_sha256_h10, + }; + + if (i >= OQS_SIG_STFL_algs_length) { + return NULL; + } else { + return a[i]; + } +} + + +OQS_API int OQS_SIG_STFL_alg_count(void) { + return OQS_SIG_STFL_algs_length; +} + + +OQS_API int OQS_SIG_STFL_alg_is_enabled(const char *method_name) { + assert(method_name != NULL); + + if (0) { + + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h10)) { +#ifdef OQS_ENABLE_SIG_STFL_XMSS_SHA256_H10 + return 1; +#else + return 0; +#endif + } else { + return 0; + } +} + + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { + assert(method_name != NULL); + + if (0) { + + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h10)) { +#ifdef OQS_ENABLE_SIG_STFL_XMSS_SHA256_H10 + return OQS_SIG_STFL_alg_xmss_sha256_h10_new(); +#else + return NULL; +#endif + } else { + return NULL; + } +} + + +OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public_key, uint8_t *secret_key) { + if (sig == NULL || sig->keypair == NULL || sig->keypair(public_key, secret_key) != 0) { + return OQS_ERROR; + } else { + return OQS_SUCCESS; + } +} + +OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key) { + if (sig == NULL || sig->sign == NULL || sig->sign(signature, signature_len, message, message_len, secret_key) != 0) { + return OQS_ERROR; + } else { + return OQS_SUCCESS; + } +} + +OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + if (sig == NULL || sig->verify == NULL || sig->verify(message, message_len, signature, signature_len, public_key) != 0) { + return OQS_ERROR; + } else { + return OQS_SUCCESS; + } +} + +OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig) { + OQS_MEM_insecure_free(sig); +} diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h new file mode 100644 index 0000000000..4e1a0679b1 --- /dev/null +++ b/src/sig_stfl/sig_stfl.h @@ -0,0 +1,199 @@ +/** + * \file sig_stfl.h + * \brief Stateful Signature schemes + * + * The file `tests/example_sig_stfl.c` contains an example on using the OQS_SIG_STFL API. + * + * SPDX-License-Identifier: MIT + */ + +#ifndef OQS_SIG_STATEFUL_H +#define OQS_SIG_STATEFUL_H + +#include +#include +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +/* Algorithm identifier for XMSS-SHA2_10_256 */ +#define OQS_SIG_STFL_alg_xmss_sha256_h10 "XMSS-SHA2_10_256" + +#define OQS_SIG_STFL_algs_length 1 + +/** + * Returns identifiers for available signature schemes in liboqs. Used with OQS_SIG_STFL_new. + * + * Note that algorithm identifiers are present in this list even when the algorithm is disabled + * at compile time. + * + * @param[in] i Index of the algorithm identifier to return, 0 <= i < OQS_SIG_algs_length + * @return Algorithm identifier as a string, or NULL. + */ +OQS_API const char *OQS_SIG_STFL_alg_identifier(size_t i); + +/** + * Returns the number of signature mechanisms in liboqs. They can be enumerated with + * OQS_SIG_STFL_alg_identifier. + * + * Note that some mechanisms may be disabled at compile time. + * + * @return The number of signature mechanisms. + */ +OQS_API int OQS_SIG_STFL_alg_count(void); + +/** + * Indicates whether the specified algorithm was enabled at compile-time or not. + * + * @param[in] method_name Name of the desired algorithm; one of the names in `OQS_SIG_STFL_algs`. + * @return 1 if enabled, 0 if disabled or not found + */ +OQS_API int OQS_SIG_STFL_alg_is_enabled(const char *method_name); + +/** + * Stateful signature scheme object + */ +typedef struct OQS_SIG_STFL { + + /** A local ordinal representing the LMS parameter of the signature scheme. */ + uint32_t oid; + + /** Printable string representing the name of the signature scheme. */ + const char *method_name; + + /** + * Printable string representing the version of the cryptographic algorithm. + * + * Implementations with the same method_name and same alg_version will be interoperable. + * See README.md for information about algorithm compatibility. + */ + const char *alg_version; + + /** Whether the signature offers EUF-CMA security (TRUE) or not (FALSE). */ + bool euf_cma; + + /** The (maximum) length, in bytes, of public keys for this signature scheme. */ + size_t length_public_key; + /** The (maximum) length, in bytes, of signatures for this signature scheme. */ + size_t length_signature; + + + /** + * Keypair generation algorithm. + * + * Caller is responsible for allocating sufficient memory for `public_key` + * based on the `length_*` members in this object or the per-scheme + * compile-time macros `OQS_SIG_STFL_*_length_*`. + * + * @param[out] public_key The public key represented as a byte string. + * @param[out] secret_key The secret key represented as a byt string + * @return OQS_SUCCESS or OQS_ERROR + */ + OQS_STATUS (*keypair)(uint8_t *public_key, uint8_t *secret_key); + + /** + * Signature generation algorithm. + * + * Caller is responsible for allocating sufficient memory for `signature`, + * based on the `length_*` members in this object or the per-scheme + * compile-time macros `OQS_SIG_STFL_*_length_*`. + * + * @param[out] signature The signature on the message represented as a byte string. + * @param[out] signature_len The length of the signature. + * @param[in] message The message to sign represented as a byte string. + * @param[in] message_len The length of the message to sign. + * @param[in] secret_key The secret key represented as a byte string. + * @return OQS_SUCCESS or OQS_ERROR + */ + OQS_STATUS (*sign)(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); + + /** + * Signature verification algorithm. + * + * @param[in] message The message represented as a byte string. + * @param[in] message_len The length of the message. + * @param[in] signature The signature on the message represented as a byte string. + * @param[in] signature_len The length of the signature. + * @param[in] public_key The public key represented as a byte string. + * @return OQS_SUCCESS or OQS_ERROR + */ + OQS_STATUS (*verify)(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); + +} OQS_SIG_STFL; + +/** + * Constructs an OQS_SIG_STFL object for a particular algorithm. + * + * Callers should always check whether the return value is `NULL`, which indicates either than an + * invalid algorithm name was provided, or that the requested algorithm was disabled at compile-time. + * + * @param[in] method_name Name of the desired algorithm; one of the names in `OQS_SIG_STFL_algs`. + * @return An OQS_SIG_STFL for the particular algorithm, or `NULL` if the algorithm has been disabled at compile-time. + */ +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name); + +/** + * Keypair generation algorithm. + * + * Caller is responsible for allocating sufficient memory for `public_key` based + * on the `length_*` members in this object or the per-scheme compile-time macros + * `OQS_SIG_STFL_*_length_*`. Caller is also responsible for initializing + * `secret_key` using the OQS_SECRET_KEY(*) function + * + * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. + * @param[out] public_key The public key represented as a byte string. + * @param[out] secret_key The secret key represented as a byte string. + * @return OQS_SUCCESS or OQS_ERROR + */ +OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *pk, uint8_t *sk); + +/** + * Signature generation algorithm. + * + * Caller is responsible for allocating sufficient memory for `signature`, + * based on the `length_*` members in this object or the per-scheme + * compile-time macros `OQS_SIG_STFL_*_length_*`. + * + * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. + * @param[out] signature The signature on the message represented as a byte string. + * @param[out] signature_len The length of the signature. + * @param[in] message The message to sign represented as a byte string. + * @param[in] message_len The length of the message to sign. + * @param[in] secret_key The secret key represented as a byte string. + * @return OQS_SUCCESS or OQS_ERROR + */ +OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); + +/** + * Signature verification algorithm. + * + * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. + * @param[in] message The message represented as a byte string. + * @param[in] message_len The length of the message. + * @param[in] signature The signature on the message represented as a byte string. + * @param[in] signature_len The length of the signature. + * @param[in] public_key The public key represented as a byte string. + * @return OQS_SUCCESS or OQS_ERROR + */ +OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); + +/** + * Frees an OQS_SIG_STFL object that was constructed by OQS_SIG_STFL_new. + * + * @param[in] sig The OQS_SIG_STFL object to free. + */ +OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig); + +#if defined(__cplusplus) +} // extern "C" +#endif + +#ifdef OQS_ENABLE_SIG_STFL_XMSS +#include +#endif // OQS_ENABLE_SIG_STFL_XMSS + +#endif /* OQS_SIG_STATEFUL_H */ diff --git a/src/sig_stfl/xmss/CMakeLists.txt b/src/sig_stfl/xmss/CMakeLists.txt new file mode 100644 index 0000000000..ff9db48a29 --- /dev/null +++ b/src/sig_stfl/xmss/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: MIT +set(SRCS sig_stfl_xmss_sha256.c +) + +add_library(xmss OBJECT ${SRCS}) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h new file mode 100644 index 0000000000..fbde5af4de --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: MIT + +#ifndef OQS_SIG_STFL_XMSS_H +#define OQS_SIG_STFL_XMSS_H + +#include + +#define XMSS_OID_LEN 4 + +#ifdef OQS_ENABLE_SIG_STFL_XMSS_SHA256_H10 + +#define OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature 2500 +#define OQS_SIG_STFL_alg_xmss_sha256_h10_length_pk 64 + XMSS_OID_LEN +#define OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk 2047 + XMSS_OID_LEN + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); + +#endif + +#endif /* OQS_SIG_STFL_XMSS_H */ diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c new file mode 100644 index 0000000000..b2a84fb75c --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +// ======================== XMSS10-SHA256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSS-SHA2_10_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha256_h10_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmss_sha256_h10_keypair; + sig->sign = OQS_SIG_STFL_alg_xmss_sha256_h10_sign; + sig->verify = OQS_SIG_STFL_alg_xmss_sha256_h10_verify; + + return sig; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(uint8_t *public_key, uint8_t *secret_key) { + return OQS_ERROR; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key) { + return OQS_ERROR; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_ERROR; +} From b0c06fa966360bad2c128b5b37255ced1266d9e3 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Mon, 8 May 2023 10:04:28 -0400 Subject: [PATCH 02/68] Fix API and build issues --- src/sig_stfl/sig_stfl.h | 2 ++ src/sig_stfl/xmss/CMakeLists.txt | 5 +++++ src/sig_stfl/xmss/sig_stfl_xmss_sha256.c | 13 ++++++++++--- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index 4e1a0679b1..b75be58ea1 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -78,6 +78,8 @@ typedef struct OQS_SIG_STFL { /** The (maximum) length, in bytes, of public keys for this signature scheme. */ size_t length_public_key; + /** The (maximum) length, in bytes, of secret keys for this signature scheme. */ + size_t length_secret_key; /** The (maximum) length, in bytes, of signatures for this signature scheme. */ size_t length_signature; diff --git a/src/sig_stfl/xmss/CMakeLists.txt b/src/sig_stfl/xmss/CMakeLists.txt index ff9db48a29..896618b167 100644 --- a/src/sig_stfl/xmss/CMakeLists.txt +++ b/src/sig_stfl/xmss/CMakeLists.txt @@ -1,5 +1,10 @@ # SPDX-License-Identifier: MIT + +set(_XMSS_OBJS "") + set(SRCS sig_stfl_xmss_sha256.c ) add_library(xmss OBJECT ${SRCS}) +set(_XMSS_OBJS ${_XMSS_OBJS} $) +set(XMSS_OBJS ${_XMSS_OBJS} PARENT_SCOPE) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c index b2a84fb75c..ce50e4493c 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c @@ -6,6 +6,12 @@ #include #include "sig_stfl_xmss.h" +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + // ======================== XMSS10-SHA256 ======================== // OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void) { @@ -21,6 +27,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void) { sig->euf_cma = true; sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha256_h10_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk; sig->length_signature = OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature; sig->keypair = OQS_SIG_STFL_alg_xmss_sha256_h10_keypair; @@ -30,14 +37,14 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void) { return sig; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(uint8_t *public_key, uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { return OQS_ERROR; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(XMSS_UNUSED_ATT uint8_t *signature, XMSS_UNUSED_ATT size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { return OQS_ERROR; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT const uint8_t *signature, XMSS_UNUSED_ATT size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { return OQS_ERROR; } From 7b591542e3455b9407be44a54e0a67ffb455eb97 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Mon, 8 May 2023 10:04:45 -0400 Subject: [PATCH 03/68] Add SIG_STFL to tests/dump_alg_info --- tests/dump_alg_info.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/dump_alg_info.c b/tests/dump_alg_info.c index 6b07b40155..3bee2d2737 100644 --- a/tests/dump_alg_info.c +++ b/tests/dump_alg_info.c @@ -54,6 +54,25 @@ int main(void) { printf(" length-signature: %zu\n", sig->length_signature); OQS_SIG_free(sig); } + + // iterate through stateful signature schemes and print info + printf("SIG_STFLs:\n"); + for (size_t i = 0; i < OQS_SIG_STFL_algs_length; i++) { + const char *sig_name = OQS_SIG_STFL_alg_identifier(i); + printf(" %s:\n", sig_name); + OQS_SIG_STFL *sig = OQS_SIG_STFL_new(sig_name); + if (sig == NULL) { + printf(" isnull: true\n"); + continue; + } + printf(" isnull: false\n"); + printf(" claimed-security: %s\n", sig->euf_cma ? "EUF-CMA" : "none"); + printf(" length-public-key: %zu\n", sig->length_public_key); + printf(" length-secret-key: %zu\n", sig->length_secret_key); + printf(" length-signature: %zu\n", sig->length_signature); + OQS_SIG_STFL_free(sig); + } + OQS_destroy(); } From 8e1dd5ce0f6efbf221f3eb1ead8c295f72ab460e Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Mon, 8 May 2023 21:08:51 -0400 Subject: [PATCH 04/68] Update sig_stfl dummy scheme and add basic test program --- .CMake/alg_support.cmake | 2 +- src/oqsconfig.h.cmake | 2 +- src/sig_stfl/sig_stfl.c | 4 +- src/sig_stfl/xmss/sig_stfl_xmss.h | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256.c | 17 +- tests/CMakeLists.txt | 8 + tests/helpers.py | 33 +++ tests/test_cmdline.py | 8 + tests/test_sig_stfl.c | 247 +++++++++++++++++++++++ 9 files changed, 313 insertions(+), 10 deletions(-) create mode 100644 tests/test_sig_stfl.c diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index 2bc0079b0d..c2c498bf54 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -498,7 +498,7 @@ endif() ##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_ADD_ENABLE_BY_ALG_END option(OQS_ENABLE_SIG_STFL_XMSS "Enable XMSS algorithm family" ON) -cmake_dependent_option(OQS_ENABLE_SIG_STFL_XMSS_SHA256_H10 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha256_h10 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) if((OQS_MINIMAL_BUILD STREQUAL "ON")) message(FATAL_ERROR "OQS_MINIMAL_BUILD option ${OQS_MINIMAL_BUILD} no longer supported") diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index 4e0ecc0875..3496e1a5f2 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -192,4 +192,4 @@ ///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_ADD_ALG_ENABLE_DEFINES_END #cmakedefine OQS_ENABLE_SIG_STFL_XMSS 1 -#cmakedefine OQS_ENABLE_SIG_STFL_XMSS_SHA256_H10 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmss_sha256_h10 1 diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index f33540f8e4..10b34293d8 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -36,7 +36,7 @@ OQS_API int OQS_SIG_STFL_alg_is_enabled(const char *method_name) { if (0) { } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h10)) { -#ifdef OQS_ENABLE_SIG_STFL_XMSS_SHA256_H10 +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h10 return 1; #else return 0; @@ -53,7 +53,7 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { if (0) { } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h10)) { -#ifdef OQS_ENABLE_SIG_STFL_XMSS_SHA256_H10 +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h10 return OQS_SIG_STFL_alg_xmss_sha256_h10_new(); #else return NULL; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index fbde5af4de..93dcd57bba 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -7,7 +7,7 @@ #define XMSS_OID_LEN 4 -#ifdef OQS_ENABLE_SIG_STFL_XMSS_SHA256_H10 +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h10 #define OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature 2500 #define OQS_SIG_STFL_alg_xmss_sha256_h10_length_pk 64 + XMSS_OID_LEN diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c index ce50e4493c..186fba20f8 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c @@ -38,13 +38,20 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void) { } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { - return OQS_ERROR; + return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(XMSS_UNUSED_ATT uint8_t *signature, XMSS_UNUSED_ATT size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { - return OQS_ERROR; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + memset(signature, 0, OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature); + *signature_len = OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature; + return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT const uint8_t *signature, XMSS_UNUSED_ATT size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - return OQS_ERROR; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + for (size_t i = 0; i < OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature; i++) { + if (signature[i] != 0) { + return OQS_ERROR; + } + } + return OQS_SUCCESS; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3468dfc550..ada020f51a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -110,6 +110,14 @@ target_link_libraries(speed_sig PRIVATE ${TEST_DEPS}) set(SIG_TESTS example_sig kat_sig test_sig test_sig_mem speed_sig vectors_sig) +# SIG_STFL API tests +add_executable(test_sig_stfl test_sig_stfl.c) +if((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_C_COMPILER_ID STREQUAL "GNU")) + target_link_libraries(test_sig_stfl PRIVATE ${API_TEST_DEPS} Threads::Threads) +else () + target_link_libraries(test_sig_stfl PRIVATE ${API_TEST_DEPS}) +endif() + add_executable(dump_alg_info dump_alg_info.c) target_link_libraries(dump_alg_info PRIVATE ${TEST_DEPS}) diff --git a/tests/helpers.py b/tests/helpers.py index fc22ef809f..58f0834511 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -108,6 +108,39 @@ def is_sig_enabled_by_name(name): return True return False +def available_sig_stfls_by_name(): + available_names = [] + with open(os.path.join('src', 'sig_stfl', 'sig_stfl.h')) as fh: + for line in fh: + if line.startswith("#define OQS_SIG_STFL_alg_"): + sig_stfl_name = line.split(' ')[2] + sig_stfl_name = sig_stfl_name[1:-2] + available_names.append(sig_stfl_name) + return available_names + +def is_sig_stfl_enabled_by_name(name): + symbol = None + with open(os.path.join('src', 'sig_stfl', 'sig_stfl.h')) as fh: + for line in fh: + if line.startswith("#define OQS_SIG_STFL_alg_"): + sig_stfl_symbol = line.split(' ')[1] + sig_stfl_symbol = sig_stfl_symbol[len("OQS_SIG_STFL_alg_"):] + sig_stfl_name = line.split(' ')[2] + sig_stfl_name = sig_stfl_name[1:-2] + if sig_stfl_name == name: + symbol = sig_stfl_symbol + break + if symbol == None: return False + header = os.path.join(get_current_build_dir_name(), 'include', 'oqs', 'oqsconfig.h') + with open(header) as fh: + for line in fh: + if line.startswith("#define OQS_ENABLE_SIG_STFL_"): + sig_stfl_symbol = line.split(' ')[1] + sig_stfl_symbol = sig_stfl_symbol[len("OQS_ENABLE_SIG_STFL_"):].rstrip() + if sig_stfl_symbol == symbol: + return True + return False + def filtered_test(func): funcname = func.__name__[len("test_"):] diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py index 5575fd4ffd..66962cd98c 100644 --- a/tests/test_cmdline.py +++ b/tests/test_cmdline.py @@ -28,6 +28,14 @@ def test_sig(sig_name): [helpers.path_to_executable('test_sig'), sig_name], ) +@helpers.filtered_test +@pytest.mark.parametrize('sig_stfl_name', helpers.available_sig_stfls_by_name()) +def test_sig_stfl(sig_stfl_name): + if not(helpers.is_sig_stfl_enabled_by_name(sig_stfl_name)): pytest.skip('Not enabled') + helpers.run_subprocess( + [helpers.path_to_executable('test_sig_stfl'), sig_stfl_name], + ) + if __name__ == "__main__": import sys pytest.main(sys.argv) diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c new file mode 100644 index 0000000000..405def1754 --- /dev/null +++ b/tests/test_sig_stfl.c @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: MIT + +#if defined(_WIN32) +#pragma warning(disable : 4244 4293) +#endif + +#include +#include +#include + +#include + +#if OQS_USE_PTHREADS_IN_TESTS +#include +#endif + +#ifdef OQS_ENABLE_TEST_CONSTANT_TIME +#include +#define OQS_TEST_CT_CLASSIFY(addr, len) VALGRIND_MAKE_MEM_UNDEFINED(addr, len) +#define OQS_TEST_CT_DECLASSIFY(addr, len) VALGRIND_MAKE_MEM_DEFINED(addr, len) +#else +#define OQS_TEST_CT_CLASSIFY(addr, len) +#define OQS_TEST_CT_DECLASSIFY(addr, len) +#endif + +#include "system_info.c" + +typedef struct magic_s { + uint8_t val[31]; +} magic_t; + +static OQS_STATUS sig_stfl_test_correctness(const char *method_name) { + + OQS_SIG_STFL *sig = NULL; + uint8_t *public_key = NULL; + uint8_t *secret_key = NULL; + uint8_t *message = NULL; + size_t message_len = 100; + uint8_t *signature = NULL; + size_t signature_len; + OQS_STATUS rc, ret = OQS_ERROR; + + //The magic numbers are random values. + //The length of the magic number was chosen to be 31 to break alignment + magic_t magic; + OQS_randombytes(magic.val, sizeof(magic_t)); + + sig = OQS_SIG_STFL_new(method_name); + if (sig == NULL) { + fprintf(stderr, "ERROR: OQS_SIG_STFL_new failed\n"); + goto err; + } + + printf("================================================================================\n"); + printf("Sample computation for stateful signature %s\n", sig->method_name); + printf("================================================================================\n"); + + public_key = malloc(sig->length_public_key + 2 * sizeof(magic_t)); + secret_key = malloc(sig->length_secret_key + 2 * sizeof(magic_t)); + message = malloc(message_len + 2 * sizeof(magic_t)); + signature = malloc(sig->length_signature + 2 * sizeof(magic_t)); + + if ((public_key == NULL) || (secret_key == NULL) || (message == NULL) || (signature == NULL)) { + fprintf(stderr, "ERROR: malloc failed\n"); + goto err; + } + + //Set the magic numbers before + memcpy(public_key, magic.val, sizeof(magic_t)); + memcpy(secret_key, magic.val, sizeof(magic_t)); + memcpy(message, magic.val, sizeof(magic_t)); + memcpy(signature, magic.val, sizeof(magic_t)); + + public_key += sizeof(magic_t); + secret_key += sizeof(magic_t); + message += sizeof(magic_t); + signature += sizeof(magic_t); + + // and after + memcpy(public_key + sig->length_public_key, magic.val, sizeof(magic_t)); + memcpy(secret_key + sig->length_secret_key, magic.val, sizeof(magic_t)); + memcpy(message + message_len, magic.val, sizeof(magic_t)); + memcpy(signature + sig->length_signature, magic.val, sizeof(magic_t)); + + OQS_randombytes(message, message_len); + OQS_TEST_CT_DECLASSIFY(message, message_len); + + rc = OQS_SIG_STFL_keypair(sig, public_key, secret_key); + OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "ERROR: OQS_SIG_STFL_keypair failed\n"); + goto err; + } + + rc = OQS_SIG_STFL_sign(sig, signature, &signature_len, message, message_len, secret_key); + OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "ERROR: OQS_SIG_STFL_sign failed\n"); + goto err; + } + + OQS_TEST_CT_DECLASSIFY(public_key, sig->length_public_key); + OQS_TEST_CT_DECLASSIFY(signature, signature_len); + rc = OQS_SIG_STFL_verify(sig, message, message_len, signature, signature_len, public_key); + OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "ERROR: OQS_SIG_STFL_verify failed\n"); + goto err; + } + + /* modify the signature to invalidate it */ + OQS_randombytes(signature, signature_len); + OQS_TEST_CT_DECLASSIFY(signature, signature_len); + rc = OQS_SIG_STFL_verify(sig, message, message_len, signature, signature_len, public_key); + OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); + if (rc != OQS_ERROR) { + fprintf(stderr, "ERROR: OQS_SIG_STFL_verify should have failed!\n"); + goto err; + } + +#ifndef OQS_ENABLE_TEST_CONSTANT_TIME + /* check magic values */ + int rv = memcmp(public_key + sig->length_public_key, magic.val, sizeof(magic_t)); + rv |= memcmp(secret_key + sig->length_secret_key, magic.val, sizeof(magic_t)); + rv |= memcmp(message + message_len, magic.val, sizeof(magic_t)); + rv |= memcmp(signature + sig->length_signature, magic.val, sizeof(magic_t)); + rv |= memcmp(public_key - sizeof(magic_t), magic.val, sizeof(magic_t)); + rv |= memcmp(secret_key - sizeof(magic_t), magic.val, sizeof(magic_t)); + rv |= memcmp(message - sizeof(magic_t), magic.val, sizeof(magic_t)); + rv |= memcmp(signature - sizeof(magic_t), magic.val, sizeof(magic_t)); + if (rv) { + fprintf(stderr, "ERROR: Magic numbers do not mtach\n"); + goto err; + } +#endif + + printf("verification passes as expected\n"); + ret = OQS_SUCCESS; + goto cleanup; + +err: + ret = OQS_ERROR; + +cleanup: + if (secret_key) { + OQS_MEM_secure_free(secret_key - sizeof(magic_t), sig->length_secret_key + 2 * sizeof(magic_t)); + } + if (public_key) { + OQS_MEM_insecure_free(public_key - sizeof(magic_t)); + } + if (message) { + OQS_MEM_insecure_free(message - sizeof(magic_t)); + } + if (signature) { + OQS_MEM_insecure_free(signature - sizeof(magic_t)); + } + OQS_SIG_STFL_free(sig); + + return ret; +} + +#ifdef OQS_ENABLE_TEST_CONSTANT_TIME +static void TEST_SIG_STFL_randombytes(uint8_t *random_array, size_t bytes_to_read) { + // We can't make direct calls to the system randombytes on some platforms, + // so we have to swap out the OQS_randombytes provider. + OQS_randombytes_switch_algorithm("system"); + OQS_randombytes(random_array, bytes_to_read); + OQS_randombytes_custom_algorithm(&TEST_SIG_STFL_randombytes); + + // OQS_TEST_CT_CLASSIFY tells Valgrind's memcheck tool to issue a warning if + // the program branches on any byte that depends on random_array. This helps us + // identify timing side-channels, as these bytes often contain secret data. + OQS_TEST_CT_CLASSIFY(random_array, bytes_to_read); +} +#endif + +#if OQS_USE_PTHREADS_IN_TESTS +struct thread_data { + char *alg_name; + OQS_STATUS rc; +}; + +void *test_wrapper(void *arg) { + struct thread_data *td = arg; + td->rc = sig_stfl_test_correctness(td->alg_name); + return NULL; +} +#endif + +int main(int argc, char **argv) { + OQS_init(); + + printf("Testing stateful signature algorithms using liboqs version %s\n", OQS_version()); + + if (argc != 2) { + fprintf(stderr, "Usage: test_sig_stfl algname\n"); + fprintf(stderr, " algname: "); + for (size_t i = 0; i < OQS_SIG_STFL_algs_length; i++) { + if (i > 0) { + fprintf(stderr, ", "); + } + fprintf(stderr, "%s", OQS_SIG_STFL_alg_identifier(i)); + } + fprintf(stderr, "\n"); + OQS_destroy(); + return EXIT_FAILURE; + } + + print_system_info(); + + char *alg_name = argv[1]; + if (!OQS_SIG_STFL_alg_is_enabled(alg_name)) { + printf("Stateful signature algorithm %s not enabled!\n", alg_name); + OQS_destroy(); + return EXIT_FAILURE; + } + +#ifdef OQS_ENABLE_TEST_CONSTANT_TIME + OQS_randombytes_custom_algorithm(&TEST_SIG_STFL_randombytes); +#else + OQS_randombytes_switch_algorithm("system"); +#endif + + OQS_STATUS rc; +#if OQS_USE_PTHREADS_IN_TESTS +#define MAX_LEN_SIG_NAME_ 64 + pthread_t thread; + struct thread_data td; + td.alg_name = alg_name; + int trc = pthread_create(&thread, NULL, test_wrapper, &td); + if (trc) { + fprintf(stderr, "ERROR: Creating pthread\n"); + OQS_destroy(); + return EXIT_FAILURE; + } + pthread_join(thread, NULL); + rc = td.rc; +#else + rc = sig_stfl_test_correctness(alg_name); +#endif + if (rc != OQS_SUCCESS) { + OQS_destroy(); + return EXIT_FAILURE; + } + OQS_destroy(); + return EXIT_SUCCESS; +} From 244288f8acdab63813fbb9514f85b5bf6f8d372c Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Thu, 1 Jun 2023 18:41:58 -0400 Subject: [PATCH 05/68] Add XMSS parameter xmss_sha256_h10 (#1482) * init external and parameters * fix the size of pk and sk * add cmakelist for xmss_sha256_h10 * add comment * fix format err * fix compiler warning of size_t * update to match local * add remain and total API * add sigs_remaining and sigs_total * add const to API * add kat_sig_stfl * to pass the format test * fix typo * verbose error * let's see if this work * use UINT64_MAX constant * goto err to avoid memory leaks * safe arithmetic using unsigned int and initialize lengths array * fix iteration type to match its comparison * using unsigned int instead of uint32_t to match with comparison * use memset to initialize default value * convert to unsigned int * propagate unsigned int * clean up * remove randombytes, use OQS_randombytes instead. * use calloc instead of malloc for secret_key memory initialization * remove randombytes from CMakeLists.txt * remove makefile * using namespace to separate core_hash.c * rename katfile * add test and kats for test_kat.py * add compile definition for core_hash.c * add type for t * fix typo --- src/sig_stfl/sig_stfl.c | 16 + src/sig_stfl/sig_stfl.h | 38 + src/sig_stfl/xmss/CMakeLists.txt | 16 +- src/sig_stfl/xmss/external/core_hash.c | 14 + src/sig_stfl/xmss/external/hash.c | 142 +++ src/sig_stfl/xmss/external/hash.h | 47 + src/sig_stfl/xmss/external/hash_address.c | 66 ++ src/sig_stfl/xmss/external/hash_address.h | 48 + src/sig_stfl/xmss/external/namespace.h | 14 + src/sig_stfl/xmss/external/params.c | 753 +++++++++++++ src/sig_stfl/xmss/external/params.h | 78 ++ src/sig_stfl/xmss/external/sign.c | 139 +++ src/sig_stfl/xmss/external/sign.h | 90 ++ src/sig_stfl/xmss/external/sign_params.h | 142 +++ src/sig_stfl/xmss/external/utils.c | 30 + src/sig_stfl/xmss/external/utils.h | 19 + src/sig_stfl/xmss/external/wots.c | 180 ++++ src/sig_stfl/xmss/external/wots.h | 40 + src/sig_stfl/xmss/external/xmss.c | 287 +++++ src/sig_stfl/xmss/external/xmss.h | 93 ++ src/sig_stfl/xmss/external/xmss_commons.c | 216 ++++ src/sig_stfl/xmss/external/xmss_commons.h | 36 + src/sig_stfl/xmss/external/xmss_core.c | 277 +++++ src/sig_stfl/xmss/external/xmss_core.h | 85 ++ src/sig_stfl/xmss/external/xmss_core_fast.c | 988 ++++++++++++++++++ src/sig_stfl/xmss/sig_stfl_xmss.h | 6 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256.c | 57 - src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c | 112 ++ tests/CMakeLists.txt | 11 +- tests/KATs/sig_stfl/kats.json | 3 + tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp | 182 ++++ tests/helpers.py | 19 +- tests/kat_sig_stfl.c | 289 +++++ tests/test_helpers.h | 1 + tests/test_kat.py | 16 + tests/test_sig.c | 2 +- tests/test_sig_stfl.c | 2 +- 37 files changed, 4484 insertions(+), 70 deletions(-) create mode 100644 src/sig_stfl/xmss/external/core_hash.c create mode 100644 src/sig_stfl/xmss/external/hash.c create mode 100644 src/sig_stfl/xmss/external/hash.h create mode 100644 src/sig_stfl/xmss/external/hash_address.c create mode 100644 src/sig_stfl/xmss/external/hash_address.h create mode 100644 src/sig_stfl/xmss/external/namespace.h create mode 100644 src/sig_stfl/xmss/external/params.c create mode 100644 src/sig_stfl/xmss/external/params.h create mode 100644 src/sig_stfl/xmss/external/sign.c create mode 100644 src/sig_stfl/xmss/external/sign.h create mode 100644 src/sig_stfl/xmss/external/sign_params.h create mode 100644 src/sig_stfl/xmss/external/utils.c create mode 100644 src/sig_stfl/xmss/external/utils.h create mode 100644 src/sig_stfl/xmss/external/wots.c create mode 100644 src/sig_stfl/xmss/external/wots.h create mode 100644 src/sig_stfl/xmss/external/xmss.c create mode 100644 src/sig_stfl/xmss/external/xmss.h create mode 100644 src/sig_stfl/xmss/external/xmss_commons.c create mode 100644 src/sig_stfl/xmss/external/xmss_commons.h create mode 100644 src/sig_stfl/xmss/external/xmss_core.c create mode 100644 src/sig_stfl/xmss/external/xmss_core.h create mode 100644 src/sig_stfl/xmss/external/xmss_core_fast.c delete mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_sha256.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c create mode 100644 tests/KATs/sig_stfl/kats.json create mode 100644 tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp create mode 100644 tests/kat_sig_stfl.c diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 10b34293d8..9ee29a9736 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -88,6 +88,22 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m } } +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, size_t *remain, const uint8_t *secret_key) { + if (sig == NULL || sig->sigs_remaining == NULL || sig->sigs_remaining(remain, secret_key) != 0) { + return OQS_ERROR; + } else { + return OQS_SUCCESS; + } +} + +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, size_t *max, const uint8_t *secret_key) { + if (sig == NULL || sig->sigs_total == NULL || sig->sigs_total(max, secret_key) != 0) { + return OQS_ERROR; + } else { + return OQS_SUCCESS; + } +} + OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig) { OQS_MEM_insecure_free(sig); } diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index b75be58ea1..67604f5b9d 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -125,6 +125,24 @@ typedef struct OQS_SIG_STFL { */ OQS_STATUS (*verify)(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); + /** + * Query number of remaining signatures + * + * @param[out] remain The number of remaining signatures + * @param[in] secret_key The secret key represented as a byte string. + * @return OQS_SUCCESS or OQS_ERROR + */ + OQS_STATUS (*sigs_remaining)(size_t *remain, const uint8_t *secret_key); + + /** + * Total number of signatures + * + * @param[out] total The total number of signatures + * @param[in] secret_key The secret key represented as a byte string. + * @return OQS_SUCCESS or OQS_ERROR + */ + OQS_STATUS (*sigs_total)(size_t *total, const uint8_t *secret_key); + } OQS_SIG_STFL; /** @@ -183,6 +201,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature */ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +/** + * Query number of remaining signatures + * + * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. + * @param[out] remain The number of remaining signatures + * @param[in] secret_key The secret key represented as a byte string. + * @return OQS_SUCCESS or OQS_ERROR + */ +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, size_t *remain, const uint8_t *secret_key); + +/** + * * Total number of signatures + * + * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. + * @param[out] max The number of remaining signatures + * @param[in] secret_key The secret key represented as a byte string. + * @return OQS_SUCCESS or OQS_ERROR + */ +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, size_t *max, const uint8_t *secret_key); + /** * Frees an OQS_SIG_STFL object that was constructed by OQS_SIG_STFL_new. * diff --git a/src/sig_stfl/xmss/CMakeLists.txt b/src/sig_stfl/xmss/CMakeLists.txt index 896618b167..83bfc2be5e 100644 --- a/src/sig_stfl/xmss/CMakeLists.txt +++ b/src/sig_stfl/xmss/CMakeLists.txt @@ -2,8 +2,20 @@ set(_XMSS_OBJS "") -set(SRCS sig_stfl_xmss_sha256.c -) +set(SRCS external/hash.c + external/hash_address.c + external/params.c + external/utils.c + external/wots.c + external/xmss.c + external/xmss_commons.c + ) + +if (OQS_ENABLE_SIG_STFL_xmss_sha256_h10) + add_compile_definitions(OQS_ENABLE_SIG_STFL_xmss_sha256_h10) + set (SRCS ${SRCS} sig_stfl_xmss_sha256_h10.c external/core_hash.c external/xmss_core.c) +endif() + add_library(xmss OBJECT ${SRCS}) set(_XMSS_OBJS ${_XMSS_OBJS} $) diff --git a/src/sig_stfl/xmss/external/core_hash.c b/src/sig_stfl/xmss/external/core_hash.c new file mode 100644 index 0000000000..5df78cb998 --- /dev/null +++ b/src/sig_stfl/xmss/external/core_hash.c @@ -0,0 +1,14 @@ +#include +#include +#include "hash.h" + +int core_hash(const xmss_params *params, + unsigned char *out, + const unsigned char *in, unsigned long long inlen) +{ +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h10 + (void)params; + OQS_SHA2_sha256(out, in, inlen); + return 0; +#endif +} diff --git a/src/sig_stfl/xmss/external/hash.c b/src/sig_stfl/xmss/external/hash.c new file mode 100644 index 0000000000..c335d7d680 --- /dev/null +++ b/src/sig_stfl/xmss/external/hash.c @@ -0,0 +1,142 @@ +#include +#include + +#include +#include + +#include "hash_address.h" +#include "utils.h" +#include "params.h" +#include "hash.h" + +#define XMSS_HASH_PADDING_F 0 +#define XMSS_HASH_PADDING_H 1 +#define XMSS_HASH_PADDING_HASH 2 +#define XMSS_HASH_PADDING_PRF 3 +#define XMSS_HASH_PADDING_PRF_KEYGEN 4 + +void addr_to_bytes(unsigned char *bytes, const uint32_t addr[8]) +{ + int i; + for (i = 0; i < 8; i++) { + ull_to_bytes(bytes + i*4, 4, addr[i]); + } +} + +/* + * Computes PRF(key, in), for a key of params->n bytes, and a 32-byte input. + */ +int prf(const xmss_params *params, + unsigned char *out, const unsigned char in[32], + const unsigned char *key) +{ + unsigned char buf[params->padding_len + params->n + 32]; + + ull_to_bytes(buf, params->padding_len, XMSS_HASH_PADDING_PRF); + memcpy(buf + params->padding_len, key, params->n); + memcpy(buf + params->padding_len + params->n, in, 32); + + return core_hash(params, out, buf, params->padding_len + params->n + 32); +} + +/* + * Computes PRF_keygen(key, in), for a key of params->n bytes, and an input + * of 32 + params->n bytes + */ +int prf_keygen(const xmss_params *params, + unsigned char *out, const unsigned char *in, + const unsigned char *key) +{ + unsigned char buf[params->padding_len + 2*params->n + 32]; + + ull_to_bytes(buf, params->padding_len, XMSS_HASH_PADDING_PRF_KEYGEN); + memcpy(buf + params->padding_len, key, params->n); + memcpy(buf + params->padding_len + params->n, in, params->n + 32); + + return core_hash(params, out, buf, params->padding_len + 2*params->n + 32); +} + +/* + * Computes the message hash using R, the public root, the index of the leaf + * node, and the message. Notably, it requires m_with_prefix to have 3*n plus + * the length of the padding as free space available before the message, + * to use for the prefix. This is necessary to prevent having to move the + * message around (and thus allocate memory for it). + */ +int hash_message(const xmss_params *params, unsigned char *out, + const unsigned char *R, const unsigned char *root, + unsigned long long idx, + unsigned char *m_with_prefix, unsigned long long mlen) +{ + /* We're creating a hash using input of the form: + toByte(X, 32) || R || root || index || M */ + ull_to_bytes(m_with_prefix, params->padding_len, XMSS_HASH_PADDING_HASH); + memcpy(m_with_prefix + params->padding_len, R, params->n); + memcpy(m_with_prefix + params->padding_len + params->n, root, params->n); + ull_to_bytes(m_with_prefix + params->padding_len + 2*params->n, params->n, idx); + + return core_hash(params, out, m_with_prefix, mlen + params->padding_len + 3*params->n); +} + +/** + * We assume the left half is in in[0]...in[n-1] + */ +int thash_h(const xmss_params *params, + unsigned char *out, const unsigned char *in, + const unsigned char *pub_seed, uint32_t addr[8]) +{ + unsigned char buf[params->padding_len + 3 * params->n]; + unsigned char bitmask[2 * params->n]; + unsigned char addr_as_bytes[32]; + unsigned int i; + + /* Set the function padding. */ + ull_to_bytes(buf, params->padding_len, XMSS_HASH_PADDING_H); + + /* Generate the n-byte key. */ + set_key_and_mask(addr, 0); + addr_to_bytes(addr_as_bytes, addr); + prf(params, buf + params->padding_len, addr_as_bytes, pub_seed); + + /* Generate the 2n-byte mask. */ + set_key_and_mask(addr, 1); + addr_to_bytes(addr_as_bytes, addr); + prf(params, bitmask, addr_as_bytes, pub_seed); + + set_key_and_mask(addr, 2); + addr_to_bytes(addr_as_bytes, addr); + prf(params, bitmask + params->n, addr_as_bytes, pub_seed); + + for (i = 0; i < 2 * params->n; i++) { + buf[params->padding_len + params->n + i] = in[i] ^ bitmask[i]; + } + return core_hash(params, out, buf, params->padding_len + 3 * params->n); +} + +int thash_f(const xmss_params *params, + unsigned char *out, const unsigned char *in, + const unsigned char *pub_seed, uint32_t addr[8]) +{ + unsigned char buf[params->padding_len + 2 * params->n]; + unsigned char bitmask[params->n]; + unsigned char addr_as_bytes[32]; + unsigned int i; + + /* Set the function padding. */ + ull_to_bytes(buf, params->padding_len, XMSS_HASH_PADDING_F); + + /* Generate the n-byte key. */ + set_key_and_mask(addr, 0); + addr_to_bytes(addr_as_bytes, addr); + prf(params, buf + params->padding_len, addr_as_bytes, pub_seed); + + /* Generate the n-byte mask. */ + set_key_and_mask(addr, 1); + addr_to_bytes(addr_as_bytes, addr); + prf(params, bitmask, addr_as_bytes, pub_seed); + + for (i = 0; i < params->n; i++) { + buf[params->padding_len + params->n + i] = in[i] ^ bitmask[i]; + } + return core_hash(params, out, buf, params->padding_len + 2 * params->n); +} diff --git a/src/sig_stfl/xmss/external/hash.h b/src/sig_stfl/xmss/external/hash.h new file mode 100644 index 0000000000..5a3d750b07 --- /dev/null +++ b/src/sig_stfl/xmss/external/hash.h @@ -0,0 +1,47 @@ +#ifndef XMSS_HASH_H +#define XMSS_HASH_H + +#include +#include "params.h" + +#define addr_to_bytes XMSS_INNER_NAMESPACE(addr_to_bytes) +void addr_to_bytes(unsigned char *bytes, const uint32_t addr[8]); + +#define core_hash XMSS_INNER_NAMESPACE(core_hash) +int core_hash(const xmss_params *params, + unsigned char *out, + const unsigned char *in, unsigned long long inlen); + +#define prf XMSS_INNER_NAMESPACE(prf) +int prf(const xmss_params *params, + unsigned char *out, const unsigned char in[32], + const unsigned char *key); + +#define prf_keygen XMSS_INNER_NAMESPACE(prf_keygen) +int prf_keygen(const xmss_params *params, + unsigned char *out, const unsigned char *in, + const unsigned char *key); + +#define h_msg XMSS_INNER_NAMESPACE(h_msg) +int h_msg(const xmss_params *params, + unsigned char *out, + const unsigned char *in, unsigned long long inlen, + const unsigned char *key, const unsigned int keylen); + +#define thash_h XMSS_INNER_NAMESPACE(thash_h) +int thash_h(const xmss_params *params, + unsigned char *out, const unsigned char *in, + const unsigned char *pub_seed, uint32_t addr[8]); + +#define thash_f XMSS_INNER_NAMESPACE(thash_f) +int thash_f(const xmss_params *params, + unsigned char *out, const unsigned char *in, + const unsigned char *pub_seed, uint32_t addr[8]); + +#define hash_message XMSS_INNER_NAMESPACE(hash_message) +int hash_message(const xmss_params *params, unsigned char *out, + const unsigned char *R, const unsigned char *root, + unsigned long long idx, + unsigned char *m_with_prefix, unsigned long long mlen); + +#endif diff --git a/src/sig_stfl/xmss/external/hash_address.c b/src/sig_stfl/xmss/external/hash_address.c new file mode 100644 index 0000000000..7aacee5a58 --- /dev/null +++ b/src/sig_stfl/xmss/external/hash_address.c @@ -0,0 +1,66 @@ +#include +#include "hash_address.h" + +void set_layer_addr(uint32_t addr[8], uint32_t layer) +{ + addr[0] = layer; +} + +void set_tree_addr(uint32_t addr[8], uint64_t tree) +{ + addr[1] = (uint32_t) (tree >> 32); + addr[2] = (uint32_t) tree; +} + +void set_type(uint32_t addr[8], uint32_t type) +{ + addr[3] = type; +} + +void set_key_and_mask(uint32_t addr[8], uint32_t key_and_mask) +{ + addr[7] = key_and_mask; +} + +void copy_subtree_addr(uint32_t out[8], const uint32_t in[8]) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; +} + +/* These functions are used for OTS addresses. */ + +void set_ots_addr(uint32_t addr[8], uint32_t ots) +{ + addr[4] = ots; +} + +void set_chain_addr(uint32_t addr[8], uint32_t chain) +{ + addr[5] = chain; +} + +void set_hash_addr(uint32_t addr[8], uint32_t hash) +{ + addr[6] = hash; +} + +/* This function is used for L-tree addresses. */ + +void set_ltree_addr(uint32_t addr[8], uint32_t ltree) +{ + addr[4] = ltree; +} + +/* These functions are used for hash tree addresses. */ + +void set_tree_height(uint32_t addr[8], uint32_t tree_height) +{ + addr[5] = tree_height; +} + +void set_tree_index(uint32_t addr[8], uint32_t tree_index) +{ + addr[6] = tree_index; +} diff --git a/src/sig_stfl/xmss/external/hash_address.h b/src/sig_stfl/xmss/external/hash_address.h new file mode 100644 index 0000000000..50ad17885e --- /dev/null +++ b/src/sig_stfl/xmss/external/hash_address.h @@ -0,0 +1,48 @@ +#ifndef XMSS_HASH_ADDRESS_H +#define XMSS_HASH_ADDRESS_H + +#include +#include "namespace.h" + +#define XMSS_ADDR_TYPE_OTS 0 +#define XMSS_ADDR_TYPE_LTREE 1 +#define XMSS_ADDR_TYPE_HASHTREE 2 + +#define set_layer_addr XMSS_INNER_NAMESPACE(set_layer_addr) +void set_layer_addr(uint32_t addr[8], uint32_t layer); + +#define set_tree_addr XMSS_INNER_NAMESPACE(set_tree_addr) +void set_tree_addr(uint32_t addr[8], uint64_t tree); + +#define set_type XMSS_INNER_NAMESPACE(set_type) +void set_type(uint32_t addr[8], uint32_t type); + +#define set_key_and_mask XMSS_INNER_NAMESPACE(set_key_and_mask) +void set_key_and_mask(uint32_t addr[8], uint32_t key_and_mask); + +/* Copies the layer and tree part of one address into the other */ +#define copy_subtree_addr XMSS_INNER_NAMESPACE(copy_subtree_addr) +void copy_subtree_addr(uint32_t out[8], const uint32_t in[8]); + +/* These functions are used for OTS addresses. */ +#define set_ots_addr XMSS_INNER_NAMESPACE(set_ots_addr) +void set_ots_addr(uint32_t addr[8], uint32_t ots); + +#define set_chain_addr XMSS_INNER_NAMESPACE(set_chain_addr) +void set_chain_addr(uint32_t addr[8], uint32_t chain); + +#define set_hash_addr XMSS_INNER_NAMESPACE(set_hash_addr) +void set_hash_addr(uint32_t addr[8], uint32_t hash); + +/* This function is used for L-tree addresses. */ +#define set_ltree_addr XMSS_INNER_NAMESPACE(set_ltree_addr) +void set_ltree_addr(uint32_t addr[8], uint32_t ltree); + +/* These functions are used for hash tree addresses. */ +#define set_tree_height XMSS_INNER_NAMESPACE(set_tree_height) +void set_tree_height(uint32_t addr[8], uint32_t tree_height); + +#define set_tree_index XMSS_INNER_NAMESPACE(set_tree_index) +void set_tree_index(uint32_t addr[8], uint32_t tree_index); + +#endif diff --git a/src/sig_stfl/xmss/external/namespace.h b/src/sig_stfl/xmss/external/namespace.h new file mode 100644 index 0000000000..d593a85c53 --- /dev/null +++ b/src/sig_stfl/xmss/external/namespace.h @@ -0,0 +1,14 @@ +#ifndef XMSS_NAMESPACE_H +#define XMSS_NAMESPACE_H + + +#define XMSS_PARAMS oqs_sig_stfl_xmss +#define XMSS_PARAMS_INNER oqs_sig_stfl_xmss_inner + +#define XMSS_NAMESPACE(funcname) XMSS_(XMSS_PARAMS, funcname) +#define XMSS_INNER_NAMESPACE(funcname) XMSS_(XMSS_PARAMS_INNER, funcname) +#define XMSS_(prefix, funcname) XMSS__(prefix, funcname) +#define XMSS__(prefix, funcname) prefix ## _ ## funcname + + +#endif diff --git a/src/sig_stfl/xmss/external/params.c b/src/sig_stfl/xmss/external/params.c new file mode 100644 index 0000000000..fdb9c76f2c --- /dev/null +++ b/src/sig_stfl/xmss/external/params.c @@ -0,0 +1,753 @@ +#include +#include + +#include "params.h" +#include "xmss_core.h" + +int xmss_str_to_oid(uint32_t *oid, const char *s) +{ + if (!strcmp(s, "XMSS-SHA2_10_256")) { + *oid = 0x00000001; + } + else if (!strcmp(s, "XMSS-SHA2_16_256")) { + *oid = 0x00000002; + } + else if (!strcmp(s, "XMSS-SHA2_20_256")) { + *oid = 0x00000003; + } + else if (!strcmp(s, "XMSS-SHA2_10_512")) { + *oid = 0x00000004; + } + else if (!strcmp(s, "XMSS-SHA2_16_512")) { + *oid = 0x00000005; + } + else if (!strcmp(s, "XMSS-SHA2_20_512")) { + *oid = 0x00000006; + } + else if (!strcmp(s, "XMSS-SHAKE_10_256")) { + *oid = 0x00000007; + } + else if (!strcmp(s, "XMSS-SHAKE_16_256")) { + *oid = 0x00000008; + } + else if (!strcmp(s, "XMSS-SHAKE_20_256")) { + *oid = 0x00000009; + } + else if (!strcmp(s, "XMSS-SHAKE_10_512")) { + *oid = 0x0000000a; + } + else if (!strcmp(s, "XMSS-SHAKE_16_512")) { + *oid = 0x0000000b; + } + else if (!strcmp(s, "XMSS-SHAKE_20_512")) { + *oid = 0x0000000c; + } + else if (!strcmp(s, "XMSS-SHA2_10_192")) { + *oid = 0x0000000d; + } + else if (!strcmp(s, "XMSS-SHA2_16_192")) { + *oid = 0x0000000e; + } + else if (!strcmp(s, "XMSS-SHA2_20_192")) { + *oid = 0x0000000f; + } + else if (!strcmp(s, "XMSS-SHAKE256_10_256")) { + *oid = 0x00000010; + } + else if (!strcmp(s, "XMSS-SHAKE256_16_256")) { + *oid = 0x00000011; + } + else if (!strcmp(s, "XMSS-SHAKE256_20_256")) { + *oid = 0x00000012; + } + else if (!strcmp(s, "XMSS-SHAKE256_10_192")) { + *oid = 0x00000013; + } + else if (!strcmp(s, "XMSS-SHAKE256_16_192")) { + *oid = 0x00000014; + } + else if (!strcmp(s, "XMSS-SHAKE256_20_192")) { + *oid = 0x00000015; + } + else { + return -1; + } + return 0; +} + +int xmssmt_str_to_oid(uint32_t *oid, const char *s) +{ + if (!strcmp(s, "XMSSMT-SHA2_20/2_256")) { + *oid = 0x00000001; + } + else if (!strcmp(s, "XMSSMT-SHA2_20/4_256")) { + *oid = 0x00000002; + } + else if (!strcmp(s, "XMSSMT-SHA2_40/2_256")) { + *oid = 0x00000003; + } + else if (!strcmp(s, "XMSSMT-SHA2_40/4_256")) { + *oid = 0x00000004; + } + else if (!strcmp(s, "XMSSMT-SHA2_40/8_256")) { + *oid = 0x00000005; + } + else if (!strcmp(s, "XMSSMT-SHA2_60/3_256")) { + *oid = 0x00000006; + } + else if (!strcmp(s, "XMSSMT-SHA2_60/6_256")) { + *oid = 0x00000007; + } + else if (!strcmp(s, "XMSSMT-SHA2_60/12_256")) { + *oid = 0x00000008; + } + else if (!strcmp(s, "XMSSMT-SHA2_20/2_512")) { + *oid = 0x00000009; + } + else if (!strcmp(s, "XMSSMT-SHA2_20/4_512")) { + *oid = 0x0000000a; + } + else if (!strcmp(s, "XMSSMT-SHA2_40/2_512")) { + *oid = 0x0000000b; + } + else if (!strcmp(s, "XMSSMT-SHA2_40/4_512")) { + *oid = 0x0000000c; + } + else if (!strcmp(s, "XMSSMT-SHA2_40/8_512")) { + *oid = 0x0000000d; + } + else if (!strcmp(s, "XMSSMT-SHA2_60/3_512")) { + *oid = 0x0000000e; + } + else if (!strcmp(s, "XMSSMT-SHA2_60/6_512")) { + *oid = 0x0000000f; + } + else if (!strcmp(s, "XMSSMT-SHA2_60/12_512")) { + *oid = 0x00000010; + } + else if (!strcmp(s, "XMSSMT-SHAKE_20/2_256")) { + *oid = 0x00000011; + } + else if (!strcmp(s, "XMSSMT-SHAKE_20/4_256")) { + *oid = 0x00000012; + } + else if (!strcmp(s, "XMSSMT-SHAKE_40/2_256")) { + *oid = 0x00000013; + } + else if (!strcmp(s, "XMSSMT-SHAKE_40/4_256")) { + *oid = 0x00000014; + } + else if (!strcmp(s, "XMSSMT-SHAKE_40/8_256")) { + *oid = 0x00000015; + } + else if (!strcmp(s, "XMSSMT-SHAKE_60/3_256")) { + *oid = 0x00000016; + } + else if (!strcmp(s, "XMSSMT-SHAKE_60/6_256")) { + *oid = 0x00000017; + } + else if (!strcmp(s, "XMSSMT-SHAKE_60/12_256")) { + *oid = 0x00000018; + } + else if (!strcmp(s, "XMSSMT-SHAKE_20/2_512")) { + *oid = 0x00000019; + } + else if (!strcmp(s, "XMSSMT-SHAKE_20/4_512")) { + *oid = 0x0000001a; + } + else if (!strcmp(s, "XMSSMT-SHAKE_40/2_512")) { + *oid = 0x0000001b; + } + else if (!strcmp(s, "XMSSMT-SHAKE_40/4_512")) { + *oid = 0x0000001c; + } + else if (!strcmp(s, "XMSSMT-SHAKE_40/8_512")) { + *oid = 0x0000001d; + } + else if (!strcmp(s, "XMSSMT-SHAKE_60/3_512")) { + *oid = 0x0000001e; + } + else if (!strcmp(s, "XMSSMT-SHAKE_60/6_512")) { + *oid = 0x0000001f; + } + else if (!strcmp(s, "XMSSMT-SHAKE_60/12_512")) { + *oid = 0x00000020; + } + else if (!strcmp(s, "XMSSMT-SHA2_20/2_192")) { + *oid = 0x00000021; + } + else if (!strcmp(s, "XMSSMT-SHA2_20/4_192")) { + *oid = 0x00000022; + } + else if (!strcmp(s, "XMSSMT-SHA2_40/2_192")) { + *oid = 0x00000023; + } + else if (!strcmp(s, "XMSSMT-SHA2_40/4_192")) { + *oid = 0x00000024; + } + else if (!strcmp(s, "XMSSMT-SHA2_40/8_192")) { + *oid = 0x00000025; + } + else if (!strcmp(s, "XMSSMT-SHA2_60/3_192")) { + *oid = 0x00000026; + } + else if (!strcmp(s, "XMSSMT-SHA2_60/6_192")) { + *oid = 0x00000027; + } + else if (!strcmp(s, "XMSSMT-SHA2_60/12_192")) { + *oid = 0x00000028; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_20/2_256")) { + *oid = 0x00000029; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_20/4_256")) { + *oid = 0x0000002a; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_40/2_256")) { + *oid = 0x0000002b; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_40/4_256")) { + *oid = 0x0000002c; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_40/8_256")) { + *oid = 0x0000002d; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_60/3_256")) { + *oid = 0x0000002e; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_60/6_256")) { + *oid = 0x0000002f; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_60/12_256")) { + *oid = 0x00000030; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_20/2_192")) { + *oid = 0x00000031; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_20/4_192")) { + *oid = 0x00000032; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_40/2_192")) { + *oid = 0x00000033; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_40/4_192")) { + *oid = 0x00000034; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_40/8_192")) { + *oid = 0x00000035; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_60/3_192")) { + *oid = 0x00000036; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_60/6_192")) { + *oid = 0x00000037; + } + else if (!strcmp(s, "XMSSMT-SHAKE256_60/12_192")) { + *oid = 0x00000038; + } + else { + return -1; + } + return 0; +} + +int xmss_parse_oid(xmss_params *params, const uint32_t oid) +{ + switch (oid) { + case 0x00000001: + case 0x00000002: + case 0x00000003: + case 0x00000004: + case 0x00000005: + case 0x00000006: + + case 0x0000000d: + case 0x0000000e: + case 0x0000000f: + params->func = XMSS_SHA2; + break; + + case 0x00000007: + case 0x00000008: + case 0x00000009: + params->func = XMSS_SHAKE128; + break; + + case 0x0000000a: + case 0x0000000b: + case 0x0000000c: + + case 0x00000010: + case 0x00000011: + case 0x00000012: + case 0x00000013: + case 0x00000014: + case 0x00000015: + params->func = XMSS_SHAKE256; + break; + + default: + return -1; + } + switch (oid) { + case 0x0000000d: + case 0x0000000e: + case 0x0000000f: + + case 0x00000013: + case 0x00000014: + case 0x00000015: + params->n = 24; + params->padding_len = 4; + break; + + case 0x00000001: + case 0x00000002: + case 0x00000003: + + case 0x00000007: + case 0x00000008: + case 0x00000009: + + case 0x00000010: + case 0x00000011: + case 0x00000012: + params->n = 32; + params->padding_len = 32; + break; + + case 0x00000004: + case 0x00000005: + case 0x00000006: + + case 0x0000000a: + case 0x0000000b: + case 0x0000000c: + params->n = 64; + params->padding_len = 64; + break; + + default: + return -1; + } + switch (oid) { + case 0x00000001: + case 0x00000004: + case 0x00000007: + case 0x0000000a: + case 0x0000000d: + case 0x00000010: + case 0x00000013: + params->full_height = 10; + break; + + case 0x00000002: + case 0x00000005: + case 0x00000008: + case 0x0000000b: + case 0x0000000e: + case 0x00000011: + case 0x00000014: + params->full_height = 16; + break; + + case 0x00000003: + case 0x00000006: + case 0x00000009: + case 0x0000000c: + case 0x0000000f: + case 0x00000012: + case 0x00000015: + params->full_height = 20; + + break; + default: + return -1; + } + + params->d = 1; + params->wots_w = 16; + + // TODO figure out sensible and legal values for this based on the above + params->bds_k = 0; + + return xmss_xmssmt_initialize_params(params); +} + +int xmssmt_parse_oid(xmss_params *params, const uint32_t oid) +{ + switch (oid) { + case 0x00000001: + case 0x00000002: + case 0x00000003: + case 0x00000004: + case 0x00000005: + case 0x00000006: + case 0x00000007: + case 0x00000008: + case 0x00000009: + case 0x0000000a: + case 0x0000000b: + case 0x0000000c: + case 0x0000000d: + case 0x0000000e: + case 0x0000000f: + case 0x00000010: + + case 0x00000021: + case 0x00000022: + case 0x00000023: + case 0x00000024: + case 0x00000025: + case 0x00000026: + case 0x00000027: + case 0x00000028: + params->func = XMSS_SHA2; + break; + + case 0x00000011: + case 0x00000012: + case 0x00000013: + case 0x00000014: + case 0x00000015: + case 0x00000016: + case 0x00000017: + case 0x00000018: + params->func = XMSS_SHAKE128; + break; + + case 0x00000019: + case 0x0000001a: + case 0x0000001b: + case 0x0000001c: + case 0x0000001e: + case 0x0000001d: + case 0x0000001f: + case 0x00000020: + + case 0x00000029: + case 0x0000002a: + case 0x0000002b: + case 0x0000002c: + case 0x0000002d: + case 0x0000002e: + case 0x0000002f: + case 0x00000030: + case 0x00000031: + case 0x00000032: + case 0x00000033: + case 0x00000034: + case 0x00000035: + case 0x00000036: + case 0x00000037: + case 0x00000038: + params->func = XMSS_SHAKE256; + break; + + default: + return -1; + } + switch (oid) { + case 0x00000021: + case 0x00000022: + case 0x00000023: + case 0x00000024: + case 0x00000025: + case 0x00000026: + case 0x00000027: + case 0x00000028: + + case 0x00000031: + case 0x00000032: + case 0x00000033: + case 0x00000034: + case 0x00000035: + case 0x00000036: + case 0x00000037: + case 0x00000038: + params->n = 24; + params->padding_len = 4; + break; + + case 0x00000001: + case 0x00000002: + case 0x00000003: + case 0x00000004: + case 0x00000005: + case 0x00000006: + case 0x00000007: + case 0x00000008: + + case 0x00000011: + case 0x00000012: + case 0x00000013: + case 0x00000014: + case 0x00000015: + case 0x00000016: + case 0x00000017: + case 0x00000018: + + case 0x00000029: + case 0x0000002a: + case 0x0000002b: + case 0x0000002c: + case 0x0000002d: + case 0x0000002e: + case 0x0000002f: + case 0x00000030: + params->n = 32; + params->padding_len = 32; + break; + + case 0x00000009: + case 0x0000000a: + case 0x0000000b: + case 0x0000000c: + case 0x0000000d: + case 0x0000000e: + case 0x0000000f: + case 0x00000010: + + case 0x00000019: + case 0x0000001a: + case 0x0000001b: + case 0x0000001c: + case 0x0000001d: + case 0x0000001e: + case 0x0000001f: + case 0x00000020: + params->n = 64; + params->padding_len = 64; + break; + + default: + return -1; + } + switch (oid) { + case 0x00000001: + case 0x00000002: + + case 0x00000009: + case 0x0000000a: + + case 0x00000011: + case 0x00000012: + + case 0x00000019: + case 0x0000001a: + + case 0x00000021: + case 0x00000022: + + case 0x00000029: + case 0x0000002a: + + case 0x00000031: + case 0x00000032: + params->full_height = 20; + break; + + case 0x00000003: + case 0x00000004: + case 0x00000005: + + case 0x0000000b: + case 0x0000000c: + case 0x0000000d: + + case 0x00000013: + case 0x00000014: + case 0x00000015: + + case 0x0000001b: + case 0x0000001c: + case 0x0000001d: + + case 0x00000023: + case 0x00000024: + case 0x00000025: + + case 0x0000002b: + case 0x0000002c: + case 0x0000002d: + + case 0x00000033: + case 0x00000034: + case 0x00000035: + params->full_height = 40; + break; + + case 0x00000006: + case 0x00000007: + case 0x00000008: + + case 0x0000000e: + case 0x0000000f: + case 0x00000010: + + case 0x00000016: + case 0x00000017: + case 0x00000018: + + case 0x0000001e: + case 0x0000001f: + case 0x00000020: + + case 0x00000026: + case 0x00000027: + case 0x00000028: + + case 0x0000002e: + case 0x0000002f: + case 0x00000030: + + case 0x00000036: + case 0x00000037: + case 0x00000038: + params->full_height = 60; + break; + + default: + return -1; + } + switch (oid) { + case 0x00000001: + case 0x00000003: + case 0x00000009: + case 0x0000000b: + case 0x00000011: + case 0x00000013: + case 0x00000019: + case 0x0000001b: + case 0x00000021: + case 0x00000023: + case 0x00000029: + case 0x0000002b: + case 0x00000031: + case 0x00000033: + params->d = 2; + break; + + case 0x00000002: + case 0x00000004: + case 0x0000000a: + case 0x0000000c: + case 0x00000012: + case 0x00000014: + case 0x0000001a: + case 0x0000001c: + case 0x00000022: + case 0x00000024: + case 0x0000002a: + case 0x0000002c: + case 0x00000032: + case 0x00000034: + params->d = 4; + break; + + case 0x00000005: + case 0x0000000d: + case 0x00000015: + case 0x0000001d: + case 0x00000025: + case 0x0000002d: + case 0x00000035: + params->d = 8; + break; + + case 0x00000006: + case 0x0000000e: + case 0x00000016: + case 0x0000001e: + case 0x00000026: + case 0x0000002e: + case 0x00000036: + params->d = 3; + break; + + case 0x00000007: + case 0x0000000f: + case 0x00000017: + case 0x0000001f: + case 0x00000027: + case 0x0000002f: + case 0x00000037: + params->d = 6; + break; + + case 0x00000008: + case 0x00000010: + case 0x00000018: + case 0x00000020: + case 0x00000028: + case 0x00000030: + case 0x00000038: + params->d = 12; + break; + + default: + return -1; + } + + params->wots_w = 16; + + // TODO figure out sensible and legal values for this based on the above + params->bds_k = 0; + + return xmss_xmssmt_initialize_params(params); +} + +/** + * Given a params struct where the following properties have been initialized; + * - full_height; the height of the complete (hyper)tree + * - n; the number of bytes of hash function output + * - d; the number of layers (d > 1 implies XMSSMT) + * - func; one of {XMSS_SHA2, XMSS_SHAKE128, XMSS_SHAKE256} + * - wots_w; the Winternitz parameter + * - optionally, bds_k; the BDS traversal trade-off parameter, + * this function initializes the remainder of the params structure. + */ +int xmss_xmssmt_initialize_params(xmss_params *params) +{ + params->tree_height = params->full_height / params->d; + if (params->wots_w == 4) { + params->wots_log_w = 2; + params->wots_len1 = 8 * params->n / params->wots_log_w; + /* len_2 = floor(log(len_1 * (w - 1)) / log(w)) + 1 */ + params->wots_len2 = 5; + } + else if (params->wots_w == 16) { + params->wots_log_w = 4; + params->wots_len1 = 8 * params->n / params->wots_log_w; + /* len_2 = floor(log(len_1 * (w - 1)) / log(w)) + 1 */ + params->wots_len2 = 3; + } + else if (params->wots_w == 256) { + params->wots_log_w = 8; + params->wots_len1 = 8 * params->n / params->wots_log_w; + /* len_2 = floor(log(len_1 * (w - 1)) / log(w)) + 1 */ + params->wots_len2 = 2; + } + else { + return -1; + } + params->wots_len = params->wots_len1 + params->wots_len2; + params->wots_sig_bytes = params->wots_len * params->n; + + if (params->d == 1) { // Assume this is XMSS, not XMSS^MT + /* In XMSS, always use fixed 4 bytes for index_bytes */ + params->index_bytes = 4; + } + else { + /* In XMSS^MT, round index_bytes up to nearest byte. */ + params->index_bytes = (params->full_height + 7) / 8; + } + params->sig_bytes = (params->index_bytes + params->n + + params->d * params->wots_sig_bytes + + params->full_height * params->n); + + params->pk_bytes = 2 * params->n; + params->sk_bytes = xmss_xmssmt_core_sk_bytes(params); + + return 0; +} diff --git a/src/sig_stfl/xmss/external/params.h b/src/sig_stfl/xmss/external/params.h new file mode 100644 index 0000000000..59b86d3da6 --- /dev/null +++ b/src/sig_stfl/xmss/external/params.h @@ -0,0 +1,78 @@ +#ifndef XMSS_PARAMS_H +#define XMSS_PARAMS_H + +#include +#include "namespace.h" + +/* These are merely internal identifiers for the supported hash functions. */ +#define XMSS_SHA2 0 +#define XMSS_SHAKE128 1 +#define XMSS_SHAKE256 2 + +/* This is a result of the OID definitions in the draft; needed for parsing. */ +#define XMSS_OID_LEN 4 + +/* This structure will be populated when calling xmss[mt]_parse_oid. */ +typedef struct { + unsigned int func; + unsigned int n; + unsigned int padding_len; + unsigned int wots_w; + unsigned int wots_log_w; + unsigned int wots_len1; + unsigned int wots_len2; + unsigned int wots_len; + unsigned int wots_sig_bytes; + unsigned int full_height; + unsigned int tree_height; + unsigned int d; + unsigned int index_bytes; + unsigned int sig_bytes; + unsigned int pk_bytes; + unsigned long long sk_bytes; + unsigned int bds_k; +} xmss_params; + +/** + * Accepts strings such as "XMSS-SHA2_10_256" + * and outputs OIDs such as 0x01000001. + * Returns -1 when the parameter set is not found, 0 otherwise + */ +#define xmss_str_to_oid XMSS_NAMESPACE(xmss_str_to_oid) +int xmss_str_to_oid(uint32_t *oid, const char *s); + +/** + * Accepts takes strings such as "XMSSMT-SHA2_20/2_256" + * and outputs OIDs such as 0x01000001. + * Returns -1 when the parameter set is not found, 0 otherwise + */ +#define xmssmt_str_to_oid XMSS_NAMESPACE(xmssmt_str_to_oid) +int xmssmt_str_to_oid(uint32_t *oid, const char *s); + +/** + * Accepts OIDs such as 0x01000001, and configures params accordingly. + * Returns -1 when the OID is not found, 0 otherwise. + */ +#define xmss_parse_oid XMSS_NAMESPACE(xmss_parse_oid) +int xmss_parse_oid(xmss_params *params, const uint32_t oid); + +/** + * Accepts OIDs such as 0x01000001, and configures params accordingly. + * Returns -1 when the OID is not found, 0 otherwise. + */ +#define xmssmt_parse_oid XMSS_NAMESPACE(xmssmt_parse_oid) +int xmssmt_parse_oid(xmss_params *params, const uint32_t oid); + + +/* Given a params struct where the following properties have been initialized; + - full_height; the height of the complete (hyper)tree + - n; the number of bytes of hash function output + - d; the number of layers (d > 1 implies XMSSMT) + - func; one of {XMSS_SHA2, XMSS_SHAKE128, XMSS_SHAKE256} + - wots_w; the Winternitz parameter + - optionally, bds_k; the BDS traversal trade-off parameter, + this function initializes the remainder of the params structure. */ +#define xmss_xmssmt_initialize_params XMSS_NAMESPACE(xmss_xmssmt_initialize_params) +int xmss_xmssmt_initialize_params(xmss_params *params); + +#endif diff --git a/src/sig_stfl/xmss/external/sign.c b/src/sig_stfl/xmss/external/sign.c new file mode 100644 index 0000000000..8bffc7f516 --- /dev/null +++ b/src/sig_stfl/xmss/external/sign.c @@ -0,0 +1,139 @@ +/*============================================================================= + * Copyright (c) 2022 by SandboxAQ Inc + * Author: Duc Tri Nguyen (ductri.nguyen@sandboxaq.com) + * SPDX-License-Identifier: MIT +=============================================================================*/ +#include +#include + +#include "sign.h" +#include "sign_params.h" + +/************************************************* + * Name: XMSS_crypto_sign_keypair + * + * Description: Generates public and private key. + * + * Arguments: - uint8_t *pk: pointer to output public key (allocated + * array of CRYPTO_PUBLICKEYBYTES bytes) + * - uint8_t *sk: pointer to output private key (allocated + * array of CRYPTO_SECRETKEYBYTES bytes) + * + * Returns 0 (success), -1 otherwise + **************************************************/ +int crypto_sign_keypair(unsigned char *pk, unsigned char *sk) +{ + xmss_params params; + uint32_t oid; + int ret = 0; + + ret |= XMSS_STR_TO_OID(&oid, XMSS_OID); + if (ret) + { + return OQS_ERROR; + } + + ret |= XMSS_PARSE_OID(¶ms, oid); + if (ret) + { + return OQS_ERROR; + } + + // TODO: set OID directly here + ret |= XMSS_KEYPAIR(pk, sk, oid); + if (ret) + { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +/************************************************* + * Name: XMSS_crypto_sign + * + * Description: Computes signature. + * + * Arguments: - uint8_t *sm: pointer to output signature (of length CRYPTO_BYTES) + * - uint64_t *smlen: pointer to output length of signature + * - uint8_t *m: pointer to message to be signed + * - uint64_t mlen: length of message + * - uint8_t *sk: pointer to bit-packed secret key + * + * Returns 0 (success), -1 otherwise + **************************************************/ +int crypto_sign(unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen, unsigned char *sk) +{ + int ret = XMSS_SIGN(sk, sm, smlen, m, mlen); + if (ret) + { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +/************************************************* + * Name: XMSS_crypto_sign_open + * + * Description: Verify signed message. + * + * Arguments: + * - uint8_t *m: pointer to output message (allocated + * array with smlen bytes), can be equal to sm + * - uint64_t *mlen: pointer to output length of message + * - uint8_t *sm: pointer to signed message + * - uint64_t smlen: length of signed message + * - uint8_t *pk: pointer to bit-packed public key + * + * Returns 0 if signed message could be verified correctly and -1 otherwise + **************************************************/ +int crypto_sign_open(const unsigned char *m, unsigned long long mlen, + const unsigned char *sm, unsigned long long smlen, const unsigned char *pk) +{ + if (XMSS_SIGN_OPEN(m, mlen, sm, smlen, pk)) + { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +/************************************************* + * Name: XMSS_crypto_remaining_signatures + * + * Description: Return number of remaining signatures + * + * Arguments: - uint64_t *remain: remaining signatures + * - uint8_t *sk: pointer to bit-packed private key + * + * Returns 0 (sucess), -1 otherwise + **************************************************/ +int crypto_remaining_signatures(unsigned long long *remain, const unsigned char *sk) +{ + if (XMSS_REMAINING_SIG(remain, sk)) + { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +/************************************************* + * Name: XMSS_crypto_total_signatures + * + * Description: Return number of total signatures + * + * Arguments: - uint64_t *max: maximum number of signatures + * - uint8_t *sk: pointer to bit-packed private key + * + * Returns 0 (sucess), -1 otherwise + **************************************************/ +int crypto_total_signatures(unsigned long long *max, const unsigned char *sk) +{ + if (XMSS_TOTAL_SIG(max, sk)) + { + return OQS_ERROR; + } + return OQS_SUCCESS; +} diff --git a/src/sig_stfl/xmss/external/sign.h b/src/sig_stfl/xmss/external/sign.h new file mode 100644 index 0000000000..df2c2fb7ca --- /dev/null +++ b/src/sig_stfl/xmss/external/sign.h @@ -0,0 +1,90 @@ +/*============================================================================= + * Copyright (c) 2022 by SandboxAQ Inc + * Author: Duc Tri Nguyen (ductri.nguyen@sandboxaq.com) + * SPDX-License-Identifier: MIT +=============================================================================*/ +#ifndef API_H +#define API_H + +#include +#include "namespace.h" +/************************************************* + * Name: XMSS_crypto_sign_keypair + * + * Description: Generates public and private key. + * + * Arguments: - uint8_t *pk: pointer to output public key (allocated + * array of CRYPTO_PUBLICKEYBYTES bytes) + * - uint8_t *sk: pointer to output private key (allocated + * array of CRYPTO_SECRETKEYBYTES bytes) + * + * Returns 0 (success), -1 otherwise + **************************************************/ +#define crypto_sign_keypair XMSS_NAMESPACE(crypto_sign_keypair) +int crypto_sign_keypair(unsigned char *pk, unsigned char *sk); + +/************************************************* + * Name: XMSS_crypto_sign + * + * Description: Computes signature. + * + * Arguments: - uint8_t *sm: pointer to output signature (of length CRYPTO_BYTES) + * - uint64_t *smlen: pointer to output length of signature + * - uint8_t *m: pointer to message to be signed + * - uint64_t mlen: length of message + * - uint8_t *sk: pointer to bit-packed secret key + * + * Returns 0 (success), -1 otherwise + **************************************************/ +#define crypto_sign XMSS_NAMESPACE(crypto_sign) +int crypto_sign(unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen, unsigned char *sk); + +/************************************************* + * Name: XMSS_crypto_sign_open + * + * Description: Verify signed message. + * + * Arguments: + * - uint8_t *m: pointer to output message (allocated + * array with smlen bytes), can be equal to sm + * - uint64_t *mlen: pointer to output length of message + * - uint8_t *sm: pointer to signed message + * - uint64_t smlen: length of signed message + * - uint8_t *pk: pointer to bit-packed public key + * + * Returns 0 if signed message could be verified correctly and -1 otherwise + **************************************************/ +#define crypto_sign_open XMSS_NAMESPACE(crypto_sign_open) +int crypto_sign_open(const unsigned char *m, unsigned long long mlen, + const unsigned char *sm, unsigned long long smlen, const unsigned char *pk); + +/************************************************* + * Name: XMSS_crypto_remaining_signatures + * + * Description: Return number of signatures left + * + * Arguments: - uint64_t *remain: remaining signatures + * - uint8_t *sk: pointer to bit-packed private key + * + * Returns 0 (sucess), -1 otherwise + **************************************************/ +#define crypto_remaining_signatures XMSS_NAMESPACE(crypto_remaining_signatures) +int crypto_remaining_signatures(unsigned long long *remain, const unsigned char *sk); + + +/************************************************* + * Name: XMSS_crypto_total_signatures + * + * Description: Return number of total signatures + * + * Arguments: - uint64_t *max: maximum number of signatures + * - uint8_t *sk: pointer to bit-packed private key + * + * Returns 0 (sucess), -1 otherwise + **************************************************/ +#define crypto_total_signatures XMSS_NAMESPACE(crypto_total_signatures) +int crypto_total_signatures(unsigned long long *max, const unsigned char *sk); + +#endif + diff --git a/src/sig_stfl/xmss/external/sign_params.h b/src/sig_stfl/xmss/external/sign_params.h new file mode 100644 index 0000000000..d9dce53e42 --- /dev/null +++ b/src/sig_stfl/xmss/external/sign_params.h @@ -0,0 +1,142 @@ +#ifndef NIST_PARAM_H +#define NIST_PARAM_H + +#include "params.h" +#include "xmss.h" + +#ifndef TREE_LEVEL +#define TREE_LEVEL 0 +#endif + +#ifndef XMSSMT +#define XMSSMT 0 +#endif + +#if XMSSMT == 0 + /* + * Maximum signatures: 2^h - 1 = 2^10 - 1 + */ + #if TREE_LEVEL == 0 + + #define XMSS_OID "XMSS-SHA2_10_256" + + #define XMSS_PUBLICKEYBYTES 64 + #define XMSS_SECRETKEYBYTES_SMALL 132 + #define XMSS_SECRETKEYBYTES 1373 + + #define XMSS_SIGNBYTES 2500 + + /* + * Maximum signatures: 2^h - 1 = 2^16 - 1 + */ + #elif TREE_LEVEL == 1 + + #define XMSS_OID "XMSS-SHA2_16_256" + + #define XMSS_PUBLICKEYBYTES 64 + #define XMSS_SECRETKEYBYTES_SMALL 132 + #define XMSS_SECRETKEYBYTES 2093 + + #define XMSS_SIGNBYTES 2692 + + /* + * Maximum signatures: 2^h - 1 = 2^20 - 1 + */ + #elif TREE_LEVEL == 2 + + #define XMSS_OID "XMSS-SHA2_20_256" + + #define XMSS_PUBLICKEYBYTES 64 + #define XMSS_SECRETKEYBYTES_SMALL 132 + #define XMSS_SECRETKEYBYTES 2573 + + #define XMSS_SIGNBYTES 2820 + + + #else + + #error "Unspecified TREE_LEVEL {0,1,2}" + + #endif +#else + /* + * Maximum signatures: 2^h - 1 = 2^20 - 1 + * XMSS^MT has bigger signature and secret key (secret is not transfer), but better speed + */ + #if TREE_LEVEL == 0 + + #define XMSS_OID "XMSSMT-SHA2_20/2_256" + + #define XMSS_PUBLICKEYBYTES 64 + #define XMSS_SECRETKEYBYTES_SMALL 131 + #define XMSS_SECRETKEYBYTES 5998 + + #define XMSS_SIGNBYTES 4963 + + /* + * Maximum signatures: 2^h - 1 = 2^40 - 1 + * XMSS^MT has bigger signature and secret key (secret is not transfer), but better speed + */ + #elif TREE_LEVEL == 1 + + #define XMSS_OID "XMSSMT-SHA2_40/2_256" + + #define XMSS_PUBLICKEYBYTES 64 + #define XMSS_SECRETKEYBYTES_SMALL 133 + #define XMSS_SECRETKEYBYTES 9600 + + #define XMSS_SIGNBYTES 5605 + + /* + * Maximum signatures: 2^h - 1 = 2^60 - 1 + * XMSS^MT has bigger signature and secret key (secret is not transfer), but better speed + */ + #elif TREE_LEVEL == 2 + + #define XMSS_OID "XMSSMT-SHA2_60/3_256" + + #define XMSS_PUBLICKEYBYTES 64 + #define XMSS_SECRETKEYBYTES_SMALL 136 + #define XMSS_SECRETKEYBYTES 16629 + + #define XMSS_SIGNBYTES 8392 + + + #else + + #error "Unspecified TREE_LEVEL {0,1,2}" + + #endif + +#endif + +#if XMSSMT == 1 + #define XMSS_PARSE_OID xmssmt_parse_oid + #define XMSS_STR_TO_OID xmssmt_str_to_oid + #define XMSS_KEYPAIR xmssmt_keypair + #define XMSS_SIGN xmssmt_sign + #define XMSS_SIGN_OPEN xmssmt_sign_open + #define XMSS_REMAINING_SIG xmssmt_remaining_signatures + #define XMSS_TOTAL_SIG xmssmt_total_signatures +#else + #define XMSS_PARSE_OID xmss_parse_oid + #define XMSS_STR_TO_OID xmss_str_to_oid + #define XMSS_KEYPAIR xmss_keypair + #define XMSS_SIGN xmss_sign + #define XMSS_SIGN_OPEN xmss_sign_open + #define XMSS_REMAINING_SIG xmss_remaining_signatures + #define XMSS_TOTAL_SIG xmss_total_signatures +#endif + +#if XMSS_SECRETKEYBYTES_SMALL_ENABLE +#define CRYPTO_SECRETKEYBYTES (XMSS_SECRETKEYBYTES_SMALL + XMSS_OID_LEN) +#define CRYPTO_ALGNAME XMSS_OID +#else +#define CRYPTO_SECRETKEYBYTES (XMSS_SECRETKEYBYTES + XMSS_OID_LEN) +#define CRYPTO_ALGNAME (XMSS_OID "_fast") +#endif + +#define CRYPTO_PUBLICKEYBYTES (XMSS_PUBLICKEYBYTES + XMSS_OID_LEN) +#define CRYPTO_BYTES XMSS_SIGNBYTES + +#endif diff --git a/src/sig_stfl/xmss/external/utils.c b/src/sig_stfl/xmss/external/utils.c new file mode 100644 index 0000000000..855f63654d --- /dev/null +++ b/src/sig_stfl/xmss/external/utils.c @@ -0,0 +1,30 @@ +#include "utils.h" + +/** + * Converts the value of 'in' to 'outlen' bytes in big-endian byte order. + */ +void ull_to_bytes(unsigned char *out, unsigned int outlen, + unsigned long long in) +{ + int i; + + /* Iterate over out in decreasing order, for big-endianness. */ + for (i = outlen - 1; i >= 0; i--) { + out[i] = in & 0xff; + in = in >> 8; + } +} + +/** + * Converts the inlen bytes in 'in' from big-endian byte order to an integer. + */ +unsigned long long bytes_to_ull(const unsigned char *in, unsigned int inlen) +{ + unsigned long long retval = 0; + unsigned int i; + + for (i = 0; i < inlen; i++) { + retval |= ((unsigned long long)in[i]) << (8*(inlen - 1 - i)); + } + return retval; +} diff --git a/src/sig_stfl/xmss/external/utils.h b/src/sig_stfl/xmss/external/utils.h new file mode 100644 index 0000000000..0cdf79475a --- /dev/null +++ b/src/sig_stfl/xmss/external/utils.h @@ -0,0 +1,19 @@ +#ifndef XMSS_UTILS_H +#define XMSS_UTILS_H + +#include "namespace.h" + +/** + * Converts the value of 'in' to 'outlen' bytes in big-endian byte order. + */ +#define ull_to_bytes XMSS_INNER_NAMESPACE(ull_to_bytes) +void ull_to_bytes(unsigned char *out, unsigned int outlen, + unsigned long long in); + +/** + * Converts the inlen bytes in 'in' from big-endian byte order to an integer. + */ +#define bytes_to_ull XMSS_INNER_NAMESPACE(bytes_to_ull) +unsigned long long bytes_to_ull(const unsigned char *in, unsigned int inlen); + +#endif diff --git a/src/sig_stfl/xmss/external/wots.c b/src/sig_stfl/xmss/external/wots.c new file mode 100644 index 0000000000..90a6bd74d0 --- /dev/null +++ b/src/sig_stfl/xmss/external/wots.c @@ -0,0 +1,180 @@ +#include +#include + +#include "utils.h" +#include "hash.h" +#include "wots.h" +#include "hash_address.h" +#include "params.h" + +/** + * Helper method for pseudorandom key generation. + * Expands an n-byte array into a len*n byte array using the `prf_keygen` function. + */ +static void expand_seed(const xmss_params *params, + unsigned char *outseeds, const unsigned char *inseed, + const unsigned char *pub_seed, uint32_t addr[8]) +{ + unsigned int i; + unsigned char buf[params->n + 32]; + + set_hash_addr(addr, 0); + set_key_and_mask(addr, 0); + memcpy(buf, pub_seed, params->n); + for (i = 0; i < params->wots_len; i++) { + set_chain_addr(addr, i); + addr_to_bytes(buf + params->n, addr); + prf_keygen(params, outseeds + i*params->n, buf, inseed); + } +} + +/** + * Computes the chaining function. + * out and in have to be n-byte arrays. + * + * Interprets in as start-th value of the chain. + * addr has to contain the address of the chain. + */ +static void gen_chain(const xmss_params *params, + unsigned char *out, const unsigned char *in, + unsigned int start, unsigned int steps, + const unsigned char *pub_seed, uint32_t addr[8]) +{ + unsigned int i; + + /* Initialize out with the value at position 'start'. */ + memcpy(out, in, params->n); + + /* Iterate 'steps' calls to the hash function. */ + for (i = start; i < (start+steps) && i < params->wots_w; i++) { + set_hash_addr(addr, i); + thash_f(params, out, out, pub_seed, addr); + } +} + +/** + * base_w algorithm as described in draft. + * Interprets an array of bytes as integers in base w. + * This only works when log_w is a divisor of 8. + */ +static void base_w(const xmss_params *params, + unsigned int *output, const unsigned int out_len, const unsigned char *input) +{ + unsigned int in = 0; + unsigned int out = 0; + unsigned char total; + unsigned int bits = 0; + unsigned int consumed; + + for (consumed = 0; consumed < out_len; consumed++) { + if (bits == 0) { + total = input[in]; + in++; + bits += 8; + } + bits -= params->wots_log_w; + output[out] = (total >> bits) & (params->wots_w - 1); + out++; + } +} + +/* Computes the WOTS+ checksum over a message (in base_w). */ +static void wots_checksum(const xmss_params *params, + unsigned int *csum_base_w, const unsigned int *msg_base_w) +{ + int csum = 0; + unsigned char csum_bytes[(params->wots_len2 * params->wots_log_w + 7) / 8]; + unsigned int i; + + /* Compute checksum. */ + for (i = 0; i < params->wots_len1; i++) { + csum += params->wots_w - 1 - msg_base_w[i]; + } + + /* Convert checksum to base_w. */ + /* Make sure expected empty zero bits are the least significant bits. */ + csum = csum << (8 - ((params->wots_len2 * params->wots_log_w) % 8)); + ull_to_bytes(csum_bytes, sizeof(csum_bytes), csum); + base_w(params, csum_base_w, params->wots_len2, csum_bytes); +} + +/* Takes a message and derives the matching chain lengths. */ +static void chain_lengths(const xmss_params *params, + unsigned int *lengths, const unsigned char *msg) +{ + base_w(params, lengths, params->wots_len1, msg); + wots_checksum(params, lengths + params->wots_len1, lengths); +} + +/** + * WOTS key generation. Takes a 32 byte seed for the private key, expands it to + * a full WOTS private key and computes the corresponding public key. + * It requires the seed pub_seed (used to generate bitmasks and hash keys) + * and the address of this WOTS key pair. + * + * Writes the computed public key to 'pk'. + */ +void wots_pkgen(const xmss_params *params, + unsigned char *pk, const unsigned char *seed, + const unsigned char *pub_seed, uint32_t addr[8]) +{ + unsigned int i; + + /* The WOTS+ private key is derived from the seed. */ + expand_seed(params, pk, seed, pub_seed, addr); + + for (i = 0; i < params->wots_len; i++) { + set_chain_addr(addr, i); + gen_chain(params, pk + i*params->n, pk + i*params->n, + 0, params->wots_w - 1, pub_seed, addr); + } +} + +/** + * Takes a n-byte message and the 32-byte seed for the private key to compute a + * signature that is placed at 'sig'. + */ +void wots_sign(const xmss_params *params, + unsigned char *sig, const unsigned char *msg, + const unsigned char *seed, const unsigned char *pub_seed, + uint32_t addr[8]) +{ + unsigned int lengths[params->wots_len]; + unsigned int i; + + memset(lengths, 0, sizeof(unsigned int)*params->wots_len); + + chain_lengths(params, lengths, msg); + + /* The WOTS+ private key is derived from the seed. */ + expand_seed(params, sig, seed, pub_seed, addr); + + for (i = 0; i < params->wots_len; i++) { + set_chain_addr(addr, i); + gen_chain(params, sig + i*params->n, sig + i*params->n, + 0, lengths[i], pub_seed, addr); + } +} + +/** + * Takes a WOTS signature and an n-byte message, computes a WOTS public key. + * + * Writes the computed public key to 'pk'. + */ +void wots_pk_from_sig(const xmss_params *params, unsigned char *pk, + const unsigned char *sig, const unsigned char *msg, + const unsigned char *pub_seed, uint32_t addr[8]) +{ + unsigned int lengths[params->wots_len]; + unsigned int i; + + memset(lengths, 0, sizeof(unsigned int)*params->wots_len); + + chain_lengths(params, lengths, msg); + + for (i = 0; i < params->wots_len; i++) { + set_chain_addr(addr, i); + gen_chain(params, pk + i*params->n, sig + i*params->n, + lengths[i], params->wots_w - 1 - lengths[i], pub_seed, addr); + } +} diff --git a/src/sig_stfl/xmss/external/wots.h b/src/sig_stfl/xmss/external/wots.h new file mode 100644 index 0000000000..0ee55b5b10 --- /dev/null +++ b/src/sig_stfl/xmss/external/wots.h @@ -0,0 +1,40 @@ +#ifndef XMSS_WOTS_H +#define XMSS_WOTS_H + +#include +#include "params.h" + +/** + * WOTS key generation. Takes a 32 byte seed for the private key, expands it to + * a full WOTS private key and computes the corresponding public key. + * It requires the seed pub_seed (used to generate bitmasks and hash keys) + * and the address of this WOTS key pair. + * + * Writes the computed public key to 'pk'. + */ +#define wots_pkgen XMSS_INNER_NAMESPACE(wots_pkgen) +void wots_pkgen(const xmss_params *params, + unsigned char *pk, const unsigned char *seed, + const unsigned char *pub_seed, uint32_t addr[8]); + +/** + * Takes a n-byte message and the 32-byte seed for the private key to compute a + * signature that is placed at 'sig'. + */ +#define wots_sign XMSS_INNER_NAMESPACE(wots_sign) +void wots_sign(const xmss_params *params, + unsigned char *sig, const unsigned char *msg, + const unsigned char *seed, const unsigned char *pub_seed, + uint32_t addr[8]); + +/** + * Takes a WOTS signature and an n-byte message, computes a WOTS public key. + * + * Writes the computed public key to 'pk'. + */ +#define wots_pk_from_sig XMSS_INNER_NAMESPACE(wots_pk_from_sig) +void wots_pk_from_sig(const xmss_params *params, unsigned char *pk, + const unsigned char *sig, const unsigned char *msg, + const unsigned char *pub_seed, uint32_t addr[8]); + +#endif diff --git a/src/sig_stfl/xmss/external/xmss.c b/src/sig_stfl/xmss/external/xmss.c new file mode 100644 index 0000000000..401e0deebe --- /dev/null +++ b/src/sig_stfl/xmss/external/xmss.c @@ -0,0 +1,287 @@ +#include + +#include "params.h" +#include "xmss_core.h" +#include "utils.h" +#include "xmss.h" + +/* This file provides wrapper functions that take keys that include OIDs to +identify the parameter set to be used. After setting the parameters accordingly +it falls back to the regular XMSS core functions. */ + +/** + * The function generates a public-private key pair for the XMSS signature scheme using the specified + * OID. + * + * @param pk Pointer to the public key buffer where the generated public key will be stored. + * @param sk sk is a pointer to an unsigned char array that will hold the secret key generated by the + * XMSS key pair generation function. The secret key is used for signing messages and should be kept + * confidential. + * @param oid The `oid` parameter is an identifier for the XMSS variant to be used. It is used to + * determine the parameters for the XMSS algorithm, such as the tree height and the number of signature + * iterations. The `oid` value is typically encoded as a 32-bit integer + * + * @return an integer value. If the function executes successfully, it will return 0. If there is an + * error, it will return -1. + */ +int xmss_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid) +{ + xmss_params params; + unsigned int i; + + if (xmss_parse_oid(¶ms, oid)) { + return -1; + } + for (i = 0; i < XMSS_OID_LEN; i++) { + pk[XMSS_OID_LEN - i - 1] = (oid >> (8 * i)) & 0xFF; + /* For an implementation that uses runtime parameters, it is crucial + that the OID is part of the secret key as well; + i.e. not just for interoperability, but also for internal use. */ + sk[XMSS_OID_LEN - i - 1] = (oid >> (8 * i)) & 0xFF; + } + return xmss_core_keypair(¶ms, pk + XMSS_OID_LEN, sk + XMSS_OID_LEN); +} + +/** + * This function parses the XMSS OID from a secret key, uses it to determine the XMSS parameters, and + * then calls the core signing function with those parameters. + * + * @param sk The secret key used for signing the message. + * @param sm A pointer to the buffer where the signed message will be stored. + * @param smlen A pointer to a 64-bit unsigned integer that will be used to store the length of the + * signed message (sm) after signing. The length is in bytes. + * @param m The message to be signed, represented as an array of unsigned characters. + * @param mlen The length of the message to be signed, in bytes. + * + * @return an integer value. If the function executes successfully, it will return 0. If there is an + * error, it will return -1. + */ +int xmss_sign(unsigned char *sk, + unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen) +{ + xmss_params params; + uint32_t oid = 0; + unsigned int i; + + for (i = 0; i < XMSS_OID_LEN; i++) { + oid |= sk[XMSS_OID_LEN - i - 1] << (i * 8); + } + if (xmss_parse_oid(¶ms, oid)) { + return -1; + } + return xmss_core_sign(¶ms, sk + XMSS_OID_LEN, sm, smlen, m, mlen); +} + +/** + * The function xmss_sign_open verifies a signature and retrieves the original message using the XMSS + * signature scheme. + * + * @param m Pointer to the buffer where the message will be stored after verification. + * @param mlen A pointer to a 64-bit unsigned integer that will be used to store the length of the + * message that is recovered during the signature verification process. + * @param sm The signature to be verified. It is a byte array of length smlen. + * @param smlen smlen is the length of the signature in bytes. + * @param pk pk is a pointer to the public key used for verifying the signature. + * + * @return The function `xmss_sign_open` returns an integer value. If the function is successful, it + * returns 0. If there is an error, it returns -1. + */ +int xmss_sign_open(const unsigned char *m, unsigned long long mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) +{ + xmss_params params; + uint32_t oid = 0; + unsigned int i; + + for (i = 0; i < XMSS_OID_LEN; i++) { + oid |= pk[XMSS_OID_LEN - i - 1] << (i * 8); + } + if (xmss_parse_oid(¶ms, oid)) { + return -1; + } + return xmss_core_sign_open(¶ms, m, mlen, sm, smlen, pk + XMSS_OID_LEN); +} + +/** + * The function calculates the remaining number of signatures that can be generated using a given XMSS + * private key. + * + * @param remain a pointer to a uint64_t variable that will store the number of remaining signatures + * that can be generated with the given secret key. + * @param sk The `sk` parameter is a pointer to an array of unsigned characters representing the secret + * key used in the XMSS signature scheme. + * + * @return This function returns an integer value. If the function executes successfully, it returns 0. + * If there is an error, it returns -1. + */ +int xmss_remaining_signatures(unsigned long long *remain, const unsigned char *sk) +{ + xmss_params params; + uint32_t oid = 0; + unsigned int i; + unsigned long long idx, max; + + for (i = 0; i < XMSS_OID_LEN; i++) { + oid |= sk[XMSS_OID_LEN - i - 1] << (i * 8); + } + + if (xmss_parse_oid(¶ms, oid)) { + *remain = 0; + return -1; + } + + idx = bytes_to_ull(sk + XMSS_OID_LEN, params.index_bytes); + max = ((1ULL << params.full_height) - 1); + + *remain = max - idx; + + return 0; +} + +/** + * The function calculates the maximum number of signatures that can be generated for a given XMSS private key. + * + * @param max a pointer to an unsigned long long variable that will store the maximum number of + * signatures that can be generated with the given XMSS private key. + * @param sk The secret key used for XMSS signature scheme. It is a pointer to an array of unsigned + * characters. + * + * @return an integer value. If the XMSS OID cannot be parsed, it returns -1. Otherwise, it sets the + * value of the variable pointed to by the "max" parameter to the maximum number of signatures that can + * be generated with the given XMSS private key and returns 0. + */ +int xmss_total_signatures(unsigned long long *max, const unsigned char *sk) +{ + xmss_params params; + uint32_t oid = 0; + + for (unsigned i = 0; i < XMSS_OID_LEN; i++) { + oid |= sk[XMSS_OID_LEN - i - 1] << (i * 8); + } + + if (xmss_parse_oid(¶ms, oid)) { + *max = 0; + return -1; + } + + *max = ((1ULL << params.full_height) - 1); + + return 0; +} + +int xmssmt_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid) +{ + xmss_params params; + unsigned int i; + + if (xmssmt_parse_oid(¶ms, oid)) { + return -1; + } + for (i = 0; i < XMSS_OID_LEN; i++) { + pk[XMSS_OID_LEN - i - 1] = (oid >> (8 * i)) & 0xFF; + sk[XMSS_OID_LEN - i - 1] = (oid >> (8 * i)) & 0xFF; + } + return xmssmt_core_keypair(¶ms, pk + XMSS_OID_LEN, sk + XMSS_OID_LEN); +} + +int xmssmt_sign(unsigned char *sk, + unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen) +{ + xmss_params params; + uint32_t oid = 0; + unsigned int i; + + for (i = 0; i < XMSS_OID_LEN; i++) { + oid |= sk[XMSS_OID_LEN - i - 1] << (i * 8); + } + if (xmssmt_parse_oid(¶ms, oid)) { + return -1; + } + return xmssmt_core_sign(¶ms, sk + XMSS_OID_LEN, sm, smlen, m, mlen); +} + +int xmssmt_sign_open(const unsigned char *m, unsigned long long mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) +{ + xmss_params params; + uint32_t oid = 0; + unsigned int i; + + for (i = 0; i < XMSS_OID_LEN; i++) { + oid |= pk[XMSS_OID_LEN - i - 1] << (i * 8); + } + if (xmssmt_parse_oid(¶ms, oid)) { + return -1; + } + return xmssmt_core_sign_open(¶ms, m, mlen, sm, smlen, pk + XMSS_OID_LEN); +} + + +/** + * The function calculates the remaining number of signatures that can be generated using a given + * XMSSMT private key. + * + * @param remain a pointer to an unsigned long long variable that will store the number of remaining + * signatures that can be generated using the given secret key. + * @param sk The `sk` parameter is a pointer to an array of unsigned characters representing the secret + * key used in the XMSSMT signature scheme. + * + * @return This function returns an integer value. If the function executes successfully, it returns 0. + * If there is an error, it returns -1. + */ +int xmssmt_remaining_signatures(unsigned long long *remain, const unsigned char *sk) +{ + xmss_params params; + uint32_t oid = 0; + unsigned int i; + unsigned long long idx, max; + + for (i = 0; i < XMSS_OID_LEN; i++) { + oid |= sk[XMSS_OID_LEN - i - 1] << (i * 8); + } + + if (xmssmt_parse_oid(¶ms, oid)) { + *remain = 0; + return -1; + } + + idx = bytes_to_ull(sk + XMSS_OID_LEN, params.index_bytes); + max = ((1ULL << params.full_height) - 1); + + *remain = max - idx; + + return 0; +} + +/** + * The function calculates the maximum number of signatures that can be generated for a given XMSSMT private key. + * + * @param max a pointer to an unsigned long long variable that will store the maximum number of + * signatures that can be generated with the given secret key. + * @param sk The `sk` parameter is a pointer to an array of unsigned characters representing the secret + * key used in the XMSS signature scheme. + * + * @return an integer value. If the XMSS OID cannot be parsed, it returns -1. Otherwise, it returns 0. + */ +int xmssmt_total_signatures(unsigned long long *max, const unsigned char *sk) +{ + xmss_params params; + uint32_t oid = 0; + + for (unsigned i = 0; i < XMSS_OID_LEN; i++) { + oid |= sk[XMSS_OID_LEN - i - 1] << (i * 8); + } + + if (xmss_parse_oid(¶ms, oid)) { + *max = 0; + return -1; + } + + *max = ((1ULL << params.full_height) - 1); + + return 0; +} diff --git a/src/sig_stfl/xmss/external/xmss.h b/src/sig_stfl/xmss/external/xmss.h new file mode 100644 index 0000000000..b21db845d3 --- /dev/null +++ b/src/sig_stfl/xmss/external/xmss.h @@ -0,0 +1,93 @@ +#ifndef XMSS_H +#define XMSS_H + +#include +#include "namespace.h" + +/** + * Generates a XMSS key pair for a given parameter set. + * Format sk: [OID || (32bit) idx || SK_SEED || SK_PRF || PUB_SEED || root] + * Format pk: [OID || root || PUB_SEED] + */ +#define xmss_keypair XMSS_NAMESPACE(xmss_keypair) +int xmss_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid); + +/** + * Signs a message using an XMSS secret key. + * Returns + * 1. an array containing the signature followed by the message AND + * 2. an updated secret key! + */ +#define xmss_sign XMSS_NAMESPACE(xmss_sign) +int xmss_sign(unsigned char *sk, + unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen); + +/** + * Verifies a given message signature pair using a given public key. + * + * Note: m and mlen are pure outputs which carry the message in case + * verification succeeds. The (input) message is assumed to be contained in sm + * which has the form [signature || message]. + */ +#define xmss_sign_open XMSS_NAMESPACE(xmss_sign_open) +int xmss_sign_open(const unsigned char *m, unsigned long long mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk); + +/* + * Write number of remaining signature to `remain` variable given `sk` + */ +#define xmss_remaining_signatures XMSS_NAMESPACE(xmss_remaining_signatures) +int xmss_remaining_signatures(unsigned long long *remain, const unsigned char *sk); + +/* + * Write number of maximum signature to `max` variable given `sk` + */ +#define xmss_total_signatures XMSS_NAMESPACE(xmss_total_signatures) +int xmss_total_signatures(unsigned long long *max, const unsigned char *sk); + +/* + * Generates a XMSSMT key pair for a given parameter set. + * Format sk: [OID || (ceil(h/8) bit) idx || SK_SEED || SK_PRF || PUB_SEED || root] + * Format pk: [OID || root || PUB_SEED] + */ +#define xmssmt_keypair XMSS_NAMESPACE(xmssmt_keypair) +int xmssmt_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid); + +/** + * Signs a message using an XMSSMT secret key. + * Returns + * 1. an array containing the signature followed by the message AND + * 2. an updated secret key! + */ +#define xmssmt_sign XMSS_NAMESPACE(xmssmt_sign) +int xmssmt_sign(unsigned char *sk, + unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen); + +/** + * Verifies a given message signature pair using a given public key. + * + * Note: m and mlen are pure outputs which carry the message in case + * verification succeeds. The (input) message is assumed to be contained in sm + * which has the form [signature || message]. + */ +#define xmssmt_sign_open XMSS_NAMESPACE(xmssmt_sign_open) +int xmssmt_sign_open(const unsigned char *m, unsigned long long mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk); + +/* + * Write number of remaining signature to `remain` variable given `sk` + */ +#define xmssmt_remaining_signatures XMSS_NAMESPACE(xmssmt_remaining_signatures) +int xmssmt_remaining_signatures(unsigned long long *remain, const unsigned char *sk); + +/* + * Write number of maximum signature to `max` variable given `sk` + */ +#define xmssmt_total_signatures XMSS_NAMESPACE(xmssmt_total_signatures) +int xmssmt_total_signatures(unsigned long long *max, const unsigned char *sk); + +#endif diff --git a/src/sig_stfl/xmss/external/xmss_commons.c b/src/sig_stfl/xmss/external/xmss_commons.c new file mode 100644 index 0000000000..882a3e39d6 --- /dev/null +++ b/src/sig_stfl/xmss/external/xmss_commons.c @@ -0,0 +1,216 @@ +#include +#include +#include + +#include "hash.h" +#include "hash_address.h" +#include "params.h" +#include "wots.h" +#include "utils.h" +#include "xmss_commons.h" + +/** + * Computes a leaf node from a WOTS public key using an L-tree. + * Note that this destroys the used WOTS public key. + */ +static void l_tree(const xmss_params *params, + unsigned char *leaf, unsigned char *wots_pk, + const unsigned char *pub_seed, uint32_t addr[8]) +{ + unsigned int l = params->wots_len; + unsigned int parent_nodes; + uint32_t i; + uint32_t height = 0; + + set_tree_height(addr, height); + + while (l > 1) { + parent_nodes = l >> 1; + for (i = 0; i < parent_nodes; i++) { + set_tree_index(addr, i); + /* Hashes the nodes at (i*2)*params->n and (i*2)*params->n + 1 */ + thash_h(params, wots_pk + i*params->n, + wots_pk + (i*2)*params->n, pub_seed, addr); + } + /* If the row contained an odd number of nodes, the last node was not + hashed. Instead, we pull it up to the next layer. */ + if (l & 1) { + memcpy(wots_pk + (l >> 1)*params->n, + wots_pk + (l - 1)*params->n, params->n); + l = (l >> 1) + 1; + } + else { + l = l >> 1; + } + height++; + set_tree_height(addr, height); + } + memcpy(leaf, wots_pk, params->n); +} + +/** + * Computes a root node given a leaf and an auth path + */ +static void compute_root(const xmss_params *params, unsigned char *root, + const unsigned char *leaf, unsigned long leafidx, + const unsigned char *auth_path, + const unsigned char *pub_seed, uint32_t addr[8]) +{ + uint32_t i; + unsigned char buffer[2*params->n]; + + /* If leafidx is odd (last bit = 1), current path element is a right child + and auth_path has to go left. Otherwise it is the other way around. */ + if (leafidx & 1) { + memcpy(buffer + params->n, leaf, params->n); + memcpy(buffer, auth_path, params->n); + } + else { + memcpy(buffer, leaf, params->n); + memcpy(buffer + params->n, auth_path, params->n); + } + auth_path += params->n; + + for (i = 0; i < params->tree_height - 1; i++) { + set_tree_height(addr, i); + leafidx >>= 1; + set_tree_index(addr, leafidx); + + /* Pick the right or left neighbor, depending on parity of the node. */ + if (leafidx & 1) { + thash_h(params, buffer + params->n, buffer, pub_seed, addr); + memcpy(buffer, auth_path, params->n); + } + else { + thash_h(params, buffer, buffer, pub_seed, addr); + memcpy(buffer + params->n, auth_path, params->n); + } + auth_path += params->n; + } + + /* The last iteration is exceptional; we do not copy an auth_path node. */ + set_tree_height(addr, params->tree_height - 1); + leafidx >>= 1; + set_tree_index(addr, leafidx); + thash_h(params, root, buffer, pub_seed, addr); +} + + +/** + * Computes the leaf at a given address. First generates the WOTS key pair, + * then computes leaf using l_tree. As this happens position independent, we + * only require that addr encodes the right ltree-address. + */ +void gen_leaf_wots(const xmss_params *params, unsigned char *leaf, + const unsigned char *sk_seed, const unsigned char *pub_seed, + uint32_t ltree_addr[8], uint32_t ots_addr[8]) +{ + unsigned char pk[params->wots_sig_bytes]; + + wots_pkgen(params, pk, sk_seed, pub_seed, ots_addr); + + l_tree(params, leaf, pk, pub_seed, ltree_addr); +} + + +/** + * Verifies a given message signature pair under a given public key. + * Note that this assumes a pk without an OID, i.e. [root || PUB_SEED] + */ +int xmss_core_sign_open(const xmss_params *params, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) +{ + /* XMSS signatures are fundamentally an instance of XMSSMT signatures. + For d=1, as is the case with XMSS, some of the calls in the XMSSMT + routine become vacuous (i.e. the loop only iterates once, and address + management can be simplified a bit).*/ + return xmssmt_core_sign_open(params, m, mlen, sm, smlen, pk); +} + +/** + * Verifies a given message signature pair under a given public key. + * Note that this assumes a pk without an OID, i.e. [root || PUB_SEED] + */ +int xmssmt_core_sign_open(const xmss_params *params, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) +{ + const unsigned char *pub_root = pk; + const unsigned char *pub_seed = pk + params->n; + unsigned char wots_pk[params->wots_sig_bytes]; + unsigned char leaf[params->n]; + unsigned char root[params->n]; + + unsigned long long prefix_length = params->padding_len + 3*params->n; + unsigned char m_with_prefix[mlen + prefix_length]; + + unsigned char *mhash = root; + unsigned long long idx = 0; + unsigned int i; + uint32_t idx_leaf; + + uint32_t ots_addr[8] = {0}; + uint32_t ltree_addr[8] = {0}; + uint32_t node_addr[8] = {0}; + + set_type(ots_addr, XMSS_ADDR_TYPE_OTS); + set_type(ltree_addr, XMSS_ADDR_TYPE_LTREE); + set_type(node_addr, XMSS_ADDR_TYPE_HASHTREE); + + // Unused since smlen is a constant + (void) smlen; + + /* Convert the index bytes from the signature to an integer. */ + idx = bytes_to_ull(sm, params->index_bytes); + + /* Put the message at the m_with_prefix buffer, so that we can + * prepend the required other inputs for the hash function. */ + memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, prefix_length); + memcpy(m_with_prefix + prefix_length, m, mlen); + + /* Compute the message hash. */ + hash_message(params, mhash, sm + params->index_bytes, pk, idx, + m_with_prefix, + mlen); + sm += params->index_bytes + params->n; + + /* For each subtree.. */ + for (i = 0; i < params->d; i++) { + idx_leaf = (idx & ((1 << params->tree_height)-1)); + idx = idx >> params->tree_height; + + set_layer_addr(ots_addr, i); + set_layer_addr(ltree_addr, i); + set_layer_addr(node_addr, i); + + set_tree_addr(ltree_addr, idx); + set_tree_addr(ots_addr, idx); + set_tree_addr(node_addr, idx); + + /* The WOTS public key is only correct if the signature was correct. */ + set_ots_addr(ots_addr, idx_leaf); + /* Initially, root = mhash, but on subsequent iterations it is the root + of the subtree below the currently processed subtree. */ + wots_pk_from_sig(params, wots_pk, sm, root, pub_seed, ots_addr); + sm += params->wots_sig_bytes; + + /* Compute the leaf node using the WOTS public key. */ + set_ltree_addr(ltree_addr, idx_leaf); + l_tree(params, leaf, wots_pk, pub_seed, ltree_addr); + + /* Compute the root node of this subtree. */ + compute_root(params, root, leaf, idx_leaf, sm, pub_seed, node_addr); + sm += params->tree_height*params->n; + } + + /* Check if the root node equals the root node in the public key. */ + if (memcmp(root, pub_root, params->n)) { + /* If not, return fail */ + return -1; + } + + return 0; +} diff --git a/src/sig_stfl/xmss/external/xmss_commons.h b/src/sig_stfl/xmss/external/xmss_commons.h new file mode 100644 index 0000000000..dbe841c6bf --- /dev/null +++ b/src/sig_stfl/xmss/external/xmss_commons.h @@ -0,0 +1,36 @@ +#ifndef XMSS_COMMONS_H +#define XMSS_COMMONS_H + +#include +#include "params.h" + +/** + * Computes the leaf at a given address. First generates the WOTS key pair, + * then computes leaf using l_tree. As this happens position independent, we + * only require that addr encodes the right ltree-address. + */ +#define gen_leaf_wots XMSS_INNER_NAMESPACE(gen_leaf_wots) +void gen_leaf_wots(const xmss_params *params, unsigned char *leaf, + const unsigned char *sk_seed, const unsigned char *pub_seed, + uint32_t ltree_addr[8], uint32_t ots_addr[8]); + +/** + * Verifies a given message signature pair under a given public key. + * Note that this assumes a pk without an OID, i.e. [root || PUB_SEED] + */ +#define xmss_core_sign_open XMSS_INNER_NAMESPACE(xmss_core_sign_open) +int xmss_core_sign_open(const xmss_params *params, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk); + +/** + * Verifies a given message signature pair under a given public key. + * Note that this assumes a pk without an OID, i.e. [root || PUB_SEED] + */ +#define xmssmt_core_sign_open XMSS_INNER_NAMESPACE(xmssmt_core_sign_open) +int xmssmt_core_sign_open(const xmss_params *params, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk); +#endif diff --git a/src/sig_stfl/xmss/external/xmss_core.c b/src/sig_stfl/xmss/external/xmss_core.c new file mode 100644 index 0000000000..daaf6aa6e4 --- /dev/null +++ b/src/sig_stfl/xmss/external/xmss_core.c @@ -0,0 +1,277 @@ +#include +#include +#include +#include + +#include "hash.h" +#include "hash_address.h" +#include "params.h" +#include "wots.h" +#include "utils.h" +#include "xmss_commons.h" +#include "xmss_core.h" + +/** + * For a given leaf index, computes the authentication path and the resulting + * root node using Merkle's TreeHash algorithm. + * Expects the layer and tree parts of subtree_addr to be set. + */ +static void treehash(const xmss_params *params, + unsigned char *root, unsigned char *auth_path, + const unsigned char *sk_seed, + const unsigned char *pub_seed, + uint32_t leaf_idx, const uint32_t subtree_addr[8]) +{ + unsigned char stack[(params->tree_height+1)*params->n]; + unsigned int heights[params->tree_height+1]; + unsigned int offset = 0; + + /* The subtree has at most 2^20 leafs, so uint32_t suffices. */ + uint32_t idx; + uint32_t tree_idx; + + /* We need all three types of addresses in parallel. */ + uint32_t ots_addr[8] = {0}; + uint32_t ltree_addr[8] = {0}; + uint32_t node_addr[8] = {0}; + + /* Select the required subtree. */ + copy_subtree_addr(ots_addr, subtree_addr); + copy_subtree_addr(ltree_addr, subtree_addr); + copy_subtree_addr(node_addr, subtree_addr); + + set_type(ots_addr, XMSS_ADDR_TYPE_OTS); + set_type(ltree_addr, XMSS_ADDR_TYPE_LTREE); + set_type(node_addr, XMSS_ADDR_TYPE_HASHTREE); + + for (idx = 0; idx < (uint32_t)(1 << params->tree_height); idx++) { + /* Add the next leaf node to the stack. */ + set_ltree_addr(ltree_addr, idx); + set_ots_addr(ots_addr, idx); + gen_leaf_wots(params, stack + offset*params->n, + sk_seed, pub_seed, ltree_addr, ots_addr); + offset++; + heights[offset - 1] = 0; + + /* If this is a node we need for the auth path.. */ + if ((leaf_idx ^ 0x1) == idx) { + memcpy(auth_path, stack + (offset - 1)*params->n, params->n); + } + + /* While the top-most nodes are of equal height.. */ + while (offset >= 2 && heights[offset - 1] == heights[offset - 2]) { + /* Compute index of the new node, in the next layer. */ + tree_idx = (idx >> (heights[offset - 1] + 1)); + + /* Hash the top-most nodes from the stack together. */ + /* Note that tree height is the 'lower' layer, even though we use + the index of the new node on the 'higher' layer. This follows + from the fact that we address the hash function calls. */ + set_tree_height(node_addr, heights[offset - 1]); + set_tree_index(node_addr, tree_idx); + thash_h(params, stack + (offset-2)*params->n, + stack + (offset-2)*params->n, pub_seed, node_addr); + offset--; + /* Note that the top-most node is now one layer higher. */ + heights[offset - 1]++; + + /* If this is a node we need for the auth path.. */ + if (((leaf_idx >> heights[offset - 1]) ^ 0x1) == tree_idx) { + memcpy(auth_path + heights[offset - 1]*params->n, + stack + (offset - 1)*params->n, params->n); + } + } + } + memcpy(root, stack, params->n); +} + +/** + * Given a set of parameters, this function returns the size of the secret key. + * This is implementation specific, as varying choices in tree traversal will + * result in varying requirements for state storage. + */ +unsigned long long xmss_xmssmt_core_sk_bytes(const xmss_params *params) +{ + return params->index_bytes + 4 * params->n; +} + +/* + * Generates a XMSS key pair for a given parameter set. + * Format sk: [(32bit) index || SK_SEED || SK_PRF || root || PUB_SEED] + * Format pk: [root || PUB_SEED], omitting algorithm OID. + */ +int xmss_core_keypair(const xmss_params *params, + unsigned char *pk, unsigned char *sk) +{ + /* The key generation procedure of XMSS and XMSSMT is exactly the same. + The only important detail is that the right subtree must be selected; + this requires us to correctly set the d=1 parameter for XMSS. */ + return xmssmt_core_keypair(params, pk, sk); +} + +/** + * Signs a message. Returns an array containing the signature followed by the + * message and an updated secret key. + */ +int xmss_core_sign(const xmss_params *params, + unsigned char *sk, + unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen) +{ + /* XMSS signatures are fundamentally an instance of XMSSMT signatures. + For d=1, as is the case with XMSS, some of the calls in the XMSSMT + routine become vacuous (i.e. the loop only iterates once, and address + management can be simplified a bit).*/ + return xmssmt_core_sign(params, sk, sm, smlen, m, mlen); +} + +/* + * Derives a XMSSMT key pair for a given parameter set. + * Seed must be 3*n long. + * Format sk: [(ceil(h/8) bit) index || SK_SEED || SK_PRF || root || PUB_SEED] + * Format pk: [root || PUB_SEED] omitting algorithm OID. + */ +int xmssmt_core_seed_keypair(const xmss_params *params, + unsigned char *pk, unsigned char *sk, + unsigned char *seed) +{ + /* We do not need the auth path in key generation, but it simplifies the + code to have just one treehash routine that computes both root and path + in one function. */ + unsigned char auth_path[params->tree_height * params->n]; + uint32_t top_tree_addr[8] = {0}; + set_layer_addr(top_tree_addr, params->d - 1); + + /* Initialize index to 0. */ + memset(sk, 0, params->index_bytes); + sk += params->index_bytes; + + /* Initialize SK_SEED and SK_PRF. */ + memcpy(sk, seed, 2 * params->n); + + /* Initialize PUB_SEED. */ + memcpy(sk + 3 * params->n, seed + 2 * params->n, params->n); + memcpy(pk + params->n, sk + 3*params->n, params->n); + + /* Compute root node of the top-most subtree. */ + treehash(params, pk, auth_path, sk, pk + params->n, 0, top_tree_addr); + memcpy(sk + 2*params->n, pk, params->n); + + return 0; +} + +/* + * Generates a XMSSMT key pair for a given parameter set. + * Format sk: [(ceil(h/8) bit) index || SK_SEED || SK_PRF || root || PUB_SEED] + * Format pk: [root || PUB_SEED] omitting algorithm OID. + */ +int xmssmt_core_keypair(const xmss_params *params, + unsigned char *pk, unsigned char *sk) +{ + unsigned char seed[3 * params->n]; + + OQS_randombytes(seed, 3 * params->n); + xmssmt_core_seed_keypair(params, pk, sk, seed); + + return 0; +} + +/** + * Signs a message. Returns an array containing the signature followed by the + * message and an updated secret key. + */ +int xmssmt_core_sign(const xmss_params *params, + unsigned char *sk, + unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen) +{ + const unsigned char *sk_seed = sk + params->index_bytes; + const unsigned char *sk_prf = sk + params->index_bytes + params->n; + const unsigned char *pub_root = sk + params->index_bytes + 2*params->n; + const unsigned char *pub_seed = sk + params->index_bytes + 3*params->n; + + unsigned long long prefix_length = params->padding_len + 3*params->n; + unsigned char m_with_prefix[mlen + prefix_length]; + + unsigned char root[params->n]; + unsigned char *mhash = root; + unsigned long long idx; + unsigned char idx_bytes_32[32]; + unsigned int i; + uint32_t idx_leaf; + + uint32_t ots_addr[8] = {0}; + set_type(ots_addr, XMSS_ADDR_TYPE_OTS); + + /* Already put the message in the right place, to make it easier to prepend + * things when computing the hash over the message. */ + memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, prefix_length); + memcpy(m_with_prefix + prefix_length, m, mlen); + *smlen = params->sig_bytes; + + /* Read and use the current index from the secret key. */ + idx = (unsigned long)bytes_to_ull(sk, params->index_bytes); + + /* Check if we can still sign with this sk. + * If not, return -2 + * + * If this is the last possible signature (because the max index value + * is reached), production implementations should delete the secret key + * to prevent accidental further use. + * + * For the case of total tree height of 64 we do not use the last signature + * to be on the safe side (there is no index value left to indicate that the + * key is finished, hence external handling would be necessary) + */ + if (idx >= ((1ULL << params->full_height) - 1)) { + // Delete secret key here. We only do this in memory, production code + // has to make sure that this happens on disk. + memset(sk, 0xFF, params->index_bytes); + memset(sk + params->index_bytes, 0, (params->sk_bytes - params->index_bytes)); + if (idx > ((1ULL << params->full_height) - 1)) + return -2; // We already used all one-time keys + if ((params->full_height == 64) && (idx == UINT64_MAX)) + return -2; // We already used all one-time keys + } + + memcpy(sm, sk, params->index_bytes); + + /************************************************************************* + * THIS IS WHERE PRODUCTION IMPLEMENTATIONS WOULD UPDATE THE SECRET KEY. * + *************************************************************************/ + /* Increment the index in the secret key. */ + ull_to_bytes(sk, params->index_bytes, idx + 1); + + /* Compute the digest randomization value. */ + ull_to_bytes(idx_bytes_32, 32, idx); + prf(params, sm + params->index_bytes, idx_bytes_32, sk_prf); + + /* Compute the message hash. */ + hash_message(params, mhash, sm + params->index_bytes, pub_root, idx, + m_with_prefix, + mlen); + sm += params->index_bytes + params->n; + + set_type(ots_addr, XMSS_ADDR_TYPE_OTS); + + for (i = 0; i < params->d; i++) { + idx_leaf = (idx & ((1 << params->tree_height)-1)); + idx = idx >> params->tree_height; + + set_layer_addr(ots_addr, i); + set_tree_addr(ots_addr, idx); + set_ots_addr(ots_addr, idx_leaf); + + /* Compute a WOTS signature. */ + /* Initially, root = mhash, but on subsequent iterations it is the root + of the subtree below the currently processed subtree. */ + wots_sign(params, sm, root, sk_seed, pub_seed, ots_addr); + sm += params->wots_sig_bytes; + + /* Compute the authentication path for the used WOTS leaf. */ + treehash(params, root, sm, sk_seed, pub_seed, idx_leaf, ots_addr); + sm += params->tree_height*params->n; + } + + return 0; +} diff --git a/src/sig_stfl/xmss/external/xmss_core.h b/src/sig_stfl/xmss/external/xmss_core.h new file mode 100644 index 0000000000..bed99862c5 --- /dev/null +++ b/src/sig_stfl/xmss/external/xmss_core.h @@ -0,0 +1,85 @@ +#ifndef XMSS_CORE_H +#define XMSS_CORE_H + +#include "params.h" + +/** + * Given a set of parameters, this function returns the size of the secret key. + * This is implementation specific, as varying choices in tree traversal will + * result in varying requirements for state storage. + * + * This function handles both XMSS and XMSSMT parameter sets. + */ +#define xmss_xmssmt_core_sk_bytes XMSS_INNER_NAMESPACE(xmss_xmssmt_core_sk_bytes) +unsigned long long xmss_xmssmt_core_sk_bytes(const xmss_params *params); + +/* + * Generates a XMSS key pair for a given parameter set. + * Format sk: [(32bit) index || SK_SEED || SK_PRF || PUB_SEED || root] + * Format pk: [root || PUB_SEED], omitting algorithm OID. + */ +#define xmss_core_keypair XMSS_INNER_NAMESPACE(xmss_core_keypair) +int xmss_core_keypair(const xmss_params *params, + unsigned char *pk, unsigned char *sk); + +/** + * Signs a message. Returns an array containing the signature followed by the + * message and an updated secret key. + */ +#define xmss_core_sign XMSS_INNER_NAMESPACE(xmss_core_sign) +int xmss_core_sign(const xmss_params *params, + unsigned char *sk, + unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen); + +/** + * Verifies a given message signature pair under a given public key. + * Note that this assumes a pk without an OID, i.e. [root || PUB_SEED] + */ +#define xmss_core_sign_open XMSS_INNER_NAMESPACE(xmss_core_sign_open) +int xmss_core_sign_open(const xmss_params *params, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk); + +/* + * Generates a XMSSMT key pair for a given parameter set. + * Format sk: [(ceil(h/8) bit) index || SK_SEED || SK_PRF || PUB_SEED || root] + * Format pk: [root || PUB_SEED] omitting algorithm OID. + */ +#define xmssmt_core_keypair XMSS_INNER_NAMESPACE(xmssmt_core_keypair) +int xmssmt_core_keypair(const xmss_params *params, + unsigned char *pk, unsigned char *sk); + +/* + * Derives a XMSSMT key pair for a given parameter set. + * Seed must be 3*n long. + * Format sk: [(ceil(h/8) bit) index || SK_SEED || SK_PRF || root || PUB_SEED] + * Format pk: [root || PUB_SEED] omitting algorithm OID. + */ +#define xmssmt_core_seed_keypair XMSS_INNER_NAMESPACE(xmssmt_core_seed_keypair) +int xmssmt_core_seed_keypair(const xmss_params *params, + unsigned char *pk, unsigned char *sk, + unsigned char *seed); + +/** + * Signs a message. Returns an array containing the signature followed by the + * message and an updated secret key. + */ +#define xmssmt_core_sign XMSS_INNER_NAMESPACE(xmssmt_core_sign) +int xmssmt_core_sign(const xmss_params *params, + unsigned char *sk, + unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen); + +/** + * Verifies a given message signature pair under a given public key. + * Note that this assumes a pk without an OID, i.e. [root || PUB_SEED] + */ +#define xmssmt_core_sign_open XMSS_INNER_NAMESPACE(xmssmt_core_sign_open) +int xmssmt_core_sign_open(const xmss_params *params, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk); + +#endif diff --git a/src/sig_stfl/xmss/external/xmss_core_fast.c b/src/sig_stfl/xmss/external/xmss_core_fast.c new file mode 100644 index 0000000000..c0517cbb29 --- /dev/null +++ b/src/sig_stfl/xmss/external/xmss_core_fast.c @@ -0,0 +1,988 @@ +#include +#include +#include +#include + +#include "hash.h" +#include "hash_address.h" +#include "params.h" +#include "wots.h" +#include "utils.h" +#include "xmss_commons.h" +#include "xmss_core.h" + +typedef struct{ + unsigned char h; + unsigned long next_idx; + unsigned char stackusage; + unsigned char completed; + unsigned char *node; +} treehash_inst; + +typedef struct { + unsigned char *stack; + unsigned int stackoffset; + unsigned char *stacklevels; + unsigned char *auth; + unsigned char *keep; + treehash_inst *treehash; + unsigned char *retain; + unsigned int next_leaf; +} bds_state; + +/* These serialization functions provide a transition between the current + way of storing the state in an exposed struct, and storing it as part of the + byte array that is the secret key. + They will probably be refactored in a non-backwards-compatible way, soon. */ + +static void xmssmt_serialize_state(const xmss_params *params, + unsigned char *sk, bds_state *states) +{ + unsigned int i, j; + + /* Skip past the 'regular' sk */ + sk += params->index_bytes + 4*params->n; + + for (i = 0; i < 2*params->d - 1; i++) { + sk += (params->tree_height + 1) * params->n; /* stack */ + + ull_to_bytes(sk, 4, states[i].stackoffset); + sk += 4; + + sk += params->tree_height + 1; /* stacklevels */ + sk += params->tree_height * params->n; /* auth */ + sk += (params->tree_height >> 1) * params->n; /* keep */ + + for (j = 0; j < params->tree_height - params->bds_k; j++) { + ull_to_bytes(sk, 1, states[i].treehash[j].h); + sk += 1; + + ull_to_bytes(sk, 4, states[i].treehash[j].next_idx); + sk += 4; + + ull_to_bytes(sk, 1, states[i].treehash[j].stackusage); + sk += 1; + + ull_to_bytes(sk, 1, states[i].treehash[j].completed); + sk += 1; + + sk += params->n; /* node */ + } + + /* retain */ + sk += ((1 << params->bds_k) - params->bds_k - 1) * params->n; + + ull_to_bytes(sk, 4, states[i].next_leaf); + sk += 4; + } +} + +static void xmssmt_deserialize_state(const xmss_params *params, + bds_state *states, + unsigned char **wots_sigs, + unsigned char *sk) +{ + unsigned int i, j; + + /* Skip past the 'regular' sk */ + sk += params->index_bytes + 4*params->n; + + // TODO These data sizes follow from the (former) test xmss_core_fast.c + // TODO They should be reconsidered / motivated more explicitly + + for (i = 0; i < 2*params->d - 1; i++) { + states[i].stack = sk; + sk += (params->tree_height + 1) * params->n; + + states[i].stackoffset = bytes_to_ull(sk, 4); + sk += 4; + + states[i].stacklevels = sk; + sk += params->tree_height + 1; + + states[i].auth = sk; + sk += params->tree_height * params->n; + + states[i].keep = sk; + sk += (params->tree_height >> 1) * params->n; + + for (j = 0; j < params->tree_height - params->bds_k; j++) { + states[i].treehash[j].h = bytes_to_ull(sk, 1); + sk += 1; + + states[i].treehash[j].next_idx = bytes_to_ull(sk, 4); + sk += 4; + + states[i].treehash[j].stackusage = bytes_to_ull(sk, 1); + sk += 1; + + states[i].treehash[j].completed = bytes_to_ull(sk, 1); + sk += 1; + + states[i].treehash[j].node = sk; + sk += params->n; + } + + states[i].retain = sk; + sk += ((1 << params->bds_k) - params->bds_k - 1) * params->n; + + states[i].next_leaf = bytes_to_ull(sk, 4); + sk += 4; + } + + if (params->d > 1) { + *wots_sigs = sk; + } +} + +static void xmss_serialize_state(const xmss_params *params, + unsigned char *sk, bds_state *state) +{ + xmssmt_serialize_state(params, sk, state); +} + +static void xmss_deserialize_state(const xmss_params *params, + bds_state *state, unsigned char *sk) +{ + xmssmt_deserialize_state(params, state, NULL, sk); +} + +static void memswap(void *a, void *b, void *t, unsigned long long len) +{ + memcpy(t, a, len); + memcpy(a, b, len); + memcpy(b, t, len); +} + +/** + * Swaps the content of two bds_state objects, swapping actual memory rather + * than pointers. + * As we're mapping memory chunks in the secret key to bds state objects, + * it is now necessary to make swaps 'real swaps'. This could be done in the + * serialization function as well, but that causes more overhead + */ +// TODO this should not be necessary if we keep better track of the states +static void deep_state_swap(const xmss_params *params, + bds_state *a, bds_state *b) +{ + // TODO this is extremely ugly and should be refactored + // TODO right now, this ensures that both 'stack' and 'retain' fit + unsigned char t[ + ((params->tree_height + 1) > ((1 << params->bds_k) - params->bds_k - 1) + ? (params->tree_height + 1) + : ((1 << params->bds_k) - params->bds_k - 1)) + * params->n]; + unsigned int i; + + memswap(a->stack, b->stack, t, (params->tree_height + 1) * params->n); + memswap(&a->stackoffset, &b->stackoffset, t, sizeof(a->stackoffset)); + memswap(a->stacklevels, b->stacklevels, t, params->tree_height + 1); + memswap(a->auth, b->auth, t, params->tree_height * params->n); + memswap(a->keep, b->keep, t, (params->tree_height >> 1) * params->n); + + for (i = 0; i < params->tree_height - params->bds_k; i++) { + memswap(&a->treehash[i].h, &b->treehash[i].h, t, sizeof(a->treehash[i].h)); + memswap(&a->treehash[i].next_idx, &b->treehash[i].next_idx, t, sizeof(a->treehash[i].next_idx)); + memswap(&a->treehash[i].stackusage, &b->treehash[i].stackusage, t, sizeof(a->treehash[i].stackusage)); + memswap(&a->treehash[i].completed, &b->treehash[i].completed, t, sizeof(a->treehash[i].completed)); + memswap(a->treehash[i].node, b->treehash[i].node, t, params->n); + } + + memswap(a->retain, b->retain, t, ((1 << params->bds_k) - params->bds_k - 1) * params->n); + memswap(&a->next_leaf, &b->next_leaf, t, sizeof(a->next_leaf)); +} + +static int treehash_minheight_on_stack(const xmss_params *params, + bds_state *state, + const treehash_inst *treehash) +{ + unsigned int r = params->tree_height, i; + + for (i = 0; i < treehash->stackusage; i++) { + if (state->stacklevels[state->stackoffset - i - 1] < r) { + r = state->stacklevels[state->stackoffset - i - 1]; + } + } + return r; +} + +/** + * Merkle's TreeHash algorithm. The address only needs to initialize the first 78 bits of addr. Everything else will be set by treehash. + * Currently only used for key generation. + * + */ +static void treehash_init(const xmss_params *params, + unsigned char *node, int height, int index, + bds_state *state, const unsigned char *sk_seed, + const unsigned char *pub_seed, const uint32_t addr[8]) +{ + unsigned int idx = index; + // use three different addresses because at this point we use all three formats in parallel + uint32_t ots_addr[8] = {0}; + uint32_t ltree_addr[8] = {0}; + uint32_t node_addr[8] = {0}; + // only copy layer and tree address parts + copy_subtree_addr(ots_addr, addr); + // type = ots + set_type(ots_addr, 0); + copy_subtree_addr(ltree_addr, addr); + set_type(ltree_addr, 1); + copy_subtree_addr(node_addr, addr); + set_type(node_addr, 2); + + uint32_t lastnode, i; + unsigned char stack[(height+1)*params->n]; + unsigned int stacklevels[height+1]; + unsigned int stackoffset=0; + unsigned int nodeh; + + lastnode = idx+(1<tree_height-params->bds_k; i++) { + state->treehash[i].h = i; + state->treehash[i].completed = 1; + state->treehash[i].stackusage = 0; + } + + i = 0; + for (; idx < lastnode; idx++) { + set_ltree_addr(ltree_addr, idx); + set_ots_addr(ots_addr, idx); + gen_leaf_wots(params, stack+stackoffset*params->n, sk_seed, pub_seed, ltree_addr, ots_addr); + stacklevels[stackoffset] = 0; + stackoffset++; + if (params->tree_height - params->bds_k > 0 && i == 3) { + memcpy(state->treehash[0].node, stack+stackoffset*params->n, params->n); + } + while (stackoffset>1 && stacklevels[stackoffset-1] == stacklevels[stackoffset-2]) { + nodeh = stacklevels[stackoffset-1]; + if (i >> nodeh == 1) { + memcpy(state->auth + nodeh*params->n, stack+(stackoffset-1)*params->n, params->n); + } + else { + if (nodeh < params->tree_height - params->bds_k && i >> nodeh == 3) { + memcpy(state->treehash[nodeh].node, stack+(stackoffset-1)*params->n, params->n); + } + else if (nodeh >= params->tree_height - params->bds_k) { + memcpy(state->retain + ((1 << (params->tree_height - 1 - nodeh)) + nodeh - params->tree_height + (((i >> nodeh) - 3) >> 1)) * params->n, stack+(stackoffset-1)*params->n, params->n); + } + } + set_tree_height(node_addr, stacklevels[stackoffset-1]); + set_tree_index(node_addr, (idx >> (stacklevels[stackoffset-1]+1))); + thash_h(params, stack+(stackoffset-2)*params->n, stack+(stackoffset-2)*params->n, pub_seed, node_addr); + stacklevels[stackoffset-2]++; + stackoffset--; + } + i++; + } + + for (i = 0; i < params->n; i++) { + node[i] = stack[i]; + } +} + +static void treehash_update(const xmss_params *params, + treehash_inst *treehash, bds_state *state, + const unsigned char *sk_seed, + const unsigned char *pub_seed, + const uint32_t addr[8]) +{ + uint32_t ots_addr[8] = {0}; + uint32_t ltree_addr[8] = {0}; + uint32_t node_addr[8] = {0}; + // only copy layer and tree address parts + copy_subtree_addr(ots_addr, addr); + // type = ots + set_type(ots_addr, 0); + copy_subtree_addr(ltree_addr, addr); + set_type(ltree_addr, 1); + copy_subtree_addr(node_addr, addr); + set_type(node_addr, 2); + + set_ltree_addr(ltree_addr, treehash->next_idx); + set_ots_addr(ots_addr, treehash->next_idx); + + unsigned char nodebuffer[2 * params->n]; + unsigned int nodeheight = 0; + gen_leaf_wots(params, nodebuffer, sk_seed, pub_seed, ltree_addr, ots_addr); + while (treehash->stackusage > 0 && state->stacklevels[state->stackoffset-1] == nodeheight) { + memcpy(nodebuffer + params->n, nodebuffer, params->n); + memcpy(nodebuffer, state->stack + (state->stackoffset-1)*params->n, params->n); + set_tree_height(node_addr, nodeheight); + set_tree_index(node_addr, (treehash->next_idx >> (nodeheight+1))); + thash_h(params, nodebuffer, nodebuffer, pub_seed, node_addr); + nodeheight++; + treehash->stackusage--; + state->stackoffset--; + } + if (nodeheight == treehash->h) { // this also implies stackusage == 0 + memcpy(treehash->node, nodebuffer, params->n); + treehash->completed = 1; + } + else { + memcpy(state->stack + state->stackoffset*params->n, nodebuffer, params->n); + treehash->stackusage++; + state->stacklevels[state->stackoffset] = nodeheight; + state->stackoffset++; + treehash->next_idx++; + } +} + +/** + * Performs treehash updates on the instance that needs it the most. + * Returns the updated number of available updates. + **/ +static char bds_treehash_update(const xmss_params *params, + bds_state *state, unsigned int updates, + const unsigned char *sk_seed, + unsigned char *pub_seed, + const uint32_t addr[8]) +{ + uint32_t i, j; + unsigned int level, l_min, low; + unsigned int used = 0; + + for (j = 0; j < updates; j++) { + l_min = params->tree_height; + level = params->tree_height - params->bds_k; + for (i = 0; i < params->tree_height - params->bds_k; i++) { + if (state->treehash[i].completed) { + low = params->tree_height; + } + else if (state->treehash[i].stackusage == 0) { + low = i; + } + else { + low = treehash_minheight_on_stack(params, state, &(state->treehash[i])); + } + if (low < l_min) { + level = i; + l_min = low; + } + } + if (level == params->tree_height - params->bds_k) { + break; + } + treehash_update(params, &(state->treehash[level]), state, sk_seed, pub_seed, addr); + used++; + } + return updates - used; +} + +/** + * Updates the state (typically NEXT_i) by adding a leaf and updating the stack + * Returns -1 if all leaf nodes have already been processed + **/ +static char bds_state_update(const xmss_params *params, + bds_state *state, const unsigned char *sk_seed, + const unsigned char *pub_seed, + const uint32_t addr[8]) +{ + uint32_t ltree_addr[8] = {0}; + uint32_t node_addr[8] = {0}; + uint32_t ots_addr[8] = {0}; + + unsigned int nodeh; + int idx = state->next_leaf; + if (idx == 1 << params->tree_height) { + return -1; + } + + // only copy layer and tree address parts + copy_subtree_addr(ots_addr, addr); + // type = ots + set_type(ots_addr, 0); + copy_subtree_addr(ltree_addr, addr); + set_type(ltree_addr, 1); + copy_subtree_addr(node_addr, addr); + set_type(node_addr, 2); + + set_ots_addr(ots_addr, idx); + set_ltree_addr(ltree_addr, idx); + + gen_leaf_wots(params, state->stack+state->stackoffset*params->n, sk_seed, pub_seed, ltree_addr, ots_addr); + + state->stacklevels[state->stackoffset] = 0; + state->stackoffset++; + if (params->tree_height - params->bds_k > 0 && idx == 3) { + memcpy(state->treehash[0].node, state->stack+state->stackoffset*params->n, params->n); + } + while (state->stackoffset>1 && state->stacklevels[state->stackoffset-1] == state->stacklevels[state->stackoffset-2]) { + nodeh = state->stacklevels[state->stackoffset-1]; + if (idx >> nodeh == 1) { + memcpy(state->auth + nodeh*params->n, state->stack+(state->stackoffset-1)*params->n, params->n); + } + else { + if (nodeh < params->tree_height - params->bds_k && idx >> nodeh == 3) { + memcpy(state->treehash[nodeh].node, state->stack+(state->stackoffset-1)*params->n, params->n); + } + else if (nodeh >= params->tree_height - params->bds_k) { + memcpy(state->retain + ((1 << (params->tree_height - 1 - nodeh)) + nodeh - params->tree_height + (((idx >> nodeh) - 3) >> 1)) * params->n, state->stack+(state->stackoffset-1)*params->n, params->n); + } + } + set_tree_height(node_addr, state->stacklevels[state->stackoffset-1]); + set_tree_index(node_addr, (idx >> (state->stacklevels[state->stackoffset-1]+1))); + thash_h(params, state->stack+(state->stackoffset-2)*params->n, state->stack+(state->stackoffset-2)*params->n, pub_seed, node_addr); + + state->stacklevels[state->stackoffset-2]++; + state->stackoffset--; + } + state->next_leaf++; + return 0; +} + +/** + * Returns the auth path for node leaf_idx and computes the auth path for the + * next leaf node, using the algorithm described by Buchmann, Dahmen and Szydlo + * in "Post Quantum Cryptography", Springer 2009. + */ +static void bds_round(const xmss_params *params, + bds_state *state, const unsigned long leaf_idx, + const unsigned char *sk_seed, + const unsigned char *pub_seed, uint32_t addr[8]) +{ + unsigned int i; + unsigned int tau = params->tree_height; + unsigned int startidx; + unsigned int offset, rowidx; + unsigned char buf[2 * params->n]; + + uint32_t ots_addr[8] = {0}; + uint32_t ltree_addr[8] = {0}; + uint32_t node_addr[8] = {0}; + + // only copy layer and tree address parts + copy_subtree_addr(ots_addr, addr); + // type = ots + set_type(ots_addr, 0); + copy_subtree_addr(ltree_addr, addr); + set_type(ltree_addr, 1); + copy_subtree_addr(node_addr, addr); + set_type(node_addr, 2); + + for (i = 0; i < params->tree_height; i++) { + if (! ((leaf_idx >> i) & 1)) { + tau = i; + break; + } + } + + if (tau > 0) { + memcpy(buf, state->auth + (tau-1) * params->n, params->n); + // we need to do this before refreshing state->keep to prevent overwriting + memcpy(buf + params->n, state->keep + ((tau-1) >> 1) * params->n, params->n); + } + if (!((leaf_idx >> (tau + 1)) & 1) && (tau < params->tree_height - 1)) { + memcpy(state->keep + (tau >> 1)*params->n, state->auth + tau*params->n, params->n); + } + if (tau == 0) { + set_ltree_addr(ltree_addr, leaf_idx); + set_ots_addr(ots_addr, leaf_idx); + gen_leaf_wots(params, state->auth, sk_seed, pub_seed, ltree_addr, ots_addr); + } + else { + set_tree_height(node_addr, (tau-1)); + set_tree_index(node_addr, leaf_idx >> tau); + thash_h(params, state->auth + tau * params->n, buf, pub_seed, node_addr); + for (i = 0; i < tau; i++) { + if (i < params->tree_height - params->bds_k) { + memcpy(state->auth + i * params->n, state->treehash[i].node, params->n); + } + else { + offset = (1 << (params->tree_height - 1 - i)) + i - params->tree_height; + rowidx = ((leaf_idx >> i) - 1) >> 1; + memcpy(state->auth + i * params->n, state->retain + (offset + rowidx) * params->n, params->n); + } + } + + for (i = 0; i < ((tau < params->tree_height - params->bds_k) ? tau : (params->tree_height - params->bds_k)); i++) { + startidx = leaf_idx + 1 + 3 * (1 << i); + if (startidx < 1U << params->tree_height) { + state->treehash[i].h = i; + state->treehash[i].next_idx = startidx; + state->treehash[i].completed = 0; + state->treehash[i].stackusage = 0; + } + } + } +} + +/** + * Given a set of parameters, this function returns the size of the secret key. + * This is implementation specific, as varying choices in tree traversal will + * result in varying requirements for state storage. + * + * This function handles both XMSS and XMSSMT parameter sets. + */ +unsigned long long xmss_xmssmt_core_sk_bytes(const xmss_params *params) +{ + return params->index_bytes + 4 * params->n + + (2 * params->d - 1) * ( + (params->tree_height + 1) * params->n + + 4 + + params->tree_height + 1 + + params->tree_height * params->n + + (params->tree_height >> 1) * params->n + + (params->tree_height - params->bds_k) * (7 + params->n) + + ((1 << params->bds_k) - params->bds_k - 1) * params->n + + 4 + ) + + (params->d - 1) * params->wots_sig_bytes; +} + +/* + * Generates a XMSS key pair for a given parameter set. + * Format sk: [(32bit) idx || SK_SEED || SK_PRF || root || PUB_SEED] + * Format pk: [root || PUB_SEED] omitting algo oid. + */ +int xmss_core_keypair(const xmss_params *params, + unsigned char *pk, unsigned char *sk) +{ + uint32_t addr[8] = {0}; + + // TODO refactor BDS state not to need separate treehash instances + bds_state state; + treehash_inst treehash[params->tree_height - params->bds_k]; + state.treehash = treehash; + + xmss_deserialize_state(params, &state, sk); + + state.stackoffset = 0; + state.next_leaf = 0; + + // Set idx = 0 + sk[0] = 0; + sk[1] = 0; + sk[2] = 0; + sk[3] = 0; + // Init SK_SEED (n byte) and SK_PRF (n byte) + OQS_randombytes(sk + params->index_bytes, 2*params->n); + + // Init PUB_SEED (n byte) + OQS_randombytes(sk + params->index_bytes + 3*params->n, params->n); + // Copy PUB_SEED to public key + memcpy(pk + params->n, sk + params->index_bytes + 3*params->n, params->n); + + // Compute root + treehash_init(params, pk, params->tree_height, 0, &state, sk + params->index_bytes, sk + params->index_bytes + 3*params->n, addr); + // copy root to sk + memcpy(sk + params->index_bytes + 2*params->n, pk, params->n); + + /* Write the BDS state into sk. */ + xmss_serialize_state(params, sk, &state); + + return 0; +} + +/** + * Signs a message. + * Returns + * 1. an array containing the signature followed by the message AND + * 2. an updated secret key! + * + */ +int xmss_core_sign(const xmss_params *params, + unsigned char *sk, + unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen) +{ + const unsigned char *pub_root = sk + params->index_bytes + 2*params->n; + + uint16_t i = 0; + + // TODO refactor BDS state not to need separate treehash instances + bds_state state; + treehash_inst treehash[params->tree_height - params->bds_k]; + state.treehash = treehash; + + /* Load the BDS state from sk. */ + xmss_deserialize_state(params, &state, sk); + + // Extract SK + unsigned long idx = ((unsigned long)sk[0] << 24) | ((unsigned long)sk[1] << 16) | ((unsigned long)sk[2] << 8) | sk[3]; + + /* Check if we can still sign with this sk. + * If not, return -2 + * + * If this is the last possible signature (because the max index value + * is reached), production implementations should delete the secret key + * to prevent accidental further use. + * + * For the case of total tree height of 64 we do not use the last signature + * to be on the safe side (there is no index value left to indicate that the + * key is finished, hence external handling would be necessary) + */ + if (idx >= ((1ULL << params->full_height) - 1)) { + // Delete secret key here. We only do this in memory, production code + // has to make sure that this happens on disk. + memset(sk, 0xFF, params->index_bytes); + memset(sk + params->index_bytes, 0, (params->sk_bytes - params->index_bytes)); + if (idx > ((1ULL << params->full_height) - 1)) + return -2; // We already used all one-time keys + if ((params->full_height == 64) && (idx == ((1ULL << params->full_height) - 1))) + return -2; // We already used all one-time keys + } + + unsigned char sk_seed[params->n]; + memcpy(sk_seed, sk + params->index_bytes, params->n); + unsigned char sk_prf[params->n]; + memcpy(sk_prf, sk + params->index_bytes + params->n, params->n); + unsigned char pub_seed[params->n]; + memcpy(pub_seed, sk + params->index_bytes + 3*params->n, params->n); + + // index as 32 bytes string + unsigned char idx_bytes_32[32]; + ull_to_bytes(idx_bytes_32, 32, idx); + + // Update SK + sk[0] = ((idx + 1) >> 24) & 255; + sk[1] = ((idx + 1) >> 16) & 255; + sk[2] = ((idx + 1) >> 8) & 255; + sk[3] = (idx + 1) & 255; + // Secret key for this non-forward-secure version is now updated. + // A production implementation should consider using a file handle instead, + // and write the updated secret key at this point! + + // Init working params + unsigned char R[params->n]; + unsigned char msg_h[params->n]; + uint32_t ots_addr[8] = {0}; + + // --------------------------------- + // Message Hashing + // --------------------------------- + + // Message Hash: + // First compute pseudorandom value + prf(params, R, idx_bytes_32, sk_prf); + + /* Already put the message in the right place, to make it easier to prepend + * things when computing the hash over the message. */ + unsigned long long prefix_length = params->padding_len + 3*params->n; + unsigned char m_with_prefix[mlen + prefix_length]; + memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, prefix_length); + memcpy(m_with_prefix + prefix_length, m, mlen); + + /* Compute the message hash. */ + hash_message(params, msg_h, R, pub_root, idx, + m_with_prefix, + mlen); + + // Start collecting signature + *smlen = 0; + + // Copy index to signature + sm[0] = (idx >> 24) & 255; + sm[1] = (idx >> 16) & 255; + sm[2] = (idx >> 8) & 255; + sm[3] = idx & 255; + + sm += 4; + *smlen += 4; + + // Copy R to signature + for (i = 0; i < params->n; i++) { + sm[i] = R[i]; + } + + sm += params->n; + *smlen += params->n; + + // ---------------------------------- + // Now we start to "really sign" + // ---------------------------------- + + // Prepare Address + set_type(ots_addr, 0); + set_ots_addr(ots_addr, idx); + + // Compute WOTS signature + wots_sign(params, sm, msg_h, sk_seed, pub_seed, ots_addr); + + sm += params->wots_sig_bytes; + *smlen += params->wots_sig_bytes; + + // the auth path was already computed during the previous round + memcpy(sm, state.auth, params->tree_height*params->n); + + if (idx < (1U << params->tree_height) - 1) { + bds_round(params, &state, idx, sk_seed, pub_seed, ots_addr); + bds_treehash_update(params, &state, (params->tree_height - params->bds_k) >> 1, sk_seed, pub_seed, ots_addr); + } + + sm += params->tree_height*params->n; + *smlen += params->tree_height*params->n; + + /* Write the updated BDS state back into sk. */ + xmss_serialize_state(params, sk, &state); + + return 0; +} + +/* + * Generates a XMSSMT key pair for a given parameter set. + * Format sk: [(ceil(h/8) bit) idx || SK_SEED || SK_PRF || root || PUB_SEED] + * Format pk: [root || PUB_SEED] omitting algo oid. + */ +int xmssmt_core_keypair(const xmss_params *params, + unsigned char *pk, unsigned char *sk) +{ + uint32_t addr[8] = {0}; + unsigned int i; + unsigned char *wots_sigs; + + // TODO refactor BDS state not to need separate treehash instances + bds_state states[2*params->d - 1]; + treehash_inst treehash[(2*params->d - 1) * (params->tree_height - params->bds_k)]; + for (i = 0; i < 2*params->d - 1; i++) { + states[i].treehash = treehash + i * (params->tree_height - params->bds_k); + } + + xmssmt_deserialize_state(params, states, &wots_sigs, sk); + + for (i = 0; i < 2 * params->d - 1; i++) { + states[i].stackoffset = 0; + states[i].next_leaf = 0; + } + + // Set idx = 0 + for (i = 0; i < params->index_bytes; i++) { + sk[i] = 0; + } + // Init SK_SEED (params->n byte) and SK_PRF (params->n byte) + OQS_randombytes(sk+params->index_bytes, 2*params->n); + + // Init PUB_SEED (params->n byte) + OQS_randombytes(sk+params->index_bytes + 3*params->n, params->n); + // Copy PUB_SEED to public key + memcpy(pk+params->n, sk+params->index_bytes+3*params->n, params->n); + + // Start with the bottom-most layer + set_layer_addr(addr, 0); + // Set up state and compute wots signatures for all but topmost tree root + for (i = 0; i < params->d - 1; i++) { + // Compute seed for OTS key pair + treehash_init(params, pk, params->tree_height, 0, states + i, sk+params->index_bytes, pk+params->n, addr); + set_layer_addr(addr, (i+1)); + wots_sign(params, wots_sigs + i*params->wots_sig_bytes, pk, sk + params->index_bytes, pk+params->n, addr); + } + // Address now points to the single tree on layer d-1 + treehash_init(params, pk, params->tree_height, 0, states + i, sk+params->index_bytes, pk+params->n, addr); + memcpy(sk + params->index_bytes + 2*params->n, pk, params->n); + + xmssmt_serialize_state(params, sk, states); + + return 0; +} + +/** + * Signs a message. + * Returns + * 1. an array containing the signature followed by the message AND + * 2. an updated secret key! + * + */ +int xmssmt_core_sign(const xmss_params *params, + unsigned char *sk, + unsigned char *sm, unsigned long long *smlen, + const unsigned char *m, unsigned long long mlen) +{ + const unsigned char *pub_root = sk + params->index_bytes + 2*params->n; + + uint64_t idx_tree; + uint32_t idx_leaf; + uint64_t i, j; + int needswap_upto = -1; + unsigned int updates; + + unsigned char sk_seed[params->n]; + unsigned char sk_prf[params->n]; + unsigned char pub_seed[params->n]; + // Init working params + unsigned char R[params->n]; + unsigned char msg_h[params->n]; + uint32_t addr[8] = {0}; + uint32_t ots_addr[8] = {0}; + unsigned char idx_bytes_32[32]; + + unsigned char *wots_sigs; + + // TODO refactor BDS state not to need separate treehash instances + bds_state states[2*params->d - 1]; + treehash_inst treehash[(2*params->d - 1) * (params->tree_height - params->bds_k)]; + for (i = 0; i < 2*params->d - 1; i++) { + states[i].treehash = treehash + i * (params->tree_height - params->bds_k); + } + + xmssmt_deserialize_state(params, states, &wots_sigs, sk); + + // Extract SK + unsigned long long idx = 0; + for (i = 0; i < params->index_bytes; i++) { + idx |= ((unsigned long long)sk[i]) << 8*(params->index_bytes - 1 - i); + } + + /* Check if we can still sign with this sk. + * If not, return -2 + * + * If this is the last possible signature (because the max index value + * is reached), production implementations should delete the secret key + * to prevent accidental further use. + * + * For the case of total tree height of 64 we do not use the last signature + * to be on the safe side (there is no index value left to indicate that the + * key is finished, hence external handling would be necessary) + */ + if (idx >= ((1ULL << params->full_height) - 1)) { + // Delete secret key here. We only do this in memory, production code + // has to make sure that this happens on disk. + memset(sk, 0xFF, params->index_bytes); + memset(sk + params->index_bytes, 0, (params->sk_bytes - params->index_bytes)); + if (idx > ((1ULL << params->full_height) - 1)) + return -2; // We already used all one-time keys + if ((params->full_height == 64) && (idx == ((1ULL << params->full_height) - 1))) + return -2; // We already used all one-time keys + } + + memcpy(sk_seed, sk+params->index_bytes, params->n); + memcpy(sk_prf, sk+params->index_bytes+params->n, params->n); + memcpy(pub_seed, sk+params->index_bytes+3*params->n, params->n); + + // Update SK + for (i = 0; i < params->index_bytes; i++) { + sk[i] = ((idx + 1) >> 8*(params->index_bytes - 1 - i)) & 255; + } + // Secret key for this non-forward-secure version is now updated. + // A production implementation should consider using a file handle instead, + // and write the updated secret key at this point! + + // --------------------------------- + // Message Hashing + // --------------------------------- + + // Message Hash: + // First compute pseudorandom value + ull_to_bytes(idx_bytes_32, 32, idx); + prf(params, R, idx_bytes_32, sk_prf); + + /* Already put the message in the right place, to make it easier to prepend + * things when computing the hash over the message. */ + unsigned long long prefix_length = params->padding_len + 3*params->n; + unsigned char m_with_prefix[mlen + prefix_length]; + memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, prefix_length); + memcpy(m_with_prefix + prefix_length, m, mlen); + + /* Compute the message hash. */ + hash_message(params, msg_h, R, pub_root, idx, + m_with_prefix, + mlen); + + // Start collecting signature + *smlen = 0; + + // Copy index to signature + for (i = 0; i < params->index_bytes; i++) { + sm[i] = (idx >> 8*(params->index_bytes - 1 - i)) & 255; + } + + sm += params->index_bytes; + *smlen += params->index_bytes; + + // Copy R to signature + for (i = 0; i < params->n; i++) { + sm[i] = R[i]; + } + + sm += params->n; + *smlen += params->n; + + // ---------------------------------- + // Now we start to "really sign" + // ---------------------------------- + + // Handle lowest layer separately as it is slightly different... + + // Prepare Address + set_type(ots_addr, 0); + idx_tree = idx >> params->tree_height; + idx_leaf = (idx & ((1 << params->tree_height)-1)); + set_layer_addr(ots_addr, 0); + set_tree_addr(ots_addr, idx_tree); + set_ots_addr(ots_addr, idx_leaf); + + // Compute WOTS signature + wots_sign(params, sm, msg_h, sk_seed, pub_seed, ots_addr); + + sm += params->wots_sig_bytes; + *smlen += params->wots_sig_bytes; + + memcpy(sm, states[0].auth, params->tree_height*params->n); + sm += params->tree_height*params->n; + *smlen += params->tree_height*params->n; + + // prepare signature of remaining layers + for (i = 1; i < params->d; i++) { + // put WOTS signature in place + memcpy(sm, wots_sigs + (i-1)*params->wots_sig_bytes, params->wots_sig_bytes); + + sm += params->wots_sig_bytes; + *smlen += params->wots_sig_bytes; + + // put AUTH nodes in place + memcpy(sm, states[i].auth, params->tree_height*params->n); + sm += params->tree_height*params->n; + *smlen += params->tree_height*params->n; + } + + updates = (params->tree_height - params->bds_k) >> 1; + + set_tree_addr(addr, (idx_tree + 1)); + // mandatory update for NEXT_0 (does not count towards h-k/2) if NEXT_0 exists + if ((1 + idx_tree) * (1 << params->tree_height) + idx_leaf < (1ULL << params->full_height)) { + bds_state_update(params, &states[params->d], sk_seed, pub_seed, addr); + } + + for (i = 0; i < params->d; i++) { + // check if we're not at the end of a tree + if (! (((idx + 1) & ((1ULL << ((i+1)*params->tree_height)) - 1)) == 0)) { + idx_leaf = (idx >> (params->tree_height * i)) & ((1 << params->tree_height)-1); + idx_tree = (idx >> (params->tree_height * (i+1))); + set_layer_addr(addr, i); + set_tree_addr(addr, idx_tree); + if (i == (unsigned int) (needswap_upto + 1)) { + bds_round(params, &states[i], idx_leaf, sk_seed, pub_seed, addr); + } + updates = bds_treehash_update(params, &states[i], updates, sk_seed, pub_seed, addr); + set_tree_addr(addr, (idx_tree + 1)); + // if a NEXT-tree exists for this level; + if ((1 + idx_tree) * (1 << params->tree_height) + idx_leaf < (1ULL << (params->full_height - params->tree_height * i))) { + if (i > 0 && updates > 0 && states[params->d + i].next_leaf < (1ULL << params->full_height)) { + bds_state_update(params, &states[params->d + i], sk_seed, pub_seed, addr); + updates--; + } + } + } + else if (idx < (1ULL << params->full_height) - 1) { + deep_state_swap(params, states+params->d + i, states + i); + + set_layer_addr(ots_addr, (i+1)); + set_tree_addr(ots_addr, ((idx + 1) >> ((i+2) * params->tree_height))); + set_ots_addr(ots_addr, (((idx >> ((i+1) * params->tree_height)) + 1) & ((1 << params->tree_height)-1))); + + wots_sign(params, wots_sigs + i*params->wots_sig_bytes, states[i].stack, sk_seed, pub_seed, ots_addr); + + states[params->d + i].stackoffset = 0; + states[params->d + i].next_leaf = 0; + + updates--; // WOTS-signing counts as one update + needswap_upto = i; + for (j = 0; j < params->tree_height-params->bds_k; j++) { + states[i].treehash[j].completed = 1; + } + } + } + + xmssmt_serialize_state(params, sk, states); + + return 0; +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index 93dcd57bba..1dd0139e5f 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -10,13 +10,15 @@ #ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h10 #define OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature 2500 -#define OQS_SIG_STFL_alg_xmss_sha256_h10_length_pk 64 + XMSS_OID_LEN -#define OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk 2047 + XMSS_OID_LEN +#define OQS_SIG_STFL_alg_xmss_sha256_h10_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk (132 + XMSS_OID_LEN) OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(size_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(size_t *total, const uint8_t *secret_key); #endif diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c deleted file mode 100644 index 186fba20f8..0000000000 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256.c +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: MIT - -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif - -// ======================== XMSS10-SHA256 ======================== // - -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->method_name = "XMSS-SHA2_10_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha256_h10_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmss_sha256_h10_keypair; - sig->sign = OQS_SIG_STFL_alg_xmss_sha256_h10_sign; - sig->verify = OQS_SIG_STFL_alg_xmss_sha256_h10_verify; - - return sig; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { - memset(signature, 0, OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature); - *signature_len = OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature; - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - for (size_t i = 0; i < OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature; i++) { - if (signature[i] != 0) { - return OQS_ERROR; - } - } - return OQS_SUCCESS; -} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c new file mode 100644 index 0000000000..8e50828095 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSS-SHA2_10_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSS-SHA2_10_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha256_h10_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmss_sha256_h10_keypair; + sig->sign = OQS_SIG_STFL_alg_xmss_sha256_h10_sign; + sig->verify = OQS_SIG_STFL_alg_xmss_sha256_h10_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total; + + return sig; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmss_sha256_h10_oid = 0x00000001; + if (oqs_sig_stfl_xmss_xmss_keypair(public_key, secret_key, xmss_sha256_h10_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (oqs_sig_stfl_xmss_xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_xmss_xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(size_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long remaining_signatures = 0; + if (oqs_sig_stfl_xmss_xmss_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (size_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(size_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long total_signatures = 0; + if (oqs_sig_stfl_xmss_xmss_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (size_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ada020f51a..22c26a053a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -99,6 +99,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND BUILD_SHARED_LIBS) endif() endif() +add_executable(kat_sig_stfl kat_sig_stfl.c test_helpers.c) +target_link_libraries(kat_sig_stfl PRIVATE ${TEST_DEPS}) + add_executable(test_sig test_sig.c) target_link_libraries(test_sig PRIVATE ${TEST_DEPS}) @@ -113,11 +116,13 @@ set(SIG_TESTS example_sig kat_sig test_sig test_sig_mem speed_sig vectors_sig) # SIG_STFL API tests add_executable(test_sig_stfl test_sig_stfl.c) if((CMAKE_C_COMPILER_ID MATCHES "Clang") OR (CMAKE_C_COMPILER_ID STREQUAL "GNU")) - target_link_libraries(test_sig_stfl PRIVATE ${API_TEST_DEPS} Threads::Threads) + target_link_libraries(test_sig_stfl PRIVATE ${TEST_DEPS} Threads::Threads) else () - target_link_libraries(test_sig_stfl PRIVATE ${API_TEST_DEPS}) + target_link_libraries(test_sig_stfl PRIVATE ${TEST_DEPS}) endif() +set(SIG_STFL_TESTS kat_sig_stfl test_sig_stfl) + add_executable(dump_alg_info dump_alg_info.c) target_link_libraries(dump_alg_info PRIVATE ${TEST_DEPS}) @@ -158,5 +163,5 @@ add_custom_target( # skip long KAT tests COMMAND ${CMAKE_COMMAND} -E env OQS_BUILD_DIR=${CMAKE_BINARY_DIR} ${PYTHON3_EXEC} -m pytest --verbose --numprocesses=auto --ignore=scripts/copy_from_upstream/repos --ignore=tests/test_kat_all.py WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - DEPENDS oqs dump_alg_info ${KEM_TESTS} ${SIG_TESTS} ${UNIX_TESTS} + DEPENDS oqs dump_alg_info ${KEM_TESTS} ${SIG_TESTS} ${SIG_STFL_TESTS} ${UNIX_TESTS} USES_TERMINAL) diff --git a/tests/KATs/sig_stfl/kats.json b/tests/KATs/sig_stfl/kats.json new file mode 100644 index 0000000000..8be3ea457f --- /dev/null +++ b/tests/KATs/sig_stfl/kats.json @@ -0,0 +1,3 @@ +{ + "XMSS-SHA2_10_256": "e71e6a390fe09c275e0fa0996d938d554d01548da229fe159ccab48e6525ae8b" +} \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp new file mode 100644 index 0000000000..5641aa1e9c --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp @@ -0,0 +1,182 @@ +# XMSS-SHA2_10_256 + +pk = 0000000157A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +sk = 0000000100000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD + + +count = 0 +seed = D260779A680342EFB7D244B1333C2FC9884B85CDB7B96F8EEEAF5FC7FBDBABF9A0AA3F0E7238F97142BCF1C561731CFE +mlen = 33 +msg = BBCB0A3E0F49152C2D8022F5AAB8AD5E80E81934BC66D468AB76F141D4E741937D +smlen = 2500 +sm = 00000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA70105CAE69218E377931AC690634219BE00AE5320712465A2B736772BA10311D81DD6E16DE90489D3963F80022BCA055736187CA55BE285B83537CE987CFECF1401D6B7DFFDA5087F9586D35A22FC8B42A3FA29A2A5F4BE53E17A9CB8D42942B5E187796E96704F8CC77119F33BAEB06B1140A484E881C4385C31F5D7D16C842E348320D1CE3556DEDB800385B782AC949821203199969DBC2F2652C256E91157096E07E49BE3133DCDD305CBB4F2077D5DE4D29C431A2968F50AB5501512524666CA7B2268C159CB047FC54ED490A963C2A7A4E936C407176C1DE9142CF8BC0CD4FE2AC3C011F531564A1B93D4BB59867CF655C9F170C5BDC6A62D93562168EF99760160982B28667681DE3D81832DA109CE5D6D3E919C459063AAA6C58D1AF2616C4198F41A8969C0F2F67DE6417390E170912482D75E5E18EB1CCA84E6914765546E3452E1219F438FDCC57D3AF82DCE3DD8B69E58FAA28B1983BDA064CE1DBA6886F23C77B2FE6F6A1427FE94649C25E1366079C5008F7E6E9DE0EFD7E8792BF1EF0948B621D309BA771BECA0592BD5D4D23AA8BD0C469D5C7D5DF396D1D75C17F8C5D632A753C32CDCCB1A3896C2C54172D1871737319A3C326AF497D7216A6CB1DF7AAA231912F2AEC85392DE82D4648B27970075EEAE2BD1A6A8A7A49B51A973B852799338E04C136EC1CB3F84825C35A7CDE243C5025B36ABD240D4698438E9323E310E320EF0833677E35A6D02DF5838C26277241C354ED9130BA6086E333168D84664AC66BDF26A3ACBC4B4D67312564FA30E94B3B7C22A1D9F4A2DF2F8458B0715E3670EBEA3B6F3CABEF3C4282E821A2BA2F2B21D16F1D130F56BBAA8CC6F5EDCC37148BB069D3404288D2BFF211193A839ABCBFEFA3069F6101A45595AAF5CDCF3F2565C14BD5AEB26642608E029600F5F973EA4952EBB78C74E0A6D5B9BCD4CE7C9A3BFD982083885AD7F92B3ED09BA1EF566A1640DA41F49325320727B0D0ED87B3EF4ACA88E3C698627C67D9E9EA656F3D66E369320CFF7D2958E9F66CB5379F66C8E69DBEE19350CD95A84055592D46C2C42606EF6B4EF63B31269665A7F2B5A00B492D60C9FAEC0FF5057D9D50D858DB86B85D902681FC873F8F865CAD7358B5EE4169CDDAC13307900AC1CB241225283861E0B871D1A56B2F433367341F7718C80AF69ABA1C359C91B4271E7A46E86522180DBD9ECB3842AF76F7757F50F243748E7F13246533B1D90CBFAD3185B781B5388C2FC0C36D08CEEAC757245ECFB9BEF58AE28F535601FB4379DEF650FB39E1C00C072E8E51BF8BE96CD88C66F2EDABF4DD04263A0B02B56196DB9106A62D98C284C839B1B4D19C8FF0FFAFAFEB732CDFFF7B5D7D65E5D4DD3D84C631439CB133033A27561C1271EA45A509AF7995511A09F2E294E8B33CE0B64EA29322E55004A7E4FEF5EF089080BDB3C2DD2AF979F46C4715E0602DFC16E8EA9FB7DD1E47A872900903B214EE7A1595C3C254F598B7460DB51FA12204A97B280E83AD0F796757D6C9E7CC6BC53F8E17DF6AC34F8450566E9E4DBD4FF2FAA4755577DFB8E90229F5B15F418C3E290AF21754336F25254BAE436E9C6839D07E45D56A0821110DBF193E1E95448A43EACE60B461F47937072A051B4C3C0D17489E393B47F2290269F171E22C571364B7F906B79C69668BA0AF81DF30C3D4AB906F5E47B50C0AB0143E9BEDF247A0EB562DB0898C104A6CCECE457033784C2640FFBC073E01E354BF068D3416B2FCC5837309FE2019CDB053F42E63EA1B1683898C506B89C6B2D390F745D3A14FFDAF9AFF26F73AE79CBA225D9A5FDCFE9CA7041D38D991064AA5D32D5CEB0A97DB58F3B5FE894FCC983F71662F4EBB6C067AF9FCA95222229AA497F8E1F9BCDDE0C59216068B0B284F148306974E3E8D785615CDD5002357D423103F02F490D3CBE413D0C9A5108444FBC85048D14AFECBD57FCD6A863155D62D6B4061F5941E989F1C10869047F82BDA5FAA6BAE01359F5CDAA5474B2EF78C4A3499D95FA85106849AF8A80F439B30DEA0D60D187F49BB5C26B05A14822D8F257C4110A2684FA444630777D6610AD8E6B08D0ECD0433B9077DA8853E9F567358300FE457B521C03B89C7B77CFBA948DB2A6BF87FDC39F1C349EFC00C17356298DDA38FD48095BAAF5B346DE3B1CCF91018785869FDD98EF8F7C12189DC13D473458228851B48725130D439AE5AD57CC700A27B51ED54380D80D80E5A770EDF368A56762E7CB037D59E73D311572411A466B7934E9B9292332F73407951CF9294CD541D4ADBC9CB624C3ED57FA33F67A72BA1AA9BB8DC95FF10B8DB6F23F996A31CA87D5DC0086BE4FA7BC7EEDFCC1D32D6D84A99618B6998FCB4A791FF9EE0855A4A7C6B5C4796E9E213C2DA5B205D5255C71B6F97D5067E5A8A579664AF2C73D5A949FCD43B36DC423E34BCBD72575D2E74DE56A97A5440F84BC2408F10E8DE519C3685D4AE28F395C52615B3B03F5D4C45D9D2C207B74734CAFA0C924822DC3E495B496C892C7556446F14BCE82DC2AAD295A65A7E6C4358311B04882FCD05B066A46B6A98FB3C2AEC438247683AD2A2DF295EC5D42B638F91E9E67DFC4B4A33831BAFE5D1C8CD6AB95A431A16D3FAF05080B1DC25B8B882BD29E2F8BDDC1407E493C5D5DB11423AC490954C66A924ADAD04842DE902ECFC37436DC6A736BB2004784599EE80ECB66B2EA06224C5961E5DB97AEF1EE4CE7D0A70C61BAF568023479601A7CAD8CDD2AE929D0C1AFA811FDEAEC6216E74516036E7E9E0E2A1E169DE38221869E46E6EE4325D37102ABE9709356223F80A4D259F45AD260AEFD801B8052A55E9848F9976497A14475D98DF3F1EB9EAC832F44C0981BA49037C116F6CDBDCF0FF043B96D225DFDF54CD890408F824CDE256CE8788601AE0705140253EFF336F060DA6855A3403EE9833C898A9E602401EF67C593A8AAE02C5BBBF8383E68C71BE4583B423CEC8E3D7CCE0C4652A9FE6097AAD64C5FC1588AC9CCDEBA3C6E435AF86E29F25399BD4EC118F665E4CC9D59327F129CECA4F359EB0547BEC24FC3E7D74B1125892F02AEBEDD1AB9A7611C4FEE5ACBB9BA8634169DB9AC73BB0704D1F8F6098CA76F2FA504D8825564A30A1D7E6E12690DE34C0521FE70D15714626DEBC8008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 0000000100000001061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1022 +max = 1023 + +count = 1 +seed = 4AF2A48BFB8912E1209AE0B00C0B52CD84183E9D2B0D63E1C9DC7E3B2920874CBBABDEBD47BF4CAA5E19B4C6BEB96D8D +mlen = 66 +msg = B81C782E781F6D005B891EAF89527B7AF65AEE14E0B668EAB7A1EC5AE188B391A733B7707E42A7AF3699ECAF1A43453C2CFE0ED61233CFF68F35F4A84ADA949812FC +smlen = 2500 +sm = 0000000196122FAE790CF4FA6D9055E159003D223857F44B3EF248882A415D76FA26BFD2892B42C27F464D13FE2026F5F1CC11B7BEC39DDB84E55A8D02733F9DE45D12F0F78174CE816C9BF2021400FFFB8A957696D2C91B8EE32984C1A7FED7D76B76E3C3877DBD912B9D53681EC0E601947D7AF1F4285EC10CEDB10156CF3B5DBE57C29056EFA6C16B9C3AFFA2835DC3395DBB7962BE6E9FDFF0D4EEAA5A7C40126638D443E00E6282A0278BCB076FB14AE295627CC9D4CB0E4C48A3D9D9394EC889363EAA2382263BE9D1B8C50D744212910B83F4180FEFE601102F1AD9AD3E592BEC45B42789D9C5949A6178226C21581388ABACDDCB988F2FFC0AD98A21DB0D728EE8F7E4E19111DF2EB74436E3CB14792B4C3FE691C27889337D984F82BBBBDB9D2A54B78CF70BE8057908959247FB5A84596DE7ABB1DA1B28BB787064F79A5270A249DE499C6FE8F6DB84B93A12C93563B658527E99786306CB3C32465127497C42E38DAD8F7E592B8585EE77AFB3E70D7F188D1AB0C9873E5005FFB4C360FA74FF8E0A6E3493EE7407D8CE5EA12310F6F51BFBDDB7290BDE558FB6A2F5317F4D11412FA7FFEF45465012D531D90EDC3A62E2EFA07CF58B3B45B5BD8431E7DBCEE38783F5D4757A0AC26D4E5C7F6A94F71BA1AC2F4DD8E9927D0A06792AFF259C2A413B678CFE937A0F3D166761DC7A6F3EFB029C8D4CC735878178BF5E97D06ACBEFC607649F48131D8C35A23278C61A333C969DB3E938011B5FF54A5A46A11392127736DC233186381B84A4A3F7B88D88A5F6519DC83F049F7C57E8CFA439187BC89CEF18CE0E53F6B79BE3DC9575DE0F16EEEFA2619D53A2D2D09078B1D03C0034D8BACFC6B329AC9969B3702AFFE04A94607324D40EFAFC0FA6AD7F0A14D8DD252583D34916D83F927DFBDA6ECDBBEB1D6ED96E881A931D7A6582394A06A53429FD4A6D0E155B533FDC73F2C8A7C7408E56CF3F318CDEA142480A95F6C398BBDF900FA09B386B096391D060F5CF6BCD2614F61E40B3E84AC0BC08FD2AC9D7AFDBC5CEF821810ECB9DF964E3391A6C869DBC59BC75575C11B75CA9C106D76D3AE2636F240B7D25F71772829307F80F6FA5C8000BFD3693407F367A7BD122EFB12493C558A4FC17DF46B892CA14B2D696AC154DA1BF51A274A35E55A8D94A0A8052AAE2C1944347CB57ADEEA0429FDD5D846F9258226A7E3B298F3E687A04B2686C740EDE8DC7A1E447A0792FF49139C33BA99A42A0E760225BFC882DD5BBD1F517126309B438F6813D411048FCE5F2C997E321CA9B6C3B16779034416B1718D962D0CF187E15FA6FBC668C7FFCFA6398D0B58E7FB4504D7623F465E6B657A8A2C4FC8FA01C94F54A3D3E5A29341248885B570B4E4D3900F82C21457782B08AE1C7798405A1CC0EC2CD22120B3EF25F41714804ECD9DB406B0D509D064888E8A2FD3DABCCE5675A3FEE01F4D4F22D0F071AD6E4D907EAB25B0E4C7C5DEF8A5B977012298F6969B9D0F515FA241701B390C605FE982BFF2A5D1375ED026686835769E1B988706A3168AD81C3FF4B394E178999FAF7E711EA6F72CE64CB7CE3ED5E557515F6C0D135401B70C687F97445AB03F49EAD2F911A5C1C21C2DDA9FB2D4A8001F698DD5C54693A515E3FD9205FFF4CDB297FE3D82CFCE9077261758798C7E31B2661E4919572822216A14496F65D6318458C1D758C413A84D4909B1D330E37B8D6CDE30DAFDDA5966559C35D1E79DB90B8B5D0D64B6B74F4781A15E34B0CFFCAE7655CD9C5FDCBD855E1A597A22F82152CE18463F1F71B5E343032BDAA71C3DD5EE7F3E5EE157390DCF4AEE17C7F204B548B0D15412B03AFE4A0E733C3D0CBEE8B2B23854DCC6D98FC7D9FF63E841210541946A048127763FB4D7BFA43EE2FDA7C52A07F1EB2A7CB3E06D8E98CAD68E1AF7C60672C35C410EBC0B7CED72E6C88FF5B2FCFD1AECDD459BB472D0CB20B4CB53102F979F5743E1F1949E30C3DC04A91625844E5780DE2E9D855EE0E03850F123BB8A092D6F4F11E9303354AA49758438C653D52EBDF36EB20FB6B2678E756907ED51879A13A4E233D61BE862DC85D8C8CD04643F783030BD4798C1BD1DFB54706E79FAE2DE8D2FC28469F74B141A571ED0C1950DBBE941965D0EE3B17DE0BC0AE16F98A72CE97B51A37C0132E051E7B2AD221926D68851F3342BD398AA5CD779AA91F1642CED4F81520255B2AF51F6941EC7CE3732553AB201756563DEBED7F6A567306E93B2263CB7B6895863ED6F1120069218A9A2BEFB5AACE3B87B5701E5CD6785E8D0D1E9B5AF7E3D312E4DF0051946B8F29655725F018A9A6315EFD2478B3AC2DA543E347A83A672A7D1C0EF91B31C154E8B57AC643D1BF4A787B53D5FB34240F0072B44E86F8BAB01335AA56D21B3F9DFBFCD10BDF2E51D0B56C1811CAED5B1F8EC8226C54EACE2EAB841B9CD9C4CF876ACD6F7030D9A6BAD21FF3D6316429B2A1AF4552576716AD3C3A8FD36CB54B6C395E43EDE8B5DF0F24927A2A46D209A5B595F4CF60F487B7C138BF59D1265AE0A40F476FBE9D4A49EE24944D5999C748E2291DF06379BA1A1B372566A19F0A3188CB1F5F66821C3B8B974CBEB27BDD80AF162ACFA954BC2207A825A4086ACD0110C677B06653F3E8D34024A01810087E55740AC10EED1E104A839EC2ADF4627FA659F4988238F25AE00B756BFCB2660A0F840DD96EC3093B3AEBCDF20EA99345FD75AE8609C4332B1A436C93B1CCA940C523FF3CA2C4C22B1E60FB7778301FC9A6D0107475433F96D086E3AF105660F7AACE01CB697BC2F495C71ABEF7B3077C75F4AEE329EB5BF9E8AFF82261C0676734C1D85312E9CC0559E26FFC2382C2E123E680F7A22F3AE9A508B856333E36155B5706A7D94596CD131AFF869168D93E45632C9F04E96479532273069D838618B606712A6BBAC7F28275B4636A32D20E677BBA12BA75286545DBE61A9D1DF7AECEBA0896017E9129CE5364A76C1E9EC4AED8E903DA3599BCE44EE44C9E3CEB67870D7D3F815B1B83E8E655A57A167C9AC6AF4B36601C726D78E1A6AA7B3A73F81CC0C8543E67883AA525DA0B828D91ED510E6EEB29AD92649947FAA463EAAB93583CE2BEFF1308D4B1125892F02AEBEDD1AB9A7611C4FEE5ACBB9BA8634169DB9AC73BB0704D1F8F6098CA76F2FA504D8825564A30A1D7E6E12690DE34C0521FE70D15714626DEBC8008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 0000000100000002061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1021 +max = 1023 + +count = 2 +seed = E7D9E1A1D2B81EFE0556C01A7386489B692F4669717A09BB491A7DEC9893F44D2758E633658AB5479168CC719711E2ED +mlen = 99 +msg = 955F970C4CEA3EDFBA0CDCA55FBF59EDF24663E837973E11658FCDD8307A9101FA2E13C4CB23F588EFF1A5201C77E9F734EAB8C76A7C5DF78A6DD8DC5F17DCFBEEED73C7B940F6D4B711CB8856B2E1653D246506DAFD05EE812D6476B53C920E0ADB6F +smlen = 2500 +sm = 00000002C8299416D392EA9885BC2583B1AC67F96AD84D563D0C301C02EA868E744C7BA3C1C7DCB7ACD5DAB40839E3945B0784FF1AD07B1E52812722E7E525CFA0B0615721FCE84472139AFAA7E03AB9D43D62C1C9F71FF0B83EE68E13E96E2D61F27BAFA1FBF91365E6E2AE524E2781040BD0040AE61C59F2BD111C6A67F4F348F25710EA652F452FFDD770306DCF94AAB169F987EAE7F7FB2617A492F9DA54BEE07689400BA5C77FBF6EA54D933F8B84D82664CBCA37FA896294DD3CB06165DCC1CC71083D74D6EEB4C0CC84864C038A52E7BCECBA7E026E4F1ABD3AD53A24F4A0F6A56DF3E0A45AF1F015FB39B04D695ABD9767EEE724D542DE41C23CE1360A69C6A0AECBBB5FA37B67777B066276DD82EF020ADCDEDE2087999C418351EFC54FC1787855C75DE7041402F8EE569D5AE49DADC3E7501F4FC1D9C7AA685E9647BEA04075EC25C3D1C4DDAE1DAB5DBC54A403B7B8B1BBB96751953B33275CFD3B1EB733292E94B32648E31BD4C6591E9705A09598C9C3F9B1FFCDEB10FC9A47C6D4B6B5E45493CC706FE39F27EA164F88DF41E164A16AE2B248E547F4198BD08A5530B5E54089FD91B6F93C533AADC2FE8C1833C8C364A047809E733036A632A91B9EE037FFDAB49021952A3808C4B8E3AD4CCCC7DD28B61C51897E4A5E0A99EC095900D5AD1A2C15685A9D8F56059AC53EAF595374DBA8E2AD2929F8ED6E1C6304831A9D6E3BE0AA1B5681C04D2E8A0300231C121CC1E92B9526D8E797822A7C5718399AFDC5306A868C20BC0F54DBEB95FA711EC79E53F0E1320FAC24BFADCEBA31B956370596A49A071C7A766EBE2118D73F2E39EB59E78BE49F74765FA0134C9B73DCA1A839FB9CC70388FE51E18922B67CF4D08765084E11CE5D45AAF87DD932AE5647C5AC2F88CBCE3FAF67C6035F40781D219C01B84A6728BD4DCD1B173C91FC69798EF1E6EC4F6E8C48A1ED68B917B7D35F3DDC88553F816A4C0F084F56E7D245430F13902459AD609E2EE59B0CDBFC46B823B0922EE41373AF43702E9F093972EE41CAD6F128317B718E87E1FA6185ADFD4C1AFEC61083E3BA5A0D22CE367FD25B98BD3A660399CD4D8A7F608C4BC0CDDE993E57EF92C1FD6EECA542D94FDD77BB0A4B1B99CE7D7E53347B7CCCE13FDA6F8F458DED1B91CAE8CED28FF8D7E39C4F144832E3223E874507BE3AB9718F6240DE0A18CF2DDCD2786940DA86517B3CBE792D5095707ACC08758CBBC307A263FA31A736F6E61EB09EF6BFF82BA7A3273B619878568D62E21D1F15A758E1E83DDCAE6BDE013494DA308A55B5B1E2FFEAF690E04BF725A3C998250067D6320A9A61B3156A5F2A4B4D53BECD0169A0C10BCC0494C2B51BA2C4904CB6A36F7D302810829CBD03E11A8BEDFE4A1ED70FF1E28992B0BBAB3BB43EDD2BBEC8C943E9382B47E24E442264060C61A826EE9812EF305EF83DFA429B7BB0DAAD700AFD47C91F01D046B398B877FF896B437DEB2D4489016CAC266D5B970013229EA33C93909B75ED6755F2FE72E1E3C90613866F85862E70227320B98A4183C4D5C04135A54987088FB17B56D1868102D1B928FC2801ABAF7B05EF137427317EA41BC44564C7BA0A4D7B1A11E494FA15D2915C5AF412AC1CE800A713528774E7B3A74FE03B83F4E30E85570F8BDA6274CF673819B6D43A4B5723B6F06E5B4C55A0D87A424816817AF489E51E8ABDBE6401FAF4732EAAC864E4A6CDD22976BE385E2EE95613FDC2743A7F9A1D60B57C364A58F4F49D414C419671852CE004CF21A2A612BA8157FD0BB2A8A2B630583AC660AF8D220C628BDEAE4973CA3BD6ACCE2193EC091E5F39B7BF0F6AE5CDCC606DBDE2FB25C81106D1B9096D22BC5562B1FD0459BF4DDB6DA835C4C63056D93EF434A55A09CF08053F05FC36FB05425A34E0203B17652B243A2330EAF2F3643EF9A38E3148D71A6B1DA95E4ABCB40376E606FA666623A2597D537B30B0846CD393CFFEF276D91656137FB596E9D9906265764B37DF4725C2BCF0E6E3BD3CFEA76CE098151FACD13AF3D43DBF1E0046ECEEC801CB1FDFB9DF6EBC5117199D98E8C60C5693D629B52334342A4605CF12C7DA172C094E6A48A74A1601F057B3DBE7D5EFB8699339A0EA6DE835507F830C3F36F5B7BAF338E3CBDFAA42E79DA29CBE2C64431890592D97485BCE2608E8B34788A17914CD59B485FFE5297BD2860AA661EB69456862EC5C68C9F5E365F90C1E42BA3B0AFDF3AF05859929EE65DEFE3C54117C05931164C42C6598C85F48D46F0AD243E59EAF0165439D934A56AAA3EEC4B123178BB2828C4F1A19484D3B832E1D376A3BCBBBB13DF1F792CF11BA16E2AC13A000431B48050E581D31696F40D1BFB3C17E98E240F2F8A49D0407E42C80169D19B37EC4046D3D60A15310DC58781060C0B53380667B7B0A13128789C0A9C83486C25F244C1549E80C7769ED738F3E00ED937CB5910B8DCF67F9EB7AED39FAB6F5C7EE9FA05CDED2148CA9E3DF2DF81B9643DF4538FD888A1BF99BEEA7378EA6B6EB86868514A9EF808FF1071FFF8D5D48A2BE6AE9D2404D9AC87D394B3A533CCE8C4A656DC649975BA1CB7F631F210BD285B0FF1BB6874B2B81A9848AED264BA8224889D65C0C64FAA546A6ECD9BC5674FAFC959C1418C0A3662A7DFAE6BDE9DCCEA5B5BDAD952DFC7FB1B969078189F691578B0F5F30343311CF6C1E629CC292A1746104BF422EC21422C15283525D9A3ACDCC9014366F20E2E17BB6D3039DCD8395C61905C23B540F4BB01E817E23FC3723E4AC95FF04BDBDBDC7D70AA1621E7C3AA13E9AC66F057EC0DC6CCF460F969CEEA3002206B2BF88093E28C24F70F1704FAE79F6521951C5B714AA2F0837A179D7B6B49C438D4CE5A8DFC8D660735C1FFF405E406ADF6EEB8D01172B4CCBA596DCCA0C1C92E50AC42D6C5F2E440D25C796456B756D4C857B0E46EDFCA5B5B648A9662C16AF94EFBCB1511027721DBE0537176E4808FDFA6A226E5552A279DE132C70DE7504A5B61A036A86A67EF126FF6F609A4887B589F12FD447180A82EE1BB355DC3216777E0A698D7BF588226E4D442E50847743F3E300BFC9EECC8C8888F69FECF8E95A015A5998F0E1BC3B4948C0EEA76004F507747FA63CDF4A10E802DC40928F4192B84EC2A9FB98D7DBD6AA556098CA76F2FA504D8825564A30A1D7E6E12690DE34C0521FE70D15714626DEBC8008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 0000000100000003061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1020 +max = 1023 + +count = 3 +seed = A344668712D7FF31F511B249BAD15D46C184C9D38442540190DD21E5E784989C56CFB7CDA3336E290F1344AC5AFFFCD1 +mlen = 132 +msg = 3472BE99A4F7CD9261B7F97B0A846790A252CF5A53035D4A6A31B5425F0852F0A63E630D97CC57A455EEF0FA171F7A06C0454D8D3713D47638C01BDB4855DE167C33019780B5EAB0D521E80F536D354756DB0D253A83674F74BE657B0B5681E0696C4294C80B712743EF9AFEC9AE6424C8C8A1810D4BB010F47FEC835AF7F65B40586CFC +smlen = 2500 +sm = 0000000368D0AF9AB3B4981A5A3687839F654ED9958EA0B19666AB0A0D13C7ACA213DB148F827E8E20518BCCBA7D22ABE71110838318A6A5FAB7278330DEFEE172F470802774094D528C66BF6CF628E256721F18E998AC89E94F4CC64B87D4A7B33CBD2EF85DC2FEC2584EA9B7A65C674917AA475663107C608FBF993520F53E87966D52C2C13C93E7B84AF63F2ADA035DADC96B0E4B3FCFA8C1C4F9C3C96866D0ACA6C7942A9C15EC1D25754A12E86B88E4903A1922D10C6378DCFE38CC7ADEB898384718ED44C328936A0C0254B76D6B6E2BEF0175B1C1CB700E724DC4CADEDFAFD35C7D054E351B7AF0E82762710952790318BE12D2D860E8635E7803A1222D4ABF87EA0D656B659D634F0454A730BB92D5E80CA6446BD798021D6B6D19FFF79859BB30D70D77144591CB86ECFC91F3236AD24176B2E8FD36DE8FED94344B3D6DCE6C136830E439ADB5C558B5DB23F5531C07DDE74EB158774D566B086EECCC5C5A7EC0EA44F1996FE3A9D3B8C39990CFED6E9D9A29B8360672B0B9F3D1B50F66775868B7EB8E94FDC741D21B7DF68E9404188EAA65965944F2036EB61F41F504D3796A154024CA4CEE846F948D67A13F820F045B4F92576749BC63692A1C184F20544C301255510F4F869721362B71D46A1B3FC103C97D16139770A8FC3A5304D7B0A82BF68518B8F6246DB32F6A73E787C6DA515D788951132F3DA9C6854599F0B97612F0D26A0AC31B0F28C87509FCD1B044E60322181263AA54DB4E2DAD046D81973EA7FD836A66D2826947DAEF5BB7C9646605E245F4AE8C331D39C585E5912D09A596D5EB66B9DBCF3765E9DF7F79BCE194FB3788A24E22210171FB985E573FE67488A941D7141B041038EA1A1E2DA34898EB8C0D79290657222ADEB49B5696D0211B9B748FEF3CF99FDF7F9FA234F5ED38BCAC44A716AD831D1085CD7CED7AE5C24B2A3C28FBF0970B4C367FF65D650234E1ADCB9BF8D874C66B66AD48DD35D01703F8FDAFEB791574750946C6BEFE20E3BB291294153BBC0D4FDBB05801BB271C4E5D67E7CBE825F03C458065B60C4E30F645BCB7700EBD90400C80843D83F5C70E3B0A6F53BD12C6525D3E37AC18274714D5CA4F9FF0D5A199A679C1B361E845427623375CC168C626D7770F23FFD26BC8121F1F37914D9C6F7758D06CA02129433945C4C975BA76FEDC0EFEB4E447B81D9333145EB86212387381C20A8AD70209008A2EAD4B56A0BDC84B706FEC1ABE2C60A096B83E345405B64EADD4786238C59303E195C5C8DE499696CCE53CD1A469E06EEE0916EB84A04B46B7809A92B6664F97483091B3F239E14D947190CEEAC71B270A1CB730886490CD8847053B9DF24F82D7A857DA3DBE952349556469BB4AD4AD70156BD1D64AC13D822F43DBA949C54CB47B0E75D116E96CFE87BB0E5B21D643B45D143F5977AB27F53BF4724B3CAEC8DF9B158A2013943BB524D1956DDBFEEC65B49CBA2306CDC188A0F18D38728E44C13ED3D309FDF4E8D33F33308273B955620686B057BA2C84BCDECF0AD37C19B4960C5B1B06D89F151E437E8963627EB667D41DF5A1BB89B271E3A5DC2DA0541B13B1212FB2578EF75013B1BFA40944D685041E82958A195475E95132C8B17BF2A090D54B00558773964B2BFC8B1EF89FEB193F0A0646C32FF4CFF26B3EFC3770662A75C3BD7D93FC58C68FE89CEBDE9B4E8C522A81E9DFA925ADCD471E27315BE08E3FD414A558ACB91D0C8BFAD659F1C45D2BE45B1B62CCECDC048EAA7B386F90244E3C2473DD550A3FDF5E1EA3DA65E789065918F8C920586AE31B8DEB3BF6442DC9FC09186CA79221850E4CA7D42CA426DBE5544E0CDA7CC27DFE210739C5D2D5A0AAD80C0F3BFFF0805F71805B5C668CFED02443CDA7A36F8FD317D8E24FEDC58385E31CB94BE00B84F5CCD188A6F0762E4F2CFE25DF4136F70892CAF5AE197556EC733C161661DABF09C3C3CA9F600E23DC9FCD9C843EA4412B2A6E0C5FAA0E67755453FC72DB4024F6A6C09ECEC00FEAF0E8AADA220317902A734CA430C84E5699DE750674A9F7CAB447DBB937E431018A050ADF6D526246767F7CB0DDF8D63BF122831FDC1686670825CA16A261534A48E712D0A5E0E68A77265EFAD238D63310B616E036C198F73D88EE6FAA0A7352A108695DC86C0CB4FEEE07719B876DCB7604C180416F6057E32455A0D7C8920DFEC3B91B9BC873629CA3D001467059D66C9E2EF4F31E2C92178C27CF24B9722FFE355C32A14951B75D53D8ED8FFA99693BD41AAD51964F7E44AD6477F9D2CE0DA2DF930AEE3904338222C51133132B0FC497A1F0B822CFB2DFC449E10F7D5B080B89920B486518FEA8AC14CF572D373A823EBC0733206DCCE604450000CA95838163BC0DB200509110E1A877221F3CDFD74DCB4895AD12AE02F30352627DA55CE4FCC0752BC84D0D88C702A030952D6A7BB43FA817D2DDABC20E5D49E8B165F2A828E1E8A0CD2E65A56287083F88F11E6D6FA76255EC84E8554E607B7F427E408A5BDF93436F9F45C2C5E850E521E12ACE3CE6964859EC4EF0B3193C3FEAF199B7B1C52EFC3617231425954F781AD53472D1312ED78A9B53C2948C2CC281E74EA8FD843265D296A0053F28EC6EE9D02BA1634A3E0A7A62C316E691CA98D5948880EF1A4210030964892AFF3E326AC29526AAA79AD83A65590F223B7E102CB44F49A2BD383887385D9FC294E5FACF72E7D358E212819DCD08AA6C0CBC366CA970DB76EE5F2FDBD89F84FA7766BAA12105E26645E9AA93DA0015C16A8C67D8C53263E83D276770C393F8807C2FDA9000F3237D50A0C246EDFEEF87157AAE7173344B0E562A10C62F252AD8B31C25EBAB7BD44F51A70FE560D6391374ACD07BFD372EF6FA019CFD1F938AAA6A243942809F13952161094F08DCA33C02F988217392F69DF32B4F8EE75AD6BF0EEB02C9A8EA177DC6C87B51B59E4CDB39C1C8E7269444E362B3755BEE8D8F9FE6D87E68B2452B2CE2B06A25FECD41D92EBB2C8F98C2548623DB4E4B37C486C85EA8F078772D5A679D6F08CC187675911260EB42DB4EEDB7D7B0C385EB20D612A9B8A8A9A515C8D5BDDEDBA678A89F26DEEC24B5AA0C071B27554573250CEEA76004F507747FA63CDF4A10E802DC40928F4192B84EC2A9FB98D7DBD6AA556098CA76F2FA504D8825564A30A1D7E6E12690DE34C0521FE70D15714626DEBC8008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 0000000100000004061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1019 +max = 1023 + +count = 4 +seed = 2629FBED0B88DCD29C3E7553B2B8C209455EEFFF7E8A3EDBA39BB1C2B4F3F1B0DAB5D1CE55060B1FAD562F945433DDC4 +mlen = 165 +msg = 1911306403C3C794EE57605D2FE311F4509324371103F69724087A7247687CD25FDD0C97319D6315E262EA581BB61987D5AAB33F331C7A7B260E92285C168DCECFC70D164D7A23110A165F456F22256A77AB7F0C5E5A69C91D7551ED437ABCB9B3101B8BD794D1939F372BEA8C5586BA15528BC4E4FEEBDD9904DF943513AA0E01FE67DF25E8F3075FC2EECB775DD2BE8D9D3EDFAD05762DD0BF1C228252BF2BFC7AD6A8A4 +smlen = 2500 +sm = 00000004F5577C9A22BA344F5F1F043B0D44721479D551BFFC0E507537E00A68CC13F73953A1229456CE0BCC2CB8E307B0117CC4166ACAA913EFC07C79D90CF54E2A8DEC96C5FF3C062CE9D634B0A1A562E7013733A934CF4B40DB2973F82FEF1C39532CF1D1A3A3E8E388AE133EF365C8F9F70CFA87DF5DCAD0D4295E0D8B6DDA3C83D729D7C1BFAF88C369D8C27564B2463171208AF1968F0C996613370B95EA9693D8152DF3B4A2D369FED6CD83DE8F81F7DD4BEB3B71A1441E3E6F37C5596F5BECACA70F7281762869CB2AB90D62557847B0AC6BBFB9486F471EE680CD8EF8E5B8B983BB876EDDDBF042D55BD96B0B6E7B29D51735A1F1319A10F5A007B98C3901D20D9734B79191DECBF5A19DD8508E22286E56373E9BD62C32BEBABF80617EE842F201A486FF8210B929BBADF6598B117D59CB623B839C93E87E1353279BC62203DD32C4838DBD0134577F633201B1E2368E517A33DF664CFB9F8B965A1B47DABEE48887D08FB2AE7586FFF0D4DFAB573F3003AE1F92C4A8DF5E992E123E38D7F980CEE7E2EB2B89CFD25BA8C8C57858A7B18118A7F57688EDFE98EB053B168140375439F281A55A610FF6C82FCE9580D66970862E149012CF4FD56F9A6899DC7A9EAB77D3514476B1D99ABC7A4F2B94EF04264CF810EF6EA9F8CD8098727AFBAD99F9DE5A4D6BF0D782FE0BBC47DB266A1699A70AE9BD276058A326A3B48E9C90A0316B774A766AE6D4518EDAE4D54560A554213C6121D8073BD1DA2D3B46961D6CA5B56AFC3CA5C5652B4A66B08D7CA9175F8D7E9368404079660BED6B7EF7AF0AC1AE89D102F0FF62C6FB8197DBD91AB2C61A041ED2E151583CBE57B99BD3645C5E2B0CB134BC7F313DEE1ACDF05124B69BC23E229FBE6328A5DC96F530481E397995B2B1D4F2E1520396EA226E00DF7158095212059B009A595FA280D074A8436041BB7878E3A50FF7EC5B7DA6EA5B60F733A8F43F5B8014DD403320F899A22D147228847BA65CCF10CDD8EDCF1B386D4F3B32663D4328562DBF528726261EAA4ED1EA6EA25039879A334D522C4ED989CDCB7B16FFE382701301CA6F3249450A279F04E9141C77E96649FA91972B9621AE55F7FE20DB34F886BAA0DB045E27AC8CDA897B64BAC0C730E616D11266DA4EFC8831B3798AAD9F3B5A9B338BD570A65542B5BC6280CFABBFBBF91D72915F5EAD42BEAFC9EF37AE5F676FC71131490BBC5CFA1D31F31BAF268B0956ED80EA6EE67CCC24E575EF2F405BA0AD453E491BA7BCF8D64BC9244C5B7B5A5243677ADDACE8743F75ED78D1D639F843380967CBF6E1B28A89B6F9F2B6748D993A4FB93BA0792DC331BA9073227DE2AE187A4118F296C95554B7075ECBD798327963322D1BC1F53B96551B8AD04C0F5106F02D6175A3DF5759A88EC1B3E9C4A93E5E9C662D39458F809FED357733F0DC98F0EB1A129DBF7AF4506CA23FE71C99C203AE1ED1D1F845BF904120EA102010E7839C789FA1EDDAB2C119AC31C93AE0FBB043D349C5800C795EB296095B296407C735A4398CD271AE3EB82DC844A33BAC423FF061D1C8AD83F1A5F277E87C9257612E7DF97169EC5064CAD3EC5D6023EA16AB0C86ADDAF13AB379D279F93E2610AE1E857DC769558335BF490DF208F8FEC57EAD1040F4DF3CAD9E319F66716E3DE25C81ECC797E73F7F520083D41369B16B5C521C0A84BDAD190F6E7BFEAB0640BCBC5339B5102441578C533E89982246D3A05CE329D203B3E9ABD016126DC3CC80116F5B9E6524A37305424F10280B3E14102548326C940B7CCE9A272DFC170DEB86C1BC48817D8D307513070EB341D0FCA9E9C17CB4EEE5DBEB61A2D503289EE4BBB7520C2E934E9BB15A2476BF1111A5D0F6573DD92B28C7DFDA5AF8F82C813EF2B72AD81FCED64DF903ACCF98EB33B8F71787F4DC780B5E3E3855B407C90FAAA62B210B23935F826FEEA939014C11EBC14083FF149354C4137602AB34673E8FEA7A0820302D4306BDA77AB22C414A7C0ECA857F9014BC4CD80249653EB51A36B83572CA45C9CBA732F93410F7F01E1B0BBC705A66C7625BD701C7D2A42181945416196B8E9756CC2D43F4669001505D00E025AA8E1B3BA8BA1EA2F062C70FAA3F6B254ED8E3A28EB72DEFC5204C76697EF6D95FBB3C94A63E5D8CAA1ABAD7C140D8C8BEDA8FF2F3B5828D26E63C680D5D034C59B0CEF85EE333AE73CEDDB2200F7551A0692D03A93FB23BF54CADB3EA26C06E016B632A4999750ACEBBFE52465F9B84618D445FB24BE42EC349CAA9608A2BFF39609F076C44388F654868B167480575C8AD72DE99BAE9CA3392F1718428C259D2F60EDDDA26F8D09FF8FAA2DAED50AFDE4063EDB37749A1E172A435EAE2030AD118C5953BB9329BAF06B4CF6F8A391D1AA908C684EF5FC855453F29933BDC17FCD73A282B411DDA3BBBCD3B3DEBEE0AB91E627203570CD3B8459872849984F72E3DD71ED762DDD7F3E32252F6B339D18AD5D0A6B5D9D2DB81016175A7E42529DDB7F15DE23CD75A241624C5B9C91749FA5CC9800CF5FBA04A03FF97FF67FDEA4F728653A6407110CDA74F2E5AE159742AE0620D1405213B6C101823FA07D454DAD1A0355BD592BE6EF059AEA34923587A34A9A9BFB75CAF93C400E2044C852FA6A9A8EFAF1A0614A06352E6DEDCAB1A10E52A7B29ED5D48821788DF5C5C12431983A9D1539A4D914DB99F5A3C8833C91140238AF60DBFC0FD7DC60E99DB34763EA9CF1BA4AD306A3B6ED36286B681AF9D5C215DB0216852A6FBBD0EC828FB756E7A2285251B490CBB4273F9ACEA149BC878383D01200C9781D063E3932A847A223F58582DDA86F2422C0CA1A991CA1ADCDB41B97DE0EB6C24DF2400626719D9B99B78B66696168E6209FB4C31B4089AFED7167D10512200BC1133590A8FFEB4861E0E4D87648DBEB9446862663AD4570877A84E8CD6755CEA8EB7B79B0B21DC390176867215C7032BD92BBC7A81B464737B62AC6F7BF5D92551718233A7DBE37EC33B1804763C025426A6778757E004E043FA9F5C89A8044992762C3734D092CF23D04EB8D9F665055FE6A256E4DE0795896F08B1B3F04E10B5553476D48EA669EBF6A5090A83BC1A00F9596E70E6F751B0A3F7C0F30D15B08B42EB0D30A5C1B528078FA366959BC1D592D86E3555A4820740E272AA2CD85C8E05202C13B89A93260496DED8FCD03F614D953E978008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 0000000100000005061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1018 +max = 1023 + +count = 5 +seed = 13E884A522FABD17D2E055694A6D931C6459A17FDFA40131E19788DC572A47056670439565685510E54B3BB94D67226D +mlen = 198 +msg = 3A46A3D825C949B1E8E68F01B523B88347F0F249F6BDC0129A11CD46F11DAB4C11CB14FCD062A67A76C0EF2798D3586968EFBC619DD949ECBA08099B3A55F6917DD922DF985F769BBC53AA03D93E029DDE2B19FC02147BFE4B4756A560C75DEF13DB7104D5A6A238ABD0364A3B3EFB7A50754528D75E47FD8349B0D88569FCAF3382FB8C6C23CC52BB87B75454A0AFBAEC15F2A19EAEAD8C8FC15668CE37C8C1BBAA75F705B9804F2C942880C01C170D8CAA3C3743A91D569837DD84B50569F52302F8066600 +smlen = 2500 +sm = 0000000549F101925AB0FD811DF00BE2C75202021F2CD6DFBC82A8B38FB3A288863E316D4089B9994A97AE8AFC236A3C6B933AA82BF624CDFC8275E3D738E9F8B70B9F28705F444E6BA204F90AE9765DF09D51F8FD493B16385FB50C264D7FBEFC02912CBB280C74523E42361691E4415E749A27F3DB2F9E7145E9FA37A41E31316D5AE4AA386427D27F0C6989EAA280FBED66B67B3BFE1FE40F4C2B3C6829EFB834F0194E36A6D5B827747380A96C03FC8D21BE870FD98865BC822DB92A43413511AA3A0AB5EB2873A5E59764F5314677CDAF139B586A0FBD262A9C1672784156CDE6D5B933E36A67995B12FEE129EF362057ADD48C9F1B99251EA903975CA2D25036E74DC518F519A5182961B92256C810890595A156372328DD4DB4BA457A4CA4CF38B2F88AFB1420B5B63D295D38ADA7D44D7C818F7726CF566E5211E421B8DDCB20C265AEEB830AAFD60ED271067EF5B551A448CA78BBA817067D97D83A0696BCFEB6AAF5DAF64856CB08228CB09EC185C4ED7D6B331D49AE6AC8CB359D93B0C4AA7818C9B53B5B3DC7D08F4706EDEB62777707C0F322065B9A8AB683171115821677D85ECC1E7ABFEB6FDD609A7D1CE0CA13564E5723908FC997EB8B2D5C020EBCC82A09F3A03A49D2514003EAF26BEE005699C461069C7248DC80B903949B4652347FFE0361400DEC51D4513E48D4CA655A72B42633200259FFD2C00FF686F9A3678ED5BE780A1273CDF2DE1CE1BDD2EC627289D2407C7883A50BD752193944D927F9AAE86831475BCB5C933F053C46CC441A8007F4461397AD391F0E5BF9C40545FE403A7C2B82E25FB43578941554BB92BF47858AE719435DFCB6E34BFF2D018BF92C0A5F4DF75DB6F0BCB1E46B68F7ACB514CFBE11D2093DD8E966180EE009FEF7DC83B9E7D6126CBFE1172D32A74C9214D8FA7BB438B8225D213939151FCD463FE7AA412B0E5764359E43F2C8844D56B04ECE2CD254094DC351A8063FD892F4C04916DE2FF996E91F9C3AB7591F16ECAA108890F5AA4907BE6A99E5537DB234B5CA31927AE36835FA74F596A0E81D52DAC70E10AA0E5405D49136EDAF38838C37F2F76C195F7B3550E609FE6C8BB34038C0105EFC2469E367437F9BAA60B6B34D50584B4BD45AE85944A639734DC8D7FA21CCBED43811F9C593DBFE64DE8D7BBFEF68AD641137B40BCA3077EB58A632A09BB5EDA3C27EDBDB54E5AB1D7F430C9748C700BF4DC00E8820EC4CD825D899E1CFFC8428DF6698C0BA957281BF123A3EEA5F4110B32C36DFD114F54F3C89EC0475C46BE27A72D049D5F959457852BE47D7D88F91D5364C0DBA8A18AFF9CE8D7329562C1E89A7EB7AEA5E8F0039D89CEFED8A3E4BF04A201522C6EE71C17CAB5A93A063EDC4A3065372F089D7E41B435738F61C0B2E5F93DFE69B83F2BA25E2625DD27EE25D2777BB5472ACE985A4294D6A6496E3A99F02E0475F9A3ADB55E58A5B9F4B8345D931CC0119AA1820AE167DDD88423D632A563DBB0B22BF72105879594E5B09152324803258E981EFD9083FADD7E581F42AA9FBB109D63DDD83FD5635C58B9B8F3A53B8A2278BC7E8435CCF8C7E713552AD0A92854137F2F564CC9D659168CD8FF073623843957A342C9A78B4964A22DE1B1D72625F9B9F2F6C74FCA632FC09EDD8EDD2A5B846CDEE8ECB9CD932F16D6E3F23C0CA047A3F3E53B0BC18F442656AA1E271CF61C8A13A0CFBA7641A5A09713D75DC732CF9B29A73CFD5BCDD8F8ED2E8F3A1688AFB539CFF010D49641D753CBEB055985369F362C6D310C5FCDD2A270A2445E9CD5C8990BEB3A34C7C5BDD350CFE136E165C21BD7BF78FA4CB9174AA23F925D9824C2505E08A1FBE1D090E366D1BCD42978C6B48E855EB4A9693A3AE93C22B673695519976560C84188D3353C2EB5C864B71A3C66489DD368D3A83376ECA99AA7FA83709A12EF6FC1E6B82FB70FA258E7171761D963F2CC8CD2A4D30A1FBE73BFB606CA6114AE3F9D038FE259FDC1E5C552E49C21694D378EA54351313DD8740CAD5E6140526AA7EEC0627ADB8DCC5096425270CB32618FE5C6F068E934EC222248F80AB1718AF9E0E737588C1BF08F7B602ED635E060809F02F76238A7743774FCB1E6361FE16D4EE275F70A518FCDB1DEB675AD29873C78A651018B125FE05B61A124A336739CC0A5033A3E83FA87785FBC3C0BB14BDD143465505BDBF9FD96F3FFC6BEE0999CA1D857DCF6C6CBCE8520E7A5D095DB288FFF07D9B98F579DA18A374C1CE1C59A73AA409A8BE98B90415168FB55EFDD97EDEF5AEFD8B3B78F98565F1964CDBE714D1006F97F3D0DB5463974AF951DE47059C5F1215C7CA8ECFC34C9AEAC679C849E39AD4FF2C55D9917AEA1802E326B59D46538841333E6B3BC210D8217F4CA0F6D27695ECFC02EA7D24A04A10373FE455FC22B805147592954131E2F898B04CEC953DA2284DB98AEE5C19B4F9F527D8172A63AD650BACB3EB29097A171C1CC63CF98D01F0A36A3B2B74B683F9F5D14390A864461D1DD8E5E125C76C367A6FA5102C2DBC2250874DC395DF8D2B94B5627EF2C4242D067006F44544763F30A76D956B9E34EF0BA9FA7AACE7E15941DDEB407CE208AC58C82681BB9308CE30BA4F0D1CBE55174771EF0ABE277FD38C0C5506625D7F5B0CD361BA4BFEFFAFE08B9283A00267F71F5689F0D7F1D281C63A06003718881FBD01F425D7719393653D22882F039656D33EDDC4AFB3B15921D85D5896CC2C50085874D62AFE96FE98830A294F102768CE4D22548AB1C8E854783243A88C401402D7643C091CFD48CF6112E056AF6A9AEECC897F6B9FE951547CC633AE8C3A60C7C1DFAEE5A11908BAF8C77BBC92D851B52A7F49C5AEE0A3AB47FB65F49EB80E5E93453A022B0DF239BB99070BFCD354E2F7490841785AAA58F4655A1837E30A710BD43BB7DFB1A390D53E7D557E2630256989B4B945DA4A4FE88FACD5BABDBF179A7543C366E07BB0C77280613105CC9AAC4093E8A277130907AD172CFF1DC09C00BDB99687EBC2D59076E8E23E9CAA773C686AB2BAADE15865663C4D94834171FBE5A670FEE2FE269FA8394841FF6C2A3227E8EDE85215C74AB6A8C66DCB3B1C709614F01DE3EF6AE6F751B0A3F7C0F30D15B08B42EB0D30A5C1B528078FA366959BC1D592D86E3555A4820740E272AA2CD85C8E05202C13B89A93260496DED8FCD03F614D953E978008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 0000000100000006061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1017 +max = 1023 + +count = 6 +seed = 473EE54361C6786036B3540D9307B3C09FA9C85FA8A210CA9FBAA3690FCD7A0D9E64793F20E9D2D40F6426C0C7B7CC3A +mlen = 231 +msg = 8A2290A20898F46A2F922A0F9E2565C7E5AF20868E6C18D7D4F659C10F0A3FA2FC4BFB6BB19E9E09DADBAEE668F8A2FBD29B1591AB80738BA63EEEC291073B9DE0F5D44B53952C940DBECC8CFEAEC7B598135BEEAAEB2A0DFD8D55F9F51A10BEFCEFF594E74BF6FDB972BF4B9B514A03A5954C6FB09FB0640CD854ED6A9E62B4E98291C3DB7D2E19EB730A865CA6239869868F512BB38C4020FEB9554B9F5631E5A5ED00562B6A665CEA045CB66A5B7437EA4E2E55EF70656A9BE301CA3577CE909BA413A8A78371A493FAB5E89FB8D836E90F560857670E3761430A9364ACC32D7005543D8541 +smlen = 2500 +sm = 00000006EE07C35A8551A62496DE1C658EA679C4EB861964165B282F6BE686038253E3AB824C03BDFE794D985AF23AF4FE2C7D99E7B937CE00A56EEF7FB838EDD55B8B6F0F2351ED5A4BCA9A6069484DA843D459877DFDFF32CDF084A375C0AF4652683D10E44DEBF3C18F1DCC249934E0D3820BB77879ECB9569C4DDC24ED1AD4F7E8C8F3EA59866C2B1CA98BA038C06EBB90AD8D55C54D55C494DBC18B6CD68A92FD6250535E0470B9EB2BAAAEB5E138FDBED73008F6D78CA8AAC316BACCD9D26BB3D438C8E92E702F6DCF48B8BC696D633DBA5DC00683E55C823B14FEA4B3B515A78FCAAAF5E4ABABE932375B23F22F63128A331320E773B713A26C2F60787A82001DD43CD62E536F48B3EC2057E543D5A4269152FBE28B8DCEDD7D7E0619A29E17CAC3CD37B0FA7578739680E529225F1F339F4728145BAB14C18DC46C0AD95F20B9655DEF9749F7CFDD61B9B463A113082C3CC27524DED08D7E973CA017A6A783AA6B6593ED9BAA72026CD8F448D4568EDA5B5356EA1FA7383E6BE65C1C99506763CC75BDAC698537D492C6125A1898F336D4783337446A90DD492AB708FE436B28C94666C9575345B6E624E08D037240E93624C07B2A8A8D00A126783ADC599ED686332C26D8CE020490B8FF89DBDA3D922E30011436454AE5B56925BF0577BDCC9FA13DF431B2DD67E465CEB310470188850C4974CB29C49AE1DCAFEC474371973D863790FE4B5FCD5D1B6385F8A2E4D89D0B4F0C1B66F614633CA1C70E6B965FB35E287FEEE7C75C49EE8E779A3163C9088089D490E4F5499C5E7645253A193FE04FECD5DF49C1773EEFFD87C8D8E27C6807F66A1FB2F39A130B92281F37A0F5FA33D948E02EFA3F95AECA8E30E69F81AC0184E79715FBECA388468ECD41F93E518888ABF3F889617B27701D6A90B8C4C316E01821FDA25C675683AE08BDCB221D7D07E8F5886DDCFB8EA909A140B0EC9532170885AA44D8431A6AF7278B00F4BDA9E361592A552BA719C8C2D8B4789B4D7032DBC1BAEC2D54B58AA294926EFF7897A17DCF62C17CA8AADDE2CA9D535E17C45941F570371B0FC251B71668BDA3DF52F974E8D39E9588A3EFB5D67FD81E120E2FEEE49DDFBEA48C792E427A5BC2E31BA4486BAA224AFD29F8B44C4460D34F5ACE470B11830361102A0676D4F367716F4C337E33F599E6B109B0106E74C4F458AF084C47E52583239386656E9FAC487EFFBE24539F83B398D643BDE10E38F399C45C5768748D1D56DFA4958A33B0DF1C853DDCAFD31E4CCE279102297B3834A26BF59AF85285A6032BFCB9C47F11FAD42111FBD3BB84D283EB72B2484FD6FB10751444E10ADE45FF2FF2684D332080DA03A2B9C7E60D0BF3386DB98EBD745273EA8A4BFE54DD1021C2547568A4C4EC8E217147A6E4291BAC5643962B5D61105568E50A2A068422B2D555EFCCB2D940DEA1E0C675B910B799635F7C492F53BFE784094B43156632994123B197B1F616BD776A205600D43F65AEC6564AEFA1490D1FA688AA10111CEEAD764E4068BD720D9F6F18A78A99FD5AF3936252BE3DCCDB6A23B44713C5BB5F0CE37E32B114C86A2D507CC6AE84A1AD7AE601D4711BC4E249D34533A291E6FD309DD2CD9AB11CFA8269F7A1F898C3FB54AFC0E889A477E8FF06FCAB49039FFB0DC278820C1B51F7E3C57A2D5C23D832EDFC0D7C744876CD001E8E21CD4B286F0EFCADE9763B810DFFF6293387B07D52BD5375F2851D9BA3BA1A9DC61EB70245B4E9AF46E271D9BD896D1178FC22D37A0DC42ADF4326A4F72D2A77F796944F32D667C4F943F14CB764E68734D4F0BB8F99B13948539BF208228027F38C0CEC77C3ADE11FF923D55314245A8CDEC403A86351001EB1E1BEBCD967F2AACAEEDD7E35B67F0F21BE2FA970B6D26EEA7E3C0C1CAB7CEB667DFCF98EA04926B2A537CC6057EB2B87F95E8AB2104B0F0EEFC7B987033C83884FC1E6D29B4225EDB6A927DBD431B38BFF224D25D5CDAF99640F2EC6B68E93CDCF7ADB26309F76CA9361D07C7192FD3DE39F7A2767D55A32FB2BBDA1FE11A432BF156B3EFBF3B621665C01F2209CDA6F2F6AC96C7C11E335C54BBE223D241A7EA222BB901FDCE1D013BB65127A4B7F3CF582A2806EB91A2A04FD0B358F3D4440D92029AAE45A3F5E4D421EACE412EA318493238E05221716F5B540130B57EB0DEC4ADE20A973EFCB39358B1AF7991EFD5A64E36F49FE66E85AFAEB5D109B39450B6E2F7A30208DAC21B5207930ECF97D6B4145DA66D97B720F10B1893BF2EC59FB1A4A9B3F27ACF7ADD9523357F4BDF58BF6927089A45906AC41666FF9D07C5F01BCB6AAFB1F143785BD4757BFFD595870973C0EDF20CB138398D4D2FB3C6BFAD43094B4D54E304B2589036F56CAFAF88B6E2DA1D2DBCB6B9836A2C4FE0AFE5740A26DEE961FEF5127E6314B22CC61ED2629A65F75453C79937600DBF35F0D617D7915BAA4315702A01AC6ECA674642A5CC4B9C9F0DB03C5E4BD0A81EC25A45103DB65A8645259FAF50EAC96DE2338AA4716C5F90281EADB561F14C8E5FFFB31AC72BEDC927111EA074A607292D2A1BE66DDB1DF86BFCD22731BDD08F2E74AF0B501C25EB78A499E5A0D8EFD8162D2F971B8905209C257A82B2A1EFFA3A71217A2D81726D27F3168573D4845633D39CC9D8C6BCC7E9E5A6526D304B115EA9EE7F9DE39E3E5C37E4B66C88AED0FDB581D9D02B86353CC7BB1D9033B4D68AC47340548E6B3765691EF0B08C6396218D196479E8A481CEB342C2AA117BED03120634C0BC0A851EC74BD8E0EB5771966C2425FF6D071AEE103686C3CB97EDB304863A1B7A2EB65AE0914051582D8F1566B65ED24EF89D3E77E72E3347B04F625C95AC5C171F475A3224F971F642503C86EF42ED2625E80F5DEBCD6F6A42317197FC85B7ADCA648BE20140CA76D6983616EF1E4C6B3F7D7546663527AE4CD6AA2DA20B2330CCDC0C19C002CE42767065F53B59D196F5EFEB930C4F575ED9BF16B75F6FE0AE739A129122CE1AD8DA6DCFC0C095D2188633C8F6B2F56593A0A4894EA8F7468B5DB974CC4FC52028602378DB8A0048A871DDF234D0795FBB5F90571D976650ED1AF81B7DF18DB27D59E76D5458129C80F3C1100AD9366CED92297A33CE6FDCB5C59A66A40AF9D17F670CA861BDC8555A4820740E272AA2CD85C8E05202C13B89A93260496DED8FCD03F614D953E978008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 0000000100000007061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1016 +max = 1023 + +count = 7 +seed = 55897A15824CE06473EC510179AF2AD3CA03B55B7B654EC9AEC393C34BF05660AFBF6B553D3412A59C7E6C8D2F9B1DA8 +mlen = 264 +msg = 962F0F7A3A6771C64F3A6A1E12200A2F73D884FFCF600456D8BAFA0181F67E807971005B2CB81328151570971CE98FB1AC42CD1A2DE020FFE42ECA9C2008873074272042E6C8CEBFAEDCA2687D7721AE9FB94C692FC344015AA917224CCD579913BC415E4412E713C0D75594E414AF8008A27B5465771C2C134C326FC902FDDE7DF59CE13D4AC1DEC6CBEDFD49F03FBE569A3D8895E93A5CC222818400DFB40F3213C4D4CA879C9B8BBC5C511095E9AE15284988826604F48A9CED36519FA903D617CEB821F5B2BE249CBC9AAEDBDA3C62CB9B0E351C95BE8DE05D934F7AF3E336308D9D3F550A8A755BE060815F8CD070F1E7A3220B0C05BF7429081033E09C2101177698BFB515 +smlen = 2500 +sm = 000000075FF58A8D31442A261E6AC66AA4135E434F09ED7F1B7BEA9060438E4FFE7550B11731FEFFAE1F7670606B1B808BDE9EF5CE855A3BC0A876B9BB0BAAD32FC65A945F106F07023485956255F8A8C53166427FB74F73F8A2E54B44F54035993CED96088A7BC0E02A9F6D48BE225FBE7E4F0DDDA995C2E674A51F3C23F6FBD14509E6E88DDDA39E7668EE9C269F94A582B7C874EB415B85F90E37B5A6F0588287732CDC59010F052B59036CD379582562E27753A24093E0805C4C0FB9D7886328BC1ACEAFD216EA7B9D38FA97F71EB3217F4E67771F8599E4152CD25B64DF752AD2CA78D8047A8C3A7BA0A1ADFB0B36BD7C70B53E68BC8DBEEF70E255A613058D1228D3A66E210783230E3396944BB5265CBBD9FBF280BA65259CFEFFD2C1A73AFC24C06BACE7A0F391943EC311989FC54C2A48D001F8017727C6A1CF686B983AA10E60B1667FB0F05434285F24AD37F702C5270555A772AB7FD63D81CC2DCD2A088BFED73E4F705140ABA5F16BE1A5E3ADF0D57E1C0973916ABE4C6B87CADFDC6C20803BA6BE08E06E2EA2AFB2C409F864937A3A1F11E2E74CE0C2E9395F57B9F2F8A45DB9F6CBB29E8302AED637B8583C35539AF80CFE945B7B42533ED2AC67A23FC8327056BB50063140286585475289EC61815B73AF54834C2BD016745EBF78140EC5A1F2A20790871960A3C3E5DD3C006052BF3062762207369CF4420E6E10AD46C2EEB6DDF685185CADF5BFF8C0A624AC2BD0B253A7AFCDFE7EF58A74D31D9E22C922367B5EB709BF0DEA0D2100D99B9C45C9047C181B00977FDDDC61828C3CBF486F9740CF834C73AEF270974AC1C6A1DD064B7D0E592E408ADFD89C1703A505FF612AA6336C48F8A313BC3B7F0C5A7E2EAA53C5921A8CF7E785AC969B9E6A270277407FBBCC4E12BFC2FA475597EA2DF27FFCD4B3FB13D5F0A7A6FC7EDFDDA60EAFAF1D6010E20D775E49A6331D1AA90DFF0A9C6DBE9A7295F06B33965FCFDD65C5D5009670116E6FC2665865CAFA4614745F91B00EAFD4CAD0E5B60134BECFDE85074181E7E5D6E88EF6372B54145CAFE0D749114F67F4F6CE9892CC463CBB41D28E6B00DBEA29167E67FD10CB66F5A86AE6B240375293A61D31FAD2A9CD83B4372052DEE199983C7EA605574AFE235F512E8A369D6803C744B271477C42666C1F6D7F62B8796AFD2B20E881A250750EAFC85C9B9D878FDAD7D213B06CBA1606F6F9E757E25656A36E8649BA1CF23F66D3455D000B6690A3150AFBA8A246F14E934D670050A792973B42C49866CF4D9D1E02477D3A6F30C2D8861B46C3082941A77211F89ECEC545CD10241911E383FF05F65C0293E0F5F7D459339954E522F01CC219BDB80EB87DB871B426BB2D8D9A2FB71BB31AF9A9565DBFF52D27CA5C500628865255028093066F928463BB78C24B039F9C77520621FBAF880148A25F9FF262AD73FE1195B32C9CAC4C11E4B794D606577C32C58AEE7EA0BED17FEF0AC62CD9D5C3CD26AC00CB72455E37D6E9D0CD953BA2C055A6C9EDE3177E38194B9D8ABBDEA35B563E4FECBC7586FC065A6E69D18915CAB3912A9E41850FB837D31B2080EAFF8599FF759DBF67B8B236AECFD2EA7377D7D1C33EB9235158D1CDE56113736156792BA04BCF40AAB95A386D7D40AC57231B769EEDAE23FFA35DE8C0D86E6A45D08CA10B376EA95B4D41C5AB9F7E83E874C438147B0BA166146825A98525CE012F0D1448D064259BF17B3D1048F0E21934FB8723410466358DF677832693CA1E70531A960196436D7188597572B4D45B0657ED0393E02BBA2B4B1FBD1E182AE57E289F3BDEBF716B83825C1691CF5C45A9CAC1F7EAFBA71883777703AF3441B1E3EB5F18D1F952155B4550B9A5C7811F7A4D99AF6F76EAD52E89D8C8A67CBB330F4796A08CBC26EAD8EB9EFDDFBA6D24C51E2B14963AECE698264AAF3B7568F5F408B4D3F3E958C3EBAB5687B31298E92802ABB3FDDAEC811CDFAAD8A255D454C3D16BE06ED4A9A508A3C1208B3B711C02090227FC1597328B211A7017ED46AF836FAC35901B58F6E0AE7164071837C5DBF536EC40CCE73D062E13AB8E420A073CCA65A908CD64E62C5ABEEDDF49C83782C120F8D5EAB3C9940D8A5A27D72C62E2EDAD8D34E9A6E28C4EF88AA6BBB4BC530B9F6D48678D63DBCC817626A0BB5ED1A7FC2B039928D4879732A5C6E3BE506008DA61F7BDC2535356FAD462B28604A2DF5F93B56B76E799017A0D652E7CD1B76A7AF256AE56E9F1B2DD8177457A204EA51C2165DA70A262D3291E5B500249114E5D4EAADCE28E43AFDE8D923219426DA704A32F3C490203353F143196D0F76D6C3BC5D2B8679982E9DF6AB1A69FF0A48C94579679A6898A42E3B902467FD3F90ED13F8F34172FDA06550DF19EBDF355E35DD192611E09C16414702A6BABC3A46D210D39B216F65F22A3EEEC77DF45919755A1C27AAB1C985C66CFF36C2A83FBC21DDE858C530F519459982D5D6F3A283876DEFC2994FD13E53A227941FF0803603A0D68E95472BC442F147CAE9CB0DBC3490265A9CA4A93415BEE3CCB3012ADA9A2B54B2770C948D30F02BB71B5D8D3A149FB93A848459CE42E65F00D71AAF3CE838DD97153BCACF4512ABDDFB3157FA091F4C92461F3CA79459E188727316A5FBF3C1824C4155DE949657162BDFEB664ECFC5D079561589A44D2EA95202D8C06C77EB87C0D9CF59EB9FCA86EFA805F9536857997FEC12E9F212A121E25F11706DC4497963306B9F30707A9DF5D80C4D3FE92CA9DE57A81D0E3A93C494B9A681B5AEC35298FB6273B9D9860ADD35C90A3AEE088746FACC13178382795D46352FD7A59D02108B83D40CC143FC6A950520A1231ECCB8012D97449CCE14836FFA75C19D20B6A948E0CB6EE2F75328056BA00D5EFE28C107541403D881284A7D920C43EBC8B1134572B7ED6CABB97D282B693BA678D3A397D29961169A00D2F0D2036E83A9635E17944EE4922CA3B28DE5B3D3244754A9FC8B5DF913EADC8ECF573013D2E483B404DAC46A85F664A3D482614B3D504E1D1F3D83BC18759C78855D256799807DC2F4338AA29720392864A3CA81CDB32C8A1120D3E2D0815F6D77F7A00AA5ACA394AE30BDB9FC80F3C1100AD9366CED92297A33CE6FDCB5C59A66A40AF9D17F670CA861BDC8555A4820740E272AA2CD85C8E05202C13B89A93260496DED8FCD03F614D953E978008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 0000000100000008061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1015 +max = 1023 + +count = 8 +seed = 798BB062FA12450D432D9692C51C6A9A837AEF567604F01A67935E28CA16434B5DB2A5B74D45661491CC0495440FA989 +mlen = 297 +msg = 289AFDBFA80F8CA4613060AF98810A2184FD3ED165F4E0AF7FF0FA6E830493C99055DB441377C1FEE9FC7D0920A77BAC8650DA3B9A35D4306C2367B3D482EFFF21C28CBA4E2F7A89CAE8A25D5AB269DB6E43E791074999039589E5B38925EA263733B97D9EC5EA4F8C411EB2ADF10B22F3A65E1FBCBEECBCF13B877BA8A7FFE187807D222C73ACD352EADBB59176F9F0EBC7DF20CA7E46F5CFC9330A68B6F45A71A553096165D70DCF2398EFB4D8005B3701D6DF4ADFDBDAD30CBA98FC8254D7A1A0DAF653BFF68B6CB72AA2633F7539772F0872348759AE0D45571CBD3621EF06F1151F18578CC04FF6B7E3E938DA1F50D6E6C82DD0C6ACD4C36E84BCCBF5A4629942BC20434DE8B6E68315A5C62DFC2357F75911634C40E2B9B4DA89F515F9280EF86620939B369F +smlen = 2500 +sm = 0000000842B446CDF177CCD300BCEFAFB8133B67EE9F6DF02088082EB873B63125391DFDE96DDF21B58DDF08B1E0E813D21723DE5861C656C71D87290B1287B9B22F0CFFD5F63BF17A33F7D4DBD56ADFF47C06B9CB73B39B867D7075B92FFD38E38990EE4E29CF5EA9EFF96FB792E2D8031D60F422748B2DE49260C0D34E93C315E19264C6A0487438A3D1073FDFD74EC015D051D4384DEEFE689D7880BFA573EEAE2E3A7CFA65477167BAD6D2FE3FBEAA431FAB155275498D72533121800E2F231A662FC1F439303F05295328BFA0AB68B196414311629461F6BAA615B0A0E92350063BF58827C14F47B1D18606DCD093571965306A7628851D1A653B64E1463FA7BA83F468676371DC39F1F27F13C41AF42814F6409C00B7C4693AFA77F01537A286970F8A0A59800F827FE8541E70C27872EFA23DB0641713454D1A3C9E595F3E74C733F1180EAAD48D1A19FAF95B88A0561A05D296374273AF651DA94C4F852185D957E308672C760E8D08027DA54B47E7F38F215D85D43C515F8F19628B505D37F37AA5174549D57F6F3D42B6A5C51BA7EBC7FE0DE9B7935982E91AEB697D952499DDB4BA855A2F9215A72235DD9449C7F1CC4B4E646ACA12E0204476146618A0E4BD8DC7434016CE03A7430BE1E8EA827A381486F50F680409AE081EA67B8C703878A5445FBD0CAF5DACE16B9CF90C62A257392B20A44806EE3E8B60025A817BCB674E8D2FD2E6BF4BB320EDDB4007EDFDF0FB62892548D310218D39C974E12064EA28920F0016A6E2636BF6D524E0912E2B64DC3EC7636ADD0A20C81CAE6C3BD62CB872634523C7D6CA8DDED004A967CE50795687E4CC41335E9A8AC976C95A270317DB7D96E6CB596D9FE594E669C0604798E453CB5A9CF36E4F4974DF1660CFE562CB63B96ED122A9A9B3C38E5015E64CC3AD37CED7C2192AFFD1A4A6BE234C6E60EFEB7F33F25A33FF5A7A332657CE759EF5B81CA28C1E497FF9E4CFA1F003B8F5F1E8FCC07E8ED6DAC6C06D2DFBBF86A463E9B71F2D1552DFFBB05755CE4AD2289EB1BA4B9AE3E56395509A65DD521EE58F06D0B4E40C772B702747F36E7DBE6CE7EEE4A1E79065E590EF37A2CF6E1CE3A88909701A70765BB1CCBFA94AE20BBBB96167BD93DA33D79DB3815319DC3F38486E64AC42E371E6EF0CCF14FB4B2B6205E89F66FE2A572ECCCF85881E6363271B58F434E38FEA4B15013C95B8F5867A09AF06D592939FABDB5B96ADD3A179D366F99150E3DFF63185569F2D862D412073B9DD13655B8AF0D87DE06B2809191D1EC754FA7342D5383EB2C7E702080A133B51B7C630CBCABA758AC54A015D53DAB9D3ED19C4ADCA361F153CF8C4CCA568FCF0367A8CC348B6C2AD139859443F6F0CEE2B6B354727265CA14F0AA2271A96F4ABD72B8954E103AD1402FDEA2390C07D1830C142A0AC4CD4583B31D54AE3A64F668FB194767EEA716AEECCFB8951419E328201F781382A198C9635400A52FAC59710273FDE792994308B7E3856C21C5F1227A3438FF54A40F4D9A29918BE7639C83D06341FACF62FDDDA8AEF74FEC6FA3F09433E6C3C5D0A5316178DC70441E38A12D8BA742FF49F5B8D3971A0276C53DA416FC6ACAA94BFAA1B73C5FBD59057E553BC71A7DD537CCD02FB22C9AD9EC122AF040C7F8F28A53686F841C84F0630E1F694872EAF34C80390D28F934A9D47E6E5FC367B187E74F2E698569A484244645F4A714500890B0B9FCC4E1130DA1D4F03F7550D625C3680335C2882D188DF4F6835B9549F1A4D33AB7B028561B43A860F4094CAEC30C81E1F073E9A1483B846B0642FB037CCCFD505065D855EFA681EBDAE286B337B8C472ACB6C310BC608C1637B01D3A1578C2B9FE032B263EF2E0C42190EEE09FCDCB555803566473114D1B05DBA7ADD15813F6023FD82AA25AA1F6AB1EBABBFFCD62FE98F83A17D7DBA719041CFC155C09B05B1E0D3D8909B1A892542FA5B31F90839AFCB68A80070DCADCAB8249B0BAF81E8D0466D9F6CB118DA6B80697F4366153FE94A53600361DF10D11D1937182F02E5832E4AC2B95AEDE0418736BBB16A285BE7B9473BDA4EB2B2665E255C6EA18A8B07111F09E9B057D5F9176BFCFDBF3E3E073143BB33A6744DB9E973130A7D7BF99F148A526630964617E4D600EA5E1A27277AF646C909AEDA2BE16BBFE7CBF037562819C4DE2AEA88CD6BFD18F69D86D37F2321AE06324D5248956964ABBF93F9B0E106C692319DD7742406F98550E5B31CF170D6EFCE0CA28465258A2D76559663F1B7BA77C340B7FE06C45988A5CE8B7B1EEBB2411F1ED856ADD6E7EAA8BE6895534D3D0BE1CE385CC416F06EB27F5C6C69D01EF1A81F4E3BB6EFF9B0F3992D490EDCBC6960F5DAB0081557D385821D08BDEDE73CDF33A9AB3207F72C85B9BA229546724DF96C87AACEC40CE3A89D414A4C2DB9F9950843F05473C6BF0A69A7AC5A366F6B4F612D71A71669A8BF4E3668003F2CF25E0C1297F5B8293598E6A7FA1299E3A5E383215A3F41BDFEC4CB9163BE8741EF08DA132A934F84164D05F4175122BC5152CD651D697AAEF291F8D1A18DD49AE8622D0DC49EC77FA23FA51B3760F6E684AAC5B949729DCE376553B16082C70BD43848584A56F136D01BE3B80B4AEB9B4BAC518F17CF44ADF14B618DD04059F55D666A7BC0AD6747E2F64C8B25F55A4DC0B178FA14E80EB6A8C6CDBBC5FAEA9BF0750E6463E3C1262E3EEE072EC95EC3AC8939DE5F4111F734FB0347D743F1EAA67DD4189B92BD8F37B2B62EA00636F48ECA262BFAF0238DE48D2D0EE04865979682741E96C05DCF28BBC40D9A7A95EF2AF8040BA3F44E72FD6E04887937055AAA644A073CC82782214A8B9948ED942283FADE73D3E3E7F14105AE3FD1613DF6BE5CBBA99008E5E4A61EB0D57400FAA7A150CD1F690C3C3FF1CC695CEF8FC746DD836025EEF5523960E786F7DA022C9E4FDD6F810DA35C9A71BA26B8BE68BB33814A5D5B47088559D4CE3C910B1A70435755466E86B74E8FAE08AC7910F177D5142FC7742BBF0A738BF76E9E72FCD7C2957CC74F299285CF21B8A71015182678FFA04F377490152E9B4BA60D4B220F04EE5A38902E62627C12B696360CBFF4C016C2896B09E62DA088FA83B58F5C0F0D645FCFF2AAA1305F5A46036716C1464372A0437EC5E25D80AC6815CAD5B7EF29F71AC68263246E725C21DEF39E6DD1316C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 0000000100000009061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1014 +max = 1023 + +count = 9 +seed = BC4285C7804C15AAAA7FBF25D494E763DDA04B15414E1EC6461BBE0B7C6962A625F087B9DA019F277CC038FACA1CDBD8 +mlen = 330 +msg = 8FFC13A7F7C0C6C20ED56AAD2FD44C9C053DFEAC4FA62446A6FA4CE691F347C89D0BACF62C54DF754CBA2591209EC1619960E6AC2612EAAFAD3D343ED32AC1233DC00FCD88CA2AA8152F13B1FF530840B6E10C7BCB4E1022BFE82F468458A45967834E141709019361BC4F6AB67326884FCAB2E3EE3DFA174B9862C078218F8BCB5718784B36725ADF2907901147AF25B621DED9521FFBB2270F2A3C98EA901EA9BCE0764968EAD9D4FC027515B478B670841A4B61DCE9FE882242FE22F3830A9BE0B546287F6E0CEAEA92002654E7BB73FAF673D4041B5880584E1FC566F90FB2FABCB3DBB2CB30D66610B73EDFF23C89F20B6BB1B3BC71C17133F64966FF9A8404CA350D2DC953736B731D63E204F50B1D5F44F27E255F8FB508892A369F9F8272078A1E988C6C105C9D37F44619CC46E7430759C67AA7B131D23B2D405C3ACE8076EDFBF21783D2E4 +smlen = 2500 +sm = 000000094E8205284069747FA1B604DAAC8F1E8BECE4756454AD65441B745B5948618129E48E5AD2C080DD21C422723EA55CAC647B30EF0A0ADD4A68ED6CF5F1AE68EEC8A5BF69C4922F886D35EC8575F036FE13253B2C2433399BC92FB4805B108CF0B810E10CE31E16808A7643AF1DC74CF71BBB9065507148629CF9246CBD6D17ECB5F12D59E88410F0F6F04CEE6F87795DB6FFC1B78D43AA1C90C54FD44B7FADD9F76C93B1FFA7EFB8185ECDC6D11A1742BE67637C90B73073DB977FA393F50B48491F03A34E9811B87116EF3F91A563F7D0799AA6962B0BF216FF3C20B86062AD1F37ABE3CB927731541F9EC9ECCC74206E1B7A42F8BD8622E92914B221C2FE884EF67E56DF122DFEBC8F3703ABBC9E038A5CC8FA5B67DAD5F5942F9CD17067B06D28669A5FFBC4A05FFC0A771BA537F922F08DE9F8EB42B28032887494D4FE03E8668F6B6F919E681F5880A273C855A073EA44890B1A410334EF24C0D25B3EEA3305EEC8793BA12EB6B076CF52F8A86DD9100F984D700969EB78ECF034DF14E3AFC9C1C2A9A37346F89480D540F72AE127E7476E95641581474966AA07B76092548FF20E4170235D597E149F0B44F17B751BF082AC74E1EC74C4CD9474E37FD587B7C50A8451EF651079B7C8FD9BEEA5BB4D6C58C6EF6C5F6D12F6868C355753C9606837AC660D3C54E9113E0DE0FB750D1C86801346B1B89F06710D531319D2D49385C7080BC6321AF6F6F89FBD36399E2E3B82BE93B0DE483712DC5D84C2DE999BA81CC850721ECE18BC31C8F39DA690D338B24927124D0F2C40C1AA5E50FC0C22D52BF200283A153E146E82C1F583BD291A3AC3B07FDFFAE57B3E4AE9CE2A4679BE9602DB5B666089359C4540D2FB8AE0031D5D8064E45FC9083B03112EEE7370676863752BED12C48E167C9FF0AB1DB5D30F2DA3C6866FE436406A7793270A6BA7BC9C859808BFD5C642C592AF045793E9FD64E5744E51E043D288AEEE79CDEBDCDAE181F3E93A3B202596754CDDF4D18F8E6DCB1414345893C8C634430CE5C3F3AAB7F02BA0BFFE16C775D062F04A43412C0C380C823427605EBDD6726FE33F43DE8FFED4BD73ABA600E550B0E710F77D8B0B158AF3957D19E2A70605227F5C13BF7367BB4A6456667F5F580F6B303536F29D70362CA4DD30DAA727F8E74006F4397482EFBF1A6C30641F720B1D772231D706B4DE2A72F1EEE2D31573238A995C22F2EB2EC5B7CE61084C88063808C4C1D3499038D7CEBF37F6C5EB9710872F24C9806BD5DFF7E079537DDC64CBAA9EA208ABE23F7EDC5A7791CF7600A6F85780B70EE9412165FFE815F02F74896ACA1EDA0DCB593B74D6D48CC6E1053B5372D767D03B4B5B4041686BDAEC4F42F2C202649CCA404572228DABA2D04604AFF5BAF85EB871B8B5C82E03BD992FA2569DC8E1E4CA9041B755A94B9E4F06F7A662EE53D8A0B019D05497FD6032D9E95C05BB59E9F9458B4389000CB46F4190A19472C4CB51D873AA1A6FF6CA591E938E25E4C898319D850E0FB8C0DB6E983155297734F0243B9DE56F880D8DCB191EB9F9CFF45CFB9E1BBC92FEDD297A3811FE691D8674B82F437891F8AF6054AC87AB48EFE883FFDCFAE21F26E1BE134B53AB544F6E9DBE06938C0C466CBAF170FBFA7EAB618357635A83411E2CDCA0BB9323EF54CCD4128D639D80B127E7729ABDC04989B06EFEFB7C87BAE7D48EA599B7EA627B98A6317BE3D70824C25747FE3D2347E01B0CF7D3F389434DD167D703291DA0CE89097F339806CE37D526B7859FEB93E6E176ACE8F6A038AFB424BE1384422278141BD3EBBF890F3E9028CC7B770B9E8928ABD210ACDE38A31D38D11DBB6B9921D915C61616B9014170AC5124B2E4CC6C66F94906682D29946577EFF47053D28BD6488640C65ABE97C8AC8F9603E1EA89E082CAB6BD13C0D010DFD8E69211CAF3FAAAAC255365E928C47C88FAEEF61A27312C50FE10F21C719445389B00E7DBB32863F90D1E13014C6267B1FEAA1D3615F30AA72CB6905A5A9E78A9F406CB1774C5BB413D73D183B3C3DDDF7D608AF61C1459DAF34C99191A3A9FB3D99F3C45DAA3DD6CE8D4FB4991F367C00540BCC233AB6545BC7BAE87B319A1CBA5A8C17D2F3EBAE53008BDB896ADA1105B17B340E28940900865DEC2FEE01652B9FF9261A1660D8B2BD82044B4F224FC3281CB8DEAF17B7B06D5398467D9655AB3A0A77EB7C3FAD129C16037B0FD3750AA356106D26B11E9ABFB1A73DD9C36BA2346B38ECB00535EEBEE63A3C0436CF70C974D26FF28C580C88509907F68AE6332461880F839644B37D8999E16418E2D0152925CC0F0D63C87F612D30404FDBB347A932432037384FE00A6D0E9B0B97A99063FE2BFCE1FF51AF5CD593F6E4A2F82845A44F174FD8647774260944DDF0D006ECF6EBB9FCA61FE5B5D6EECEF44E4187EA3E9AC8C17294740E5B016C7DCB10E603FEC2C3960F3A83B41B84E14705129894B682AC1A52FC190CA10CA3218C5BA67A6A0314F6F059435A6D3B6E347219243E33808FE0E12F188BC30DE394F5AD725421DDA0EF686282DA121461BBCD039EEE6D500BA10BA92078BD4A3A44B9389F7778114BD126FFABB724ACEA754DB959624D8167A8FBB90BA4F38BCDBE3CD172F4972B189F1D08548C4AF7F14D9C405FC5831BFE59D13716CB9B1941DA438EF93E6770DDE04386DFCED416B3BB9A911DAA57423E0DACA2B93A2839AF26F1D3B49587A46BCB694A4323B08E8DAB4FC80E94B80319EC849445530339BABDFC4131275444636526496420453C5E917894C9F6459492D6F7F24728C83FD45D0F2BCDFBBBDD718768D8B83BE2DCC2CE080F3E48973BBE6AA1577858C9AFD2AC2FF2066562C4EB88ABED1F284A6D40982F4F3A2C2CC9A34FF7F30BA1FFD4F629EB8A3434FE46C523F903FBF457860F50F2D0ACE9A4D7E2FDF5E6EE7036C5DE8EF9CB7270E93D5F84E5A097417C2194BB54534B66D1A1761B165B6549EC8D7AAA2BAD5775C3C5CA78FCC38D738772746666765F8909B8327D3427F0F8BCB815D5BCAB5621B4FFD0AFD5F2DC983DCBCBBEE1622FFCB09748081B59F493821B467DF8B22B2652F4E3D112C38A15CE733E4610833DF3F16C2896B09E62DA088FA83B58F5C0F0D645FCFF2AAA1305F5A46036716C1464372A0437EC5E25D80AC6815CAD5B7EF29F71AC68263246E725C21DEF39E6DD1316C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 000000010000000A061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1013 +max = 1023 + +count = 10 +seed = BEEC566BC26E2DC13FBA54ACFB667A5C77FEC1BFFEFDC42F9131F1524FB0F71AABFDAEFF6894DBEAC6B89CE3ED236239 +mlen = 363 +msg = E24DC9F0A986B4F5A349DD1567A80B7C1170C980444F715998681BFFC2417661BF0B503E11D2BCA8D135968E6F07FF0144308AE69E55F4CD663A3CEC5C5D84D00E5C0FB2E458CE22C7E41761852CDA6EC268A8FC06E76D1E4F03A90A6FA9D1502F6F21295106F3485C9B3A1DC6C40C8E304DBC55AB2B90F6E6DDB404D8487D736E5466243F0B055B060287DF589D66B88C6DCF6D2FC8E88DC20BC9D693BE9B9744C31D181558289C3F2406BDA3CD3FFEE90249D95214C7D77E1A9927123335573E952FFF9A8D3BD66E020AC1FFFE5C1921DD7FF6B48295B6D2496376AE1E98CDEA032BCB8662A915301FBD014224CB7D899CAE2889FE0D673E0B55F4A56C914DE868D61775D3DC92366524F606C9E279ED231B0662ADC50A4161C19149830305B9BB38AA2606DA23830C3951386E63DA6DC2176F48B2ABB26619833074E95391323F0EE3B6151B2FF463EA3CF3BE55C2875EA93586AFF0CDB4B43DC7E8A156510B74E566233066EAAAF845 +smlen = 2500 +sm = 0000000AD719AEED657AB07C7C37DD7CBE31796106E1FD0448B52C745F3773B1D50910E79EAD6FA89925264FFAC1873AC0B4D744E5F0A51D3DFE9CA072561CEE80760E69933415428EF853336DCED466E4FD65EEC9D9F361E8883129A682149E6D96C071586DC062FD19FFE475FE59874DEDED58930E7DF5ADABFCEFCE81B1C3174FC2C0E32E286DCC466A672C9045508DA5E4A6AC78C8D1AD546D069AB0F33AFEC74539652D3F8F9426CC4A5B3E73FEEA8C21F775D8B723AB587207CCAAF744230BB44F7797A963353D6E0EAC03D072E4078F097B37FB8BC0FC83D8F1CAB838EB9873862751E67166F04988ADA52B4025523B5063DBF2CEC43FB19E5DAEBE09654694D5FF40DE664CEE993D9D5E407A2097E5817AF42433A63F6A9B8C7CCC77B0B459A8AA829D6D900949C7CDB3D2BDA3D9F2842EE570F86E6344AA35D4E7082C8A9F9D4CF49D66B731CDACF75F6E3D22E1E9A8FB5BE26C512C280E1DF08D6967DEABD487E5FAF709E753E29A9639EF57B8EA9B45AE707B2C7955A2383CA90CD5B287879AE1232ED73A3B3E8EEC33A42A3FAF56217AA2AD9B05CA2B25CC0F947697469926EE97A2C54D00024B9E1E1E41B62AB63F4CBFE6A1566E85976BD113CDBF5A32857ABB1609D21A43A52B7591733E0C9F72EF6F5723838F16303563930ED35FB2400984B59FE13A8B156AAE6F463F428AB90C867DCA52191713668D1F7D81B9D4C9027F2BA691F3ED6B68466CE6AEF9798554EAC31AD758F24F2F25D36CA9452658FBB70AAFA9D1E969AA2D99E5F2C95F8B2ACB75ED02EA71BDBCB935E2E4FDA5E40CD437810FF824FCFD4979099584A4C3C8C1B50E00F19736879D25F35D135C7743477DC01F8F722FA5E302356582CB65A242EF7BE4AD511E73024F65EC0478537697F98CBE4DC8DC67BE9C14C224F6E0263578882822B08905389B92C9C9CC42CD0E680C9968F6FDAC42089471C8AD79D94EDDC54AA1EF469117A9A69352F7E191A23E6878E575E9CDFA20B554EE736989A95BA228903AF625C02886F5FCFF7AAC3AC091F35B3DC2B75A66EFBD144547FC5C60BE0A3E25EA1C2BB31EFAE728BE70BA224140C564D1E5DC2FD9AD95578F7BA901E06008B929774CADD8BF8B59BCD73AFA8357C765AE0AAC542F89EE0B91D095467BAE38CB09AD25B19485780FF7A1CACAB02C04067ADC82750F4F10CC041EAE21D661E993265F19AC7E84BAFDA92785C8DAC4E68B08080EF0C6A193C049B8280EA9B36D69268840E3F2967E56AE5F10FF2B0DD087EEFFF4A669FBD29ECA6E6EAD8BB4A410651141075B95C0EF198A4DB1962919A12EC994738112EFEC20C4B80755B9E2A529E727AA345D77E6ED5D2FDD0E3C6F007EA46289528F9EC43AB064BA941C33428F6DD44049C0FE1E047C566AEA77A9B7790599637F8D009E63EB07EA142136F103B02F0C8C18268A68F2716C9FDD30D4FE657363BCF45773BA8899CD207C7ADB06CCFE023251DBC7D16AB06A8C83677BA461CBD9AC99A3770878727FDC198A886267F4068D298A24E7DB244E7AFDB84BC911A1AA6522A472DDC3C8F7181871FD9AAC322811EA172DB1EFA784967ECD11D4B1C677214FDE6833F5F18C69E46D5870487B557DB91D97CA3E1C85DF74B9B9DEBC8E8A067F59938AC93614D3F55A174C9038054FC3788A42EFD8E412F1FC27B7C3BCB7F035FFFDA4346304F3F4530A86F2F91BB48BEDE554A97F4BE765DE44FCC5B6CE5E0BAC23EC8392799049A1BED546D3C99390B153A1084DDD4E78D8F908723BDF8149A18AE593EC9226EF1182C9F5119E2909136C04B220F1D5B517B6E031E1D0A182564A7279AACAE12D9A1F180FC9F98A902E13A598988F32F9B36AB34C04EF0AEA3CA9148515C27B0416B46AA4E659A6139C2313961CDB7BC94A67F0FAB92AAC6DAFF04457C93C303764D03C893E06D5078F1803241A5ABF45B4D543E860475A93A3058190C1330501C4991E436DCDD6AF534E50210CD45C09577F951E2C10EEA286A905CBDF6431FD627EFC3EF88EF524DF80A95FE062F65C859E0B40FB4D842347FA037B28B02DED61D9E65AC77DA20DEB236C1E5BF5BC4EE34B1DD200221FC9BF231D7223D25D8877E794090A88C87C70563AF05C150421464A0D324E0C673835163FF86DC8D95741DF4D793C00E7E25508294BCD0D1039AE2C38CB4D0709514C4905ED2A5187AC8B289B567D3AE59620E4517ACD1675A2548E6B8EDBD0CFA3006DD6774757BCDF684F7983D6D5E7A9F73508FE6A25F8487BB6EC8A9610B480C8F11E5A6E60300213348CC172B7724BF5AEE19A39EF9D98BE5524A349046CB3E381A73E2F9EC83677BED29B47A759C73E33583FC278FA35D328A52A2CED5A30AB1DCA0219D58832D22AAF4E20A8DFCC848E4E1DFB11A74166EE19B0BE943B00F8CED64F86B537221CE7B13F3BF616CCC8A8690668305550D4318FBB8AA4D8F2B7AA0F15BFD13EFD90F64D16DA924163FCD8C7EB983B66361D9A0C81B14224EBDA2941096082F551CA8106D85BEAEC1A08141C4E94866C51CC0360B0C3816930C8C1A22A682754EC0C92B7909B9A6363DC0432ADA9ED300CBD7EE17591FE27A17C6FB9821F95669C47DFDAC6FF8BBA66B5C59B4FE6B8BC7CAB52D5E63A4AC372E89BF12ED7F92B8517E4D749E9705A8A29E592F27E41E5121CEC6D1751224B15010BEB0333F9ECF9D62AE2BBBA821A4DF8E5BAB730A238DC2E88B6AFE89EDED65A563A6B99335A99973057596D66C6F27E0D09D24C025C5853C2FFBE82AD54A86546CC4616A7F19746293BD4E90C3F8A903413FE2FDA45EC6C4F3E2F306510D592442D08FF4B2952C5D75C987364DA5801E5A64BA09761ED1A6653C6EE9106C3D5E0BD5A592896B4857271AB4BE38CB489D981503E7F2123C53D46BE9358C51C218F6EAACF5A2983B8C4AA04D34B56A16F3DA944A51280AD282EDA076F0F20B5237CB2DA1667DBF06F5A2BBD471F52EB1B89AACABE9FA1CA7A1B33BB904456256E83ADC4E8AF144DC1C4822114793B558534842DE033536D35C51DE23218417D3C99D30D994B0ABD740DD423BA73FAB5CA570F37152B0A3EAC6A98B344548F790FC0E51343E31FCFEE5DAF8E7EB4D1A3EF935750C2CD15888F03DED5904065F4CB00EC42F7106F41F11E69246E59737AD06772A0437EC5E25D80AC6815CAD5B7EF29F71AC68263246E725C21DEF39E6DD1316C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 000000010000000B061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1012 +max = 1023 + +count = 11 +seed = 66638FA3A92FACE1BA5B311362842ECE73B6EBE5637EDB3E16B0EBABAAC6BA9335BD63DA0253518A6B9648BA490AD60A +mlen = 396 +msg = 942D9CEE1FC9325A8E6456194FF3E1ED7562E19AF59C7A0F7569911EFC22A89EEAE8831E66B528797A6DED2E0AFF50933AE425245953BF95637826F3483F1E8E12E12BA8D6A42D320235405E422ED3522F25F630AEB0A63635AD70A51CBFEF6DA246562A10529B3DAC58C50BB08F88469987DB5EF8B3E37BC07639E56058B93DDDD88E9735B3632E37B3DC0146E3EE9A55F29DF71DA5DAF7A14CDD8276F363F3E1E4C6DEE2BF623DE44F0C96DD03AB00BE02D5BB90C61B870E3CCB41ACE1D1FB5902FB1FB2F866E92CBEB41117C5C5C0D367D20D797BF09E0C8EE934209351A149A306E34A62DFF428687C6285FB3682F94FE3C6B1C28F1F0537A60B4C9D71E2B01DB08DB7A033E426C73C86A061345B0596CDC6FFFFA005CCCA8C7807BC293D3E14D5881D6099103C98449640AA2E806592D345781D81D6EEF1CBA823E0DA1858C3647CAE811D7FF87B9E08C7AA1E2EF8ED615AD32B744CA253B6F172636A964A1E2719CF7DCCADC61569DAE0BB1A37F4A942EE17762586BB9A9BDE8B66671D50ABB592947337AA71D35EE1 +smlen = 2500 +sm = 0000000B455CEF8ADB9FA246879773E4AED4C367473AD23FB89C5BCAFB1BAF65F9615D4408268EB928B66B1709C9A932AD9A450B20263301918FE23671583B5674AF03A96A38194A098992E96D278B8B68F9B56451652E5C7B90F3A8FD0DE39BE575675EF6D1ED6655052DF350B420E90A070CE2592CE4B832969A07B513E3C7A8F3AA8F025A596591F339E09EFF624D89F97C65E131E0289DD0B34286DC38AB98A56B09AFC9B14A5A2DFEBAD49D476A2F8829E881591EA506C3AA5B1A91F7830127437078E74288A6237956BB16E90BD69079E19792A01CCFF507DF31D99CC6AB1D654A133CFB22A9DF43D1C427B2079EEFA43EE6F2858683E90440ADD529EB1965298EABA124DF53A0C4B1E41FA0C0FBCA4E52ADE2D0D19EA2090390F4608518EE8B3B9FB051C9466F601684B6109B2533A6A3E2CB7530F49EC9F1E1271210C90CB3F4B798ADD65CF9033077CC4DD74549FC87D2744B1303F3C7406330A40E4546BD76B979E9EEB8AE22DDEF7A2B2A3F5EC9E8289466FE038C1EB224ED4CC8248BAA09827E2A8E08ED2E64B233EBAA973D459DE59ECD7A4E47A36D12CC86EEAC6D2DE57AFC79BB41177F6E7E0853F8E2D43DD9E206F242501794E73F049A046522434E35FC255BE32996A9A67188440C78F39309060FE62121D5FFC0CD8DC91F220403049390212DC9A0BF50D1D58A3D4E5ABBD1CC6D50020FBBD7AE31683E01648F71828594311B45C60EC2272144C6D8548777E74D79B5F83C4AB3E26F1C05F99A3CF59F8E63CBEE6E5BB2A10F7B9512D6BDED02314516526854DAC0349897B9DFA3FAABE9A886C6AE8281FFBA9E71FC4D35DE35B7B456C7C6B95BD4BA0DCCE93323F055890226E95F267F03B166509C3788184BAF6B3236BC674190B2D3ABF2876717D90324B6A7715CA39B77CDE920E7E39F2DBED6A4FE6AF3C5AF8BCF555B0F77FD63F9FC15E622323F8D0BEE79450F367250B5E77568C5E650B06346AD938FF4345833B98CDE075CA1D4F36EED5A0CEC89F6A2E33D22B64D0A4C39780E62A21E4106DFDC3CCA753F659F3CCB9FFA760EE79FB6D6ACE22B8FBFDEF1F1D297860E07D726C667BB13653A391A839AD24DA7FC889C194879D4AA22E3CA7F7929040F8325FFEFD805B769B02F39042B03B04B4DAFCB23C360A4811F70E7F95DC20CF5E0FE8D5567A96D95896BA67938E5458685527636DC1CC38389A25A1EF8A44D04ADB2113613323637478C6992466AA02BA69462D85F8FAD94F3228A9374B26FD050BF0BDBB18502C5507C74C40850FCC6BBD9A771FEA0772B5FDD7EA346867A444AFACBF6F2FA4C781E8C49A1FC4B3CA4068F737FBADF261C25B264C2FD8B9623E55941534EF53933BBD2E8628CC0DE5C60B472170B204867623AF8441F84486240114D164C54F316A6DB6EFC6A35BC7FC1A06A17E9E5B410E26C67E78857BFC6FBD8A4F71F9F81D8DD85958B486EF132E983BFFA0EE4E2F2D13600A51C331FE58EB164F58757A0649F0D0A0CE7665A6A099856EFE3150C3AA79299DC1DD4DFFB0E939611A74B69D821E33CECD5FA2F012F2D40E494085CC3DEFED33E101E5240F7C2116BE78D3843EA1ACB017D27888D76E17654A3F0C9CE653D4910C09F883B8D4A7A6DA7BE70B3356EE4F253C583C086A6ED94B0E87CA9BC0DEF3AD297C76FE001EF31B028DFB7A1D430B7F569EFB8EABFEEB09063F0ABCCB87A66D58230D947EC0D3F233457FA206FEA765837168525F5B70095EBE76CF3F5FD69CB65F7DF3917BEC3D843F39B65789A28ECE4ECF35FD54F9D5881CFAECEEC601589C17C227477836EB11989474CE24B64956022E16ED7275FB32833E22AEDA33E89E2810F479E886F2B42DCBB1D4F7D662BEE7AAA6C942C38AFFA6BE24EDC48E2F47131D7CBCAD87C639969B2E58E71005393294A1FB75CECE19DBB87F309D9989D3F1D98744608AA73B53887660E22BFA6087678F52A636F5A0DD00EE1A40D721ABFFAC571852F5301A71F23DA7F2D21B49B36C4D0E85D3BA7A9D15A5364B799F696EE31701A6F53F22D2111F025D4919C6B305304AA180FC6551F7A9997D9A5A242692DC8C146B282FCB864062119C89050DD8952C563D336A2D00560A5C5EA5A1DFDC8273CEE2B9546813198F011D9C7D640A7D75CF036445E58E566A2434CEB19EF8870E190E9451D537E0B5E4471446366834DB65649F58DB535152061A5BD598F9D940F299B42775290719DEEDC87CE332EE592DD40E687B5D6A19E68CB24293F3AAECA1B0059CE264562190DA057A230C98222A0664741B63D570B195A510B5DFFEE9831C7CDB05936F0EBF0A9339324D1E42BC9157216D5F61C177D08C620E2F997259C7323143F0B968EDD22EA9A003C8CB3A74C2481B3596E64B261129B96F345B4927F144C6F1D744D88FCCCE76368B915C75D09089D9542C0CFB45A770A0EE5E03F6C4AF3C49735317136E25197C589958D0155F97DA3BC054CBCDEC2730A8B4D680CA67C358B887285BFF3EBBB3EB6379EE79E2BA86C7887C8EB4983833E48C9D1BD56E1013969C7E040196E9AD08980284760CD737FD46AA537D8B1274DD8267CC7F82889B1AB9B2F6CE75FDDEEBB7315B710A1A2BC6D286832E2FA6E0AE88B6AEB5CC99E99567E5CB106FED3747D132F1AE277DF8FDAD615328E2C7F3CE2BF4B1D75B9E6E6B68758FF634158D3CA893C49070FCB5F5D0C491334537BF3D33723E09996843177A77BA37A268D63CC95B36AD8F53BD9CA859345DC7A2535E488BC4D5C2B889F1CBCF242C35181121C8997734A0E614038FF6ECC1C15F9BC6B1F4B3F40DF1D612A1633485AD2A8040401F1915405565F4716A5CA159B7B6EB09A7EBAADDE2E5DA3D936B2CE5847CC9BFF737A2978F92AF3C5B907B370E49133D6E162B89BFCFF176965497A24EE4A6C0C6FE05C544A4C00D5352F6DE408D34DA24248EA94601201E6C0EA92B2562E030B16AD3E3C391445D3EC63591470D2E9896E07C7A17FBCCF45D69B1C9BB1BA07B6311FF2B97C620CD0AA0E500222E7F17C816BF5EA50F85302F198830A7E4B47A80896290F8DDDBE63E1646947C7EF5ADA43249E35DA580A61AD34EA9DE90785B144564C936090F2C725C86246723B5750C2CD15888F03DED5904065F4CB00EC42F7106F41F11E69246E59737AD06772A0437EC5E25D80AC6815CAD5B7EF29F71AC68263246E725C21DEF39E6DD1316C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 000000010000000C061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1011 +max = 1023 + +count = 12 +seed = 495AC157AF18D1563D6A03CCFF53807D532FD46AC67A624D433DAE418CD1E0F5FB76789EEBE1FE0A50279D28E411CFFC +mlen = 429 +msg = 0FF7A2C1D92BE47802CFA7186033B611FFC9C4C385F016D1762A79ADE356C85E9D81F35F5B3095927B855C194DA184B90A54B6241B8915A5F989130248E28A92C9A7EB5A1C6FCC96432C4DB091C75923BECA9C4666320D955EA2AEC268E47DB6735CF0297B9BC6E4A033D413A3CA7B7BC6B8393268AC91DAD4DA427DBDB14A20F16CFDC9CA0E7C904EA182F060BF6458147ABBDBBAF69C631B9DF27330F8AF63122F32D0099F5CAE7FE0DC3AF91E8FBAC3591B5A8B5ABDFCCD714F6643D4D3D65C6CE7C73194A8A3193FF8DD2AA8ED8113548C0BBBBE4C68F96BEC93D799B64149B010EF776B191E6246498B19286B8D53D67CE09D5CAC398917B46D8530EE55B67BF8D4D00164A519288D9112309713B9EEDEAB11346264221FAF4BADCA7E6578B3EDDE6F37EE9CE2C2CCA03FD61383213C2252D35178918476B7A1B9E6FBEFDCDF1B3F02BA60562EDC5B68C6AC6FADFC1CAE6E9C267DEDED7ECFA507F277C18F80FE0A9E160654F1F4234E5EFCA51D9754C12CA0C5E96395835F3465E6AF793ACA81DC57EA044D43DED72BEFC8806DCFBEC917E89DD816A48CC726A39EA8EDA3917744EB45C6B4C09A08636D +smlen = 2500 +sm = 0000000C6C944B219F09B49DC2CED1253423D44E077C7F3DAE0800CA631065BBE52798C4E653D169BF64C7079434812664FE304668BBADE2BBBD8C134B28B4329FFE9FCAC65DC99709926439D826FF40E2C01197B72E13FE0DAB97E60D22F788827FAC992C971498927E62ABE5111A3193E7DB4D5A4686879722F82267CADDB672D312FA2FB88AC548574C251C89F00A567A3AB4EF5437FF1234AFF5682C510729F2AF387CC9BEC4D6D6AEE5F3BDCEE55A829AD0374B536D3CCCE4F94F8A75EFEAAA529AD3ECCCBFD7029F6B78329126C085FA15EEBB4C5A791E8A836C95D2E1C48D009BF7564FF869B4C45DBEBCBF87670A848B6F7804E27F253474941B4A5FD08B586F9F2D4AED97E8DF5786936675D8CFC9CC45A7951EDDCDBC419045B52782870CADF2577CCB2223BC4CC133162771F0E0735F141367F8EEC344AB8D73B919BEBD83183E4BF93543C748E80B298CB4FE81D079E1E9909C74F131FF4198DA648625A41F32DFAC5840F0D0C6746652F2B0C296CE736C4AB8C6B57BEB6BCAABCA9F4670BED8C3412419D1E3ACBF1D1A2AAAB6D6B2B7228D0610A08E6A7A1EFB8A7FC310E4168E9ED8281E08AA6A6512832149516586453D8F9E635E92AD9291929A0FB7610C9AB1701E220276F121BC687287E685F662FD9F01253DFD824B231CC969780567B1A0E861C1A29F5496EAD4667F08242FA7ADD1650719EB2164E86A14F4CF10EABA980AC33D84BE707EBFDD335046C0768CA319D2415528627CCA6449250B9F6504A160B41C205C76C1C45E087A741D7AEB880007EE9C119C5B8BA623B6F71BA290596FA4E9EF7856601E334F1851CCEC5234507E67CF917971E6EDA51DB86D6CE3FBBEC887DFC71E4BE3ACDB7CF3C10AE6FF1972B35F829421CA8426C7D6B54B8C30B1E6D866B626B099BECDFEF1FDBD3FC9BDE733E80E5C27416D8199890949D067C0B92F97B8EC2D7FD1869A987BE954919D340B4A3429A5D8AB13E1033506566DB3CFC50AA2DFC801718342B386F53FC4BE889CF07BD42E153649C03BF5BA87460572DF176E682362070E78486DBC7CB61C0782A64E542CC4D15850E6F80B22B45BD3E974E23CC819A855E195125A876C435562ACC5E6AFEF0359E389972BA7DD42E5F960737C2451B1345F8EFC8078570E1FF80BC6E3195DAC526F70649D44C6737B7391DDCF241D8AC0CF5551AA5BCF85E54350B89E0CEA57B1B7A4A1EA3DCADAA4AA55D432928813DE1635412954A152CE6D8CD8AA7A017A968C41415DB6B8CDDDFD762DA1829825E0FE303F3FAAFEA07E65A322F1496A4D648582FE7AC25EEA883DDA11894CCDA6AEAD9E57683F819D99CB64FFF21AB68D21173ADE9FA7BD5FCF92B5F880D7AB500E592DC2918C15131FBFCE891C9132504A9DDAE33209066ADA28134E843310D7B2C0066D446C00002689174401B4D9307DF58037FE157E7EE37406275510726E3B8F298A65A99509D2DEA839834BE87E449BC69903832FE827DFA477424F5F33524398AB14D5280F9289386C33B3D4791C62F44E81E0DEADC13B5E7C43E1E56DF769E7D89D3BC981DE0CCA1D682930512F9635D597D14A4BDF554CAF26F86492195EBACFCF921F464E07CB8BD184AA8686762C637AB309F5F8A2BAAE48450809BEE33112380576DF9A864A8434C10C6A93F8ED326D2F105DBE2F011717B25A5B622E85D286ED9085AA4492DBEA368D90D52B7EEC7F004C8F1D667525954C53B2A95FC0107D8309ACF865F12D1047DF7AF7017F94FA1AA9D1B45946C6D85DC849F6ABDBD393E0B8208576959FF757CE2D4E7018B78BF38D38DA114CEF8120C4B961A02834EAA331727CBD0AC79156C787740DFFA4D1610AE7DF2E1F7AF47C68243B44459AF8BA15A2504971297D40B70976A1B76B8CFF2E0FA5158B209FF5F78F2240C4F83980DD24426AD934AF0E0B6E5A6667A018E4D2B41DFDA509E823673BBB3CA8D39F38332386DE2048C002718361CA171ADFBA0C16F23B8F43CE7C3D9E2184101BDF3EE15AAC0878587C480816AC9B37870FC07B8C9A1F5666658882BB8C724296083298AA01CBC1E714431A37922D283E06F4E7D6E7F0E359784D04B686D8CB70E082424C2E1219FCBBFB17FD9A3564179D5D9791E9FE3DE6DEF0579470F7CD9175C7A3DF64B16E8434AF8F205A23075BD781195C96180B4E756C1B13A009B91F12039A447E58ECBAC183F833668433F244FEA2FF946F0642996387D1AE09DC932AFEDB10CEB0B25385F39587E55D3BCA8D42F570703998807081E107DE538256DB2A9EA25CA355EDB5C25E3A2E7E5CFB9DBA44675005924B7CB5BFD4920D337CCEEE50755B4A30B25EC29B4D4C656165F6BBD279591236FACD816BB685CEA3844A6BF76A24ADA1915653F47C0AC9859113DA4DB62653370CC2F39CD693E4DBE375C3099FE0F0DDCD1F57334501B0DAB3EAE9C10984B48670C483E20D8067AED50F93A6C4582703FC61DE0816EB30D10D904726993381E17487FADDA620AAF2415A2730F8819D81D9412F308984AB15006CE3015EA65420979AC0A253069454EEA9EE629152E004506B2B1B647AFDA1A3F5E25C83393A43768C18A984E2127D1C07E44C979DCD04D005ABBF1094861A1D5C28262B0A40168829D4EFA346F2803E6615C676991E6A5C90F27AE4B8F0C8FA53B8170D96C0517B97FC46CC1DA18FB16B3248CA0EB03DD4A8125732B5B94B45F85D316EC5088AE34A3603F33FC4FFB1DA574617A7957435E29C292948CB23DC21BB1326C91E65CA869330DCDFD50CCAAC8CA7F161402AB7044B33626C898C5299AA9ABD8BAF3ED559FC097C74774693C6BC3E8A3752590DE39AD836BF4AF6BE77E65639629787F6C9A4C314DED81358CED733443BD057230140C6ED6692A8386CDECED9ED6BAB06B58D66EF260237455AB56A8C6A2E2EB200B35D2FDAC16827CA6FF68D4791C9E654C85973AC8C62629ECC4B04A4242602DCC1BA4ABE256A26D95247BEF9F1C201752EAD7DE44F0D4A5CFC4EC5E04E8D778A1A874241E632534F4BD6B961421F198F87C8D3097267E7E45CF63DAE7F4ACC35EA8FD2C559B7C3EB5601EC90E1380A002DEA4BCC54D083A5634F8223AF145B35306EB9DF25BE2B95A2A28182D717A05E0798BFF294A94E29A13626EB6590C9BAF810C977A9E37C574540C6BD3EEDE15DF113D2E8492260FEEAA8049ADE7A99AF98CFBB7C67F06C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 000000010000000D061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1010 +max = 1023 + +count = 13 +seed = 21905954F5B96B48D223480BE10EED13A16F59C175072AFC3FBF0B6A69939917E07EA5D998523CBED0993F9D5C5F603D +mlen = 462 +msg = DE4F0CEFC7B6A7A83AF41268C268EBDDFD5C01366509402723283AC6BF6EBB5330CF62190E4ED61F8C232C9DD0DABE0628782029CD7BFC67765EA0167294CBC6EDD7C63829ACD5D09447AF5B13AB605FC51CA16044336DC888AEF43C7312E38BEA5E4378E7B260E01A9566FE2A8B2893429BF5B4F5A755EF901EB19BB2E6365FA83F11BC1CC5BDFE57E2A009340A034644AD8A72B467430D42AF7DEE753572E00A41886D971D4145A8D0B7540A63D26BFAA06BAFBA4C46FC5672047C56D7D5BE1E12F50AB0B3430A815B43901FA2BB1921956492692A6943E6035099D509CFA0CCA8077329786962ABD134909643BBD89D7A5F81A8F96CAA93E80BCC35BD75AB6F7CC43F1563EAC9FBCC697061C7FBC391E55AB545105B70555490F10C86D0B0ACBE5758B06132530E90D9F35B3E23C1E42F46405BB54D485B8A78264EA8E612A4332FCC46EA04938465B94298900129231E974159CF5359C6BEDBD7CC4CFCF0E79DAFD0738307105590AFC8F076AE6F026B9FCE281727D1DA9D3064BD534810EF08E05181F1496B0F014F7F895D67465781A905F3B90CD203C78442EC4F289DB7814763473FFB29B60645FDDD910C35F5D3AFAAAF516AB5060CE9AD57C616D15D90F8277ED658A6D2089535E437 +smlen = 2500 +sm = 0000000DA2F4E9C5D816C4EE8E82A8DA08F2EF56C0A4DE60731B6548C230E3C2764A98BF2F099D12D167218EF2502301F410D3154F2960CC92CDFA4FB623626985FCC7A259A095ED95F09D6BA7B67D525D1AF0A55060859E7F5EECD5627819D49CC76D6B7B264D36308DFE13DE699BABCE8F88F1F3FE4C4E89FF0D39E22F408D95EF787C760A340776B92481B995A52129A592E92EDCF5E080219B74D191E5D0B8D6905A85365DF865B59A883B7401D3061FD3462731FA25731428E1D6F0CC439439500A979D4D4DE8F2C9F3C75F9AE87309D77194A5EDA8F1602B0F5D323BB07F40ADDC72AEE9AB8D9970EF6EE82CAB84F61D58E4B2CBF01FCDAFC77F8BC46F003699A0F66E46FF3200CD0701660BE454FCB98ED1EDE0492D74C9EA98EC60BD6DD321E46AB34286DB1DC6300FBF34A4AE8D3725EE416117E2366B0A85D55516F236CDF34ED3302667F80F6EBDA13930F7D1F38909F98330D0F309EA024CAA1C5E62340D8AEF9BC289498763B3E322A938DEF14463D1DD761CFA1F3224DDA5828A0ACD682D670D72C50E2138FF4D6B4853CB64B51CE1DC1821AC1E03699849C4A6C2EF111AE893ABD703AD453D6F8DC042E482BD14D41D3FF261C1134E12FDEDED59F6F6C2D1242DF2AA2C3F0F4DAD14065C7DBF26FEEC5E863FA38E06A4BA51EE5D59B44052583F12BE9709551278D78825D2860E23C1B191ACA3DC53033B65F629779A762C6DBFBAF0E0DF785744DAE59FC6A4305BCA4811740D5C4B0C60F8822FB248BEC3827F34D9C3E9C5637D17678E43078E5A9C39435BD5081194690373672C78E228FA5116C59B07F9D7ECA7ADF828072CDD9880FADB36A7B6E3F3823690DB4029DF45E94E9E1784F7EAA8D8C2C338ABFA8EA67D00037902D4E671F2D8A9291096E3C0759E0348137DE00B6295592EC311E13EC42A3B8E35C3DAFF289B8A00ECFC8F8C05BE60F4D1679328199AE9CEAD6E0653D582D745463C61BA11E5C4E7329CE08BFCF96B879B7241A975FAF8DC09FAA11BB332F40C38AC643D3B44F0CAC2DCD600C2A73BA91652B9CD89D9FE606436D9CAE225DDBA8673487C7DC91D49CDC9B03F63068A4E4B2E95B565492188711A1894F597D04369FB9CC3FC0577C81F4ACEDA050C11F8F8A671B638E2CA7CCBCF5E7F18E1A878171F2E00D2ACAEB7C91334BAB49A065BD4034041B7B064201D846C765EE0C92D03C5964F6193D2D11653D755246AAEE62200ED21327E19EC2A66DECD6B480EABB59CC574DD9E8BBFFAEBC478428B0F78E335300C4322C4351E5AD7E9C2B673947EBFE42BB874F8158A880C4ABB59E4A48D9A8C2C4718212F9DE0BD0CBD55447EBA4F93DCD2DCD143E5A66E16FBA34C0AF0FBCD14F9F50A6449E8F9AEBFE1EFA63C4473D38499DA73337FDC50DAE7EB38DE5DDC00952FB38DCE1B915C0D160B85A9146BAD1D2BB53152B4DD3919609279F59C7791D65C66330EB4270CD7CBAA68342DE2517B3D69162349B66AE62140487C07D0957FD5FC54A0F4C05FFD62BAE733EA6891B330D3DE39BAF2401572E013A7F1F696CAC53402DBFB4CA425252DD990CFB668B95DAD3B85189EB971B691BA54AA3279E696EDCA00E5CCCA8BD60C9FD948309AB867767BE58155E49AC8C2C780C4940CCBC30559E71DE7893CBB6D6E45D40C1013FFF2D81A146894021AF7005BB6D2BA35ADBD5E1B4AC529598459FC86DCC011FA72AFF832DC6F5B8813AEBFB793195C95795B48764FF59E352990C328B0474F8E0D888F014218A82A3EFA5F58F80540908EA060B26E1E96A81872C285AC778049DDEE94EA598195ED878D11AE6C7282A609826A59B365D374873CB5EE3B5577179DF51928B0976200EEFAF020D4B3E9D3190BE44B50A4D91EB3DB1C1FE0F01AFBDAA39F6277C8F06496E1F2B6FC0DF2D01BB8C7BC94427F7A3731A3FACDE421B2B080CCDB009B228944C9F663B25813391EF7472DB01AE8212A1FBC274A41623013ED6056E64B4AF1BDC3F3571C6A9F4FCB560C1F621316A27288FC1B093447FBC1E930C823F5AEF8C33A57FCFE8E3E08E41DC861D3F8A4F30AB624413396DC4D414F2EA4EFFBEB3A03F6496533836094ADB2427826A1D289150836788045F8640F5D0F600A56F4956AB85DA0D31F206CF188F1630A1810916C6ACDF2897B54964391A975AA224F6870B5EADD1A3C56C51A21362795BE240977187C7231EDFC56CE71F8B997D390CC7E3343755EDE9FF3794A875451CCBA634AB6761B85ADCB56E28E5483E7AA9F017333D2EBB1C3B40EBC330F5A46F03117D9059351769C88B8BF03D90BAC63B4EA073CE2D3C6C5FF7A67DFA8F6B27858668C1056E8020BACA62EEA224BDA4257DF3B7045D8655A8361B5195F150216D8EB045E4047916FF03BFE8FAA6AD5F789E881B1D8434D3ECC06CFB46E4D25323E74605DA75BEFA5B5B796C6A3587710B1A03912332C84A089E055A4AF938FC1325D120E80FA2FABEC57FA3EB197CBC7E0548E2ED397F1ED1A128AC26CC4B7F9EF399F2AF01540463C929C6483EFF1B55DA0E06F574EB3C2C21A55199C37B35FE5F8C2CE2C4276146F5E96CC4F0CA9B36B40AAF426FB2F6345E7245233928F13EDA38A6BB2872E590919D99497D4430A89AD2830E9131B46C41C51547F0A908A753F79B7671EB69F5DA919A987B9B8DBD0098A2F1B3DA8CBEFBD5AF73FA729DC9524989AF8B0853CDFFE345DAB39379D401135E19FF844C4AA89B3C69BD72FB57160CFE28E6F927A00BF94A5B9ED7A0C78977381B24B93A4C6E5893652D6B2C8B9BA89D3BB074325C328FDE52BC96322715538235BEB0890DF1567A473117C8F48A425BBC84327E9E0882AA128828B6862EF11CC54EBFD80891404C83C86F6376B8F3D009BA9C02675456F534C75BF0F6D1A52AF39CB1D10945A5A3EEAAB9C0F331D41FE855CDD5F2EBC18AF5B79E23078BAD54DD8E67EADA8700D96979BF7D121FCA304E81158FE2B181EB4A1EAEDE044D99EDEA7AB8D9D8056035D9B1307FCF23E5354CEDD51FB67BFBEB92DB445E92C1EC813B68A45CD1FCF0BA2EA0DC42746951161B77480E3E13D811B1F8DFA30E90EFF64C7B9F0A129BF4085A2F11F537EEE2E04B80C3B93E101A0FAD94B2B95A2A28182D717A05E0798BFF294A94E29A13626EB6590C9BAF810C977A9E37C574540C6BD3EEDE15DF113D2E8492260FEEAA8049ADE7A99AF98CFBB7C67F06C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 000000010000000E061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1009 +max = 1023 + +count = 14 +seed = 5B9F2A1DFD877CBE4E30BCB6F022FE142E1611189F83AE628D64EBB329AB0D9C66461CB73EE17E69F5B637CF4886BDD0 +mlen = 495 +msg = 971DA327D2195078632898AF79691F8F5F93189EF0807714096D27480E82B1F0B884AD43FEB3151AB6B7261A501416AB982BF9F2234B8199F89EDDCD56E160E1825E79365625A979FE157E9FA937926E7F12C4B5091EE6572CF8D4FB9FB8E1090BEABCED73AC36B35A5020EAE0134A3291CB10A05C3EF778038702843739E59ADA2C3CEBA6353B482C5F80E751E10BF13DDACFC6C0E3FDD09B21710ECE846ACFA1305074ED4328B90E65B1FBABC53ADFD964A4527CB1B8101C30A41804A5EAB9A00D135C38C52EB5149B6655B60D5A1AF50E3D0DBDF63A035924102495B46327A063292503F4D72BEAE063B577B57226175AD58DB98AB164521EA9C21A78D2BFADCC109B78082FA4AB1FF3FAA2B768BE3FDB1F929B67010944DC3AE6941877F599B478B03F0C267616AEE949197CF7D230EFE0930CD01D6D4E0A6A628068C6006B06C75F2DACF6027D5A2721B34A232A73DADA62A1721F2903983A5A04EF8ACC4C5E29114A9BED0BBE492C1972212DF08D3D2D8041E5658A42442821044AC7A8151F621BC88A56B53E84B5F342154C1109716BDF877A631EDF7BD64E5FE45A0DD40BB58C91F9DD5005736DB32DB3B57B9DAAC0ECCB66860689F5C1F6BF9D5115544601260F22A90EF77B340DE9B4C7F38250528D57140EA5FFDDCCA4C4254252CAA34A4DBB9F643B18ED950DC89A06 +smlen = 2500 +sm = 0000000EC2BDBED877538AEAC597717A7AFBEA0D0954ABE8A2E303FD5386BE09B9145B0C4F5203CC3771E11D3EBF99F8CDB84B8B59940B570676EA55FDF6996BF8A8EBC5293080B32CEFD214031A7CE6C9A239751D15738EF36195812AE0553CA5054C8DACBBCBF686C371801CC80544E9BE47B1E01090090D7BB51B52DF71D91417FB922D6235B34464CB75D6357A9FD3FB19789C78A1B5445265157A8F58C97083C9A3F77E1CB62F400722ECF9EA9607872D3C6A12925EA7F4D0FAE1359D3CAD5B84BAC51B5E18DC6F915D9D3877248331E841CA5E2A9E5E22ED89FF387200E50F52CCEABD27D6826EB2287DB82D7EE520391FD597B6E73139D84BE3C1378B822898C4A8EC07FC922FFBF9DA07B3A08A3CEA274606F312AAE564D581E8E2E7DFC83C26D7FB29C88996A6363BFDA2115931D23AFA9E1345B9D8DE542FBB8AE1A883EA2C3DD893029D9DDB7320E0B8CCD1E864D04FB2A0F88F8974FC26841D212F70F7714EA7676B20C0EDB14F3551FEDF6A6F9A81C06F5409791E02B2152E90B3647D326890361887E005819E758367695243C60DF2CA9611B9836478290A82E471494336FA2D40D2C5768047EE8B2837D82E232F8A52A5F28D79A5E0EDF59E8FB27FE189BB5B0F3E8F2112955DEA9435CD0E8DC59671930528016B04B05864D309080A6A142F0ADA36AABBF0A7565F08B7AE8F893D0E724DA5DDEE68CF6EB05DD8ED5BF327B3F681FCDB708F47894072B5A60C1FC4DA918A8BF40E01A1B85D546A9CCD65CA4C45EC66B81D15BEEC0BB1114CC87C8768EE0C1787EFAEF0B623754DF068A9530EEF7E4A19434BE78605C5230F8351AFB855920EB056BE2A3C38AA1130479E653E93869E556170CD10F9A9820E6B6A17BCAD164A16E0AFD1F57FC7C517AEE878241675E44B8F85ABD1404E4C55F17B05C4D3E3E6C7197B1B90CC1C770758BDBA381E61BBDC0E4BA9E36FCD992EC1FD2A8E598CBB9F6374A3665E10DFD38E1087998DA2875594CD5712639D28F4614C3A5238FB611ABAA56ECD0D80CA77AC229B6B7CF9F0678A4C9ACB41E232B29BE6A7C3973364801E1DF151E9B947F768CB76FF97E4C7F00902FCA4D83DCFB51359F01C68314BE71B7311F4A93AD651014F35BA773E27EE81E38018FF840FB5456120021B04B9CD5503D5829A7394EB0FAB8E211BEB08DD5063CE686B34CFCDF0101F29CA63D1A6AFCE6ED512B3D4E06DEF655C1E70C09072911F6ED8E75B35A466941CD98B91927A59F89D4E417B4457FF686CB305BE08A9FCA46AE7B3D0515374A3A15CEDCF67BC0ADFB84605471C5D17141D89B4930B8D16309FC3FE1B4BE671671C67761A2A65565ADFC7BBA5EBA03D46675DC407511A8AF49055628E47BB8148F69A0DD542AF9A8ACAE95042D2173FF559AB30689BF2DD6CE2E9BC177DCC38954F5019B7F9CC6D9B6966D6B5F3ADEDB3CE772A017DC98CFE1C3EEEC6CEA804D9A862CA7CBA4F3CE71D27647784840F22DB7DC1D24FFCFCC73CD086AC0C2F5CF6F090CF508BF802C397A53EB393B6A8E3B890615C690AC84C7111BDA73D772AAC3D3A85A23A10299C98D8CF31A96F75E69B00A1C7E73A5DF7F5E5156315D60A26D2620720EB7D2D1218328BA7CEA44C0E4F67F5390CD395DE53A2A1284B643BD496D4622739BE6D6D20967E6D295ED74753859E43762105686FE56BAE2BB7D7DFE92148123BE34FC191A3A095ABEB7D62D9276986F6A6E5E491707750CD9397315A8E0A116E730EF0DC1F872DD3CE6C7EAEEB299016940A49D6D858E1130B4BC0DBEEB28DCC45507477E149AA8F89165494D20DB95960788B7056F3C300664C51B6E57AFFB185760E7CFEA4E0950A6087327FE90B85525EAAA477EE77A3E5CDDC7BD7BCF2E0527B04BBEE19531131335F280406CF18AD9755ED995F5D7DFF50C2843719A8A65626F978D15F738019C5CF0E9C83639EED862E518F29FB0D70D80A3C36E565AAE7BBB04BA42809C591002BA8D1B7FF8579A1D50761A10A0CCC32219784A7C79DAC25CF1495B2409D5743D93CC3371BBBB66D1CC54CA6B5FDFF6F55AF6439CE48B2B54420214147E247AD6AFE0612556F092C9A3009DCD78D322374D111B8097AB516402CB129CF3CDB02EC6F86D85B67B8E3C46637A20CD853E0419DA7351803B6B716B143636C6B67E911508FBA163FD126C895E916FDA1E61652AD18B5F875CD954CB401820DD4B33D42F6AC6EEEF32FC6F002F93A02DA8B94996676D189C1EC49DC3B50883300654904C3FF42EE2204AFC09F10FD31840DFC03C6F1DB94E9B4717A81BA75EA6414E25EAF1EBB07EB10A06DC8F6E998C8BD2B4FC11B0A39132787BCF8EF204325CD749CA55C0C0F181C860506422AD1533DF054CE2C4A14336CFC2F491D8898881C7BDEA290F03B592F41803DBFA4242B36A00AD5679A4B399F6BFE5CAD3651C20864278C1E21108FC5C931DD609DF0C862DD5580D143122B31752EC50166449897AB37CBD781A38FBAA8AEC433CFE069375345000C149664AD80A49A42D63E6ABA5EF18A7D5BF3DB41A2AC6F37EEBE6EB51D6A33DCD0D8696060CCE1588E4F5FFFC9FDD71D77841C999E305A89FCC77FA47DBEF546787A18D5BD3B245069E12BFD01EB979D661194A65B9F63B2B618A924BF6EDA90F10457A10F90BD0D8EC793ABD8826A7858691A600BDCB889CABAC8D6DE95D68A2AFC1B6A7D62286302D6C639BAF3BB56CC040D33B0187220708B7B9FB9B61EDB2919585F39171A084EBA668007357DBED95E8A9F4E19B91CCFEE25DCFD85CFAFA286A77451934373B5F100621C794E375F6E69F6DFFAF61B9375EC5B5EBC8F0AECA1E2AA2437D0DA7331207270FFDFD83CD40C3EAB2A4BD452DD5567FE4794C74509A840815F12EF9CD26DBD164B677FA61C06CE7280C7A1A9D2570081161C15CE3F39183F8D7DEA87966BF87E191261E810A4E476A29E8FBAC4C51BEBB86630CE74538E9161F05E001E7AB2DEDF2C4E85957B0E9DB53E2190CAA2513CFBEAE419499E68303810DD604475B2DDE732DCC42FA8BD29FECD128393E422E35D9ACC7BC70F43787A4F755BE4A04D21DB18559FCE2F8C54EF3BFF39348DA5E63456B063063786637ADA04174AB9B37257E6024EB56767E439125B55B23CB29B00820BF6C9F81CFE63392A76BD3DC57C574540C6BD3EEDE15DF113D2E8492260FEEAA8049ADE7A99AF98CFBB7C67F06C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 000000010000000F061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1008 +max = 1023 + +count = 15 +seed = 6F41B5F7648FBC1B70F35CED64B3EA95E04EF08CA2C96D8AA264D85F1556C15B295E98699431B072AB2EB621390B6BC1 +mlen = 528 +msg = B0B98E653197404F869906E4E247A0C65C485EDB719D0F24508F55E2E6B2F10247C431B7D02E7107375D6E3DE9F289993C5C082026EC982D0B3998448E4E82610A7EAC8ADB3C2BB1FA3FDCA3ED8151CA94DEEDCDBC6022FCC2E89C2CE89D3C3DDFF2BF86C3AA47FDB7992E1DFED195E2AD2DC46D8E8D67DF6C7157B85E941DA8A703040741DEAAA88FD97642B546C40A135E5D184403A218EF425069D698D9D2B765FC7DBDE46661644F616DDEA73FF9E0ABDBACE39A00DF1802BADE7059DEF4E2FD622DA13154612DE5A74EE2B38EC29D3F4C8AD96EFB347B29B77902E0020919C32E698EDF88816F4D8E55F6EB84B273B879D51AF6DFEFDCEC72113EA9947E7448C2D15A56E748D389FA84C94F8F67DD52B5AE6393EF4B48ACE2B45F4A47007F33CF1C40F0DD043D964B403104290FDCDF56AC39DD3BD28F7AB3EE8BB455CDB0E9AC9129363E8979B53E34320C6516F6861D70AD47A605A13D00E59506A6FD48D8DDFCFBAEFA0A3FC6A1D4B8599D440EE71AECF85F3456098F361C3BCD1562C8537CDA207B1911E33C58CDA460A7A349528DDF8B2AD41E979C858FEA5BE70F2147316FC92103D6786A75D1B3D3B5B18C9DC0A702710D3E4EF0AC9BE325CD0E8F1AE09ACFB0CDE162153CA8E894AEE6B9059AF9BB37150FFA76C532122531B3DBD4D323BCC10F3D0FC7E814C6074B9C5D9328510415D7DD236D478D3F349D5338DDA8D4BB273C8D0290664D6661080B +smlen = 2500 +sm = 0000000F6380E9DD17D8D82C80034710AFF3D2405CDE036AE70A8708C52A514783B2DD9212717E6AD1CD1A850658EDA7D055CF04648DD80D6DA435DBBD4140B90DE079C064D1FD5611B0F5810264A148DECD4E62A8554FE38D50E43CE5F8E1D72723C12134BDFA3105F5D90C8D21FACC87EFF761589B23AAB9DA9154E7E252ED30AA186221D640903E2A7D2328629B8E7C2BDC9CA34886171ADA9E8533C983738A84A2982797D8E200BF43FC145B4F4897D06F3BFA36D57146777A34ED9A331BF33028A1CA92C0B24E849A3217EA488BD91743A44700928532C0953C227CB2D55589A8F340AE7ADB2C032A35B79E35C718CAE4BC28B3DE25C031116DB97C9542E3782AD56511A9D5403A93A06482A84469362E83F35EA57660602E3E0A37F0173CE0DF978678609AAE4EF9A413E09A78B1F29534CDB9087B494AF99ED2FABDADDD2341EE50B9CDB3F70C3C04225599FC5BEABE0E4F1643685E5F2D9DFCD239E40E9F26AE5BCB355845BF3803B7A4FDCAA5CE632740C32B6988B8EEDFF960F9489C4A45CB5147A69658D73B1591B6C6867BE801E95EAA2F6881370EF61D17CA8FEEAB89C3914C7095AF2F119820585193CBB91F70D5408A623C518B6EC2468937C3D9960E217B79BA016809ED28604DE75C9FCC65F77503FC95CBFE6415F4C06B6750A88387F8AF1825C982369AC1B97CDA8B96CAAB4EEA9C4A1771427A64DF8F9F8E2C1DD9A2106D16216D1411D8F3FE17C191729A75075AF3001721472A311810E26471832BA89143A762DF88E00C3F958DF6DB414602AEB08E97A4FCE7219362EF3800EC2B3BDC1E2B936D8F4B1E4F2F65F2A40B404E397765181CC40D0BE334793D827F5151A66CA637E5914ACE7B72C7DF2E20841CB2CC3DAB8D00C30E7392F146B55770D4AD23365373C4FF113255C9DB98319A2ECD5B2CA74216B623F1E3AC2351B322C2F8296677E5A1C6E499019087B2AED8B8F7634F4BF74454B65DF2CEE89C3BF4458A240F2CDE6E5D6598607303746F22A5813DD284E458C1875A23738D2D061F738C45875CF1C09895424AF5B16C444935DA630958D036FBE7E8112307027410012162EF755B11A9A717FCE491597659C1C7D613917A3EE153C0DA747BA30979A75DABC39CE1C4DAFC9B8CA4B9CAD9389759564DBF6E5C44338DA26AB20BB89884ACE11C23C80C772F338026D679BA493BA54B43EEBC894FCFCB82037CA9B87610C3CDB6B40FE2A4D0D994736E41BFCD52B1E353DCD1F6A936D46A088658F29AEF70E52CB10B7C9913161D534DEDB19F3052642B2FBE3B7F13A9DFC90ED2F31CB13E40851E63477EBCA17AE8DD57162DBD50229E53CE2F7BE182BFDAFB1CBF7411BF81A6347D36EF370A80C214BD810DCC51AF6D41339450967BB1D64C83D291F6A83A34DFE75F8EAD9BCE44A1C35D63B5052DC6D1453BEA470CC4A305353E5AC54316FAFDE70CA0DA16DE0558F99ADAE0817EF389DB33520A86E1BA5AEB53F9AECC98ADEF00D191EF7366F35A95FA5875D9E9328B8B60E7F55B49BF8D813CCDD1ABD4D06F44B09819A2E8EFC61EE12DC83A5D46A2B673A8B985F763CD7D1A396F7E0ECEC0BFC0D4916946B68C6CAFE5F2B45F345ADD145ED25BA9BBDAF5DDB7EA6BE3B8E89D7A9837BB55851AC5DE3F0ADE35A3C5E1E39561FB850D238ACA632997059755FC1F5C9B7A58479CCED5251F39811885AB916CBAAE4698E8F6CC67D14071317FA79DABF2F3C9098438BFCE22F64EDCD49EBF75FCB7CF0D5804821B1892F7F417FF77B2C61020A1DBF66561B351503E8DED31427B50CA896A2BA37627477F33FC50CB0E51107ADD6391C5290C9CEB0AEFB837EE3BAE99FAE78C2215CFD10E008BD0F26490DD5A1ACC9727405EEFCE6CCACFC4F291D9CCFD726957477487E3B64200EC4FABB79A38BF7E1F4B00FEDE43C28D1E7A0EEF3B8E1639436DE69B53A13EF5267837A28B1E0788E736F08C5DE95BCF030F9B24DA8616218B983D22C20C6A5C4436EF236C6DBD6AED69D86F5BEEF250FE21FE4F75630C2D77D39FF35C205363A40A7461B12E2A52BF0BDF70FB8C6879D2A00B8CC6B44DB4F7FB8806DC5D80CE9AA2F72268BFC256848618F25C46260D013D3F0B0D2139B63829F1D616CF4D47749CFEA5E5336539214FA73F1048C0E012CB702B4D1C0407DEE769A4AD046480EC020E90622A2BF1BB6480E52E8CD6EA4AAB9F861FB3B9F2C8853F3FBB397BF7F58ED6EC2033FE0579ECD921C24B03A446ED3BC2F7C8B93D59E52EBC8CA571A6DA8AD8C4B2DA83C0A3EB19B5439235097CF87710D9378FAAA12EC6BF5AE6E36D3DDF2A4809CCAAE552E41F404006785C9BF30A7EAB3AA5CC9C9FBF7F8DFE93A356993D3752FE88C77E9FA9B40A2B5272855B8C7307119946E5577037E2382EC700F57B8B962DECDCD2AC7D6C4EE1887EB9EAD542753548A60BFE6FF83F8F9D8950B82C4642FAFB58C152D69F5E993F762A86CB9A13290F07AE77CF788361E5013B3D1EAF5174D4184AE7BF8711EA50B04163CB4CC7EF645A2822BD5ADFA0DEB85D6E1CFF105B1BC96F2C0644DD375E5078B8E3F7A0962C54BD89121DE087243ECF73588938F487F163CF333E5B5212EE3E71264D21A3965785F09CD97737CF0FD3206347A33DC95A7A31BBB2FDB52C0988A35AA3EF74EE257C3096FB0AC40CF11DCB91C09E1A19B86F57E20FC6C1B868D10B990BEFB03C975A0E010D131344557C8CB49BD1351E166B712B351771D7935E5A26BA1DCBC7832D467F6B8D2BDC69078E1AA40D236700EFEC54E7E7D26C67B2167DBE76C9F529F28CB8C2078EBFDB364886686DD3D251C6F060C1971504984D33AAFA4503043339A494FA48165B42CF153DF2DFB6B5ABC2716DFA6FFCCDC60C49C82D27773B0D7E6194BD5840ECCCDD59C776501F7C2793F726FBB79C7E174689BDD5D47E50DEE6B1FC2DBFD7A968A57DFFB2D646192DFF2B4AB63A284A9FC4583FBCD0128BF3831F579BE0F2000E31C7C98C43104304CBC168F60AFF77E65DE4BFB716B9F3619688945BEB34ED112E619B017A744A9AE1624A3DFF9E935E639D9DBF5700D99575A8681F83BF86EE67ED1D9E75F03622149FBAE8E916A1DAF2255304CC3676687257E6024EB56767E439125B55B23CB29B00820BF6C9F81CFE63392A76BD3DC57C574540C6BD3EEDE15DF113D2E8492260FEEAA8049ADE7A99AF98CFBB7C67F06C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 +sklen = 136 +sk = 0000000100000010061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +remain = 1007 +max = 1023 + diff --git a/tests/helpers.py b/tests/helpers.py index 58f0834511..f050f83366 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -12,6 +12,7 @@ kats = {} kats["kem"] = None kats["sig"] = None +kats["sig_stfl"] = None def run_subprocess(command, working_dir='.', env=None, expected_returncode=0, input=None, ignore_returncode=False): """ @@ -192,10 +193,20 @@ def is_use_option_enabled_by_name(name): return name in available_use_options_by_name() def get_kats(t): - if kats[t] is None: - with open(os.path.join('tests', 'KATs', t, 'kats.json'), 'r') as fp: - kats[t] = json.load(fp) - return kats[t] + if kats[t] is None: + with open(os.path.join('tests', 'KATs', t, 'kats.json'), 'r') as fp: + kats[t] = json.load(fp) + return kats[t] + +def get_katfile(t: str, sig_stfl_name: str) -> str: + algo_dir = '' + if "XMSS" in sig_stfl_name: + algo_dir = 'xmss' + if not algo_dir: + return '' + kat_filename = f"{sig_stfl_name}.rsp" + katfile = os.path.join('tests', 'KATs', t, algo_dir, kat_filename) + return katfile @functools.lru_cache() def get_valgrind_version(): diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c new file mode 100644 index 0000000000..9685265902 --- /dev/null +++ b/tests/kat_sig_stfl.c @@ -0,0 +1,289 @@ +// SPDX-License-Identifier: MIT + +// This KAT test only generates a subset of the NIST KAT files. +// To extract the subset from a submission file, use the command: +// cat PQCsignKAT_XMSS-SHA2_10_256.rsp | head -n 16 | tail -n 14 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "test_helpers.h" + +#include "system_info.c" + +#define MAX_MARKER_LEN 50 + +// +// ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) +// +int +FindMarker(FILE *infile, const char *marker) { + char line[MAX_MARKER_LEN]; + int i, len; + int curr_line; + + len = (int)strlen(marker); + if ( len > MAX_MARKER_LEN - 1 ) { + len = MAX_MARKER_LEN - 1; + } + + for ( i = 0; i < len; i++ ) { + curr_line = fgetc(infile); + line[i] = curr_line; + if (curr_line == EOF ) { + return 0; + } + } + line[len] = '\0'; + + while ( 1 ) { + if ( !strncmp(line, marker, len) ) { + return 1; + } + + for ( i = 0; i < len - 1; i++ ) { + line[i] = line[i + 1]; + } + curr_line = fgetc(infile); + line[len - 1] = curr_line; + if (curr_line == EOF ) { + return 0; + } + line[len] = '\0'; + } + + // shouldn't get here + return 0; +} + +// +// ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) +// +int +ReadHex(FILE *infile, unsigned char *a, int Length, char *str) { + int i, ch, started; + unsigned char ich; + + if ( Length == 0 ) { + a[0] = 0x00; + return 1; + } + memset(a, 0x00, Length); + started = 0; + if ( FindMarker(infile, str) ) + while ( (ch = fgetc(infile)) != EOF ) { + if ( !isxdigit(ch) ) { + if ( !started ) { + if ( ch == '\n' ) { + break; + } else { + continue; + } + } else { + break; + } + } + started = 1; + if ( (ch >= '0') && (ch <= '9') ) { + ich = ch - '0'; + } else if ( (ch >= 'A') && (ch <= 'F') ) { + ich = ch - 'A' + 10; + } else if ( (ch >= 'a') && (ch <= 'f') ) { + ich = ch - 'a' + 10; + } else { // shouldn't ever get here + ich = 0; + } + + for ( i = 0; i < Length - 1; i++ ) { + a[i] = (a[i] << 4) | (a[i + 1] >> 4); + } + a[Length - 1] = (a[Length - 1] << 4) | ich; + } else { + return 0; + } + + return 1; +} + +static inline uint16_t UINT16_TO_BE(const uint16_t x) { + union { + uint16_t val; + uint8_t bytes[2]; + } y; + y.bytes[0] = (x >> 8) & 0xFF; + y.bytes[1] = x & 0xFF; + return y.val; +} + +OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { + + uint8_t entropy_input[48]; + uint8_t seed[48]; + FILE *fh = NULL; + FILE *fp_rsp = NULL; + OQS_SIG_STFL *sig = NULL; + uint8_t *msg = NULL; + size_t msg_len = 0; + uint8_t *public_key = NULL; + uint8_t *secret_key = NULL; + uint8_t *signature = NULL; + uint8_t *signed_msg = NULL; + size_t signature_len = 0; + size_t signed_msg_len = 0; + size_t sigs_remain = 0; + size_t sigs_maximum = 0; + OQS_STATUS rc, ret = OQS_ERROR; + OQS_KAT_PRNG *prng = NULL; + + prng = OQS_KAT_PRNG_new(method_name); + if (prng == NULL) { + goto err; + } + + sig = OQS_SIG_STFL_new(method_name); + if (sig == NULL) { + printf("[sig_stfl_kat] %s was not enabled at compile-time.\n", method_name); + goto algo_not_enabled; + } + + if ( (fp_rsp = fopen(katfile, "r")) == NULL ) { + printf("Couldn't open <%s> for read\n", katfile); + return OQS_ERROR; + } + + // Grab the pk and sk from KAT file + public_key = malloc(sig->length_public_key); + secret_key = calloc(sig->length_secret_key, sizeof(uint8_t)); + signature = malloc(sig->length_signature); + + if ((public_key == NULL) || (secret_key == NULL) || (signature == NULL)) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: malloc failed!\n", method_name); + goto err; + } + + if (!ReadHex(fp_rsp, public_key, sig->length_public_key, "pk = ")) { + printf("ERROR: unable to read 'pk' from <%s>\n", katfile); + goto err; + } + + if (!ReadHex(fp_rsp, secret_key, sig->length_secret_key, "sk = ")) { + printf("ERROR: unable to read 'sk' from <%s>\n", katfile); + goto err; + } + + fh = stdout; + fprintf(fh, "# %s\n\n", sig->method_name); + + OQS_fprintBstr(fh, "pk = ", public_key, sig->length_public_key); + OQS_fprintBstr(fh, "sk = ", secret_key, sig->length_secret_key); + fprintf(fh, "\n\n"); + + fprintf(fh, "count = 0\n"); + if ( !ReadHex(fp_rsp, seed, 48, "seed = ") ) { + printf("ERROR: unable to read 'seed' from <%s>\n", katfile); + goto err; + } + + OQS_fprintBstr(fh, "seed = ", seed, 48); + OQS_KAT_PRNG_seed(prng, seed, NULL); + + msg_len = 33 * (0 + 1); + fprintf(fh, "mlen = %zu\n", msg_len); + + msg = malloc(msg_len); + OQS_randombytes(msg, msg_len); + OQS_fprintBstr(fh, "msg = ", msg, msg_len); + + rc = OQS_SIG_STFL_sign(sig, signature, &signature_len, msg, msg_len, secret_key); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sign failed!\n", method_name); + goto err; + } + + fprintf(fh, "smlen = %zu\n", signature_len); + OQS_fprintBstr(fh, "sm = ", signature, signature_len); + + rc = OQS_SIG_STFL_verify(sig, msg, msg_len, signature, signature_len, public_key); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_verify failed!\n", method_name); + goto err; + } + + // print sklen and sk to check the updated secret key + fprintf(fh, "sklen = %zu\n", sig->length_secret_key); + OQS_fprintBstr(fh, "sk = ", secret_key, sig->length_secret_key); + + rc = OQS_SIG_STFL_sigs_remaining(sig, &sigs_remain, secret_key); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_remaining failed!\n", method_name); + goto err; + } + fprintf(fh, "remain = %zu\n", sigs_remain); + + rc = OQS_SIG_STFL_sigs_total(sig, &sigs_maximum, secret_key); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_total failed!\n", method_name); + goto err; + } + fprintf(fh, "max = %zu\n", sigs_maximum); + + ret = OQS_SUCCESS; + goto cleanup; + +err: + ret = OQS_ERROR; + goto cleanup; + +algo_not_enabled: + ret = OQS_SUCCESS; + +cleanup: + if (sig != NULL) { + OQS_MEM_secure_free(secret_key, sig->length_secret_key); + OQS_MEM_secure_free(signed_msg, signed_msg_len); + } + OQS_MEM_insecure_free(public_key); + OQS_MEM_insecure_free(signature); + OQS_MEM_insecure_free(msg); + OQS_SIG_STFL_free(sig); + OQS_KAT_PRNG_free(prng); + return ret; +} + +int main(int argc, char **argv) { + OQS_init(); + + if (argc != 3) { + fprintf(stderr, "Usage: kat_stfl_sig algname katfile\n"); + fprintf(stderr, " algname: "); + for (size_t i = 0; i < OQS_SIG_STFL_algs_length; i++) { + if (i > 0) { + fprintf(stderr, ", "); + } + fprintf(stderr, "%s", OQS_SIG_STFL_alg_identifier(i)); + } + fprintf(stderr, "\n"); + printf("\n"); + print_system_info(); + OQS_destroy(); + return EXIT_FAILURE; + } + + char *alg_name = argv[1]; + char *katfile = argv[2]; + OQS_STATUS rc = sig_stfl_kat(alg_name, katfile); + if (rc != OQS_SUCCESS) { + OQS_destroy(); + return EXIT_FAILURE; + } + OQS_destroy(); + return EXIT_SUCCESS; +} diff --git a/tests/test_helpers.h b/tests/test_helpers.h index 5b1c17d7bc..a4ab668c2a 100644 --- a/tests/test_helpers.h +++ b/tests/test_helpers.h @@ -7,6 +7,7 @@ #include #include +#include typedef union { OQS_SHA3_shake256_inc_ctx hqc_state; diff --git a/tests/test_kat.py b/tests/test_kat.py index 2ce19d3593..c69f76c981 100644 --- a/tests/test_kat.py +++ b/tests/test_kat.py @@ -35,6 +35,22 @@ def test_sig(sig_name): assert(kats[sig_name]['single'] == h256.hexdigest()) +@helpers.filtered_test +@pytest.mark.parametrize('sig_stfl_name', helpers.available_sig_stfls_by_name()) +def test_sig_stfl(sig_stfl_name): + kats = helpers.get_kats("sig_stfl") + if not(helpers.is_sig_stfl_enabled_by_name(sig_stfl_name)): pytest.skip('Not enabled') + katfile = helpers.get_katfile("sig_stfl", sig_stfl_name) + if not katfile: pytest.skip("KATs file is missing") + output = helpers.run_subprocess( + [helpers.path_to_executable('kat_sig_stfl'), sig_stfl_name, katfile], + ) + output = output.replace("\r\n", "\n") + h256 = sha256() + h256.update(output.encode()) + + assert(kats[sig_stfl_name] == h256.hexdigest()) + if __name__ == "__main__": import sys pytest.main(sys.argv) diff --git a/tests/test_sig.c b/tests/test_sig.c index eb3ab0af12..90990adad2 100644 --- a/tests/test_sig.c +++ b/tests/test_sig.c @@ -129,7 +129,7 @@ static OQS_STATUS sig_test_correctness(const char *method_name) { rv |= memcmp(message - sizeof(magic_t), magic.val, sizeof(magic_t)); rv |= memcmp(signature - sizeof(magic_t), magic.val, sizeof(magic_t)); if (rv) { - fprintf(stderr, "ERROR: Magic numbers do not mtach\n"); + fprintf(stderr, "ERROR: Magic numbers do not match\n"); goto err; } #endif diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 405def1754..e80aface60 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -129,7 +129,7 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name) { rv |= memcmp(message - sizeof(magic_t), magic.val, sizeof(magic_t)); rv |= memcmp(signature - sizeof(magic_t), magic.val, sizeof(magic_t)); if (rv) { - fprintf(stderr, "ERROR: Magic numbers do not mtach\n"); + fprintf(stderr, "ERROR: Magic numbers do not match\n"); goto err; } #endif From c9c3835c577e52d5da0fdf3c83334d59594fcfa8 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Wed, 12 Jul 2023 09:09:02 -0400 Subject: [PATCH 06/68] Re-add OQS_SECRET_KEY (#1493) * Re-add OQS_SECRET_KEY * Updates per review and formating changes * Set function callback for 'free'. * Address escaped PR comment * fix formatting * Update src/sig_stfl/sig_stfl.h Co-authored-by: Douglas Stebila --------- Co-authored-by: Norman Ashley --- src/sig_stfl/sig_stfl.c | 33 +++++++ src/sig_stfl/sig_stfl.h | 96 +++++++++++++++++++- src/sig_stfl/xmss/sig_stfl_xmss.h | 2 + src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c | 35 ++++++- tests/test_sig_stfl.c | 37 +++++++- 5 files changed, 199 insertions(+), 4 deletions(-) diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 9ee29a9736..2b68e6dd94 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -107,3 +107,36 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, size_t *max, OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig) { OQS_MEM_insecure_free(sig); } + + + +// ================================= OQS_SIG_STFL_SECRET_KEY FUNCTION =============================================== + + +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_name) { + assert(method_name != NULL); + + if (0) { + + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h10)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h10 + return OQS_SECRET_KEY_XMSS_SHA256_H10_new(); +#else + return NULL; +#endif + } else { + return NULL; + } +} + +OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL) { + return; + } + + /* Call object specif free */ + if (sk->free_key) { + sk->free_key(sk); + } + OQS_MEM_secure_free(sk, sizeof(sk)); +} diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index 67604f5b9d..6beeb8c24d 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -145,6 +145,81 @@ typedef struct OQS_SIG_STFL { } OQS_SIG_STFL; +/** + * @brief OQS_SIG_STFL_SECRET_KEY object for stateful signature schemes + */ +typedef struct OQS_SIG_STFL_SECRET_KEY OQS_SIG_STFL_SECRET_KEY; + +typedef struct OQS_SIG_STFL_SECRET_KEY { + + /** Associated signature object */ + OQS_SIG_STFL *sig; + + /* The (maximum) length, in bytes, of secret keys for this signature scheme. */ + size_t length_secret_key; + + /* The variant specific secret key data */ + void *secret_key_data; + + /* Function that returns the total number of signatures for the secret key */ + unsigned long long (*sigs_total)(const OQS_SIG_STFL_SECRET_KEY *secret_key); + + /* Function that returns the number of signatures left for the secret key */ + unsigned long long (*sigs_left)(const OQS_SIG_STFL_SECRET_KEY *secret_key); + + /** + * Secret Key retrieval Function + * + * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object + * @param[out] key_len length of the returned byte string + * @returns newly created pointer to ley byte string if none-zero length. Caller + * deletes the buffer. + */ + uint8_t *(*serialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len); + + /** + * set Secret Key to internal structure Function + * + * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object + * @param[out] key_len length of the returned byte string + * @returns newly created pointer to ley byte string if none-zero length. Caller + * deletes the buffer. + */ + uint8_t *(*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, uint8_t *sk_key); + + /** + * Secret Key Locking Function + * + * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object + * @return OQS_SUCCESS or OQS_ERROR + */ + OQS_STATUS (*lock_key)(OQS_SIG_STFL_SECRET_KEY *sk); + + /** + * Secret Key Unlocking / Releasing Function + * + * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object + * @return OQS_SUCCESS or OQS_ERROR + */ + OQS_STATUS (*unlock_key)(OQS_SIG_STFL_SECRET_KEY *sk); + + /** + * Secret Key Saving Function + * + * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object + * @return OQS_SUCCESS or OQS_ERROR + */ + OQS_STATUS (*save_secret_key)(const OQS_SIG_STFL_SECRET_KEY *sk); + + /** + * Secret Key free internal variant specific data + * + * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object + * @return none + */ + void (*free_key)(OQS_SIG_STFL_SECRET_KEY *sk); +} OQS_SIG_STFL_SECRET_KEY; + /** * Constructs an OQS_SIG_STFL object for a particular algorithm. * @@ -162,7 +237,7 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name); * Caller is responsible for allocating sufficient memory for `public_key` based * on the `length_*` members in this object or the per-scheme compile-time macros * `OQS_SIG_STFL_*_length_*`. Caller is also responsible for initializing - * `secret_key` using the OQS_SECRET_KEY(*) function + * `secret_key` using the OQS_SIG_STFL_SECRET_KEY(*) function * * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. * @param[out] public_key The public key represented as a byte string. @@ -228,6 +303,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, size_t *max, */ OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig); +/** + * Constructs an OQS_SIG_STFL_SECRET_KEY object for a particular algorithm. + * + * Callers should always check whether the return value is `NULL`, which indicates either than an + * invalid algorithm name was provided, or that the requested algorithm was disabled at compile-time. + * + * @param[in] method_name Name of the desired algorithm; one of the names in `OQS_SIG_STFL_algs`. + * @return An OQS_SIG_STFL_SECRET_KEY for the particular algorithm, or `NULL` if the algorithm has been disabled at compile-time. + */ +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_name); + +/** + * Frees an OQS_SIG_STFL_SECRET_KEY object that was constructed by OQS_SECRET_KEY_new. + * + * @param[in] sig The OQS_SIG_STFL_SECRET_KEY object to free. + * @return OQS_SUCCESS if successful, or OQS_ERROR if the object could not be freed. + */ +OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk); + #if defined(__cplusplus) } // extern "C" #endif diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index 1dd0139e5f..e932f3f063 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -6,6 +6,7 @@ #include #define XMSS_OID_LEN 4 +void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk); #ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h10 @@ -14,6 +15,7 @@ #define OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk (132 + XMSS_OID_LEN) OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c index 8e50828095..cfb6899af6 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c @@ -41,6 +41,30 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void) { return sig; } +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { if (public_key == NULL || secret_key == NULL) { @@ -109,4 +133,13 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(size_t *total, co *total = (size_t) total_signatures; return OQS_SUCCESS; -} \ No newline at end of file +} + +void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL) { + return; + } + + OQS_MEM_secure_free(sk->secret_key_data, sk->length_secret_key); + sk->secret_key_data = NULL; +} diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index e80aface60..45f700608b 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -159,6 +159,35 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name) { return ret; } +static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { + OQS_STATUS rc = OQS_SUCCESS; + OQS_SIG_STFL_SECRET_KEY *sk = NULL; + + sk = OQS_SIG_STFL_SECRET_KEY_new(method_name); + if (sk == NULL) { + fprintf(stderr, "ERROR: OQS_SECRET_KEY_new failed\n"); + goto err; + } + + printf("================================================================================\n"); + printf("Create for statefull Secret Key %s\n", method_name); + printf("================================================================================\n"); + + if (!sk->secret_key_data) { + fprintf(stderr, "ERROR: OQS_SECRET_KEY_new incomplete.\n"); + goto err; + } + + OQS_SIG_STFL_SECRET_KEY_free(sk); + printf("Secret Key created as expected.\n"); + goto end_it; + +err: + rc = OQS_ERROR; +end_it: + return rc; +} + #ifdef OQS_ENABLE_TEST_CONSTANT_TIME static void TEST_SIG_STFL_randombytes(uint8_t *random_array, size_t bytes_to_read) { // We can't make direct calls to the system randombytes on some platforms, @@ -178,11 +207,13 @@ static void TEST_SIG_STFL_randombytes(uint8_t *random_array, size_t bytes_to_rea struct thread_data { char *alg_name; OQS_STATUS rc; + OQS_STATUS rc1; }; void *test_wrapper(void *arg) { struct thread_data *td = arg; td->rc = sig_stfl_test_correctness(td->alg_name); + td->rc1 = sig_stfl_test_secret_key(td->alg_name); return NULL; } #endif @@ -221,7 +252,7 @@ int main(int argc, char **argv) { OQS_randombytes_switch_algorithm("system"); #endif - OQS_STATUS rc; + OQS_STATUS rc, rc1; #if OQS_USE_PTHREADS_IN_TESTS #define MAX_LEN_SIG_NAME_ 64 pthread_t thread; @@ -235,10 +266,12 @@ int main(int argc, char **argv) { } pthread_join(thread, NULL); rc = td.rc; + rc1 = td.rc1; #else rc = sig_stfl_test_correctness(alg_name); + rc1 = sig_stfl_test_secret_key(alg_name); #endif - if (rc != OQS_SUCCESS) { + if ((rc != OQS_SUCCESS) || (rc1 != OQS_SUCCESS)) { OQS_destroy(); return EXIT_FAILURE; } From e356ebf33167f7514466ce4c44c90a46e6f213bd Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Thu, 13 Jul 2023 14:26:03 -0400 Subject: [PATCH 07/68] Na lms (#1486) * Add base LMS library * ignore use of free() by adding // IGNORE free-check * ignore use of free() by adding // IGNORE free-check --- src/sig_stfl/lms/external/common_defs.h | 178 ++++ src/sig_stfl/lms/external/config.h | 36 + src/sig_stfl/lms/external/endian.c | 23 + src/sig_stfl/lms/external/endian.h | 9 + src/sig_stfl/lms/external/hash.c | 119 +++ src/sig_stfl/lms/external/hash.h | 57 ++ src/sig_stfl/lms/external/hss.c | 169 ++++ src/sig_stfl/lms/external/hss.h | 417 ++++++++ src/sig_stfl/lms/external/hss_alloc.c | 555 +++++++++++ src/sig_stfl/lms/external/hss_aux.c | 355 +++++++ src/sig_stfl/lms/external/hss_aux.h | 59 ++ src/sig_stfl/lms/external/hss_common.c | 48 + src/sig_stfl/lms/external/hss_common.h | 22 + src/sig_stfl/lms/external/hss_compute.c | 174 ++++ src/sig_stfl/lms/external/hss_derive.c | 325 ++++++ src/sig_stfl/lms/external/hss_derive.h | 74 ++ src/sig_stfl/lms/external/hss_generate.c | 932 ++++++++++++++++++ src/sig_stfl/lms/external/hss_internal.h | 243 +++++ src/sig_stfl/lms/external/hss_keygen.c | 368 +++++++ src/sig_stfl/lms/external/hss_param.c | 153 +++ src/sig_stfl/lms/external/hss_reserve.c | 194 ++++ src/sig_stfl/lms/external/hss_reserve.h | 21 + src/sig_stfl/lms/external/hss_sign.c | 736 ++++++++++++++ src/sig_stfl/lms/external/hss_sign_inc.c | 218 ++++ src/sig_stfl/lms/external/hss_sign_inc.h | 81 ++ src/sig_stfl/lms/external/hss_thread.h | 135 +++ .../lms/external/hss_thread_pthread.c | 298 ++++++ src/sig_stfl/lms/external/hss_thread_single.c | 63 ++ src/sig_stfl/lms/external/hss_verify.c | 196 ++++ src/sig_stfl/lms/external/hss_verify.h | 23 + src/sig_stfl/lms/external/hss_verify_inc.c | 203 ++++ src/sig_stfl/lms/external/hss_verify_inc.h | 82 ++ src/sig_stfl/lms/external/hss_zeroize.c | 49 + src/sig_stfl/lms/external/hss_zeroize.h | 10 + src/sig_stfl/lms/external/lm_common.c | 79 ++ src/sig_stfl/lms/external/lm_common.h | 20 + src/sig_stfl/lms/external/lm_ots.h | 64 ++ src/sig_stfl/lms/external/lm_ots_common.c | 99 ++ src/sig_stfl/lms/external/lm_ots_common.h | 16 + src/sig_stfl/lms/external/lm_ots_sign.c | 168 ++++ src/sig_stfl/lms/external/lm_ots_verify.c | 122 +++ src/sig_stfl/lms/external/lm_ots_verify.h | 23 + src/sig_stfl/lms/external/lm_verify.c | 107 ++ src/sig_stfl/lms/external/lm_verify.h | 12 + src/sig_stfl/lms/external/sha256.c | 183 ++++ src/sig_stfl/lms/external/sha256.h | 43 + 46 files changed, 7561 insertions(+) create mode 100644 src/sig_stfl/lms/external/common_defs.h create mode 100644 src/sig_stfl/lms/external/config.h create mode 100644 src/sig_stfl/lms/external/endian.c create mode 100644 src/sig_stfl/lms/external/endian.h create mode 100644 src/sig_stfl/lms/external/hash.c create mode 100644 src/sig_stfl/lms/external/hash.h create mode 100644 src/sig_stfl/lms/external/hss.c create mode 100644 src/sig_stfl/lms/external/hss.h create mode 100644 src/sig_stfl/lms/external/hss_alloc.c create mode 100644 src/sig_stfl/lms/external/hss_aux.c create mode 100644 src/sig_stfl/lms/external/hss_aux.h create mode 100644 src/sig_stfl/lms/external/hss_common.c create mode 100644 src/sig_stfl/lms/external/hss_common.h create mode 100644 src/sig_stfl/lms/external/hss_compute.c create mode 100644 src/sig_stfl/lms/external/hss_derive.c create mode 100644 src/sig_stfl/lms/external/hss_derive.h create mode 100644 src/sig_stfl/lms/external/hss_generate.c create mode 100644 src/sig_stfl/lms/external/hss_internal.h create mode 100644 src/sig_stfl/lms/external/hss_keygen.c create mode 100644 src/sig_stfl/lms/external/hss_param.c create mode 100644 src/sig_stfl/lms/external/hss_reserve.c create mode 100644 src/sig_stfl/lms/external/hss_reserve.h create mode 100644 src/sig_stfl/lms/external/hss_sign.c create mode 100644 src/sig_stfl/lms/external/hss_sign_inc.c create mode 100644 src/sig_stfl/lms/external/hss_sign_inc.h create mode 100644 src/sig_stfl/lms/external/hss_thread.h create mode 100644 src/sig_stfl/lms/external/hss_thread_pthread.c create mode 100644 src/sig_stfl/lms/external/hss_thread_single.c create mode 100644 src/sig_stfl/lms/external/hss_verify.c create mode 100644 src/sig_stfl/lms/external/hss_verify.h create mode 100644 src/sig_stfl/lms/external/hss_verify_inc.c create mode 100644 src/sig_stfl/lms/external/hss_verify_inc.h create mode 100644 src/sig_stfl/lms/external/hss_zeroize.c create mode 100644 src/sig_stfl/lms/external/hss_zeroize.h create mode 100644 src/sig_stfl/lms/external/lm_common.c create mode 100644 src/sig_stfl/lms/external/lm_common.h create mode 100644 src/sig_stfl/lms/external/lm_ots.h create mode 100644 src/sig_stfl/lms/external/lm_ots_common.c create mode 100644 src/sig_stfl/lms/external/lm_ots_common.h create mode 100644 src/sig_stfl/lms/external/lm_ots_sign.c create mode 100644 src/sig_stfl/lms/external/lm_ots_verify.c create mode 100644 src/sig_stfl/lms/external/lm_ots_verify.h create mode 100644 src/sig_stfl/lms/external/lm_verify.c create mode 100644 src/sig_stfl/lms/external/lm_verify.h create mode 100644 src/sig_stfl/lms/external/sha256.c create mode 100644 src/sig_stfl/lms/external/sha256.h diff --git a/src/sig_stfl/lms/external/common_defs.h b/src/sig_stfl/lms/external/common_defs.h new file mode 100644 index 0000000000..83739949ee --- /dev/null +++ b/src/sig_stfl/lms/external/common_defs.h @@ -0,0 +1,178 @@ +#if !defined( COMMON_DEFS_H_ ) +#define COMMON_DEFS_H_ + +/* + * These are defintions for the LMS implementation that are common throughout + * the system (and so are collected in one place) + */ + +#include +#include + +#define MAX_HASH 32 /* Length of the largest hash we support */ + +/* The I (Merkle tree identifier) value is 16 bytes long */ +#define I_LEN 16 + +/* The maximum height of a Merkle tree */ +#define MAX_MERKLE_HEIGHT 25 + +/* The mininum height of a Merkle tree. Some of our update logic assumes */ +/* this isn't too small */ +#define MIN_MERKLE_HEIGHT 5 + +/* The minimum/maximum number of levels of Merkle trees within an HSS trees */ +#define MIN_HSS_LEVELS 1 /* Minumum levels we allow */ +#define MAX_HSS_LEVELS 8 /* Maximum levels we allow */ + +/* This is the length of our internal seed values */ +#define SEED_LEN 32 /* Enough to make Grover's infeasible */ + +/* Here are some internal types used within the code. They are listed more */ +/* for documentation ("this is what this variable is expected to be") rather */ +/* than to let the compiler do any sort of type checking */ + + /* This is an index into a Merkle tree */ + /* Used for both the leaf index (0..N-1) and the node number (1..2*N-1), */ + /* where N is the size 2**h of the tre */ +#if MAX_MERKLE_HEIGHT > 31 + /* We need to express more than 32 bits in this type */ +typedef uint_fast64_t merkle_index_t; +#error We need to extend the id we place within a hash to more than 4 bytes +#else +typedef uint_fast32_t merkle_index_t; +#endif + + /* This is the name of a parameter set */ + /* Used for both an OTS parameter set or an LM parameter set */ + /* Both are 32 bits */ +typedef uint_fast32_t param_set_t; + + /* This is a sequence number over an HSS tree */ + /* This means we can never generate more than 2**64 signatures from a */ + /* private key (even if the parameter set would, in theory, allow us */ + /* to do more) */ +typedef uint_fast64_t sequence_t; + +/* Defined LM parameter sets */ +#define LMS_SHA256_N32_H5 0x00000005 +#define LMS_SHA256_N32_H10 0x00000006 +#define LMS_SHA256_N32_H15 0x00000007 +#define LMS_SHA256_N32_H20 0x00000008 +#define LMS_SHA256_N32_H25 0x00000009 + +/* LM-OTS registry */ +#define LMOTS_SHA256_N32_W1 0x00000001 +#define LMOTS_SHA256_N32_W2 0x00000002 +#define LMOTS_SHA256_N32_W4 0x00000003 +#define LMOTS_SHA256_N32_W8 0x00000004 + +/* + * Internal formats of various hashes + * + * We do a number of different hashes as a part of this package; some + * specified by the draft, some specific to us. + * For each such hash, we list the values being hashed, and the offset + * from the start where they go. We treat them as indicies into unsigned char + * arrays, and not structs, to avoid any potential padding issues with structs + * + * For a hash of type XXXX, XXXX_Z is the offset where component Z goes, + * XXXX_LEN(hash_len) is the length being hashed (assuming that hash length), + * XXXX_MAXLEN is the maximum length it can be (for allocation), and D_XXXX + * is the hash distinguisher (the value that makes it different from any other + * hash) + */ + +/* The initial message hashing */ +#define MESG_I 0 +#define MESG_Q 16 +#define MESG_D 20 /* The fixed D_MESG value */ +#define MESG_C 22 +#define MESG_PREFIX_LEN(n) (MESG_C + (n)) /* Length not counting the actual */ + /* message being signed */ +#define MESG_PREFIX_MAXLEN MESG_PREFIX_LEN(MAX_HASH) +#define D_MESG 0x8181 + +/* The Winternitz iteration hashes */ +#define ITER_I 0 +#define ITER_Q 16 +#define ITER_K 20 /* The RFC uses i here */ +#define ITER_J 22 +#define ITER_PREV 23 /* Hash from previous iteration; RFC uses tmp */ +#define ITER_LEN(hash_len) (ITER_PREV + (hash_len)) +#define ITER_MAX_LEN ITER_LEN(MAX_HASH) + +/* Hashing the OTS public key */ +#define PBLC_I 0 +#define PBLC_Q 16 +#define PBLC_D 20 /* The fixed D_PBLC value */ +#define PBLC_PREFIX_LEN 22 /* Not counting the OTS public keys */ +#define D_PBLC 0x8080 + +/* Hashing Merkle tree leaf nodes */ +#define LEAF_I 0 +#define LEAF_R 16 +#define LEAF_D 20 +#define LEAF_PK 22 +#define LEAF_LEN(root_len) (LEAF_PK + (root_len)) +#define LEAF_MAX_LEN LEAF_LEN(MAX_HASH) +#define D_LEAF 0x8282 + +/* Hashing Merkle tree internal nodes */ +#define INTR_I 0 +#define INTR_R 16 +#define INTR_D 20 +#define INTR_PK 22 +#define INTR_LEN(root_len) (INTR_PK + 2 * (root_len)) +#define INTR_MAX_LEN INTR_LEN(MAX_HASH) +#define D_INTR 0x8383 + +/* The determanistic key generation */ +/* Also used to generate subkeys in the j-tree hierarchy */ +/* As we'll always do either one or the other, we can reuse the structure */ +/* for both purposes */ +#define PRG_I 0 +#define PRG_Q 16 +#define PRG_J 20 +#define PRG_FF 22 /* A fixed 0xff goes here */ +#define PRG_SEED 23 +#define PRG_LEN(seed_len) (23 + (seed_len)) +#define PRG_MAX_LEN PRG_LEN(MAX_HASH) + +/* The below are hash formats that the draft does not list, but we */ +/* implement ourselves (largely because we need to be determanistic */ +/* based on the seed) */ + +/* Hash used to generate subkeys in the q tree hierarchy */ +#define QTREE_I 0 +#define QTREE_Q 16 +#define QTREE_D 20 /* D_QTREE goes here */ +#define QTREE_SEED 22 +#define QTREE_LEN (22 + 32) /* We assume a fixed length seed */ +#define QTREE_MAX_LEN QTREE_LEN +#define D_QTREE 0xffff + +/* Hash used to generate the master seed for the top level Merkle tree */ +#define TOPSEED_I 0 /* 16 0's here (we don't have an I value) */ +#define TOPSEED_Q 16 /* 0's here (as we don't have a Q value) */ +#define TOPSEED_D 20 /* D_TOPSEED */ +#define TOPSEED_WHICH 22 /* 0 -> Gen Master seed (used as seed for */ + /* the next two) */ + /* 1 -> Create top level seed */ + /* 2 -> Create top level I */ +#define TOPSEED_SEED 23 /* 32 bytes long */ +#define TOPSEED_LEN (TOPSEED_SEED + 32) +#define D_TOPSEED 0xfefe + +/* Hash used to generate the key used for the authenticating the aux values */ +#define DAUX_I 0 /* 16 0's here (no I value) */ +#define DAUX_Q 16 /* 4 more 0's here (no Q value) */ +#define DAUX_D 20 /* D_AUX_SEED_DERIVE */ +#define DAUX_PREFIX_LEN 22 /* Not counting the seed value */ +#define D_DAUX 0xfdfd + +/* Macro to set the D_XXXX value to the XXXX_D offset */ +#define SET_D(p, value) (void)(((p)[0] = (value) >> 8), \ + ((p)[1] = (value) & 0xff)) + +#endif /* COMMON_DEFS_H_ */ diff --git a/src/sig_stfl/lms/external/config.h b/src/sig_stfl/lms/external/config.h new file mode 100644 index 0000000000..e23d19fa9a --- /dev/null +++ b/src/sig_stfl/lms/external/config.h @@ -0,0 +1,36 @@ +#if !defined( CONFIG_H_ ) +#define CONFIG_H_ + +#define LMS_UNUSED(x) (void)(x) + +/* + * This file has #define's that specify how this package operates, and + * are designed to be tweaked by the user. + * + * These can be adjusted to be appropriate for what the application and + * the operating environment needs + */ + +/* + * This modifies which seed generation logic we use + * Note that changing these parameters will change the mapping + * between private keys. + * + * 0 -> We generate seeds using the process defined in Appendix A of the draft + * This is slightly faster + * 1 -> We use a side channel resistant process, never using any single secret + * seed in more than a defined number of distinct hashes + * 2 -> We generate seeds and secrets in a way which is compatible with ACVP + */ +#define SECRET_METHOD 2 + +/* + * If we're using the side channel resistant method, this defines the max + * number of times we'll use a single secret. Note that this is the log2 + * of the max number of times, and so 3 means 'no more than 8 times' + * Reducing SECRET_MAX is a bit more costly; however I don't know that if + * it is significant + */ +#define SECRET_MAX 4 /* Never use a seed more than 16 times */ + +#endif /* CONFIG_H_ */ diff --git a/src/sig_stfl/lms/external/endian.c b/src/sig_stfl/lms/external/endian.c new file mode 100644 index 0000000000..709dc7bf98 --- /dev/null +++ b/src/sig_stfl/lms/external/endian.c @@ -0,0 +1,23 @@ +#include "endian.h" + +void put_bigendian( void *target, unsigned long long value, size_t bytes ) { + unsigned char *b = target; + int i; + + for (i = bytes-1; i >= 0; i--) { + b[i] = value & 0xff; + value >>= 8; + } +} + +unsigned long long get_bigendian( const void *target, size_t bytes ) { + const unsigned char *b = target; + unsigned long long result = 0; + size_t i; + + for (i=0; i + +void put_bigendian( void *target, unsigned long long value, size_t bytes ); +unsigned long long get_bigendian( const void *target, size_t bytes ); + +#endif /* ENDIAN_H_ */ diff --git a/src/sig_stfl/lms/external/hash.c b/src/sig_stfl/lms/external/hash.c new file mode 100644 index 0000000000..dffcdaf6a6 --- /dev/null +++ b/src/sig_stfl/lms/external/hash.c @@ -0,0 +1,119 @@ +#include +#include "hash.h" +#include "sha256.h" +#include "hss_zeroize.h" + +#define ALLOW_VERBOSE 0 /* 1 -> we allow the dumping of intermediate */ + /* states. Useful for debugging; horrid */ + /* for security */ + +/* + * This is the file that implements the hashing APIs we use internally. + * At the present, our parameter sets support only one hash function + * (SHA-256, using full 256 bit output), however, that is likely to change + * in the future + */ + +#if ALLOW_VERBOSE +#include +#include +/* + * Debugging flag; if this is set, we chat about what we're hashing, and what + * the result is it's useful when debugging; however we probably don't want to + * do this if we're multithreaded... + */ +bool hss_verbose = false; +#endif + +/* + * This will hash the message, given the hash type. It assumes that the result + * buffer is large enough for the hash + */ +void hss_hash_ctx(void *result, int hash_type, union hash_context *ctx, + const void *message, size_t message_len) { +#if ALLOW_VERBOSE + if (hss_verbose) { + int i; for (i=0; i< message_len; i++) printf( " %02x%s", ((unsigned char*)message)[i], (i%16 == 15) ? "\n" : "" ); + } +#endif + + switch (hash_type) { + case HASH_SHA256: { + SHA256_Init(&ctx->sha256); + SHA256_Update(&ctx->sha256, message, message_len); + SHA256_Final(result, &ctx->sha256); +#if ALLOW_VERBOSE + if (hss_verbose) { + printf( " ->" ); + int i; for (i=0; i<32; i++) printf( " %02x", ((unsigned char *)result)[i] ); printf( "\n" ); + } +#endif + break; + } + } +} + +void hss_hash(void *result, int hash_type, + const void *message, size_t message_len) { + union hash_context ctx; + hss_hash_ctx(result, hash_type, &ctx, message, message_len); + hss_zeroize(&ctx, sizeof ctx); +} + + +/* + * This provides an API to do incremental hashing. We use it when hashing the + * message; since we don't know how long it could be, we don't want to + * allocate a buffer that's long enough for that, plus the decoration we add + */ +void hss_init_hash_context(int h, union hash_context *ctx) { + switch (h) { + case HASH_SHA256: + SHA256_Init( &ctx->sha256 ); + break; + } +} + +void hss_update_hash_context(int h, union hash_context *ctx, + const void *msg, size_t len_msg) { +#if ALLOW_VERBOSE + if (hss_verbose) { + int i; for (i=0; isha256, msg, len_msg); + break; + } +} + +void hss_finalize_hash_context(int h, union hash_context *ctx, void *buffer) { + switch (h) { + case HASH_SHA256: + SHA256_Final(buffer, &ctx->sha256); +#if ALLOW_VERBOSE + if (hss_verbose) { + printf( " -->" ); + int i; for (i=0; i<32; i++) printf( " %02x", ((unsigned char*)buffer)[i] ); + printf( "\n" ); + } +#endif + break; + } +} + + +unsigned hss_hash_length(int hash_type) { + switch (hash_type) { + case HASH_SHA256: return 32; + } + return 0; +} + +unsigned hss_hash_blocksize(int hash_type) { + switch (hash_type) { + case HASH_SHA256: return 64; + } + return 0; +} diff --git a/src/sig_stfl/lms/external/hash.h b/src/sig_stfl/lms/external/hash.h new file mode 100644 index 0000000000..a61f9f5039 --- /dev/null +++ b/src/sig_stfl/lms/external/hash.h @@ -0,0 +1,57 @@ +#if !defined( HASH_H__ ) +#define HASH_H__ +#include "sha256.h" +#include +#include + +/* + * This defines the hash interface used within HSS. + * All globals are prefixed with hss_ to avoid name conflicts + * Gee, C++ namespaces would be nice... + */ + +/* + * Hash types + */ +enum { + HASH_SHA256 = 1, /* SHA256 */ +}; + +union hash_context { + SHA256_CTX sha256; + /* Any other hash contexts would go here */ +}; + +/* Hash the message */ +void hss_hash(void *result, int hash_type, + const void *message, size_t message_len); + +/* Does the same, but with the passed hash context (which isn't zeroized) */ +/* This is here to save time; let the caller use the same ctx for multiple */ +/* hashes, and then finally zeroize it if necessary */ +void hss_hash_ctx(void *result, int hash_type, union hash_context *ctx, + const void *message, size_t message_len); + +/* + * This is a debugging flag; turning this on will cause the system to dump + * the inputs and the outputs of all hash functions. It only works if + * debugging is allowed in hash.c (it's off by default), and it is *real* + * chatty; however sometimes you really need it for debugging + */ +extern bool hss_verbose; + +/* + * This constant has migrated to common_defs.h + */ +/* #define MAX_HASH 32 */ /* Length of the largest hash we support */ + +unsigned hss_hash_length(int hash_type); +unsigned hss_hash_blocksize(int hash_type); + +void hss_init_hash_context( int h, union hash_context *ctx ); +void hss_update_hash_context( int h, union hash_context *ctx, + const void *msg, size_t len_msg ); +void hss_finalize_hash_context( int h, union hash_context *ctx, + void *buffer); + +#endif /* HASH_H__ */ diff --git a/src/sig_stfl/lms/external/hss.c b/src/sig_stfl/lms/external/hss.c new file mode 100644 index 0000000000..c38455daed --- /dev/null +++ b/src/sig_stfl/lms/external/hss.c @@ -0,0 +1,169 @@ +/* + * This is an implementation of the HSS signature scheme from LMS + * This is designed to be full-featured + * + * Currently, this file consists of functions that don't have a better home + */ +#include +#include +#include "common_defs.h" +#include "hss.h" +#include "hash.h" +#include "endian.h" +#include "hss_internal.h" +#include "hss_aux.h" +#include "hss_derive.h" +#include "config.h" +#include "lm_ots_common.h" + +/* + * Allocate and load an ephemeral key + */ +struct hss_working_key *hss_load_private_key( + bool (*read_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + size_t memory_target, + const unsigned char *aux_data, size_t len_aux_data, + struct hss_extra_info *info ) { + + /* Step 1: determine the parameter set */ + unsigned levels; + param_set_t lm[ MAX_HSS_LEVELS ]; + param_set_t ots[ MAX_HSS_LEVELS ]; + if (!hss_get_parameter_set( &levels, lm, ots, read_private_key, context)) { + /* Can't read private key, or private key invalid */ + return 0; + } + + /* Step 2: allocate the ephemeral key */ + struct hss_working_key *w = allocate_working_key(levels, lm, ots, + memory_target, info); + if (!w) { + /* Memory allocation failure, most likely (we've already vetted */ + /* the parameter sets) */ + return 0; + } + + /* Step 3: load the ephemeral key */ + if (! hss_generate_working_key( read_private_key, context, + aux_data, len_aux_data, w, info )) { + /* About the only thing I can see failing here is perhaps */ + /* attempting to reread the private key failed the second time; */ + /* seems unlikely, but not impossible */ + hss_free_working_key( w ); + return 0; + } + + /* Success! */ + return w; +} + +/* + * Internal function to generate the root seed and I value (based on the + * private seed). We do this (rather than select seed, I at random) so that + * we don't need to store it in our private key; we can recompute them + */ +bool hss_generate_root_seed_I_value(unsigned char *seed, unsigned char *I, + const unsigned char *master_seed) { +#if SECRET_METHOD == 2 + /* In ACVP mode, we use the master seed as the source for both the */ + /* root seed, and the root I value */ + memcpy( seed, master_seed, SEED_LEN ); + memcpy( I, master_seed + SEED_LEN, I_LEN ); +#else + /* + * We use a two-level hashing scheme so that we end up using the master + * seed only twice throughout the system (once here, once to generate the + * aux hmac key) + */ + unsigned char hash_preimage[ TOPSEED_LEN ]; + unsigned char hash_postimage[ MAX_HASH ]; + + memset( hash_preimage + TOPSEED_I, 0, I_LEN ); + memset( hash_preimage + TOPSEED_Q, 0, 4 ); + SET_D( hash_preimage + TOPSEED_D, D_TOPSEED ); + hash_preimage[TOPSEED_WHICH] = 0x00; + memcpy( hash_preimage + TOPSEED_SEED, master_seed, SEED_LEN ); + + /* We use a fixed SHA256 hash; we don't care about interoperability */ + /* so we don't need to worry about what parameter set the */ + /* user specified */ +#if I_LEN > 32 || SEED_LEN != 32 +#error This logic needs to be reworked +#endif + union hash_context ctx; + + hss_hash_ctx(hash_postimage, HASH_SHA256, &ctx, hash_preimage, + TOPSEED_LEN ); + memcpy( hash_preimage + TOPSEED_SEED, hash_postimage, SEED_LEN ); + + /* Now compute the top level seed */ + hash_preimage[TOPSEED_WHICH] = 0x01; + hss_hash_ctx(seed, HASH_SHA256, &ctx, hash_preimage, TOPSEED_LEN ); + + /* Now compute the top level I value */ + hash_preimage[TOPSEED_WHICH] = 0x02; + hss_hash_ctx(hash_postimage, HASH_SHA256, &ctx, hash_preimage, + TOPSEED_LEN ); + memcpy( I, hash_postimage, I_LEN ); + + hss_zeroize( hash_preimage, sizeof hash_preimage ); /* There's keying */ + /* data here */ + hss_zeroize( &ctx, sizeof ctx ); +#endif + return true; +} + +/* + * Internal function to generate the child I value (based on the parent's + * I value). While this needs to be determanistic (so that we can create the + * same I values between reboots), there's no requirement for interoperability. + * So we use a fixed SHA256; when we support a hash function other than SHA256, + * we needn't update this. + */ +bool hss_generate_child_seed_I_value( unsigned char *seed, unsigned char *I, + const unsigned char *parent_seed, + const unsigned char *parent_I, + merkle_index_t index, + param_set_t lm, param_set_t ots) { + struct seed_derive derive; + if (!hss_seed_derive_init( &derive, lm, ots, parent_I, parent_seed )) { + return false; + } + + hss_seed_derive_set_q( &derive, index ); + + /* Compute the child seed value */ + hss_seed_derive_set_j( &derive, SEED_CHILD_SEED ); + hss_seed_derive( seed, &derive, true ); + /* True sets the j value to SEED_CHILD_I */ + + /* Compute the child I value; with increment_j set to true in the */ + /* above call, derive has been set to the SEED_CHILD_I position */ + unsigned char postimage[ SEED_LEN ]; + hss_seed_derive( postimage, &derive, false ); + memcpy( I, postimage, I_LEN ); + + hss_seed_derive_done( &derive ); + + return true; +} + +void hss_init_extra_info( struct hss_extra_info *p ) { + if (p) memset( p, 0, sizeof *p ); +} + +void hss_extra_info_set_threads( struct hss_extra_info *p, int num_threads ) { + if (p) p->num_threads = num_threads; +} + +bool hss_extra_info_test_last_signature( struct hss_extra_info *p ) { + if (!p) return false; + return p->last_signature; +} + +enum hss_error_code hss_extra_info_test_error_code( struct hss_extra_info *p ) { + if (!p) return hss_error_got_null; + return p->error_code; +} diff --git a/src/sig_stfl/lms/external/hss.h b/src/sig_stfl/lms/external/hss.h new file mode 100644 index 0000000000..b4e5e1698d --- /dev/null +++ b/src/sig_stfl/lms/external/hss.h @@ -0,0 +1,417 @@ +#if !defined(HSS_H_) +#define HSS_H_ + +#include +#include +#include "common_defs.h" + +/* + * This is intended to be a usable (nontoy) implementation of the LMS + * signature scheme. The public data (public keys, signatures) are + * precisely the same as the standard LMS implmentation; however it + * strives to be more usable, in the following ways: + * + * - During signature generation time, it incrementally computes the next + * trees; that means that it doesn't need to generate the next Merkle tree + * from scratch on the 1025th signature. + * - It doesn't try to hold the entire Merkle tree in memory; hence a level + * 25 Merkle tree doesn't need to save 2**25 internal node values. This + * does increase the time to generate the next siganture (as we will need + * to recompute some internal nodes); however by only a small constant factor + * - It divides the private key into three parts, only one of which needs to + * be kept secret, and updated dynamically; the other parts are a working + * copy (that can be kept in RAM, and can be dynamically regenerated as + * needed), and some optional static (nonprivate) data (which can speed up + * the regeneration process) + * - API to explicitly reserve the next N signatures (so that we don't need + * to update the secure storage copy quite as often) + * + * + * We use a nonflat memory structure for the working_key. Part of the reason + * we use a flat representation elsewhere is so that they can be written (and + * later read) to/from disk as required; we specifically assume that the + * working_key is never written to disk. And, being able to use C structures + * makes this rather nontrivial structure a bit more transparent + * + * Here is the intended order of usage: + * Step 1: generate the private/public keypair: + * The API to do this is hss_generate_private_key; this is done once per + * private key; and you should write the private key to secure storage + * (which the passed update_private_key function could do) + * + * Step 2: (which you can do per restart): + * Load the private keypair into memory: hss_load_private_key + * + * Step 3: generate signatures (which you can do lots of time after you've + * loaded the key into memory): + * The API to do this is hss_generate_signature. Note that this needs + * to update the private key state; the update_private_key function pointer + * can be useful here + * + * Step 4: (when you're done with the loaded private key; optional) + * Free the ephemeral copy (hss_free_working_key). Note that this is not + * required for correctness; this just does a free() + * + * + * One can also verify signatures at any time; all that needs is a public + * key, a signature and a message; it's not a part of the intended order + * of usage + */ + +struct hss_extra_info; + +/* + * This will generate a fresh (unadorned) private key, with the selected + * parameter set, the corresponding public key, and (optionally) the aux_data + * that is associated with the private key. + * + * The generate_random function will be called when this function needs + * random values; it is assumed to generate cryptographically secure ones. + * We ask you to pass a function, rather than an array of random values, + * to emphasize that we really do need fresh random data here; the security + * of this entire system depends on it. + * + * levels, lm_type, lm_ots_type is the parameter set for the new key. + * levels is the number of levels in the HSS hierarchy (1-8), while + * lm_type[], lm_ots_type[] are arrays giving the parameter set of each + * individual level; level i of the hierarchy will have LMS parameter set + * lm_type[i] and OTS parameter set lm_ots_type[i] (where i=0 is the topmost + * Merkle tree. + * + * The update_private_key function will be called when the private key is + * generated; it is expected to write the private key to secure storage (and + * the context pointer is a value that is passed to the update_private_key + * function; it can be used to tell the update_private_key function where + * in the secure storage to place the key). If the passed update_private_key + * function pointer is NULL, the private will will be written to the context + * pointer (which is expected to hold 48 bytes of data) + * + * public_key is where the freshly generated public key will be placed, and + * len_public_key is the size of the array (and this will generate an error + * if the public key is larger than the array). See the hss_get_public_key_len + * function for the expected length of the public key + * + * aux_data is where to place internal nodes of the Merkle tree, and + * len_aux_data is the length of the provided buffer. This aux_data + * is optional (pass in a NULL if it's not being used), but does significantly + * speed the generate_working_key process. It's envisioned use is to write + * this aux_data to disk, and reread it when it's time to regenerate the + * ephemeral key; it need not be kept in secure storage; revealing it doesn't + * help an attacker to generate forgeries, and if an attacker does manage to + * corrupt it, the regeneration process will detect the corruption and ignore + * it. Also, even if writing it to disk is not possible, passing in a + * small array here and passing that to the initial regeneration call will + * speed that up (and later ones can omit it; those will go slow, but at + * least you got the speed up benefit the first time). + * + * One slightly tricky thing about aux data is that the required length of the + * aux data; there are several different possible time/memory trade-offs. + * Depending on the length, we'll automatically pick the fastest option that + * fits. If we have N bytes available total, see hss_get_aux_data_len for + * the amount of data we'll actually use (and so the amount you need to write + * to disk) + */ +bool hss_generate_private_key( + bool (*generate_random)(void *output, size_t length), + unsigned levels, + const param_set_t *lm_type, const param_set_t *lm_ots_type, + bool (*update_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + unsigned char *public_key, size_t len_public_key, + unsigned char *aux_data, size_t len_aux_data, + struct hss_extra_info *info); + +/* + * This is the routine to load a private key into memory, and + * initialize the working data structures; these data structures + * allow us to generate signtures quickly + * + * The read_private_key is a function to read the private key from secure + * storage, with context being a value passed to that function. + * If the read_private_key pointer is NULL, we assume that the context + * pointer points to the private key. + * This assumes that the key has already been generated by + * hss_generate_private_key + * + * memory_target is a value which gives a goal for the amount of memory (in + * bytes) that this structure should take up. There are a number of + * time/memory trade-offs possible; the function uses this parameter as a + * guide as to what trade-offs it should take. This structure tries to + * allocate no more than memory_target bytes; however it is considered + * advisatory; this function will never fail beccause memory_target was too + * small (so passing 0 will work, and will minimize the memory used) + * + * aux_data points to a buffer containing the auxiliary data generated + * during the key generation process, with len_aux_data being the length + * of the buffer. Passing it a NULL means that we're not providing that + * data (which is fine; it just means this will take longer) + * + * On success, this malloc's the ephemeral key (struct hss_working_key*) and + * retursn it. Because it mallocs it, it asssumes that the caller will + * eventually free it (via the hss_free_working_key function, don't try + * calling free() yourself) + */ +struct hss_working_key; +struct hss_working_key *hss_load_private_key( + bool (*read_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + size_t memory_target, + const unsigned char *aux_data, size_t len_aux_data, /* Optional */ + struct hss_extra_info *info); + +/* + * Corresponding function to free the working key + */ +void hss_free_working_key( struct hss_working_key * ); + +/* + * This will actually generate a signature + * + * working_key is the key that has been allocated by allocate_working_key and + * initialied by hss_generate_working_key + * + * The update_private_key function will be called when the private key is + * updated; it is expected to write the private key to secure storage (and the + * context pointer is a value that is passed to the update_private_key + * function; it can be used to tell the update_private_key function where + * in the secure storage to place the key). And, if it is NULL, the context + * is expected to point to a copy of the private_key in RAM. + * One distinction is that, on an update, len_private_key will be 8; + * the update_private_key can choose to update only the first 8 bytes + * of the private key (the rest will be unchanged), or write all + * 48 bytes (private_key will point to the full 48 byte value) + * + * message, message_len are the message being signed + * + * signature is where the signature will be written, with signature_len being + * the length of the buffer. See the hss_get_signature_len function for the + * expected signature length for this parameter set; if signature_len is too + * short for the signature to fit, this will fail. + */ +bool hss_generate_signature( + struct hss_working_key *working_key, + bool (*update_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + const void *message, size_t message_len, + unsigned char *signature, size_t signature_len, + struct hss_extra_info *info); + +/* + * See hss_verify.h for the signature verfication routine; it's in a + * separate file for those programs that only need to verify a signature + */ +#include "hss_verify.h" + +/* + * Lower level routines to allocate and initialize a working key. + * + * hss_load_working_key will do the work of the below routines; these are + * provided separately in case you need more control (e.g. reuse an already + * allocated working key) + * + * First, the routine to allocate (but not initialize) a working key. + * + * The levels/lm_type/lm_ots_type are the same parameter sets as in the + * generate public/private keypair call; the parameter set must match the + * values for the private key. + * + * memory_target is a value which gives a goal for the amount of memory that + * this structure should take up. There are a number of time/memory trade-offs + * possible; the function uses this parameter as a guide as to what trade-offs + * it should take. This structure tries to allocate no more than memory_target + * bytes; however it is considered advisatory; this function will never fail + * beccause memory_target was too small (so passing 0 will work, and will + * minimize the memory used) + */ +struct hss_working_key *allocate_working_key( + unsigned levels, + const param_set_t *lm_type, const param_set_t *lm_ots_type, + size_t memory_target, + struct hss_extra_info *info); + +/* + * This is called on reload (or initial key generation), it'll take the + * working key that's been allocated by allocate_working_key, and initialize + * it based on the private key; this working key is what we need to actually + * generate signatures. + * + * The read_private_key is a function to read the private key from secure + * storage, with context being a value passed to that function. + * If NULL, we assume that the context pointer points to the private key + * + * aux_data points to a buffer containing the auxiliary data generated + * during the key generation process, with len_aux_data being the length + * of the buffer. Passing it a NULL means that we're not providing that + * data (which is fine; it just means this will take longer) + * + * working_key is a pointer to the allocated working key + */ +bool hss_generate_working_key( + bool (*read_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + const unsigned char *aux_data, size_t len_aux_data, /* Optional */ + struct hss_working_key *working_key, + struct hss_extra_info *info); + +/* + * This will make sure that (at least) N signatures are reserved; that is, we + * won't need to actually call the update function for the next N signatures + * generated + * + * This can be useful if the update_private_key function is expensive. + * + * Note that if, N (or more) signatures are already reserved, this won't do + * anything. + */ +bool hss_reserve_signature( + struct hss_working_key *w, + bool (*update_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + unsigned sigs_to_reserve, + struct hss_extra_info *info); + +/* + * This will set the autoreserve, so that when the signing process runs out, + * it will automatically reserve N more signatures (in addition to the one + * that is being used for the current signature) + * + * This can be useful if the update_private_key function is expensive, + * setting sigs_to_autoreserve=99 means will actually update the private + * key once every 100 signatures + */ +bool hss_set_autoreserve( + struct hss_working_key *w, + unsigned sigs_to_autoreserve, + struct hss_extra_info *info); + +/* + * This returns the required lengths for the various objects we export + * + * This is the length of the private key (which is written to secure storage) + */ +size_t hss_get_private_key_len(unsigned levels, + const param_set_t *lm_type, + const param_set_t *lm_ots_type); +#define HSS_MAX_PRIVATE_KEY_LEN (8 + 8 + SEED_LEN + 16) + +/* + * This include file has the functions that contains the lengths of the other + * public objects + */ +#include "hss_common.h" + +/* + * Get the signature length. We don't put this in hss_common because we + * assume we have a loaded private key + * Returns 0 on error + */ +size_t hss_get_signature_len_from_working_key( + struct hss_working_key *working_key); + +/* + * This returns the amount of aux data we use + * This is slightly different from the above routines; given the bound on the + * amount of data the aux_data is allowed to take (max_length), this returns + * the amount of data we'll actually use + */ +size_t hss_get_aux_data_len(size_t max_length, + unsigned levels, + const param_set_t *lm_type, + const param_set_t *lm_ots_type); + +/* + * This returns the parameter set for a given private key. + * This is here to solve a chicken-and-egg problem: the hss_working_key + * must be initialized to the same parameter set as the private key, + * but (other than this function, or somehow remembering it) there's + * no way to retreive the parameter set. + * + * read_private_key/context will read the private key (if read_private_key is + * NULL, context is assumed to point to the private key) + * + * On success, *levels will be set to the number of levels, and lm_type[] + * and lm_ots_type[] will be set to the lm/ots parameter sets + * + * On success, this returns true; on failure (can't read the private key, or + * the * private key is invalid), returns false + */ +bool hss_get_parameter_set( unsigned *levels, + param_set_t lm_type[ MAX_HSS_LEVELS ], + param_set_t lm_ots_type[ MAX_HSS_LEVELS ], + bool (*read_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context); + +enum hss_error_code { + hss_error_none = 0, /* I don't know nothing about any error */ + + hss_range_normal_failures, /* There errors happen during normal use */ + /* of the signature scheme */ + hss_error_bad_signature, /* Invalid signature */ + hss_error_private_key_expired, /* This private key has generated all */ + /* the signatures it is allowed */ + hss_error_not_that_many_sigs_left, /* Reservation request failed */ + /* because the key couldn't do that many */ + /* signatures */ + + hss_range_bad_parameters, /* These errors are cause by the */ + /* application passing in a bad parameter */ + hss_error_no_randomness, /* No RNG supplied */ + hss_error_bad_param_set, /* Application asked for an illegal parmaeter */ + /* set */ + hss_error_buffer_overflow, /* Buffer provide not big enough */ + hss_error_got_null, /* Application passed in a NULL pointer */ + hss_error_bad_aux, /* Error with provided aux buffer */ + hss_error_no_private_buffer, /* Application didn't provide a place */ + /* to put the private key */ + hss_error_incompatible_param_set, /* The parameter set of the working */ + /* set didn't agree with the private key */ + hss_error_key_uninitialized, /* The working key used had never been */ + /* initialized with a private key */ + hss_error_key_mismatch, /* The working set and the private key */ + /* do not correspond */ + hss_error_ctx_uninitialized, /* The incremental ctx wasn't initialized */ + /* properly */ + hss_error_ctx_already_used, /* The ctx has already been used */ + hss_error_bad_public_key, /* Somehow, we got an invalid public key */ + + hss_range_processing_error, /* These errors are cause by an */ + /* error while processing */ + hss_error_bad_randomness, /* The RNG claimed failure */ + hss_error_private_key_write_failed, /* The write of the private key */ + /* to NVRAM failed */ + hss_error_private_key_read_failed, /* The read of the private key */ + /* from NVRAM failed */ + hss_error_out_of_memory, /* A malloc failure caused us to fail */ + + hss_range_my_problem, /* These are caused by internal errors */ + /* within the HSS implementation */ + hss_error_internal, /* Some internal assertion failed (should */ + /* never happen) */ +}; + +/* + * This is the structure that allows us to pass noncritical information + * to and from the above routines (without requiring us to add each + * one as an additional parameter + */ +struct hss_extra_info { + int num_threads; /* Number of threads we're allowed to ues */ + bool last_signature; /* Set if we just signed the last signature */ + /* allowed by this private key */ + enum hss_error_code error_code; /* The more recent error detected */ +}; + +/* Accessor APIs in case someone doesn't feel comfortable about reaching */ +/* into the structure */ +void hss_init_extra_info( struct hss_extra_info * ); +void hss_extra_info_set_threads( struct hss_extra_info *, int ); +bool hss_extra_info_test_last_signature( struct hss_extra_info * ); +enum hss_error_code hss_extra_info_test_error_code( struct hss_extra_info * ); + +#endif /* HSS_H_ */ diff --git a/src/sig_stfl/lms/external/hss_alloc.c b/src/sig_stfl/lms/external/hss_alloc.c new file mode 100644 index 0000000000..8f7cf6054b --- /dev/null +++ b/src/sig_stfl/lms/external/hss_alloc.c @@ -0,0 +1,555 @@ +/* + * This is the code which allocates a working key (and initializes the fields + * that are independent of the key) + */ +#include +#include +#include +#include "hss.h" +#include "hss_internal.h" +#include "lm_common.h" + +#define MALLOC_OVERHEAD 8 /* Our simplistic model about the overhead */ + /* that malloc takes up is that it adds 8 */ + /* bytes to any request we make. This isn't */ + /* precise (especially if we consider external */ + /* fragmentation), it's just a guideline */ + +/* + * Function to estimate the amount of memory we'd use at a particular level, + * if we went with a particular subtree size + * - i is which tree in the scheme we're talking about; 0 is the root tree + * We have this because we allocate less for the root tree + * - subtree_size is the size of the subtrees we're considering + * - total_length is the size of the trees + * - size_hash is the length of the hash output (always 32 currently) + * - if psubtree_levels is non-NULL, we'll return the number of subtree levels + * here + * - if pstack_total is non-NULL, we'll return the bytes of stack space needed + * by the subtrees of this level here + * The value returned is the amount of space used by the merkle + * level structures, the subtree structures, plus the additional stack + * space required + */ +static size_t compute_level_memory_usage(int i, unsigned subtree_size, + unsigned total_height, unsigned size_hash, + unsigned *psubtree_levels, + size_t *pstack_total) { + /* Compute the number of subtree levels we'd have */ + unsigned subtree_levels = (total_height + subtree_size - 1) / subtree_size; + unsigned top_subtree_size = total_height - (subtree_levels-1)*subtree_size; + /* The top level tree has no next subtrees */ + int have_next_subtree = (i == 0) ? 0 : 1; + size_t stack_total = 0; + + /* Compute the memory this would use */ + size_t memory_used = sizeof(struct merkle_level) + MALLOC_OVERHEAD; + unsigned j; + for (j=0; j 2 +#error We assume that a subtree of size 2 is allowed +#endif + return 2; +} + +/* + * This allocates a working key for a particular parameter set, and sets up + * the data fields that are key independent; it doesn't set anything that + * does depend on the key. memory_target is used to guide time/memory + * trade-offs; it's the target memory budget that we try to stay below if + * possible + */ +struct hss_working_key *allocate_working_key( + unsigned levels, + const param_set_t *lm_type, const param_set_t *lm_ots_type, + size_t memory_target, + struct hss_extra_info *info) { + struct hss_extra_info temp_info = { 0 }; + if (!info) info = &temp_info; + + if (levels < MIN_HSS_LEVELS || levels > MAX_HSS_LEVELS) { + info->error_code = hss_error_bad_param_set; + return 0; + } + + /* Assign the memory target to a *signed* variable; signed so that it */ + /* can take on negative values meaningfully (to account for cases where */ + /* we are "overbudget") */ + unsigned long mem_target; + if (memory_target > LONG_MAX) { + mem_target = LONG_MAX; + } else { + mem_target = memory_target; + } +#if 0 +signed long initial_mem_target = mem_target; /* DEBUG HACK */ +#endif + + struct hss_working_key *w = malloc( sizeof *w ); + if (!w) { + info->error_code = hss_error_out_of_memory; + return NULL; + } + mem_target -= sizeof(*w) + MALLOC_OVERHEAD; + unsigned i; + w->levels = levels; + w->status = hss_error_key_uninitialized; /* Not usable until we see a */ + /* private key */ + w->autoreserve = 0; + + /* Initialize all the allocated data structures to NULL */ + /* We do this up front so that if we hit an error in the middle, we can */ + /* just free everything */ + for (i=0; isigned_pk[i] = NULL; + } + for (i=0; itree[i] = NULL; + } + w->stack = NULL; + + /* Allocate all the memory for the level signatures */ + size_t signature_len = 4; /* At the same time, ocmpute the sig length */ + for (i=0; i < levels; i++) { + w->siglen[i] = lm_get_signature_len( lm_type[i], lm_ots_type[i] ); + signature_len += w->siglen[i]; + /* Size of this level's Merkle public key */ + size_t pklen = lm_get_public_key_len(lm_type[i]); + if (i != 0) signature_len += pklen; + if (w->siglen[i] == 0) { + hss_free_working_key(w); + info->error_code = hss_error_bad_param_set; + return 0; + } + /* We don't need a allocate a signature for the topmost */ + if (i == 0) continue; + + w->signed_pk_len[i] = w->siglen[i-1] + pklen; + + w->signed_pk[i] = malloc( w->signed_pk_len[i] ); + if (!w->signed_pk[i]) { + hss_free_working_key(w); + info->error_code = hss_error_out_of_memory; + return 0; + } + mem_target -= w->signed_pk_len[i] + MALLOC_OVERHEAD; + } + w->signature_len = signature_len; + + /* Also account for the overhead for the stack allocation (the memory */ + /* used by the stack will be accounted as a part of the tree level size */ + mem_target -= MALLOC_OVERHEAD; + + /* + * Plot out how many subtree sizes we have at each level. We start by + * computing how much memory we'd use if we minimize each level + */ + unsigned subtree_size[MAX_HSS_LEVELS]; + unsigned subtree_levels[MAX_HSS_LEVELS]; + unsigned level_hash[MAX_HSS_LEVELS]; + unsigned level_height[MAX_HSS_LEVELS]; + unsigned hash_size[MAX_HSS_LEVELS]; + unsigned total_height = 0; + + /* Parse the parameter sets */ + for (i=0; ierror_code = hss_error_bad_param_set; + return 0; + } + + total_height += level_height[i]; /* Also track the number of */ + /* signatures we can generate with this parm set */ + } + + /* + * Select which subtree sizes that is faster, and fit within the memory + * we've been given. For the nonbottom levels, we always use what's the + * smallest for that particular tree height; there's no point in wasting + * extra memory to make them faster (in that each one can be done during + * the time the bottom level BUILDING subtrees don't need updating). + */ + size_t stack_usage = 0; + for (i=0; i mem_target) { + /* This would use more memory than we'd like; accept it if */ + /* either we have no solution, or it uses less memory than what */ + /* we've seen */ + if (search_status != nothing_yet && mem > best_mem) continue; + + /* This solution is the best so far (however, it doesn't fit) */ + search_status = found_overbudget; + } else { + /* This is within our budget; accept it if we haven't seen a */ + /* previous solution within our budget, or this uses fewer */ + /* levels than the previous solution */ + if (search_status == found_plenty_memory) { + if (sub_levels > best_levels) { + /* We've already seen a faster solution */ + continue; + } + if (sub_levels == best_levels && mem > best_mem) { + /* We've already seen an equally fast solution that */ + /* uses less memory */ + continue; + } + } + + /* This solution is the best so far (and it fits) */ + search_status = found_plenty_memory; + } + /* This is the best option so far; record it */ + best_j = j; + best_mem = mem; + best_levels = sub_levels; + best_stack_used = stack_used; + } + + if (search_status == nothing_yet) { + /* This can't really happen */ + hss_free_working_key(w); + info->error_code = hss_error_internal; + return 0; + } +#if 0 +printf( "Allocation = %ld\n", initial_mem_target - mem_target + best_mem ); /* DEBUG HACK */ +#endif + + subtree_size[i] = best_j; + subtree_levels[i] = (level_height[i] + best_j - 1) / best_j; + stack_usage += best_stack_used; + + unsigned char *stack; + if (stack_usage == 0) { + stack = NULL; /* Hey! No stack required */ + /* Avoid the malloc, as malloc(0) is allowed to fail */ + } else { + stack = malloc(stack_usage); + if (!stack) { + hss_free_working_key(w); + info->error_code = hss_error_out_of_memory; + return 0; + } + } + w->stack = stack; + size_t stack_index = 0; + + /* + * Ok, we've figured out the sizes for everything; now do the actual + * allocations + */ + for (i = 0; ierror_code = hss_error_out_of_memory; + return 0; + } + unsigned h0 = level_height[i]; + tree->level = h0; + tree->h = level_hash[i]; + tree->hash_size = hash_size[i]; + tree->lm_type = lm_type[i]; + tree->lm_ots_type = lm_ots_type[i]; + /* We'll initialize current_index from the private key */ + tree->max_index = (1L << tree->level) - 1; + tree->sublevels = subtree_levels[i]; + tree->subtree_size = subtree_size[i]; + unsigned top_subtree_size = h0 - (subtree_levels[i]-1)*subtree_size[i]; + tree->top_subtree_size = top_subtree_size; + + unsigned k; + for (j=0; jsubtree[j][k] = NULL; + w->tree[i] = tree; + + unsigned subtree_level = 0; + unsigned levels_below = h0; + for (j=0; jerror_code = hss_error_out_of_memory; + return 0; + } + + s->level = subtree_level; + s->levels_below = levels_below; + tree->subtree[j][k] = s; + if (k == ACTIVE_TREE) { + /* Active trees don't need no stack */ + s->stack = NULL; + } else if (levels_below == 0) { + /* Bottom level subtrees don't need no stack */ + s->stack = NULL; + } else { + s->stack = &stack[stack_index]; + stack_index += hash_size[i] * levels_below; + } + } + + subtree_level += height; + } + } + +/* SANITY CHECK */ + if (stack_index != stack_usage) { + hss_free_working_key(w); + info->error_code = hss_error_internal; + return 0; + } +/* SANITY CHECK */ + + /* Compute the max number of signatures we can generate */ + if (total_height > 64) total_height = 64; /* (bounded by 2**64) */ + w->max_count = ((sequence_t)2 << (total_height-1)) - 1; /* height-1 so */ + /* we don't try to shift by 64, and hit undefined behavior */ + + /* We use the count 0xffff..ffff to signify 'we've used up all our */ + /* signatures'. Make sure that is above max_count, even for */ + /* parameter sets that can literally generate 2**64 signatures (by */ + /* letting them generate only 2**64-1) */ + if (total_height == 64) w->max_count--; + + return w; +} + +void hss_free_working_key(struct hss_working_key *w) { + int i; + if (!w) return; + for (i=0; itree[i]; + if (tree) { + unsigned j, k; + for (j=0; jsubtree[j][k]); // IGNORE free-check + hss_zeroize( tree, sizeof *tree ); /* We have seeds here */ + } + free(tree); // IGNORE free-check + } + for (i=0; isigned_pk[i]); // IGNORE free-check + } + free(w->stack); // IGNORE free-check + hss_zeroize( w, sizeof *w ); /* We have secret information here */ + free(w); // IGNORE free-check +} diff --git a/src/sig_stfl/lms/external/hss_aux.c b/src/sig_stfl/lms/external/hss_aux.c new file mode 100644 index 0000000000..5817b76c81 --- /dev/null +++ b/src/sig_stfl/lms/external/hss_aux.c @@ -0,0 +1,355 @@ +/* + * This is the implementation of the aux data within the HSS tree + */ + +#include +#include "hss_aux.h" +#include "hss_internal.h" +#include "common_defs.h" +#include "lm_common.h" +#include "endian.h" +#include "hash.h" +#include "hss_zeroize.h" + +/* + * The structure of aux data + * + * The current format of the file is: + * [4 bytes of marker]: + * - bit 31 is set (to indicate that the aux data is nonempty; a 0 first byte + * indicates that, yes, we have no bananas); because we store the marker + * in bigendian format, this bit 31 is in the first byte. + * - bit i is set if we have the hashes for intermediate level i + * For each set bit i (in ascending sequence): + * - 1<= len_this_level) { + /* This level fits; add it */ + max_length -= len_this_level; + /* We also set the MSBit to signify that we're saving something */ + aux_level |= 0x80000000UL | ((aux_level_t)1<>= 1) { + if (aux_level & 1) { + temp->data[h] = (void *)aux_data; + aux_data += (size_t)size_hash << h; + } else { + temp->data[h] = 0; /* No data at this level */ + } + } + + /* Now, check if the data is valid */ + if (w) { + /* Check to see if the data is valid */ + size_t expected_len = (aux_data - orig_aux_data) + size_hash; + if (expected_len > len_aux_data) { + /* Either the first 4 bytes were messed up, or the file was */ + /* truncated */ + return 0; + } + if (len_aux_data < 4 + size_hash) return 0; + + /* Now, MAC the entire aux file */ + union hash_context ctx; + unsigned char key[ MAX_HASH ]; + compute_seed_derive( key, w->tree[0]->h, w->working_key_seed, &ctx ); + unsigned char expected_mac[ MAX_HASH ]; + compute_hmac( expected_mac, w->tree[0]->h, size_hash, &ctx, key, + orig_aux_data, aux_data - orig_aux_data ); + hss_zeroize( key, size_hash ); + hss_zeroize( &ctx, sizeof ctx ); + if (0 != memcmp_consttime( expected_mac, aux_data, size_hash)) { + /* The MAC did not agree; ignore the aux data */ + return 0; + } + } + return temp; +} + +/* + * This returns the amount of aux data we would use, given the maximum bound + * on how much aux data we are allowed, and the parameter sets + */ +size_t hss_get_aux_data_len(size_t max_length, + unsigned levels, + const param_set_t *lm_type, + const param_set_t *lm_ots_type) { + size_t len = 0; + LMS_UNUSED(levels); + if (!hss_optimal_aux_level( max_length, lm_type, lm_ots_type, &len )) { + return 1; /* 1 byte marker to say 'we're not using it */ + } + + return len; +} + +/* + * Save the marker within the aux data + */ +void hss_store_aux_marker( unsigned char *aux_data, aux_level_t aux_level ) { + if (aux_level == 0) { + /* Aux data doesn't help; mark it as unused */ + aux_data[AUX_DATA_MARKER] = NO_AUX_DATA; + } else { + put_bigendian( &aux_data[AUX_DATA_MARKER], aux_level, 4 ); + } +} + +/* + * This is called while we are building the initial top level Merkle tree (to + * compute the root). This is called for each internal node, and allows the + * aux data a chance to save the intermediate value + */ +void hss_save_aux_data( struct expanded_aux_data *data, unsigned level, + unsigned size_hash, merkle_index_t q, + const unsigned char *cur_val ) { + if (!data) return; /* We're not recording anything */ + if (!data->data[level]) return; /* We're not recording anything for */ + /* this level */ + + /* We are recording it; save a copy in the aux data */ + memcpy( data->data[level] + size_hash * q, cur_val, size_hash ); +} + +/* + * This generates the derived value that we'll use as a key the authenticate + * the aux data. We pass the ctx (rather than using a local one) so we have + * one less thing to zeroize + * + * We use a derived key (rather than using the seed directly) because the + * outer hash within the HMAC don't use the diversification factors that every + * other hash within this packet does; hence for HMAC, we use a key that + * is independent of every other hash used + */ +static void compute_seed_derive( unsigned char *result, unsigned hash, + const unsigned char *seed, union hash_context *ctx) { + hss_init_hash_context( hash, ctx ); + unsigned char prefix[ DAUX_PREFIX_LEN ]; + memset( prefix, 0, DAUX_D ); + SET_D( prefix + DAUX_D, D_DAUX ); + hss_update_hash_context( hash, ctx, prefix, sizeof prefix ); + hss_update_hash_context( hash, ctx, seed, SEED_LEN ); + hss_finalize_hash_context( hash, ctx, result ); + + hss_zeroize( &ctx, sizeof ctx ); +} + +static void xor_key( unsigned char *key, unsigned xor_val, unsigned len_key) { + unsigned i; + for (i = 0; idata[i]) { + total_length += (size_t)size_hash << i; + if (!aux) { + aux = data->data[i] - 4; + } + } + } + if (aux) { + compute_hmac( aux+total_length, hash, size_hash, &ctx, aux_seed, + aux, total_length ); + } + + hss_zeroize( &ctx, sizeof ctx ); + hss_zeroize( aux_seed, size_hash ); +} + +/* + * This is called when we need to use aux data; it checks to see if we've + * stored the nodes within the aux data; if we have, it extracts them, + * and returns true + */ +bool hss_extract_aux_data(const struct expanded_aux_data *aux, unsigned level, + const struct hss_working_key *w, unsigned char *dest, + merkle_index_t node_offset, /* Offset of node on this level */ + merkle_index_t node_count) { /* # of nodes to restore */ + if (!aux) return false; /* No aux data */ + if (!aux->data[level]) return false; /* We don't have that specific */ + /* level saved */ + unsigned hash_size = w->tree[0]->hash_size; + + /* We do have the data; copy it to the destination */ + memcpy( dest, + aux->data[level] + node_offset*hash_size, + node_count * hash_size ); + + return true; +} diff --git a/src/sig_stfl/lms/external/hss_aux.h b/src/sig_stfl/lms/external/hss_aux.h new file mode 100644 index 0000000000..634df88684 --- /dev/null +++ b/src/sig_stfl/lms/external/hss_aux.h @@ -0,0 +1,59 @@ +#if !defined( HSS_AUX_H_ ) +#define HSS_AUX_H_ + +/* + * This is the internal API to the subsystem that deals with aux data + * This should not be included by files outside this subsystem + */ + +#include "common_defs.h" +#include +#include + +struct hss_working_key; + +/* This is a bitmap that lists which aux levels we have */ +typedef uint_fast32_t aux_level_t; + +/* This is the expanded version of the aux data */ +struct expanded_aux_data { + unsigned char *data[ MAX_MERKLE_HEIGHT+1 ]; +}; + +/* + * These are some internal routines that handle aux data + */ +/* Internal function used to compute the optimal aux level */ +aux_level_t hss_optimal_aux_level( size_t max_length, + const param_set_t *lm_type, + const param_set_t *lm_ots_type, + size_t *actual_len ); + +/* Generate pointers into a saved aux data */ +/* If w is provided, we do sanity checking on the data within aux_data */ +struct expanded_aux_data *hss_expand_aux_data( const unsigned char *aux_data, + size_t len_aux_data, + struct expanded_aux_data *temp, unsigned size_hash, + struct hss_working_key *w ); + +/* + * Save the marker within the aux data + */ +void hss_store_aux_marker( unsigned char *aux_data, aux_level_t aux_level ); + +/* Save an intermediate node */ +void hss_save_aux_data( struct expanded_aux_data *data, unsigned level, + unsigned size_hash, merkle_index_t q, + const unsigned char *cur_val ); + +/* Do the final touches on the aux data */ +void hss_finalize_aux_data(struct expanded_aux_data *data, + unsigned size_hash, unsigned hash, + const unsigned char *seed); + +/* Get a set of intermediate nodes from the aux data */ +bool hss_extract_aux_data(const struct expanded_aux_data *aux, unsigned level, + const struct hss_working_key *w, unsigned char *dest, + merkle_index_t node_offset, merkle_index_t node_count); + +#endif /* HSS_AUX_H_ */ diff --git a/src/sig_stfl/lms/external/hss_common.c b/src/sig_stfl/lms/external/hss_common.c new file mode 100644 index 0000000000..d07261dd26 --- /dev/null +++ b/src/sig_stfl/lms/external/hss_common.c @@ -0,0 +1,48 @@ +/* + * This is the code that is common between an HSS verifier, and a full HSS + * implementation that both signs and verifies + */ +#include +#include "common_defs.h" +#include "hss_common.h" +#include "lm_common.h" +#include "config.h" +/* + * Get the length of the public key, given this particular parameter set + */ +size_t hss_get_public_key_len(unsigned levels, + const param_set_t *lm_type, + const param_set_t *lm_ots_type) { + LMS_UNUSED(lm_ots_type); + if (levels < MIN_HSS_LEVELS || levels > MAX_HSS_LEVELS) return 0; + + size_t first_pubkey = lm_get_public_key_len(lm_type[0]); + if (first_pubkey == 0) return 0; + + return 4 + first_pubkey; +} + +/* + * Get the length of a signature, given this particular parameter set + */ +size_t hss_get_signature_len(unsigned levels, + const param_set_t *lm_type, + const param_set_t *lm_ots_type) { + if (levels < MIN_HSS_LEVELS || levels > MAX_HSS_LEVELS) return 0; + + unsigned i; + size_t tot_len = 4; + for (i=0; i 0 */ + if (i > 0) { + size_t next_pub_len = lm_get_public_key_len(lm_type[i]); + if (next_pub_len == 0) return 0; + tot_len += next_pub_len; + } + } + return tot_len; +} diff --git a/src/sig_stfl/lms/external/hss_common.h b/src/sig_stfl/lms/external/hss_common.h new file mode 100644 index 0000000000..c455b9af5e --- /dev/null +++ b/src/sig_stfl/lms/external/hss_common.h @@ -0,0 +1,22 @@ +#if !defined( HSS_COMMON_H_ ) +#define HSS_COMMON_H_ + +#include +#include "common_defs.h" + +/* + * This returns the length of the public key for the given parameter set + */ +size_t hss_get_public_key_len(unsigned levels, + const param_set_t *lm_type, + const param_set_t *lm_ots_type); +#define HSS_MAX_PUBLIC_KEY_LEN (4 + 8 + ((I_LEN+3) & ~3) + MAX_HASH) + +/* + * This returns the length of the signature for the given parameter set + */ +size_t hss_get_signature_len(unsigned levels, + const param_set_t *lm_type, + const param_set_t *lm_ots_type); + +#endif /* HSS_COMMON_H_ */ diff --git a/src/sig_stfl/lms/external/hss_compute.c b/src/sig_stfl/lms/external/hss_compute.c new file mode 100644 index 0000000000..353ec939fb --- /dev/null +++ b/src/sig_stfl/lms/external/hss_compute.c @@ -0,0 +1,174 @@ +/* + * This includes some computation methods that are shared between different + * subsystems of the HSS signature package + */ + +#include +#include "hss_internal.h" +#include "hss.h" +#include "hash.h" +#include "hss_thread.h" +#include "lm_ots_common.h" +#include "lm_ots.h" +#include "endian.h" +#include "hss_derive.h" + +/* Count the number of 1 bits at the end (lsbits) of the integer */ +/* Do it in the obvious way; straightline code may be faster (no */ +/* unpredictable jumps, which are costly), but that would be less scrutable */ +/* (and this code is "fast enough") */ +static int trailing_1_bits(merkle_index_t n) { + int i; + for (i=0; n&1; n>>=1, i++) + ; + return i; +} + +/* + * Compute the value of an internal node within a Merkle tree + */ +static enum hss_error_code hss_compute_internal_node( unsigned char *dest, + merkle_index_t node_num, + const unsigned char *seed, + param_set_t lm_type, + param_set_t lm_ots_type, + unsigned h, + unsigned leaf_level, + const unsigned char *I) { + unsigned hash_size = hss_hash_length(h); + + /* We're store intermediate nodes here */ + unsigned char stack[ MAX_HASH * MAX_MERKLE_HEIGHT]; + + merkle_index_t tree_size = (merkle_index_t)1 << leaf_level; + merkle_index_t r = node_num; + int levels_to_bottom = 0; + if (r == 0) return hss_error_internal; /* So no to infinite loops */ + while (r < tree_size) { + r <<= 1; + levels_to_bottom++; + } + merkle_index_t q = r - tree_size; + + merkle_index_t i; + unsigned ots_len = lm_ots_get_public_key_len(lm_ots_type); + unsigned char pub_key[ LEAF_MAX_LEN ]; + memcpy( pub_key + LEAF_I, I, I_LEN ); + SET_D( pub_key + LEAF_D, D_LEAF ); + + struct seed_derive derive; + if (!hss_seed_derive_init( &derive, lm_type, lm_ots_type, + I, seed)) { + return hss_error_bad_param_set; + } + + for (i=0;; i++, r++, q++) { + /* Generate the next OTS public key */ + hss_seed_derive_set_q( &derive, q ); + if (!lm_ots_generate_public_key(lm_ots_type, I, + q, &derive, pub_key + LEAF_PK, ots_len)) { + return hss_error_bad_param_set; /* The only reason the above */ + /* could fail */ + } + + /* + * For the subtree which this leaf node forms the final piece, put the + * destination to where we'll want it, either on the stack, or if this + * is the final piece, to where the caller specified + */ + unsigned char *current_buf; + int stack_offset = trailing_1_bits( i ); + if (stack_offset == levels_to_bottom) { + current_buf = dest; + } else { + current_buf = &stack[stack_offset * hash_size ]; + } + + /* Hash it to form the leaf node */ + put_bigendian( pub_key + LEAF_R, r, 4); + union hash_context ctx; + hss_hash_ctx( current_buf, h, &ctx, pub_key, LEAF_LEN(hash_size) ); + + /* Work up the stack, combining right nodes with the left nodes */ + /* that we've already computed */ + int sp; + for (sp = 1; sp <= stack_offset; sp++) { + hss_combine_internal_nodes( current_buf, + &stack[(sp-1) * hash_size], current_buf, + h, I, hash_size, + r >> sp ); + } + + /* We're not at a left branch, or at the target node */ + + /* Because we've set current_buf to point to where we want to place */ + /* the result of this loop, we don't need to memcpy it */ + + /* Check if this was the last leaf (and so we've just computed the */ + /* target node) */ + if (stack_offset == levels_to_bottom) { + /* We're at the target node; the node we were asked to compute */ + /* We've already placed the value into dest, so we're all done */ + break; + } + } + + hss_seed_derive_done( &derive ); + + return hss_error_none; +} + +/* + * Combine adjacent left and right nodes within the Merkle tree + * together + */ +void hss_combine_internal_nodes( unsigned char *dest, + const unsigned char *left_node, const unsigned char *right_node, + int h, const unsigned char *I, unsigned hash_size, + merkle_index_t node_num) { + unsigned char hash_val[ INTR_MAX_LEN ]; + memcpy( hash_val + INTR_I, I, I_LEN ); + put_bigendian( hash_val + INTR_R, node_num, 4 ); + SET_D( hash_val + INTR_D, D_INTR ); + + memcpy( hash_val + INTR_PK, left_node, hash_size ); + memcpy( hash_val + INTR_PK + hash_size, right_node, hash_size ); + union hash_context ctx; + hss_hash_ctx( dest, h, &ctx, hash_val, INTR_LEN(hash_size) ); +} + +/* + * This computes an array of intermediate Merkle nodes given by data + * This may be run in a worker (non-main) thread + */ +void hss_gen_intermediate_tree(const void *data, + struct thread_collection *col) { + const struct intermed_tree_detail *d = data; + unsigned hash_len = hss_hash_length(d->h); + unsigned i; + + for (i=0; inode_count; i++) { + unsigned char result[ MAX_HASH ]; + enum hss_error_code status = hss_compute_internal_node( result, + d->node_num + i, + d->seed, + d->lm_type, + d->lm_ots_type, + d->h, + d->tree_height, + d->I); + + /* Report the results */ + hss_thread_before_write(col); + if (status == hss_error_none) { + /* Copy out the resulting hash */ + memcpy( d->dest + i*hash_len, result, hash_len ); + } else { + /* Something went wrong; report the bad news */ + *d->got_error = status; + hss_thread_after_write(col); /* No point in working more */ + return; + } + hss_thread_after_write(col); + } +} diff --git a/src/sig_stfl/lms/external/hss_derive.c b/src/sig_stfl/lms/external/hss_derive.c new file mode 100644 index 0000000000..fc8833594a --- /dev/null +++ b/src/sig_stfl/lms/external/hss_derive.c @@ -0,0 +1,325 @@ +/* + * This is the file that contains the routines that generate various 'random' + * values from the master seed. + * + * Values generated by this routine: + * - OTS private keys + * - Message randomizers (the random value we hash with the message when we + * sign it) + * - I values + * - SEED values (which are the secret to derive all the above for a specific + * LMS tree) + * + * We do things determanisticly, rather than picking things from random, so + * that if we reload from scratch, the values we use after the reload are + * consistent with what we used previously + * + * This provides several different possible derivation methods; they can be + * selected by setting SECRET_METHOD in config.h + */ +#include +#include "hss_derive.h" +#include "hss_internal.h" +#include "hash.h" +#include "endian.h" +#include "config.h" + +#if SECRET_METHOD == 2 + /* We use a hash function based on the parameter set */ +#include "lm_common.h" /* To get the prototype for the parameter set -> */ + /* hash function mapping */ +#else +#if SEED_LEN == 32 +#define HASH HASH_SHA256 /* We always use SHA-256 to derive seeds */ +#else +#error We need to define a hash function for this seed length +#endif +#endif + +#if SECRET_METHOD == 0 || SECRET_METHOD == 2 +/* + * This is the method of deriving LM-OTS keys that conforms to the + * Appendix A method + * As you can see, it's fairly simple + */ + +/* This creates a seed derivation object */ +bool hss_seed_derive_init( struct seed_derive *derive, + param_set_t lm, param_set_t ots, + const unsigned char *I, const unsigned char *seed ) { + derive->I = I; + derive->master_seed = seed; + LMS_UNUSED(ots); + /* q, j will be set later */ +#if SECRET_METHOD == 2 + /* Grab the hash function to use */ + if (!lm_look_up_parameter_set(lm, &derive->hash, &derive->m, 0)) { + return false; + } + + /* Note: currently, this assumes that the hash length is always 256 */ + /* bits; error out if that isn't the case */ + if (derive->m != SEED_LEN) { + return false; + } +#endif + + return true; +} + +/* This sets the internal 'q' value for seed derivation object */ +void hss_seed_derive_set_q( struct seed_derive *derive, merkle_index_t q ) { + derive->q = q; +} + +/* This sets the internal 'j' value for seed derivation object */ +void hss_seed_derive_set_j( struct seed_derive *derive, unsigned j ) { + derive->j = j; +} + + +/* This derives the current seed value. If increment_j is set, it'll then */ +/* reset the object to the next j value */ +void hss_seed_derive( unsigned char *seed, struct seed_derive *derive, + bool increment_j ) { + unsigned char buffer[ PRG_MAX_LEN ]; + memcpy( buffer + PRG_I, derive->I, I_LEN ); + put_bigendian( buffer + PRG_Q, derive->q, 4 ); + put_bigendian( buffer + PRG_J, derive->j, 2 ); + buffer[PRG_FF] = 0xff; + memcpy( buffer + PRG_SEED, derive->master_seed, SEED_LEN ); + +#if SECRET_METHOD == 2 + int hash = derive->hash; /* Our the parameter set's hash function */ +#else + int hash = HASH; /* Use our standard one */ +#endif + + hss_hash( seed, hash, buffer, PRG_LEN(SEED_LEN) ); + + hss_zeroize( buffer, PRG_LEN(SEED_LEN) ); + + if (increment_j) derive->j += 1; +} + +/* This is called when we're done with a seed derivation object */ +void hss_seed_derive_done( struct seed_derive *derive ) { + /* No secrets here */ + LMS_UNUSED(derive); +} + +#elif SECRET_METHOD == 1 +/* + * This is a method of deriving LM-OTS keys that tries to be more + * side-channel resistant; in particular, we never include any + * specific secret value in more than 2**SECRET_MAX distinct + * hashes. + * We do this by deriving subseeds using a tree-based structure; + * each node in the tree has up to 2**SECRET_MAX children, and we use any + * seed within the node (including the root) in no other hash. + * We actually have two levels of trees; one based on q (Merkle tree index), + * the other based on j (Winternitz digit); we could design a single level + * tree that could incorporate both, but it'd be more complex + * + * Much of the complexity that does exist is there to avoid recomputation + */ +#include "lm_common.h" +#include "lm_ots_common.h" +static unsigned my_log2(merkle_index_t n); + +/* This creates a seed derivation object */ +bool hss_seed_derive_init( struct seed_derive *derive, + param_set_t lm, param_set_t ots, + const unsigned char *I, const unsigned char *seed ) { + derive->I = I; + derive->master_seed = seed; + + /* These parameter sets will define the size of the trees we'll use */ + unsigned height, p; + if (!lm_look_up_parameter_set(lm, 0, 0, &height) || + !lm_ots_look_up_parameter_set(ots, 0, 0, 0, &p, 0)) { + return false; + } + + p += NUM_ARTIFICIAL_SEEDS; /* We use one artifical value for the */ + /* randomizer and two artificial values to generate seed, I */ + /* for child trees */ + + /* Compute the number of r-levels we have */ + derive->q_levels = (height + SECRET_MAX - 1)/SECRET_MAX; + + /* And which bit to set when converting 'q' to 'r' */ + derive->r_mask = (merkle_index_t)1 << height; + + /* Compute the number of j-levels we have */ + unsigned j_height = my_log2(p); + derive->j_levels = (j_height + SECRET_MAX - 1)/SECRET_MAX; + + /* And which bit to set when writing q values into the hash */ + derive->j_mask = 1 << j_height; + + /* We reset the current 'q' value to am impossible value; we do this so */ + /* that the initial 'q' value given to use by the application will */ + /* rebuild the entire path through the tree */ + derive->q = derive->r_mask; + + return true; +} + +/* This sets the internal 'q' value for seed derivation object */ +/* This also updates our internal q-path (the q_index/q_seed arrays) */ +/* to reflect the new 'q' value, while minimizing the number of hashes */ +/* done (by reusing as much of the previous path as possible) */ +void hss_seed_derive_set_q( struct seed_derive *derive, merkle_index_t q ) { + merkle_index_t change = q ^ derive->q; + derive->q = q; + unsigned bits_change = my_log2(change); + unsigned q_levels = derive->q_levels; + + /* levels_change will be the number of levels of the q-tree we'll */ + /* need to recompute */ + unsigned levels_change = (bits_change + SECRET_MAX - 1) / SECRET_MAX; + if (levels_change > q_levels) levels_change = q_levels; + + int i; + union hash_context ctx; + unsigned char buffer[ QTREE_MAX_LEN ]; + merkle_index_t r = q | derive->r_mask; + + for (i = levels_change; i > 0; i--) { + int j = q_levels - i; + int shift = (i-1) * SECRET_MAX; + + memcpy( buffer + QTREE_I, derive->I, I_LEN ); + put_bigendian( buffer + QTREE_Q, r >> shift, 4 ); + SET_D( buffer + QTREE_D, D_QTREE ); + if (j == 0) { + memcpy( buffer + QTREE_SEED, derive->master_seed, SEED_LEN ); + } else { + memcpy( buffer + QTREE_SEED, derive->q_seed[j-1], SEED_LEN ); + } + + hss_hash_ctx( derive->q_seed[j], HASH, &ctx, buffer, QTREE_LEN ); + } + + hss_zeroize( buffer, PRG_LEN(SEED_LEN) ); + hss_zeroize( &ctx, sizeof ctx ); +} + +/* Helper function to recompute the j_seed[i] value, based on the */ +/* j_value[i] already set */ +/* ctx, buffer are passed are areas this function can use; we reuse those */ +/* areas so we need to zeroize those buffers only once */ +static void set_j_seed( struct seed_derive *derive, int i, + union hash_context *ctx, unsigned char *buffer) { + + memcpy( buffer + PRG_I, derive->I, I_LEN ); + put_bigendian( buffer + PRG_Q, derive->q, 4 ); + put_bigendian( buffer + PRG_J, derive->j_value[i], 2 ); + buffer[PRG_FF] = 0xff; + if (i == 0) { + /* The root of this tree; it gets its seed from the bottom level */ + /* of the q-tree */ + memcpy( buffer + PRG_SEED, derive->q_seed[ derive->q_levels-1], + SEED_LEN ); + } else { + /* Non-root node; it gets its seed from its parent */ + memcpy( buffer + PRG_SEED, derive->j_seed[i-1], SEED_LEN ); + } + + hss_hash_ctx( derive->j_seed[i], HASH, ctx, buffer, PRG_LEN(SEED_LEN) ); +} + +/* This sets the internal 'j' value for seed derivation object */ +/* This computes the entire path to the 'j' value. Because this is used */ +/* immediately after resetting the q value, we don't try to reuse the */ +/* previous hashes (as there won't be anything there we could reuse) */ +/* Note that we don't try to take advantage of any preexisting hashes */ +/* in the j_seed array; we don't bother because this function is typically */ +/* used only immediately after a set_q call, and so there aren't any */ +/* hashes we could take advantage of */ +void hss_seed_derive_set_j( struct seed_derive *derive, unsigned j ) { + int i; + unsigned j_levels = derive->j_levels; + unsigned shift = SECRET_MAX * j_levels; + + unsigned j_mask = derive->j_mask; + j &= j_mask-1; /* Set the high-order bit; clear any bits above that */ + j |= j_mask; /* This ensures that when we do the hashes, that the */ + /* prefix for the hashes at two different levels of the */ + /* tree are distinct */ + + union hash_context ctx; + unsigned char buffer[ PRG_MAX_LEN ]; + + for (i = 0; ij_value[i] = (j >> shift); + set_j_seed( derive, i, &ctx, buffer ); + } + + hss_zeroize( &ctx, sizeof ctx ); + hss_zeroize( buffer, PRG_LEN(SEED_LEN) ); +} + +/* This derives the current seed value (actually, we've already computed */ +/* it); we just need to copy it to the buffer) */ +/* If increment_j is set, it'll then reset the object to the next j value */ +/* (which means incrementally computing that path) */ +void hss_seed_derive( unsigned char *seed, struct seed_derive *derive, + bool increment_j ) { + memcpy( seed, derive->j_seed[ derive->j_levels - 1], SEED_LEN ); + + if (increment_j) { + int i; + + /* Update the j_values, and figure out which hashes we'll need */ + /* to recompute */ + for (i = derive->j_levels-1;; i--) { + unsigned index = derive->j_value[i]; + index += 1; + derive->j_value[i] = index; + if (0 != (index & SECRET_MAX_MASK)) { + /* The increment didn't cause a carry to the next level; */ + /* we can stop propogating the increment here (and we */ + /* also know this is the top level that we need to */ + /* recompute the hashes */ + break; + } + if (i == 0) { + /* This is the top level; stop here */ + break; + } + } + + /* Recompute the hashes that need updating; we need to do it */ + /* top-down, as each hash depends on the previous one */ + union hash_context ctx; + unsigned char buffer[ PRG_MAX_LEN ]; + for (; i < derive->j_levels; i++) { + set_j_seed( derive, i, &ctx, buffer ); + } + hss_zeroize( &ctx, sizeof ctx ); + hss_zeroize( buffer, PRG_LEN(SEED_LEN) ); + } +} + +/* This is called when we're done with a seed derivation object */ +/* This makes sure any secret values are zeroized */ +void hss_seed_derive_done( struct seed_derive *derive ) { + /* These values are secret, and should never be leaked */ + hss_zeroize( derive->q_seed, sizeof derive->q_seed ); + hss_zeroize( derive->j_seed, sizeof derive->j_seed ); +} + +static unsigned my_log2(merkle_index_t n) { + unsigned lg; + for (lg = 0; n > 0; lg++) n >>= 1; + return lg; +} + +#else + +#error Unknown secret method + +#endif diff --git a/src/sig_stfl/lms/external/hss_derive.h b/src/sig_stfl/lms/external/hss_derive.h new file mode 100644 index 0000000000..ee47eb6cfc --- /dev/null +++ b/src/sig_stfl/lms/external/hss_derive.h @@ -0,0 +1,74 @@ +#if !defined( HSS_DERIVE_H_ ) +#define HSS_DERIVE_H_ + +#include "common_defs.h" + +#include "config.h" + +#if SECRET_MAX > 31 +#error The code is not designed for a SECRET_MAX that high +#endif +#define SECRET_MAX_MASK (((merkle_index_t)1 << SECRET_MAX) - 1) + +struct seed_derive { + const unsigned char *I; + const unsigned char *master_seed; + merkle_index_t q; + unsigned j; +#if SECRET_METHOD == 2 + unsigned hash; /* Hash function to use */ + unsigned m; /* Length of hash function */ +#endif + +#if SECRET_METHOD == 1 + unsigned q_levels, j_levels; + merkle_index_t r_mask; + unsigned j_mask; +#define MAX_Q_HEIGHT ((MAX_MERKLE_HEIGHT + SECRET_MAX - 1) / SECRET_MAX) +#define MAX_J_HEIGHT (( 9 + SECRET_MAX - 1) / SECRET_MAX) + /* '9' is the number of bits a maximum 'p' can take up */ + + unsigned j_value[MAX_J_HEIGHT]; /* these are the values we insert */ + /* into the hash. The lower SECRET_MAX bits are which child of */ + /* the parent it is; the higher bits indicate the parents' */ + /* identities */ + + unsigned char q_seed[MAX_Q_HEIGHT][SEED_LEN]; + unsigned char j_seed[MAX_Q_HEIGHT][SEED_LEN]; +#endif +}; + +bool hss_seed_derive_init( struct seed_derive *derive, + param_set_t lm, param_set_t ots, + const unsigned char *I, const unsigned char *seed ); + +/* This sets the internal 'q' value */ +/* If we've already have a 'q' value set, it'll try to minimize the number */ +/* of hashes done */ +/* Once you've done that, you'll need to reset the 'h' */ +void hss_seed_derive_set_q( struct seed_derive *derive, merkle_index_t q ); + +/* This sets the internal 'j' value */ +void hss_seed_derive_set_j( struct seed_derive *derive, unsigned j ); + +#define NUM_ARTIFICIAL_SEEDS 3 /* 3 seeds are listed below */ + /* This is the j value used when we're deriving the seed value */ + /* for child Merkle trees */ +#define SEED_CHILD_SEED (~1) + /* This is the j value used when we're deriving the I value */ + /* used; either in the context of the parent tree, or of this tree */ +#define SEED_CHILD_I (SEED_CHILD_SEED + 1) + /* This is the j value used when we're asking for the randomizer C */ + /* for signing a message */ +#define SEED_RANDOMIZER_INDEX (~2) + +/* This generates the current seed. If increment_j is set, this will set */ +/* up for the next j value */ +void hss_seed_derive( unsigned char *seed, struct seed_derive *derive, + bool increment_j ); + +/* This needs to be called when we done with a seed_derive */ +/* That structure contains keying data, this makes sure those are cleaned */ +void hss_seed_derive_done( struct seed_derive *derive ); + +#endif /* HSS_DERIVE_H_ */ diff --git a/src/sig_stfl/lms/external/hss_generate.c b/src/sig_stfl/lms/external/hss_generate.c new file mode 100644 index 0000000000..b604ab3593 --- /dev/null +++ b/src/sig_stfl/lms/external/hss_generate.c @@ -0,0 +1,932 @@ +/* + * This is the routine that generates the ephemeral ("working") key from the + * short private value. It builds all the various current, building and + * next subtrees for the various levels (to at least the extent required + * for the current count within the key). + * + * The code is made considerably more complex because we try to take + * advantage of parallelism. To do this, we explicitly list the parts + * of the subtrees we need to build (which is most of the computation), and + * have different worker threads build the various parts, + * + * However, it turns out that this is sometimes insufficient; sometimes, + * the work consists of one or two expensive nodes (perhaps the top level + * subtree), and a lot of comparatively cheap ones; in this case, we'd have + * most of our threads go through the cheap ones quickly, and have one or + * two threads working on the expensive one, and everyone will end up waiting + * for that. To mitigate that, we attempt to subdivide the most expensive + * requests; instead of having a single thread computing the expensive node, + * we may issue four or eight threads to compute the nodes two or three + * levels below (and have the main thread do the final computation when + * all the threads are completed). + * + * This works out pretty good; however man does add complexity :-( + */ +#include +#include +#include "hss.h" +#include "hss_internal.h" +#include "hss_aux.h" +#include "hash.h" +#include "hss_thread.h" +#include "hss_reserve.h" +#include "lm_ots_common.h" +#include "endian.h" + +#define DO_FLOATING_POINT 1 /* If clear, we avoid floating point operations */ + /* You can turn this off for two reasons: */ + /* - Your platform doesn't implement floating point */ + /* - Your platform is single threaded (we use floating point to figure */ + /* out how to split up tasks between threads; if the same thread */ + /* will do all the work, dividing it cleverly doesn't buy anything */ + /* (and that's a quite a bit of code that gets eliminated) */ + /* On the other hand, if you are threaded, you'd really want this if */ + /* at all possible; without this, one thread ends up doing the bulk of */ + /* the work, and so we end up going not that much faster than single */ + /* threaded mode */ + +/* + * This routine assumes that we have filled in the bottom node_count nodes of + * the subtree; it tries to compute as many internal nodes as possible + */ +static void fill_subtree(const struct merkle_level *tree, + struct subtree *subtree, + merkle_index_t node_count, + const unsigned char *I) { + if (node_count <= 1) return; /* If we can't compute any more nodes, */ + /* don't bother trying */ + unsigned h_subtree = (subtree->level == 0) ? tree->top_subtree_size : + tree->subtree_size; + + /* Index into the node array where we're starting */ + merkle_index_t lower_index = ((merkle_index_t)1 << h_subtree) - 1; + + unsigned hash_size = tree->hash_size; + + /* The node identier (initially of the bottom left node of the */ + /* subtree */ + merkle_index_t node_id = (((merkle_index_t)1 << tree->level) + + subtree->left_leaf) + >> subtree->levels_below; + + /* Fill in as many levels of internal nodes as possible */ + int sublevel; + for (sublevel = h_subtree-1; sublevel >= 0; sublevel--) { + node_count >>= 1; + if (node_count == 0) break; /* Can't do any more */ + merkle_index_t prev_lower_index = lower_index; + lower_index >>= 1; + node_id >>= 1; + + merkle_index_t i; + for (i=0; inodes[ hash_size *(lower_index + i)], + &subtree->nodes[ hash_size *(prev_lower_index + 2*i)], + &subtree->nodes[ hash_size *(prev_lower_index + 2*i+1)], + tree->h, I, hash_size, + node_id + i); + } + } +} + +/* + * This routine takes the 2**num_level hashes, and computes up num_level's, + * returning the value of the top node. This is sort of like fill_tree, + * except that it returns only the top node, not the intermediate ones + * One warning: this does modify the passed value of hashes; our current + * caller doesn't care about that. + */ +static void hash_subtree( unsigned char *dest, + unsigned char *hashes, + unsigned num_level, merkle_index_t node_index, + unsigned hash_size, + int h, const unsigned char *I) { + + /* Combine the nodes to form the tree, until we get to the two top nodes */ + /* This will overwrite the hashes array; that's OK, because we don't */ + /* need those anymore */ + for (; num_level > 1; num_level--) { + unsigned i; + merkle_index_t this_level_node_index = node_index << (num_level-1); + for (i = 0; i < ((unsigned)1<<(num_level-1)); i++) { + hss_combine_internal_nodes( + &hashes[ hash_size * i ], + &hashes[ hash_size * (2*i) ], + &hashes[ hash_size * (2*i + 1) ], + h, I, hash_size, + this_level_node_index + i); + } + } + + /* Combine the top two nodes to form our actual target */ + hss_combine_internal_nodes( + dest, + &hashes[ 0 ], + &hashes[ hash_size ], + h, I, hash_size, + node_index); +} + +#if DO_FLOATING_POINT +/* + * This structure is a note reminding us that we've decided to split this + * init_order into several requests, which can be run on independent threads + */ +struct sub_order { + unsigned num_hashes; /* The number of hashes this suborder is */ + /* split up into */ + unsigned level; /* Levels deep into the tree we go */ + merkle_index_t node_num_first_target; /* The node number of the left */ + /* most hash that we're standing in for */ + unsigned char h[1]; /* The hashes go here; we'll malloc */ + /* enough space to let them fit */ +}; +#endif + +/* + * This is an internal request to compute the bottom N nodes (starting from the + * left) of a subtree (and to contruct the internal nodes that based solely on + * those N leaf nodes) + */ +struct init_order { + const struct merkle_level *tree; + struct subtree *subtree; + merkle_index_t count_nodes; /* # of bottom level nodes we need to */ + /* generate */ + const unsigned char *prev_node; /* For nonbottom subtrees, sometimes one */ + /* of the nodes is the root of the */ + /* next level subtree that we compute in */ + /* its entirety. If so, this is a pointer */ + /* to where we will find the precomputed */ + /* value. This allows us to avoid */ + /* computing that specific node */ + merkle_index_t prev_index; /* This is the index of the */ + /* precomputed node, where 0 is the */ + /* leftmost bottom node of this subtree */ + char next_tree; /* If clear, we do this on the current */ + /* tree level (seed, I values); if set, */ + /* we do this on the next */ + char already_computed_lower; /* If set, we've already computed the */ + /* lower nodes (and all we need to do is */ + /* fill the upper); no need to ask the */ + /* threads do do anything */ + /* We may still need to build the */ + /* interiors of the subtrees, of course */ +#if DO_FLOATING_POINT + float cost; /* Approximate number of hash compression */ + /* operations per node */ + struct sub_order *sub; /* If non-NULL, this gives details on how */ + /* we want to subdivide the order between */ + /* different threads */ +#endif +}; + +#if DO_FLOATING_POINT + /* This comparison function sorts the most expensive orders first */ +static int compare_order_by_cost(const void *a, const void *b) { + const struct init_order *p = a; + const struct init_order *q = b; + + if (p->cost > q->cost) return -1; + if (p->cost < q->cost) return 1; + + return 0; +} +#else + /* This comparison function sorts the higher level subtrees first */ +static int compare_order_by_subtree_level(const void *a, const void *b) { + const struct init_order *p = a; + unsigned p_subtree = p->subtree->level; + const struct init_order *q = b; + unsigned q_subtree = q->subtree->level; + + if (p_subtree < q_subtree) return -1; + if (p_subtree > q_subtree) return 1; + + return 0; +} +#endif + +#if DO_FLOATING_POINT +static float estimate_total_cost(struct init_order *order, + unsigned count_order); + +/* + * This is a simple minded log function, returning an int. Yes, using the + * built-in log() function would be easier, however I don't want to pull in + * the -lm library just for this + */ +static unsigned my_log2(float f) { +#define MAX_LOG 10 + unsigned n; + for (n=1; f > 2 && n < MAX_LOG; n++) + f /= 2; + return n; +} +#endif + +/* + * This is the point of this entire file. + * + * It fills in an already allocated working key, based on the private key + */ +bool hss_generate_working_key( + bool (*read_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + const unsigned char *aux_data, size_t len_aux_data, /* Optional */ + struct hss_working_key *w, + struct hss_extra_info *info) { + struct hss_extra_info temp_info = { 0 }; + if (!info) info = &temp_info; + + if (!w) { + info->error_code = hss_error_got_null; + return false; + } + w->status = hss_error_key_uninitialized; /* In case we detect an */ + /* error midway */ + + if (!read_private_key && !context) { + info->error_code = hss_error_no_private_buffer; + return false; + } + + /* Read the private key */ + unsigned char private_key[ PRIVATE_KEY_LEN ]; + if (read_private_key) { + if (!read_private_key( private_key, PRIVATE_KEY_LEN, context)) { + info->error_code = hss_error_private_key_read_failed; + goto failed; + } + } else { + memcpy( private_key, context, PRIVATE_KEY_LEN ); + } + + /* + * Make sure that the private key and the allocated working key are + * compatible; that the working_key was initialized with the same + * parameter set + */ + { + if (w->levels > MAX_HSS_LEVELS) { + info->error_code = hss_error_internal; + goto failed; + } + unsigned char compressed[PRIVATE_KEY_PARAM_SET_LEN]; + param_set_t lm_type[MAX_HSS_LEVELS], lm_ots_type[MAX_HSS_LEVELS]; + unsigned i; + for (i=0; ilevels; i++) { + lm_type[i] = w->tree[i]->lm_type; + lm_ots_type[i] = w->tree[i]->lm_ots_type; + } + + if (!hss_compress_param_set( compressed, w->levels, + lm_type, lm_ots_type, + sizeof compressed )) { + /* We're passed an unsupported param set */ + info->error_code = hss_error_internal; + goto failed; + } + if (0 != memcmp( private_key + PRIVATE_KEY_PARAM_SET, compressed, + PRIVATE_KEY_PARAM_SET_LEN )) { + /* The working set was initiallized with a different parmset */ + info->error_code = hss_error_incompatible_param_set; + goto failed; + } + } + + sequence_t current_count = get_bigendian( + private_key + PRIVATE_KEY_INDEX, PRIVATE_KEY_INDEX_LEN ); + if (current_count > w->max_count) { + info->error_code = hss_error_private_key_expired; /* Hey! We */ + goto failed; /* can't generate any more signatures */ + } + hss_set_reserve_count(w, current_count); + + memcpy( w->private_key, private_key, PRIVATE_KEY_LEN ); + + /* Initialize all the levels of the tree */ + + /* Initialize the current count for each level (from the bottom-up) */ + sequence_t i; + sequence_t count = current_count; + for (i = w->levels; i >= 1 ; i--) { + struct merkle_level *tree = w->tree[i-1]; + unsigned index = count & tree->max_index; + count >>= tree->level; + tree->current_index = index; + } + + /* Initialize the I values */ + for (i = 0; i < w->levels; i++) { + struct merkle_level *tree = w->tree[i]; + + /* Initialize the I, I_next elements */ + if (i == 0) { + /* The root seed, I value is derived from the secret key */ + hss_generate_root_seed_I_value( tree->seed, tree->I, + private_key+PRIVATE_KEY_SEED ); + /* We don't use the I_next value */ + } else { + /* The seed, I is derived from the parent's values */ + + /* Where we are in the Merkle tree */ + struct merkle_level *parent = w->tree[i-1]; + merkle_index_t index = parent->current_index; + + hss_generate_child_seed_I_value( tree->seed, tree->I, + parent->seed, parent->I, + index, parent->lm_type, + parent->lm_ots_type ); + /* The next seed, I is derived from either the parent's I */ + /* or the parent's next value */ + if (index == tree->max_index) { + hss_generate_child_seed_I_value( tree->seed_next, tree->I_next, + parent->seed_next, parent->I_next, + 0, parent->lm_type, + parent->lm_ots_type); + } else { + hss_generate_child_seed_I_value( tree->seed_next, tree->I_next, + parent->seed, parent->I, + index+1, parent->lm_type, + parent->lm_ots_type); + } + } + } + + /* Generate the expanded aux data structure (or NULL if we don't have a */ + /* viable aux structure */ + struct expanded_aux_data *expanded_aux, temp_aux; + expanded_aux = hss_expand_aux_data( aux_data, len_aux_data, &temp_aux, + w->tree[0]->hash_size, w ); + + /* + * Now, build all the subtrees within the tree + * + * We initialize the various data structures, and create a list of + * the nodes on the bottom levels of the subtrees that need to be + * initialized + */ + /* There are enough structures in this array to handle the maximum */ + /* number of orders we'll ever see */ + struct init_order order[MAX_HSS_LEVELS * MAX_SUBLEVELS * NUM_SUBTREE]; + struct init_order *p_order = order; + int count_order = 0; + + /* Step through the levels, and for each Merkle tree, compile a list of */ + /* the orders to initialize the bottoms of the subtrees that we'll need */ + for (i = w->levels; i >= 1 ; i--) { + struct merkle_level *tree = w->tree[i-1]; + unsigned hash_size = tree->hash_size; + /* The current count within this tree */ + merkle_index_t tree_count = tree->current_index; + /* The index of the leaf we're on */ + merkle_index_t leaf_index = tree_count; + + /* Generate the active subtrees */ + int j; + /*int bot_level_subtree = (int)tree->level;*/ /* The level of the bottom of */ + /* the subtree */ + unsigned char *active_prev_node = 0; + unsigned char *next_prev_node = 0; + for (j=tree->sublevels-1; j>=0; j--) { + /* The height of this subtree */ + int h_subtree = (j == 0) ? tree->top_subtree_size : + tree->subtree_size; + + /* Initialize the active tree */ + struct subtree *active = tree->subtree[j][ACTIVE_TREE]; + + /* Total number of leaf nodes below this subtree */ + merkle_index_t size_subtree = (merkle_index_t)1 << + (h_subtree + active->levels_below); + /* Fill in the leaf index that's on the left side of this subtree */ + /* This is the index of the leaf that we did when we first */ + /* entered the active subtree */ + merkle_index_t left_leaf = leaf_index & ~(size_subtree - 1); + /* This is the number of leaves we've done in this subtree */ + merkle_index_t subtree_count = leaf_index - left_leaf; + /* If we're not in the bottom tree, it's possible that the */ + /* update process will miss the very first update before we */ + /* need to sign. To account for that, generate one more */ + /* node than what our current count would suggest */ + if (i != w->levels - 1) { + subtree_count++; + } + active->current_index = 0; + active->left_leaf = left_leaf; + merkle_index_t num_bottom_nodes = (merkle_index_t)1 << h_subtree; + + /* Check if we have aux data at this level */ + int already_computed_lower = 0; + if (i == 0) { + merkle_index_t lower_index = num_bottom_nodes-1; + merkle_index_t node_offset = active->left_leaf>>active->levels_below; + if (hss_extract_aux_data(expanded_aux, active->level+h_subtree, + w, &active->nodes[ hash_size * lower_index ], + node_offset, num_bottom_nodes)) { + /* We do have it precomputed in our aux data */ + already_computed_lower = 1; + } + } + /* No aux data at this level; schedule the bottom row to be computed */ + /* Schedule the creation of the entire active tree */ + p_order->tree = tree; + p_order->subtree = active; + p_order->count_nodes = (merkle_index_t)1 << h_subtree; /* All */ + /* the nodes in this subtree */ + p_order->next_tree = 0; + /* Mark the root we inherented from the subtree just below us */ + p_order->prev_node = already_computed_lower ? NULL : active_prev_node; + p_order->prev_index = (tree->current_index >> active->levels_below) & (num_bottom_nodes-1); + + p_order->already_computed_lower = already_computed_lower; + p_order++; count_order++; + + /* For the next subtree, here's where our root will be */ + active_prev_node = &active->nodes[0]; + + /* And initialize the building tree, assuming there is one, and */ + /* assuming that the active subtree isn't at the right edge of */ + /* the Merkle tree */ + if (j > 0 && (leaf_index + size_subtree <= tree->max_index )) { + struct subtree *building = tree->subtree[j][BUILDING_TREE]; + + /* The number of leaves that make up one bottom node */ + /* of this subtree */ + merkle_index_t size_below_tree = (merkle_index_t)1 << building->levels_below; + /* We need to initialize the building tree current index */ + /* to a value at least as large as subtree_count */ + /* We'd prefer not to have to specificallly initialize */ + /* the stack, and so we round up to the next place the */ + /* stack is empty */ + merkle_index_t building_count = + (subtree_count + size_below_tree - 1) & + ~(size_below_tree - 1); + /* # of bottom level nodes we've building right now */ + merkle_index_t num_nodes = building_count >> building->levels_below; + building->left_leaf = left_leaf + size_subtree; + building->current_index = building_count; + + /* Check if this is already in the aux data */ + already_computed_lower = 0; + if (i == 0) { + merkle_index_t lower_index = num_bottom_nodes-1; + merkle_index_t node_offset = building->left_leaf>>building->levels_below; + if (hss_extract_aux_data(expanded_aux, building->level+h_subtree, + w, &building->nodes[ hash_size * lower_index ], + node_offset, num_nodes)) { + /* We do have it precomputed in our aux data */ + already_computed_lower = 1; + } + } + + /* Schedule the creation of the subset of the building tree */ + p_order->tree = tree; + p_order->subtree = building; + /* # of nodes to construct */ + p_order->count_nodes = num_nodes; + p_order->next_tree = 0; + /* We generally can't use the prev_node optimization */ + p_order->prev_node = NULL; + p_order->prev_index = 0; + + p_order->already_computed_lower = already_computed_lower; + p_order++; count_order++; + } else if (j > 0) { + tree->subtree[j][BUILDING_TREE]->current_index = 0; + } + + /* And the NEXT_TREE (which is always left-aligned) */ + if ((i-1) > 0) { + struct subtree *next = tree->subtree[j][NEXT_TREE]; + next->left_leaf = 0; + merkle_index_t leaf_size = + (merkle_index_t)1 << next->levels_below; + + merkle_index_t next_index = tree_count; + /* If we're not in the bottom tree, it's possible that the */ + /* update process will miss the very first update before we */ + /* need to sign. To account for that, potetially generate */ + /* one more node than what our current count would suggest */ + if ((i-1) != w->levels - 1) { + next_index++; + } + + /* Make next_index the # of leaves we'll need to process to */ + /* forward this NEXT subtree to this state */ + next_index = (next_index + leaf_size - 1)/leaf_size; + + /* This is set if we have a previous subtree */ + merkle_index_t prev_subtree = (next->levels_below ? 1 : 0); + merkle_index_t num_nodes; + unsigned char *next_next_node = 0; + + /* If next_index == 1, then if we're on a nonbottom subtree */ + /* the previous subtree is still building (and so we */ + /* needn't do anything). The exception is if we're on the */ + /* bottom level, then there is no subtree, and so we still */ + /* need to build the initial left leaf */ + if (next_index <= prev_subtree) { + /* We're not started on this subtree yet */ + next->current_index = 0; + num_nodes = 0; + } else if (next_index < num_bottom_nodes) { + /* We're in the middle of building this tree */ + next->current_index = next_index << next->levels_below; + num_nodes = next_index; + } else { + /* We've completed building this tree */ + /* How we note "we've generated this entire subtree" */ + next->current_index = MAX_SUBINDEX; + num_nodes = num_bottom_nodes; + /* We've generated this entire tree; allow it to */ + /* be inhereited for the next one */ + next_next_node = &next->nodes[0]; + } + if (num_nodes > 0) { + /* Schedule the creation of these nodes */ + p_order->tree = tree; + p_order->subtree = next; + /* # of nodes to construct */ + p_order->count_nodes = num_nodes; + p_order->next_tree = 1; + p_order->prev_node = next_prev_node; + p_order->prev_index = 0; + + p_order->already_computed_lower = 0; + p_order++; count_order++; + } + next_prev_node = next_next_node; + } + +// bot_level_subtree -= h_subtree; + if (j == 0) break; //This is a single level tree + } + if (i == 0) break; //This is a single level tree + } + +#if DO_FLOATING_POINT + /* Fill in the cost estimates */ + for (i=0; i<(sequence_t)count_order; i++) { + p_order = &order[i]; + + /* + * While we're here, NULL out all the suborders; we'll fill them in + * later if necessary + */ + p_order->sub = 0; + if (p_order->already_computed_lower) { + /* If we pulled the data from the aux, no work required */ + p_order->cost = 0; + continue; + } + unsigned winternitz = 8; + unsigned p = 128; + (void)lm_ots_look_up_parameter_set(p_order->tree->lm_ots_type, 0, 0, + &winternitz, &p, 0); + + struct subtree *subtree = p_order->subtree; + unsigned levels_below = subtree->levels_below; + + /* + * Estimate the number of hashes that we'll need to compute to compute + * one node; this is the number of leaf nodes times the number of + * hashes used during a winternitz computation. This ignores a few + * other hashes, but gets the vast bulk of them + */ + p_order->cost = (float)((merkle_index_t)1<num_threads); + if (num_tracks == 0) num_tracks = 4; /* Divide by 0; just say no */ + float est_max_per_work_item = est_total / num_tracks; + + /* Scan through the items, and see which ones should be subdivided */ + for (i=0; i<(sequence_t)count_order; i++) { + p_order = &order[i]; + if (p_order->cost <= est_max_per_work_item) { + break; /* Break because once we hit this point, the rest of the */ + /* items will be cheaper */ + } + + /* Try to subdivide each item into subdiv pieces */ + unsigned subdiv = my_log2(p_order->cost / est_max_per_work_item); + struct subtree *subtree = p_order->subtree; + /* Make sure we don't try to subdivide lower than what the */ + /* Merkle tree structure allows */ + if (subdiv > subtree->levels_below) subdiv = subtree->levels_below; + if (subdiv == 0) continue; + merkle_index_t max_subdiv = (merkle_index_t)1 << subtree->levels_below; + if (subdiv > max_subdiv) subdiv = max_subdiv; + if (subdiv <= 1) continue; + + const struct merkle_level *tree = p_order->tree; + size_t hash_len = tree->hash_size; + merkle_index_t count_nodes = p_order->count_nodes; + size_t total_hash = (hash_len * count_nodes) << subdiv; + unsigned h_subtree = (subtree->level == 0) ? tree->top_subtree_size : + tree->subtree_size; + struct sub_order *sub = malloc( sizeof *sub + total_hash ); + if (!sub) continue; /* On malloc failure, don't bother trying */ + /* to subdivide */ + + /* Fill in the details of this suborder */ + sub->level = subdiv; + sub->num_hashes = 1 << subdiv; + sub->node_num_first_target = + (subtree->left_leaf >> subtree->levels_below) + + ((merkle_index_t)1 << (h_subtree + subtree->level)); + p_order->sub = sub; + } +#endif + + /* Now, generate all the nodes we've listed in parallel */ + struct thread_collection *col = hss_thread_init(info->num_threads); + enum hss_error_code got_error = hss_error_none; + + /* We use this to decide the granularity of the requests we make */ +#if DO_FLOATING_POINT + unsigned core_target = 5 * hss_thread_num_tracks(info->num_threads); + float prev_cost = 0; +#endif + + for (i=0; i<(sequence_t)count_order; i++) { + p_order = &order[i]; + if (p_order->already_computed_lower) continue; /* If it's already */ + /* done, we needn't bother */ + /* If this work order is cheaper than what we've issued, allow */ + /* for a greater amount of consolidation */ +#if DO_FLOATING_POINT + if (prev_cost > 0) { + if (p_order->cost <= 2 * prev_cost) { + /* The cost per node has decreased by a factor of 2 (at */ + /* least); allow a single core to do more of the work */ + float ratio = prev_cost / p_order->cost; + if (ratio > 1000) { + core_target = 1; + } else { + core_target = core_target / ratio; + if (core_target == 0) core_target = 1; + } + prev_cost = p_order->cost; + } + } else { + prev_cost = p_order->cost; + } +#endif + + const struct merkle_level *tree = p_order->tree; + struct subtree *subtree = p_order->subtree; + unsigned h_subtree = (subtree->level == 0) ? tree->top_subtree_size : + tree->subtree_size; + merkle_index_t lower_index = ((merkle_index_t)1 << h_subtree) - 1; + unsigned hash_size = tree->hash_size; +#if DO_FLOATING_POINT + unsigned max_per_request = p_order->count_nodes / core_target; + if (max_per_request == 0) max_per_request = 1; +#else + unsigned max_per_request = UINT_MAX; +#endif + + /* If we're skipping a value, make sure we compute up to there */ + merkle_index_t right_side = p_order->count_nodes; + if (p_order->prev_node && right_side > p_order->prev_index) { + right_side = p_order->prev_index; + } + + merkle_index_t n; + struct intermed_tree_detail detail; + + detail.seed = (p_order->next_tree ? tree->seed_next : tree->seed); + detail.lm_type = tree->lm_type; + detail.lm_ots_type = tree->lm_ots_type; + detail.h = tree->h; + detail.tree_height = tree->level; + detail.I = (p_order->next_tree ? tree->I_next : tree->I); + detail.got_error = &got_error; + +#if DO_FLOATING_POINT + /* Check if we're actually doing a suborder */ + struct sub_order *sub = p_order->sub; + if (sub) { + /* Issue all the orders separately */ + unsigned hash_len = tree->hash_size; + for (n = 0; n < p_order->count_nodes; n++ ) { + if (n == right_side) continue; /* Skip the omitted value */ + unsigned char *dest = &sub->h[ n * sub->num_hashes * hash_len ]; + merkle_index_t node_num = (sub->node_num_first_target+n) << sub->level; + unsigned k; + for (k=0; k < sub->num_hashes; k++) { + detail.dest = dest; + dest += hash_len; + detail.node_num = node_num; + node_num++; + detail.node_count = 1; + + hss_thread_issue_work(col, hss_gen_intermediate_tree, + &detail, sizeof detail ); + } + } + continue; + } +#endif + { + /* We're not doing a suborder; issue the request in as large of */ + /* a chunk as we're allowed */ + for (n = 0; n < p_order->count_nodes; ) { + merkle_index_t this_req = right_side - n; + if (this_req > max_per_request) this_req = max_per_request; + if (this_req == 0) { + /* We hit the value we're skipping; skip it, and go on to */ + /* the real right side */ + n++; + right_side = p_order->count_nodes; + continue; + } + + /* Issue a work order for the next this_req elements */ + detail.dest = &subtree->nodes[ hash_size * (lower_index + n)]; + detail.node_num = (subtree->left_leaf >> subtree->levels_below) + + n + ((merkle_index_t)1 << (h_subtree + subtree->level)); + detail.node_count = this_req; + + hss_thread_issue_work(col, hss_gen_intermediate_tree, + &detail, sizeof detail ); + + n += this_req; + } + } + } + + /* We've issued all the order; now wait until all the work is done */ + hss_thread_done(col); + if (got_error != hss_error_none) { + /* One of the worker threads detected an error */ +#if DO_FLOATING_POINT + /* Don't leak suborders on an intermediate error */ + for (i=0; i<(sequence_t)count_order; i++) { + free( order[i].sub ); // IGNORE free-check + } +#endif + info->error_code = got_error; + goto failed; + } + +#if DO_FLOATING_POINT + /* + * Now, if we did have suborders, recombine them into what was actually + * wanted + */ + for (i=0; i<(sequence_t)count_order; i++) { + p_order = &order[i]; + struct sub_order *sub = p_order->sub; + if (!sub) continue; /* This order wasn't subdivided */ + + const struct merkle_level *tree = p_order->tree; + const unsigned char *I = (p_order->next_tree ? tree->I_next : tree->I); + struct subtree *subtree = p_order->subtree; + unsigned hash_size = tree->hash_size; + unsigned h_subtree = (subtree->level == 0) ? tree->top_subtree_size : + tree->subtree_size; + merkle_index_t lower_index = ((merkle_index_t)1 << h_subtree) - 1; + + merkle_index_t n; + for (n = 0; n < p_order->count_nodes; n++ ) { + if (p_order->prev_node && n == p_order->prev_index) continue; + + hash_subtree( &subtree->nodes[ hash_size * (lower_index + n)], + &sub->h[ hash_size * sub->num_hashes * n ], + sub->level, sub->node_num_first_target + n, + hash_size, tree->h, I); + } + + free( sub ); // IGNORE free-check + p_order->sub = 0; + } +#endif + + /* + * Now we have generated the lower level nodes of the subtrees; go back and + * fill in the higher level nodes. + * We do this in backwards order, so that we do the lower levels of the trees + * first (as lower levels are cheaper, they'll be listed later in the + * array; that's how we sorted, them, remember?). + * That means if any subtrees inherit the root values of lower trees, + * we compute those root values first + */ + for (i=count_order; i>0; i--) { + p_order = &order[i-1]; + const struct merkle_level *tree = p_order->tree; + const unsigned char *I = (p_order->next_tree ? tree->I_next : tree->I); + struct subtree *subtree = p_order->subtree; + + if (p_order->prev_node) { + /* This subtree did have a bottom node that was the root node */ + /* of a lower subtree; fill it in */ + unsigned hash_size = tree->hash_size; + unsigned h_subtree = (subtree->level == 0) ? tree->top_subtree_size : + tree->subtree_size; + merkle_index_t lower_index = ((merkle_index_t)1 << h_subtree) - 1; + + /* Where in the subtree we place the previous root */ + unsigned set_index = (lower_index + p_order->prev_index) * hash_size; + memcpy( &subtree->nodes[ set_index ], p_order->prev_node, hash_size ); + } + + /* Now, fill in all the internal nodes of the subtree */ + fill_subtree(tree, subtree, p_order->count_nodes, I); + } + + /* + * Hey; we've initialized all the subtrees (at least, as far as what + * they'd be expected to be given the current count); hurray! + */ + + /* + * Now, create all the signed public keys + * Again, we could parallelize this; it's also fast enough not to be worth + * the complexity + */ + for (i = 1; i < w->levels; i++) { + if (!hss_create_signed_public_key( w->signed_pk[i], w->siglen[i-1], + w->tree[i], w->tree[i-1], w )) { + info->error_code = hss_error_internal; /* Really shouldn't */ + /* happen */ + goto failed; + } + } + hss_zeroize( private_key, sizeof private_key ); + + /* + * And, we make each level as not needing an update from below (as we've + * initialized them as already having the first update) + */ + for (i = 0; i < w->levels - 1; i++) { + w->tree[i]->update_count = UPDATE_DONE; + } + + w->status = hss_error_none; /* This working key has been officially */ + /* initialized, and now can be used */ + return true; + +failed: + hss_zeroize( private_key, sizeof private_key ); + return false; +} + +#if DO_FLOATING_POINT +/* + * This goes through the order, and estimates the total amount + * This assumes that the highest cost element is listed first + * + * It returns the estimated number of hash compression operations total + * + * We use floating point because the number of hash compression functions can + * vary a *lot*; floating point has great dynamic range. + */ +static float estimate_total_cost( struct init_order *order, + unsigned count_order ) { + if (count_order == 0) return 0; + float total_cost = 0; + + unsigned i; + + for (i=0; i +#include "common_defs.h" +#include "hss.h" +#include "config.h" + +/* + * This is the central internal include file for the functions that make up + * this subsystem. It should not be used by applications + */ + +#define PARAM_SET_COMPRESS_LEN 1 /* We assume that we can compress the */ + /* lm_type and the lm_ots type for a */ + /* single level into 1 byte */ + +#define PARM_SET_END 0xff /* We set this marker in the parameter set */ + /* when fewer than the maximum levels are used */ + + +/* + * The internal structure of a private key + */ +#define PRIVATE_KEY_INDEX 0 +#define PRIVATE_KEY_INDEX_LEN 8 /* 2**64 signatures should be enough for */ + /* everyone */ +#define PRIVATE_KEY_PARAM_SET (PRIVATE_KEY_INDEX + PRIVATE_KEY_INDEX_LEN) +#define PRIVATE_KEY_PARAM_SET_LEN (PARAM_SET_COMPRESS_LEN * MAX_HSS_LEVELS) +#define PRIVATE_KEY_SEED (PRIVATE_KEY_PARAM_SET + PRIVATE_KEY_PARAM_SET_LEN) +#if SECRET_METHOD == 2 +#define PRIVATE_KEY_SEED_LEN (SEED_LEN + I_LEN) +#else +#define PRIVATE_KEY_SEED_LEN SEED_LEN +#endif +#define PRIVATE_KEY_LEN (PRIVATE_KEY_SEED + PRIVATE_KEY_SEED_LEN) /* That's */ + /* 48 bytes */ + +struct merkle_level; +struct hss_working_key { + unsigned levels; + enum hss_error_code status; /* What is the status of this key */ + /* hss_error_none if everything looks ok */ + /* Otherwise, the error code we report if */ + /* we try to use this key to sign */ + sequence_t reserve_count; /* The value written to the private key */ + /* Will be higher than the 'current count' */ + /* if some signaures are 'reserved' */ + sequence_t max_count; /* The maximum count we can ever have */ + unsigned autoreserve; /* How many signatures to attempt to */ + /* reserve if the signing process hits */ + /* the end of the current reservation */ + + size_t signature_len; /* The length of the HSS signature */ + + unsigned char *stack; /* The stack memory used by the subtrees */ + + /* The private key (in its entirety) */ + unsigned char private_key[PRIVATE_KEY_LEN]; + /* The pointer to the seed (contained within the private key) */ + /* Warning: nonsyntaxic macro; need to be careful how we use this */ +#define working_key_seed private_key + PRIVATE_KEY_SEED + + size_t siglen[MAX_HSS_LEVELS]; /* The lengths of the signatures */ + /* generated by the various levels */ + size_t signed_pk_len[MAX_HSS_LEVELS]; /* The lengths of the signed */ + /* public keys for the various levels */ + unsigned char *signed_pk[MAX_HSS_LEVELS]; /* The current signed public */ + /* keys for the nontop levels */ + /* Each array element is that level's */ + /* current root value, signed by the */ + /* previous level. Unused for the */ + /* topmost level */ + struct merkle_level *tree[MAX_HSS_LEVELS]; /* The structures that manage */ + /* each individual level */ +}; + +#define MIN_SUBTREE 2 /* All subtrees (other than the root subtree) have */ + /* at least 2 levels */ +#define MAX_SUBLEVELS ((MAX_MERKLE_HEIGHT + MIN_SUBTREE - 1) / MIN_SUBTREE) +#if MAX_SUBLEVELS > (1 << (MIN_MERKLE_HEIGHT-1)) - 2 +#error We need to rethink our parent tree update logic, as there is a +#error possibility we do not give the tree enough updates between signatures +/* One possible fix would be to increase the subtree size for extremely */ +/* tall trees */ +#endif + +struct merkle_level { + unsigned level; /* Total number of levels */ + unsigned h, hash_size; /* Hash function, width */ + param_set_t lm_type; + param_set_t lm_ots_type; /* OTS parameter */ + merkle_index_t current_index; /* The number of signatures this tree has */ + /* generated so far */ + merkle_index_t max_index; /* 1<levels) */ + unsigned level; /* The level that the root of this subtree */ + /* is within the larger Merkle tree */ + unsigned levels_below; /* The number of levels below this subtree */ + /* in the Merkle tree */ + unsigned char *stack; /* Pointer to the stack used when */ + /* generating nodes; will be a pointer */ + /* into the hss_working_key::stack array */ + /* Used to incrementally compute bottom */ + /* node values */ + unsigned char nodes[1]; /* The actual subtree node values */ + /* 2*(1< +#include +#include "common_defs.h" +#include "hss.h" +#include "hss_internal.h" +#include "hss_aux.h" +#include "endian.h" +#include "hash.h" +#include "hss_thread.h" +#include "lm_common.h" +#include "lm_ots_common.h" + +/* Count the number of 1 bits at the end (lsbits) of the integer */ +/* Do it in the obvious way; straightline code may be faster (no */ +/* unpredictable jumps, which are costly), but that would be less scrutable */ +static int trailing_1_bits(merkle_index_t n) { + int i; + for (i=0; n&1; n>>=1, i++) + ; + return i; +} + +/* + * This creates a private key (and the correspond public key, and optionally + * the aux data for that key) + * Parameters: + * generate_random - the function to be called to generate randomness. This + * is assumed to be a pointer to a cryptographically secure rng, + * otherwise all security is lost. This function is expected to fill + * output with 'length' uniformly distributed bits, and return 1 on + * success, 0 if something went wrong + * levels - the number of levels for the key pair (2-8) + * lm_type - an array of the LM registry entries for the various levels; + * entry 0 is the topmost + * lm_ots_type - an array of the LM-OTS registry entries for the various + * levels; again, entry 0 is the topmost + * update_private_key, context - the function that is called when the + * private key is generated; it is expected to store it to secure NVRAM + * If this is NULL, then the context pointer is reinterpretted to mean + * where in RAM the private key is expected to be placed + * public_key - where to store the public key + * len_public_key - length of the above buffer; see hss_get_public_key_len + * if you need a hint. + * aux_data - where to store the optional aux data. This is not required, but + * if provided, can be used to speed up the hss_generate_working_key + * process; + * len_aux_data - the length of the above buffer. This is not fixed length; + * the function will run different time/memory trade-offs based on the + * length provided + * + * This returns true on success, false on failure + */ +bool hss_generate_private_key( + bool (*generate_random)(void *output, size_t length), + unsigned levels, + const param_set_t *lm_type, + const param_set_t *lm_ots_type, + bool (*update_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + unsigned char *public_key, size_t len_public_key, + unsigned char *aux_data, size_t len_aux_data, + struct hss_extra_info *info) { + + struct hss_extra_info info_temp = { 0 }; + if (!info) info = &info_temp; + + if (!generate_random) { + /* We *really* need random numbers */ + info->error_code = hss_error_no_randomness; + return false; + } + if (levels < MIN_HSS_LEVELS || levels > MAX_HSS_LEVELS) { + /* parameter out of range */ + info->error_code = hss_error_bad_param_set; + return false; + } + + unsigned h0; /* The height of the root tree */ + unsigned h; /* The hash function used */ + unsigned size_hash; /* The size of each hash that would appear in the */ + /* aux data */ + if (!lm_look_up_parameter_set(lm_type[0], &h, &size_hash, &h0)) { + info->error_code = hss_error_bad_param_set; + return false; + } + + /* Check the public_key_len */ + if (4 + 4 + 4 + I_LEN + size_hash > len_public_key) { + info->error_code = hss_error_buffer_overflow; + /* public key won't fit in the buffer we're given */ + return false; + } + + /* If you provide an aux_data buffer, we have to write something */ + /* into it (at least, enough to mark it as 'we're not really using */ + /* aux data) */ + if (aux_data && len_aux_data == 0) { + /* not enough aux data buffer to mark it as 'not really used' */ + info->error_code = hss_error_bad_aux; + return false; + } + + unsigned len_ots_pub = lm_ots_get_public_key_len(lm_ots_type[0]); + if (len_ots_pub == 0) { + info->error_code = hss_error_bad_param_set; + return false; + } + + unsigned char private_key[ PRIVATE_KEY_LEN ]; + + /* First step: format the private key */ + put_bigendian( private_key + PRIVATE_KEY_INDEX, 0, + PRIVATE_KEY_INDEX_LEN ); + if (!hss_compress_param_set( private_key + PRIVATE_KEY_PARAM_SET, + levels, lm_type, lm_ots_type, + PRIVATE_KEY_PARAM_SET_LEN )) { + info->error_code = hss_error_bad_param_set; + return false; + } + if (!(*generate_random)( private_key + PRIVATE_KEY_SEED, + PRIVATE_KEY_SEED_LEN )) { + info->error_code = hss_error_bad_randomness; + return false; + } + + /* Now make sure that the private key is written to NVRAM */ + if (update_private_key) { + if (!(*update_private_key)( private_key, PRIVATE_KEY_LEN, context)) { + /* initial write of private key didn't take */ + info->error_code = hss_error_private_key_write_failed; + hss_zeroize( private_key, sizeof private_key ); + return false; + } + } else { + if (context == 0) { + /* We weren't given anywhere to place the private key */ + info->error_code = hss_error_no_private_buffer; + hss_zeroize( private_key, sizeof private_key ); + return false; + } + memcpy( context, private_key, PRIVATE_KEY_LEN ); + } + + /* Figure out what would be the best trade-off for the aux level */ + struct expanded_aux_data *expanded_aux_data = 0, aux_data_storage; + if (aux_data != NULL) { + aux_level_t aux_level = hss_optimal_aux_level( len_aux_data, lm_type, + lm_ots_type, NULL ); + hss_store_aux_marker( aux_data, aux_level ); + + /* Set up the aux data pointers */ + expanded_aux_data = hss_expand_aux_data( aux_data, len_aux_data, + &aux_data_storage, size_hash, 0 ); + } + + unsigned char I[I_LEN]; + unsigned char seed[SEED_LEN]; + if (!hss_generate_root_seed_I_value( seed, I, private_key+PRIVATE_KEY_SEED)) { + info->error_code = hss_error_internal; + hss_zeroize( private_key, sizeof private_key ); + return false; + } + + /* Now, it's time to generate the public key, which means we need to */ + /* compute the entire top level Merkle tree */ + + /* First of all, figure out the appropriate level to compute up to */ + /* in parallel. We'll do the lower of the bottom-most level that */ + /* appears in the aux data, and 4*log2 of the number of core we have */ + unsigned num_cores = hss_thread_num_tracks(info->num_threads); + unsigned level; + unsigned char *dest = 0; /* The area we actually write to */ + void *temp_buffer = 0; /* The buffer we need to free when done */ + for (level = h0-1; level > 2; level--) { + /* If our bottom-most aux data is at this level, we want it */ + if (expanded_aux_data && expanded_aux_data->data[level]) { + /* Write directly into the aux area */ + dest = expanded_aux_data->data[level]; + break; + } + + /* If going to a higher levels would mean that we wouldn't */ + /* effectively use all the cores we have, use this level */ + if (((unsigned)1<num_threads); + + struct intermed_tree_detail details; + /* Set the values in the details structure that are constant */ + details.seed = seed; + details.lm_type = lm_type[0]; + details.lm_ots_type = lm_ots_type[0]; + details.h = h; + details.tree_height = h0; + details.I = I; + enum hss_error_code got_error = hss_error_none; /* This flag is set */ + /* on an error */ + details.got_error = &got_error; + + merkle_index_t j; + /* # of nodes at this level */ + merkle_index_t level_nodes = (merkle_index_t)1 << level; + /* the index of the node we're generating right now */ + merkle_index_t node_num = level_nodes; + /* + * We'd prefer not to issue a separate work item for every node; we + * might be doing millions of node (if we have a large aux data space) + * and we end up malloc'ing a large structure for every work order. + * So, if we do have a large number of requires, aggregate them + */ + merkle_index_t increment = level_nodes / (10 * num_cores); +#define MAX_INCREMENT 20000 + if (increment > MAX_INCREMENT) increment = MAX_INCREMENT; + if (increment == 0) increment = 1; + for (j=0; j < level_nodes; ) { + unsigned this_increment; + if (level_nodes - j < increment) { + this_increment = level_nodes - j; + } else { + this_increment = increment; + } + + /* Set the particulars of this specific work item */ + details.dest = dest + j*size_hash; + details.node_num = node_num; + details.node_count = this_increment; + + /* Issue a separate work request for every node at this level */ + hss_thread_issue_work(col, hss_gen_intermediate_tree, + &details, sizeof details ); + + j += this_increment; + node_num += this_increment; + } + /* Now wait for all those work items to complete */ + hss_thread_done(col); + + hss_zeroize( seed, sizeof seed ); + + /* Check if something went wrong. It really shouldn't have, however if */ + /* something returns an error code, we really should try to handle it */ + if (got_error != hss_error_none) { + /* We failed; give up */ + info->error_code = got_error; + hss_zeroize( private_key, sizeof private_key ); + if (update_private_key) { + (void)(*update_private_key)(private_key, PRIVATE_KEY_LEN, context); + } else { + hss_zeroize( context, PRIVATE_KEY_LEN ); + } + free(temp_buffer); // IGNORE free-check + return false; + } + + /* Now, we complete the rest of the tree. This is actually fairly fast */ + /* (one hash per node) so we don't bother to parallelize it */ + + unsigned char stack[ MAX_HASH * (MAX_MERKLE_HEIGHT+1) ]; + unsigned char root_hash[ MAX_HASH ]; + + /* Generate the top levels of the tree, ending with the root node */ + merkle_index_t r, leaf_node; + for (r=level_nodes, leaf_node = 0; leaf_node < level_nodes; r++, leaf_node++) { + + /* Walk up the stack, combining the current node with what's on */ + /* the atack */ + merkle_index_t q = leaf_node; + + /* + * For the subtree which this leaf node forms the final piece, put the + * destination to where we'll want it, either on the stack, or if this + * is the final piece, to where the caller specified + */ + unsigned char *current_buf; + unsigned stack_offset = trailing_1_bits( leaf_node ); + if (stack_offset == level) { + current_buf = root_hash; + } else { + current_buf = &stack[stack_offset * size_hash ]; + } + memcpy( current_buf, dest + leaf_node * size_hash, size_hash ); + + unsigned sp; + unsigned cur_lev = level; + for (sp = 1;; sp++, cur_lev--, q >>= 1) { + /* Give the aux data routines a chance to save the */ + /* intermediate value. Note that we needn't check for the */ + /* bottommost level; if we're saving aux data at that level, */ + /* we've already placed it there */ + if (sp > 1) { + hss_save_aux_data( expanded_aux_data, cur_lev, + size_hash, q, current_buf ); + } + + if (sp > stack_offset) break; + + + hss_combine_internal_nodes( current_buf, + &stack[(sp-1) * size_hash], current_buf, + h, I, size_hash, + r >> sp ); + } + } + /* The top entry in the stack is the root value (aka the public key) */ + + /* Complete the computation of the aux data */ + hss_finalize_aux_data( expanded_aux_data, size_hash, h, + private_key+PRIVATE_KEY_SEED ); + + /* We have the root value; now format the public key */ + put_bigendian( public_key, levels, 4 ); + public_key += 4; len_public_key -= 4; + put_bigendian( public_key, lm_type[0], 4 ); + public_key += 4; len_public_key -= 4; + put_bigendian( public_key, lm_ots_type[0], 4 ); + public_key += 4; len_public_key -= 4; + memcpy( public_key, I, I_LEN ); + public_key += I_LEN; len_public_key -= I_LEN; + memcpy( public_key, root_hash, size_hash ); + public_key += size_hash; len_public_key -= size_hash; + + /* Hey, what do you know -- it all worked! */ + hss_zeroize( private_key, sizeof private_key ); /* Zeroize local copy of */ + /* the private key */ + free(temp_buffer); // IGNORE free-check + return true; +} + +/* + * The length of the private key + */ +size_t hss_get_private_key_len(unsigned levels, + const param_set_t *lm_type, + const param_set_t *lm_ots_type) { + /* A private key is a 'public object'? Yes, in the sense that we */ + /* export it outside this module */ + LMS_UNUSED(levels); + LMS_UNUSED(lm_type); + LMS_UNUSED(lm_ots_type); + return PRIVATE_KEY_LEN; +} diff --git a/src/sig_stfl/lms/external/hss_param.c b/src/sig_stfl/lms/external/hss_param.c new file mode 100644 index 0000000000..a1c20ab14c --- /dev/null +++ b/src/sig_stfl/lms/external/hss_param.c @@ -0,0 +1,153 @@ +#include +#include "hss.h" +#include "hss_internal.h" +#include "endian.h" +#include "hss_zeroize.h" + +/* + * Convert a parameter set into the compressed version we use within a private + * key. This is the private key that'll end up being updated constantly, and + * so we try to make it as small as possible + */ +bool hss_compress_param_set( unsigned char *compressed, + int levels, + const param_set_t *lm_type, + const param_set_t *lm_ots_type, + size_t len_compressed ) { + int i; + + for (i=0; i 0x0e || b > 0x0e) return false; + /* Make sure the parm sets are supported */ + switch (a) { + case LMS_SHA256_N32_H5: case LMS_SHA256_N32_H10: + case LMS_SHA256_N32_H15: case LMS_SHA256_N32_H20: + case LMS_SHA256_N32_H25: + break; + default: + return false; + } + switch (b) { + case LMOTS_SHA256_N32_W1: case LMOTS_SHA256_N32_W2: + case LMOTS_SHA256_N32_W4: case LMOTS_SHA256_N32_W8: + break; + default: + return false; + } + + *compressed++ = (a<<4) + b; + len_compressed--; + } + + while (len_compressed) { + *compressed++ = PARM_SET_END; + len_compressed--; + } + + return true; +} + +/* + * This returns the parameter set for a given private key. + * This is here to solve a chicken-and-egg problem: the hss_working_key + * must be initialized to the same parameter set as the private key, + * but (other than this function, or somehow remembering it) there's + * no way to retreive the parameter set. + * + * read_private_key/context will read the private key (if read_private_key is + * NULL, context is assumed to point to the private key) + * + * On success, *levels will be set to the number of levels, and lm_type[] + * and lm_ots_type[] will be set to the lm/ots parameter sets + * + * On success, this returns true; on failure (can't read the private key, or + * the private key is invalid), returns false + */ +bool hss_get_parameter_set( unsigned *levels, + param_set_t lm_type[ MAX_HSS_LEVELS ], + param_set_t lm_ots_type[ MAX_HSS_LEVELS ], + bool (*read_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context) { + unsigned char private_key[ PRIVATE_KEY_LEN ]; + bool success = false; + + if (read_private_key) { + if (!read_private_key( private_key, PRIVATE_KEY_SEED, context )) { + goto failed; + } + } else { + if (!context) return false; + memcpy( private_key, context, PRIVATE_KEY_SEED ); + } + + /* Scan through the private key to recover the parameter sets */ + unsigned total_height = 0; + unsigned level; + for (level=0; level < MAX_HSS_LEVELS; level++) { + unsigned char c = private_key[PRIVATE_KEY_PARAM_SET + level]; + if (c == PARM_SET_END) break; + /* Decode this level's parameter set */ + param_set_t lm = (c >> 4); + param_set_t ots = (c & 0x0f); + /* Make sure both are supported */ + /* While we're here, add up the total Merkle height */ + switch (lm) { + case LMS_SHA256_N32_H5: total_height += 5; break; + case LMS_SHA256_N32_H10: total_height += 10; break; + case LMS_SHA256_N32_H15: total_height += 15; break; + case LMS_SHA256_N32_H20: total_height += 20; break; + case LMS_SHA256_N32_H25: total_height += 25; break; + default: goto failed; + } + switch (ots) { + case LMOTS_SHA256_N32_W1: + case LMOTS_SHA256_N32_W2: + case LMOTS_SHA256_N32_W4: + case LMOTS_SHA256_N32_W8: + break; + default: goto failed; + } + lm_type[level] = lm; + lm_ots_type[level] = ots; + } + + if (level < MIN_HSS_LEVELS || level > MAX_HSS_LEVELS) goto failed; + + *levels = level; + + /* Make sure that the rest of the private key has PARM_SET_END */ + unsigned i; + for (i = level+1; i 64) total_height = 64; /* (bounded by 2**64) */ + sequence_t max_count = ((sequence_t)2 << (total_height-1)) - 1; + /* height-1 so we don't try to shift by 64, and hit U.B. */ + + /* We use the count 0xffff..ffff to signify 'we've used up all our */ + /* signatures'. Make sure that is above max_count, even for */ + /* parameter sets that can literally generate 2**64 signatures (by */ + /* letting them generate only 2**64-1) */ + if (total_height == 64) max_count--; + sequence_t current_count = get_bigendian( + private_key + PRIVATE_KEY_INDEX, PRIVATE_KEY_INDEX_LEN ); + + if (current_count > max_count) goto failed; /* Private key expired */ + + success = true; /* It worked! */ +failed: + /* There might be private keying material here */ + hss_zeroize( private_key, sizeof private_key ); + return success; +} diff --git a/src/sig_stfl/lms/external/hss_reserve.c b/src/sig_stfl/lms/external/hss_reserve.c new file mode 100644 index 0000000000..7ef8585560 --- /dev/null +++ b/src/sig_stfl/lms/external/hss_reserve.c @@ -0,0 +1,194 @@ +#include +#include "common_defs.h" +#include "hss_internal.h" +#include "hss_reserve.h" +#include "endian.h" + +/* + * Initialize the reservation count to the given value + */ +void hss_set_reserve_count(struct hss_working_key *w, sequence_t count) { + w->reserve_count = count; +} + +/* + * Set the autoreserve count + */ +bool hss_set_autoreserve(struct hss_working_key *w, + unsigned sigs_to_autoreserve, struct hss_extra_info *info) { + if (!w) { + if (info) info->error_code = hss_error_got_null; + return false; + } + + /* Note: we do not check if the working key is in a usable state */ + /* There are a couple of odd-ball scenarios (e.g. when they've */ + /* manually allocated the key, but haven't loaded it yet) that we */ + /* don't have a good reason to disallow */ + + w->autoreserve = sigs_to_autoreserve; + return true; +} + +/* + * This is called when we generate a signature; it checks if we need + * to write out a new private key (and advance the reservation); if it + * decides it needs to write out a new private key, it also decides how + * far it needs to advance it + */ +bool hss_advance_count(struct hss_working_key *w, sequence_t cur_count, + bool (*update_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + struct hss_extra_info *info, bool *trash_private_key) { + + if (cur_count == w->max_count) { + /* We hit the end of the root; this will be the last signature */ + /* this private key can do */ + w->status = hss_error_private_key_expired; /* Fail if they try to */ + /* sign any more */ + info->last_signature = true; + /* Make sure we zeroize the private key */ + *trash_private_key = true; /* We can't trash our copy of the */ + /* private key until after we've generated the signature */ + /* We can trash the copy in secure storage, though */ + if (update_private_key) { + unsigned char private_key[PRIVATE_KEY_LEN]; + memset( private_key, PARM_SET_END, PRIVATE_KEY_LEN ); + if (!update_private_key(private_key, PRIVATE_KEY_LEN, context)) { + info->error_code = hss_error_private_key_write_failed; + return false; + } + } else { + memset( context, PARM_SET_END, PRIVATE_KEY_LEN ); + } + return true; + } + sequence_t new_count = cur_count + 1; + + if (new_count > w->reserve_count) { + /* We need to advance the reservation */ + + /* Check if we have enough space to do the entire autoreservation */ + if (w->max_count - new_count > w->autoreserve) { + new_count += w->autoreserve; + } else { + /* If we don't have enough space, reserve what we can */ + new_count = w->max_count; + } + + put_bigendian( w->private_key + PRIVATE_KEY_INDEX, new_count, + PRIVATE_KEY_INDEX_LEN ); + if (update_private_key) { + if (!update_private_key(w->private_key, PRIVATE_KEY_INDEX_LEN, + context)) { + /* Oops, we couldn't write the private key; undo the */ + /* reservation advance (and return an error) */ + info->error_code = hss_error_private_key_write_failed; + put_bigendian( w->private_key + PRIVATE_KEY_INDEX, + w->reserve_count, PRIVATE_KEY_INDEX_LEN ); + return false; + } + } else { + put_bigendian( context, new_count, PRIVATE_KEY_INDEX_LEN ); + } + w->reserve_count = new_count; + } + + return true; +} + +/* + * This will make sure that (at least) N signatures are reserved; that is, we + * won't need to actually call the update function for the next N signatures + * generated + * + * This can be useful if the update_private_key function is expensive. + * + * Note that if, N (or more) signatures are already reserved, this won't do + * anything. + */ +bool hss_reserve_signature( + struct hss_working_key *w, + bool (*update_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + unsigned sigs_to_reserve, + struct hss_extra_info *info) { + struct hss_extra_info temp_info = { 0 }; + if (!info) info = &temp_info; + if (!w) { + info->error_code = hss_error_got_null; + return false; + } + if (w->status != hss_error_none) { + info->error_code = w->status;; + return false; + } + + if (sigs_to_reserve > w->max_count) { + info->error_code = hss_error_not_that_many_sigs_left; + return false; /* Very funny */ + } + + /* + * If we're given a raw private key, make sure it's the one we're + * thinking of. + * I have no idea why someone would reserve signatures if they have + * a raw private key (which is cheap to update), however there's no + * reason we shouldn't support it + */ + if (!update_private_key) { + if (0 != memcmp( context, w->private_key, PRIVATE_KEY_LEN)) { + info->error_code = hss_error_key_mismatch; + return false; /* Private key mismatch */ + } + } + + /* Figure out what the current count is */ + sequence_t current_count = 0; + unsigned i; + for (i = 0; ilevels; i++) { + struct merkle_level *tree = w->tree[i]; + /* -1 because the current_index counts the signatures to the */ + /* current next level */ + current_count = (current_count << tree->level) + + tree->current_index - 1; + } + current_count += 1; /* The bottom-most tree isn't advanced */ + + sequence_t new_reserve_count; /* This is what the new reservation */ + /* setting would be (if we accept the reservation) */ + if (current_count > w->max_count - sigs_to_reserve) { + /* Not that many sigantures left */ + /* Reserve as many as we can */ + new_reserve_count = w->max_count; + } else { + new_reserve_count = current_count + sigs_to_reserve; + } + + if (new_reserve_count <= w->reserve_count) { + /* We already have (at least) that many reserved; do nothing */ + return true; + } + + /* Attempt to update the count in the private key */ + put_bigendian( w->private_key + PRIVATE_KEY_INDEX, new_reserve_count, + PRIVATE_KEY_INDEX_LEN ); + /* Update the copy in NV storage */ + if (update_private_key) { + if (!update_private_key(w->private_key, PRIVATE_KEY_INDEX_LEN, + context)) { + /* Oops, couldn't update it */ + put_bigendian( w->private_key + PRIVATE_KEY_INDEX, + w->reserve_count, PRIVATE_KEY_INDEX_LEN ); + info->error_code = hss_error_private_key_write_failed; + return false; + } + } else { + memcpy( context, w->private_key, PRIVATE_KEY_INDEX_LEN ); + } + w->reserve_count = new_reserve_count; + + return true; +} diff --git a/src/sig_stfl/lms/external/hss_reserve.h b/src/sig_stfl/lms/external/hss_reserve.h new file mode 100644 index 0000000000..3b101c1130 --- /dev/null +++ b/src/sig_stfl/lms/external/hss_reserve.h @@ -0,0 +1,21 @@ +#if !defined( HSS_RESERVE_H_ ) +#define HSS_RESERVE_H_ + +/* + * This is the internal include file for the reservation functions for this + * subsystem. It should not be used by applications + */ + +#include "common_defs.h" + +struct hss_working_key; + +void hss_set_reserve_count(struct hss_working_key *w, sequence_t count); + +bool hss_advance_count(struct hss_working_key *w, sequence_t new_count, + bool (*update_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + struct hss_extra_info *info, bool *trash_private_key); + +#endif /* HSS_RESERVE_H_ */ diff --git a/src/sig_stfl/lms/external/hss_sign.c b/src/sig_stfl/lms/external/hss_sign.c new file mode 100644 index 0000000000..359e59df7b --- /dev/null +++ b/src/sig_stfl/lms/external/hss_sign.c @@ -0,0 +1,736 @@ +/* + * This is an implementation of the HSS signature scheme from LMS + * This is the part that actually generates the signature + */ +#include +#include +#include "common_defs.h" +#include "hss.h" +#include "hash.h" +#include "endian.h" +#include "hss_internal.h" +#include "hss_aux.h" +#include "hss_thread.h" +#include "hss_reserve.h" +#include "lm_ots.h" +#include "lm_ots_common.h" +#include "hss_derive.h" + +/* + * This adds one leaf to the building and next subtree. + */ +enum subtree_build_status { + subtree_got_error, /* Oops, something broke */ + subtree_more_to_do, /* Processed node, still more to do */ + subtree_did_last_node, /* Processed last node */ + subtree_all_done /* We're good */ +}; +static enum subtree_build_status subtree_add_next_node( + struct subtree *subtree, + struct merkle_level *tree, + int next_tree, + struct thread_collection *col) { + unsigned subtree_size = (subtree->level>0 ? tree->subtree_size : + tree->top_subtree_size); + unsigned log_leafs = subtree_size + subtree->levels_below; + merkle_index_t max_index = (merkle_index_t)1 << log_leafs; + /* Check if there is anything more to do */ + if (subtree->current_index == max_index) return subtree_all_done; + unsigned hash_size = tree->hash_size; + unsigned char cur_val[MAX_HASH]; + + /* Compute the leaf node */ + merkle_index_t i; + unsigned ots_len = lm_ots_get_public_key_len(tree->lm_ots_type); + unsigned char pub_key[ LEAF_MAX_LEN ]; + const unsigned char *I = (next_tree ? tree->I_next : tree->I); + memcpy( pub_key + LEAF_I, I, I_LEN ); + SET_D( pub_key + LEAF_D, D_LEAF ); + merkle_index_t r = subtree->left_leaf + subtree->current_index; + merkle_index_t q = r | ((merkle_index_t)1 << tree->level); + put_bigendian( pub_key + LEAF_R, q, 4); + + const unsigned char *seed = (next_tree ? tree->seed_next : tree->seed); + struct seed_derive derive; + if (!hss_seed_derive_init( &derive, tree->lm_type, tree->lm_ots_type, + I, seed )) return subtree_got_error; + hss_seed_derive_set_q(&derive, r); + if (!lm_ots_generate_public_key(tree->lm_ots_type, I, + r, &derive, pub_key + LEAF_PK, ots_len)) { + hss_seed_derive_done(&derive); + return subtree_got_error; + } + hss_seed_derive_done(&derive); + + /* Hash it to form the leaf node */ + union hash_context ctx; + hss_hash_ctx( cur_val, tree->h, &ctx, pub_key, LEAF_LEN(hash_size)); + + /* Where in the subtree we store the values */ + merkle_index_t subtree_index = subtree->current_index + + ((merkle_index_t)1 << log_leafs); + enum subtree_build_status status = subtree_more_to_do; + + /* Walk up the stack, and then up the tree */ + for (i=0;; i++) { + if (i >= subtree->levels_below) { + /* This node is within the subtree; save it */ + memcpy( &subtree->nodes[ (subtree_index-1) * hash_size ], cur_val, hash_size ); + } + if (subtree_index == 1) { /* Hit the root */ + status = subtree_did_last_node; + break; + } + if ((q & 1) == 0) break; /* Hit a left node */ + q >>= 1; + + /* This is a right node; combine it with the left node */ + unsigned char *left_node; + if (i >= subtree->levels_below) { + /* The left node is in the tree */ + left_node = &subtree->nodes[ (subtree_index-2) * hash_size ]; + } else { + /* The left node is on the stack */ + left_node = subtree->stack + (i * hash_size); + } + hss_combine_internal_nodes( cur_val, + left_node, cur_val, + tree->h, I, hash_size, + q); + subtree_index >>= 1; + } + + /* If we haven't got out of the stack, put the value there */ + if (i < subtree->levels_below) { + if (col) hss_thread_before_write(col); + memcpy( subtree->stack + (i * hash_size), cur_val, hash_size ); + if (col) hss_thread_after_write(col); + } + + /* Ok, we've done another node */ + subtree->current_index += 1; + + return status; +} + +/* + * This steps the next tree by one. We need to do this 2**tree->level times, + * and then the next tree will be ready + */ +static int hss_step_next_tree (struct merkle_level *tree, + const struct hss_working_key *w, + struct thread_collection *col) { + struct subtree *prev_subtree = 0; + struct subtree *subtree = 0; + int j; + + LMS_UNUSED(w); + /* Search for the subtree to update */ + for (j = tree->sublevels-1; j>=0; j--) { + subtree = tree->subtree[j][NEXT_TREE]; + if (subtree->current_index < MAX_SUBINDEX) break; + prev_subtree = subtree; + } + unsigned height_subtree = (j == 0) ? tree->top_subtree_size : + tree->subtree_size; + if (j >= 0) { + /* For subtrees other than the bottom one, we get the first */ + /* node 'for free' (as it's the root of the previous subtree */ + if (subtree->current_index == 0 && prev_subtree) { + /* For the initial node of the subtree, reuse the root */ + /* of the previous one */ + unsigned hash_size = tree->hash_size; + memcpy( &subtree->nodes[ hash_size * (((merkle_index_t)1<nodes[ 0 ], + hash_size ); + subtree->current_index = ((merkle_index_t)1 << subtree->levels_below); + } + + /* Add the next node */ + switch (subtree_add_next_node( subtree, tree, 1, col )) { + case subtree_got_error: default: return 0; /* Huh? */ + case subtree_more_to_do: + break; + case subtree_did_last_node: + case subtree_all_done: + /* Mark this subtree as 'all processed' */ + subtree->current_index = MAX_SUBINDEX; + break; + } + } + + return 1; +} + +/* + * Generate the next Merkle signature for a given level + */ +static int generate_merkle_signature( + unsigned char *signature, unsigned signature_len, + struct merkle_level *tree, + const struct hss_working_key *w, + const void *message, size_t message_len) { + /* First off, write the index value */ + LMS_UNUSED(w); + if (signature_len < 4) return 0; + merkle_index_t current_index = tree->current_index; + put_bigendian( signature, current_index, 4 ); + signature += 4; signature_len -= 4; + + /* Write the OTS signature */ + size_t ots_sig_size = lm_ots_get_signature_len( tree->lm_ots_type ); + if (ots_sig_size == 0 || ots_sig_size > signature_len) return 0; + if (message == NULL) { + /* Internal interface: if message = NULL, we're supposed to */ + /* generate everything *except* the OTS signature */ + memset( signature, 0, ots_sig_size ); + } else { + struct seed_derive derive; + if (!hss_seed_derive_init( &derive, + tree->lm_type, tree->lm_ots_type, + tree->I, tree->seed )) return 0; + hss_seed_derive_set_q(&derive, current_index); + bool success = lm_ots_generate_signature( tree->lm_ots_type, tree->I, + current_index, &derive, + message, message_len, false, + signature, ots_sig_size); + hss_seed_derive_done(&derive); + if (!success) return 0; + } + signature += ots_sig_size; signature_len -= ots_sig_size; + + /* Write the LM parameter set */ + if (signature_len < 4) return 0; + put_bigendian( signature, tree->lm_type, 4 ); + signature += 4; signature_len -= 4; + + /* Now, write the authentication path */ + int i, j; + merkle_index_t index = current_index; + unsigned n = tree->hash_size; + for (i = tree->sublevels-1; i>=0; i--) { + int height = (i == 0) ? tree->top_subtree_size : tree->subtree_size; + struct subtree *subtree = tree->subtree[i][ACTIVE_TREE]; + merkle_index_t subtree_index = (index & + (((merkle_index_t)1 << height) - 1)) + + ((merkle_index_t)1 << height); + for (j = height-1; j>=0; j--) { + if (signature_len < n) return 0; + memcpy( signature, subtree->nodes + n * ((subtree_index^1) - 1), n ); + signature += n; signature_len -= n; + subtree_index >>= 1; + } + index >>= height; + } + + /* Mark that we've generated a signature */ + tree->current_index = current_index + 1; + + return 1; +} + +/* + * This signed the root of tree with the parent; it places both the signature + * and the public key into signed_key + */ +bool hss_create_signed_public_key(unsigned char *signed_key, + size_t len_signature, + struct merkle_level *tree, + struct merkle_level *parent, + struct hss_working_key *w) { + /* Where we place the public key */ + unsigned char *public_key = signed_key + len_signature; + + /* Place the public key there */ + put_bigendian( public_key + 0, tree->lm_type, 4 ); + put_bigendian( public_key + 4, tree->lm_ots_type, 4 ); + memcpy( public_key + 8, tree->I, I_LEN ); + unsigned hash_size = tree->hash_size; + /* This is where the root hash is */ + memcpy( public_key + 8 + I_LEN, + tree->subtree[0][ACTIVE_TREE]->nodes, + hash_size ); + unsigned len_public_key = 8 + I_LEN + hash_size; + + /* Now, generate the signature */ + if (!generate_merkle_signature( signed_key, len_signature, + parent, w, public_key, len_public_key)) { + return false; + } + + parent->update_count = UPDATE_NEXT; /* The parent has generated a */ + /* signature; it's now eligible for another */ + /* round of updates */ + + return true; +} + +struct gen_sig_detail { + unsigned char *signature; + size_t signature_len; + const unsigned char *message; + size_t message_len; + struct hss_working_key *w; + enum hss_error_code *got_error; +}; +/* This does the actual signature generation */ +/* It is (potentially) run within a thread */ +static void do_gen_sig( const void *detail, struct thread_collection *col) { + const struct gen_sig_detail *d = detail; + size_t signature_len = d->signature_len; + unsigned char *signature = d->signature; + struct hss_working_key *w = d->w; + unsigned levels = w->levels; + + /* The number of signed public keys */ + if (signature_len < 4) goto failed; + put_bigendian( signature, levels - 1, 4 ); + signature += 4; signature_len -= 4; + /* The signed public keys */ + unsigned i; + for (i=1; isigned_pk_len[i]; + if (signature_len < len_signed_pk) goto failed; + memcpy( signature, w->signed_pk[i], len_signed_pk ); + signature += len_signed_pk; signature_len -= len_signed_pk; + } + /* And finally the signature of the actual message */ + if (signature_len < w->siglen[levels-1]) goto failed; /* Oops, not enough room */ + + const unsigned char *message = d->message; + size_t message_len = d->message_len; + + if (!generate_merkle_signature(signature, signature_len, + w->tree[ levels-1 ], w, message, message_len)) { + goto failed; + } + + /* Success! */ + return; + +failed: + /* Report failure */ + hss_thread_before_write(col); + *d->got_error = hss_error_internal; + hss_thread_after_write(col); +} + +struct step_next_detail { + struct hss_working_key *w; + struct merkle_level *tree; + enum hss_error_code *got_error; +}; +/* This steps the next tree */ +/* It is (potentially) run within a thread */ +static void do_step_next( const void *detail, struct thread_collection *col) { + const struct step_next_detail *d = detail; + struct hss_working_key *w = d->w; + struct merkle_level *tree = d->tree; + + if (!hss_step_next_tree( tree, w, col )) { + /* Report failure */ + hss_thread_before_write(col); + *d->got_error = hss_error_internal; + hss_thread_after_write(col); + } +} + +struct step_building_detail { + struct merkle_level *tree; + struct subtree *subtree; + enum hss_error_code *got_error; +}; +/* This steps the building tree */ +/* It is (potentially) run within a thread */ +static void do_step_building( const void *detail, + struct thread_collection *col) { + const struct step_building_detail *d = detail; + struct merkle_level *tree = d->tree; + struct subtree *subtree = d->subtree; + + switch (subtree_add_next_node( subtree, tree, 0, col )) { + case subtree_got_error: default: + /* Huh? Report failure */ + hss_thread_before_write(col); + *d->got_error = hss_error_internal; + hss_thread_after_write(col); + break; + case subtree_more_to_do: + case subtree_did_last_node: + case subtree_all_done: + break; + } +} + +struct update_parent_detail { + struct hss_working_key *w; + enum hss_error_code *got_error; +}; +/* + * This gives an update to the parent (non-bottom Merkle trees) + */ +static void do_update_parent( const void *detail, + struct thread_collection *col) { + const struct update_parent_detail *d = detail; + struct hss_working_key *w = d->w; + unsigned levels = w->levels; + unsigned current_level = levels - 2; /* We start with the first */ + /* non-bottom level */ + for (;;) { + struct merkle_level *tree = w->tree[current_level]; + switch (tree->update_count) { + case UPDATE_DONE: return; /* No more updates needed */ + case UPDATE_NEXT: /* Our job is to update the next tree */ + tree->update_count = UPDATE_PARENT; + if (current_level == 0) return; /* No next tree to update */ + if (!hss_step_next_tree( tree, w, col )) goto failed; + return; + case UPDATE_PARENT: /* Our job is to update our parent */ + tree->update_count = UPDATE_BUILDING + 0; + if (current_level == 0) return; /* No parent to update */ + current_level -= 1; + continue; + default: { + /* Which building tree we need to update */ + unsigned level_to_update = + (tree->update_count - UPDATE_BUILDING) + 1; + if (level_to_update >= tree->sublevels) { + /* We've completed all the updates we need to do (until */ + /* the next time we need to sign something) */ + tree->update_count = UPDATE_DONE; + return; + } + + /* Next time, update the next BUILDING subtree */ + tree->update_count += 1; + + struct subtree *subtree = + tree->subtree[level_to_update][BUILDING_TREE]; + + /* The number of leaves in this tree */ + merkle_index_t tree_leaves = (merkle_index_t)1 << tree->level; + + /* Check if we'd actually use the building tree */ + if (subtree->left_leaf >= tree_leaves) { + /* We'll never use it; don't bother updating it */ + return; + } + + /* We'll use the BUILDING_TREE, actually add a node */ + switch (subtree_add_next_node( subtree, tree, 0, col )) { + case subtree_got_error: default: goto failed; /* Huh? */ + case subtree_did_last_node: + case subtree_all_done: + case subtree_more_to_do: + /* We're done everything we need to do for this step */ + return; + } + } + } + } + +failed: + /* Huh? Report failure */ + hss_thread_before_write(col); + *d->got_error = hss_error_internal; + hss_thread_after_write(col); +} + +/* + * Code to actually generate the signature + */ +bool hss_generate_signature( + struct hss_working_key *w, + bool (*update_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + const void *message, size_t message_len, + unsigned char *signature, size_t signature_buf_len, + struct hss_extra_info *info) { + struct hss_extra_info temp_info = { 0 }; + if (!info) info = &temp_info; + unsigned i; + bool trash_private_key = false; + + info->last_signature = false; + + if (!w) { + info->error_code = hss_error_got_null; + goto failed; + } + if (w->status != hss_error_none) { + info->error_code = w->status; + goto failed; + } + + /* If we're given a raw private key, make sure it's the one we're */ + /* thinking of */ + if (!update_private_key) { + if (0 != memcmp( context, w->private_key, PRIVATE_KEY_LEN)) { + info->error_code = hss_error_key_mismatch; + return false; /* Private key mismatch */ + } + } + + /* Check if the buffer we were given is too short */ + if (w->signature_len > signature_buf_len) { + /* The signature would overflow the buffer */ + info->error_code = hss_error_buffer_overflow; + goto failed; + } + + unsigned levels = w->levels; + /* + * Compile the current count + */ + sequence_t current_count = 0; + for (i=0; i < levels; i++) { + struct merkle_level *tree = w->tree[i]; + current_count <<= tree->level; + /* We subtract 1 because the nonbottom trees are already advanced */ + current_count += (sequence_t)tree->current_index - 1; + } + current_count += 1; /* Bottom most tree isn't already advanced */ + + /* Ok, try to advance the private key */ + if (!hss_advance_count(w, current_count, + update_private_key, context, info, + &trash_private_key)) { + /* hss_advance_count fills in the error reason */ + goto failed; + } + + /* Ok, now actually generate the signature */ + + /* We'll be doing several things in parallel */ + struct thread_collection *col = hss_thread_init(info->num_threads); + enum hss_error_code got_error = hss_error_none; + + /* Generate the signature */ + { + struct gen_sig_detail gen_detail; + gen_detail.signature = signature; + gen_detail.signature_len = w->signature_len; + gen_detail.message = message; + gen_detail.message_len = message_len; + gen_detail.w = w; + gen_detail.got_error = &got_error; + + hss_thread_issue_work(col, do_gen_sig, &gen_detail, sizeof gen_detail); + } + + /* Update the bottom level next tree */ + if (levels > 1) { + struct step_next_detail step_detail; + step_detail.w = w; + step_detail.tree = w->tree[levels-1]; + step_detail.got_error = &got_error; + + hss_thread_issue_work(col, do_step_next, &step_detail, sizeof step_detail); + } + + /* Issue orders to step each of the building subtrees in the bottom tree */ + int skipped_a_level = 0; /* Set if the below issued didn't issue an */ + /* order for at least one level */ + { + struct merkle_level *tree = w->tree[levels-1]; + merkle_index_t updates_before_end = tree->max_index - tree->current_index + 1; + int h_subtree = tree->subtree_size; + for (i=1; isublevels; i++) { + struct subtree *subtree = tree->subtree[i][BUILDING_TREE]; + /* Check if there is a building tree */ + if (updates_before_end < (merkle_index_t)1 << + (subtree->levels_below + h_subtree)) { + /* No; we're at the last subtree within this tree */ + skipped_a_level = 1; + continue; + } + struct step_building_detail step_detail; + step_detail.tree = tree; + step_detail.subtree = subtree; + step_detail.got_error = &got_error; + + hss_thread_issue_work(col, do_step_building, &step_detail, sizeof step_detail); + + } + /* If there's only one sublevel, act as if we always skipped a sublevel */ + if (tree->sublevels == 1) skipped_a_level = 1; + } + + /* + * And, if we're allowed to give the parent a chance to update, and + * there's a parent with some updating that needs to be done, schedule + * that to be done + */ + if (skipped_a_level && + levels > 1 && w->tree[levels-2]->update_count != UPDATE_DONE) { + struct update_parent_detail detail; + detail.w = w; + detail.got_error = &got_error; + hss_thread_issue_work(col, do_update_parent, &detail, sizeof detail); + } + + /* Wait for all of them to finish */ + hss_thread_done(col); + + /* Check if any of them reported a failure */ + if (got_error != hss_error_none) { + info->error_code = got_error; + goto failed; + } + + current_count += 1; /* The new count is one more than what is */ + /* implied by the initial state of the Merkle trees */ + + /* + * Now, we scan to see if we exhausted a Merkle tree, and need to update it + * At the same time, we check to see if we need to advance the subtrees + */ + sequence_t cur_count = current_count; + unsigned merkle_levels_below = 0; + int switch_merkle = w->levels; + struct merkle_level *tree; + for (i = w->levels; i>=1; i--, merkle_levels_below += tree->level) { + tree = w->tree[i-1]; + + if (0 == (cur_count & (((sequence_t)1 << (merkle_levels_below + tree->level))-1))) { + /* We exhausted this tree */ + if ((i-1) == 0) { + /* We've run out of signatures; we've already caught this */ + /* above; just make *sure* we've marked the key as */ + /* unusable, and give up */ + w->status = hss_error_private_key_expired; + break; + } + + /* Remember we'll need to switch to the NEXT_TREE */ + switch_merkle = i-1; + continue; + } + + /* Check if we need to advance any of the subtrees */ + unsigned subtree_levels_below = 0; + unsigned j; + for (j = tree->sublevels-1; j>0; j--) { + subtree_levels_below += tree->subtree_size; + if (0 != (cur_count & (((sequence_t)1 << (merkle_levels_below + subtree_levels_below))-1))) { + /* We're in the middle of this subtree */ + goto done_advancing; + } + + /* Switch to the building subtree */ + struct subtree *next = tree->subtree[j][BUILDING_TREE]; + struct subtree *prev = tree->subtree[j][ACTIVE_TREE]; + unsigned char *stack = next->stack; /* Stack stays with */ + /* building tree */ + tree->subtree[j][ACTIVE_TREE] = next; + /* We need to reset the parameters on the new building subtree */ + prev->current_index = 0; + prev->left_leaf += (merkle_index_t)2 << subtree_levels_below; + tree->subtree[j][BUILDING_TREE] = prev; + next->stack = NULL; + prev->stack = stack; + } + } +done_advancing: + /* Check if we used up any Merkle trees; if we have, switch to the */ + /* NEXT_TREE (which we've built in our spare time) */ + for (i = switch_merkle; i < w->levels; i++) { + struct merkle_level *tree_l = w->tree[i]; + struct merkle_level *parent = w->tree[i-1]; + unsigned j; + + /* Rearrange the subtrees */ + for (j=0; jsublevels; j++) { + /* Make the NEXT_TREE active; replace it with the current active */ + struct subtree *active = tree_l->subtree[j][NEXT_TREE]; + struct subtree *next = tree_l->subtree[j][ACTIVE_TREE]; + unsigned char *stack = active->stack; /* Stack stays with */ + /* next tree */ + + active->left_leaf = 0; + next->current_index = 0; + next->left_leaf = 0; + tree_l->subtree[j][ACTIVE_TREE] = active; + tree_l->subtree[j][NEXT_TREE] = next; + active->stack = NULL; + next->stack = stack; + if (j > 0) { + /* Also reset the building tree */ + struct subtree *building = tree->subtree[j][BUILDING_TREE]; + building->current_index = 0; + merkle_index_t size_subtree = (merkle_index_t)1 << + (tree->subtree_size + building->levels_below); + building->left_leaf = size_subtree; + } + } + + /* Copy in the value of seed, I we'll use for the new tree */ + memcpy( tree_l->seed, tree->seed_next, SEED_LEN ); + memcpy( tree_l->I, tree->I_next, I_LEN ); + + /* Compute the new next I, which is derived from either the parent's */ + /* I or the parent's I_next value */ + merkle_index_t index = parent->current_index; + if (index == parent->max_index) { + hss_generate_child_seed_I_value(tree->seed_next, tree->I_next, + parent->seed_next, parent->I_next, 0, + parent->lm_type, + parent->lm_ots_type); + } else { + hss_generate_child_seed_I_value( tree->seed_next, tree->I_next, + parent->seed, parent->I, index+1, + parent->lm_type, + parent->lm_ots_type); + } + + tree_l->current_index = 0; /* We're starting this from scratch */ + + /* Generate the signature of the new level */ + if (!hss_create_signed_public_key( w->signed_pk[i], w->siglen[i-1], + tree_l, parent, w )) { + info->error_code = hss_error_internal; + goto failed; + } + } + + /* And we've set things up for the next signature... */ + + if (trash_private_key) { + memset( w->private_key, PARM_SET_END, PRIVATE_KEY_LEN ); + } + + return true; + +failed: + + if (trash_private_key) { + memset( w->private_key, PARM_SET_END, PRIVATE_KEY_LEN ); + } + + /* On failure, make sure that we don't return anything that might be */ + /* misconstrued as a real signature */ + memset( signature, 0, signature_buf_len ); + return false; +} + +/* + * Get the signature length + */ +size_t hss_get_signature_len_from_working_key(struct hss_working_key *w) { + if (!w || w->status != hss_error_none) return 0; + + int levels = w->levels; + if (levels > MAX_HSS_LEVELS) return 0; + param_set_t lm[MAX_HSS_LEVELS], ots[MAX_HSS_LEVELS]; + int i; + for (i=0; itree[i]->lm_type; + ots[i] = w->tree[i]->lm_ots_type; + } + + return hss_get_signature_len(levels, lm, ots); +} diff --git a/src/sig_stfl/lms/external/hss_sign_inc.c b/src/sig_stfl/lms/external/hss_sign_inc.c new file mode 100644 index 0000000000..e455b5cd2b --- /dev/null +++ b/src/sig_stfl/lms/external/hss_sign_inc.c @@ -0,0 +1,218 @@ +/* + * This is the code that implements the hierarchical part of the LMS hash + * based signatures; in this case, incremental signing + */ +#include +#include "hss.h" +#include "common_defs.h" +#include "hss_verify_inc.h" +#include "lm_verify.h" +#include "lm_common.h" +#include "lm_ots.h" +#include "lm_ots_verify.h" +#include "hash.h" +#include "endian.h" +#include "hss_internal.h" +#include "hss_sign_inc.h" +#include "hss_derive.h" + +/* + * Start the process of creating an HSS signature incrementally. Parameters: + * ctx - The state we'll use to track the incremental signature + * working_key - the in-memory version of the in-memory private key + * update_private_key - function to call to update the master private key + * context - context pointer for above + * siganture - the buffer to hold the signature + * signature_len - the length of the buffer + * this_is_the_last_signature - if non-NULL, this will be set if this + * signature is the last for this private key + */ +bool hss_sign_init( + struct hss_sign_inc *ctx, + struct hss_working_key *w, + bool (*update_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + unsigned char *signature, size_t signature_len, + struct hss_extra_info *info) { + struct hss_extra_info temp_info = { 0 };; + if (!info) info = &temp_info; + + if (!ctx) { + info->error_code = hss_error_got_null; + return false; + } + ctx->status = hss_error_ctx_uninitialized; /* Until we hear otherwise, */ + /* we got a failure */ + + if (!w) { + info->error_code = hss_error_got_null; + return false; + } + if (w->status != hss_error_none) { + info->error_code = w->status; + return false; + } + + struct merkle_level *bottom = w->tree[ w->levels - 1 ]; + + unsigned char I[I_LEN]; + memcpy( I, bottom->I, I_LEN ); + + /* Compute the value of C we'll use */ + merkle_index_t q = bottom->current_index; + ctx->q = q; + int h = bottom->h; + ctx->h = h; + + struct seed_derive derive; + if (!hss_seed_derive_init( &derive, bottom->lm_type, bottom->lm_ots_type, + bottom->I, bottom->seed )) return false; + hss_seed_derive_set_q(&derive, q); + lm_ots_generate_randomizer( ctx->c, bottom->hash_size, &derive ); + hss_seed_derive_done(&derive); + + /* + * Ask the signature generation process to do everything *except* + * the bottom level OTS signature + */ + bool success = hss_generate_signature( w, + update_private_key, context, + NULL, 0, /* <--- we don't have the message yet */ + signature, signature_len, info ); + if (!success) { + /* On failure, hss_generate_signature fills in the failure reason */ + ctx->status = info->error_code; + hss_zeroize( &ctx->c, sizeof ctx->c ); /* People don't get to */ + /* learn what randomizer we would have used */ + return false; + } + + /* Now, initialize the context */ + hss_init_hash_context( h, &ctx->hash_ctx ); + { + unsigned char prefix[ MESG_PREFIX_MAXLEN ]; + memcpy( prefix + MESG_I, I, I_LEN ); + unsigned q_bin[4]; put_bigendian( q_bin, q, 4 ); + memcpy( prefix + MESG_Q, q_bin, 4 ); /* q */ + SET_D( prefix + MESG_D, D_MESG ); + int n = bottom->hash_size; + memcpy( prefix + MESG_C, ctx->c, n ); /* C */ + hss_update_hash_context(h, &ctx->hash_ctx, prefix, MESG_PREFIX_LEN(n) ); + } + + /* It succeeded so far... */ + ctx->status = hss_error_none; + return true; +} + +/* This adds another piece of the message to validate */ +bool hss_sign_update( + struct hss_sign_inc *ctx, + const void *message_segment, + size_t len_message_segment) { + if (!ctx || ctx->status != hss_error_none) return false; + + hss_update_hash_context(ctx->h, &ctx->hash_ctx, + message_segment, len_message_segment ); + + return true; +} + +/* We've added all the pieces of the messages, now do the validation */ +bool hss_sign_finalize( + struct hss_sign_inc *ctx, + const struct hss_working_key *working_key, + unsigned char *signature, + struct hss_extra_info *info) { + struct hss_extra_info temp_info = { 0 }; + if (!info) info = &temp_info; + + if (!ctx) { + info->error_code = hss_error_got_null; + return false; + } + if (ctx->status != hss_error_none) { + info->error_code = ctx->status; + return false; + } + + /* Success or fail, we can't use the context any more */ + ctx->status = hss_error_ctx_already_used; + + int L = working_key->levels; + + /* Step through the signature, looking for the place to put the OTS */ + /* signature, and (while we're at it) recovering the I and seed values */ + const unsigned char *I = working_key->tree[0]->I; + const unsigned char *seed = working_key->tree[0]->seed; + /* Note: we alternate buffers during generation in case */ + /* hss_generate_child_seed_I_value doesn't allow new values to */ + /* overwrite old ones */ + unsigned char I_buff[2][I_LEN]; + unsigned char seed_buff[2][SEED_LEN]; + + /* Q: should we double check the various fixed fields of the signatures */ + /* (e.g. the number of signed keys, the parameter sets? */ + + signature += 4; + + int i; + for (i=0; i working_key->tree[i]->max_index) { + hss_zeroize( seed_buff, sizeof seed_buff ); + return 0; + } + if (!hss_generate_child_seed_I_value( seed_buff[i&1], I_buff[i&1], + seed, I, q, + working_key->tree[i]->lm_type, + working_key->tree[i]->lm_ots_type )) { + hss_zeroize( seed_buff, sizeof seed_buff ); + info->error_code = hss_error_internal; + return false; + } + + seed = seed_buff[i&1]; + I = I_buff[i&1]; + + /* Step to the end of this signed key */ + signature += lm_get_signature_len( working_key->tree[i]->lm_type, + working_key->tree[i]->lm_ots_type); + signature += lm_get_public_key_len(working_key->tree[i+1]->lm_type); + } + + /* Now, signature points to where the bottom LMS signature should go */ + /* It starts with the q value */ + put_bigendian( signature, ctx->q, 4 ); + signature += 4; + /* And then the LM-OTS signature */ + + /* Copy in the C value into the signature */ + memcpy( signature+4, ctx->c, 32 ); + + /* Generate the final hash */ + unsigned char hash[ MAX_HASH ]; + hss_finalize_hash_context( ctx->h, &ctx->hash_ctx, hash ); + + /* And the final OTS signature based on that hash */ + param_set_t lm_type = working_key->tree[i]->lm_type; + param_set_t ots_type = working_key->tree[i]->lm_ots_type; + struct seed_derive derive; + bool success = hss_seed_derive_init( &derive, lm_type, ots_type, + I, seed ); + if (success) { + hss_seed_derive_set_q( &derive, ctx->q ); + success = lm_ots_generate_signature( + ots_type, I, ctx->q, &derive, hash, 0, true, + signature, lm_ots_get_signature_len( ots_type )); + + hss_seed_derive_done( &derive ); + } + if (!success) { + info->error_code = hss_error_internal; + } + + hss_zeroize( seed_buff, sizeof seed_buff ); + return success; +} diff --git a/src/sig_stfl/lms/external/hss_sign_inc.h b/src/sig_stfl/lms/external/hss_sign_inc.h new file mode 100644 index 0000000000..426d271abd --- /dev/null +++ b/src/sig_stfl/lms/external/hss_sign_inc.h @@ -0,0 +1,81 @@ +#if !defined( HSS_SIGN_INC_H_ ) +#define HSS_SIGN_INC_H_ +#include +#include +#include "hash.h" +#include "common_defs.h" + +/* + * These are the functions to sign a message incrementally. + * That is, we assume that we don't have the entire message at + * once, instead, we have it in pieces (for example, the signature + * is of a multigigabyte file) + * + * Usage: + * struct hss_sign_inc ctx; + * bool success = hss_sign_init( &ctx, working_key, + * update_private_key, private_key_context, + * signature, signature_buffer_len, + * &lsat_signature ); + * hss_sign_update( &ctx, message_part_1, len_1 ); + * hss_sign_update( &ctx, message_part_2, len_2 ); + * hss_sign_update( &ctx, message_part_3, len_3 ); + * success = hss_sign_finalize( &ctx, working_key, signature ); + * if (success) printf( "We generated the signature\n" ); + * + * This is in its own include file because we need to import some + * 'not-generally-for-general-consumption' include files to make + * it work (as they're in the hss_sign_inc structure) + */ + +/* + * This is the context structure that holds the intermedate results of an + * in-process signature + * It's a application-visible structure for ease of use: the application can + * allocate it as an automatic, and if the application aborts in the middle of + * signing, it doesn't cause a memory leak + */ +struct hss_sign_inc { + enum hss_error_code status; /* Either hss_error_none if we're in */ + /* process, or the reason why we'd fail */ + + int h; /* The hash function */ + merkle_index_t q; /* The index of the bottom level signature */ + union hash_context hash_ctx; /* For the running hash we use */ + + unsigned char c[MAX_HASH]; /* The C value we used */ +}; + +struct hss_extra_info; + +/* Starts off the process of incrementally signing a message */ +/* If it detects a failure, this returns false */ +/* Handing the return code is optional; if this fails, the finalization */ +/* step will fail too */ +bool hss_sign_init( + struct hss_sign_inc *ctx, + struct hss_working_key *working_key, + bool (*update_private_key)(unsigned char *private_key, + size_t len_private_key, void *context), + void *context, + unsigned char *signature, size_t signature_len, + struct hss_extra_info *info); + +/* This adds another piece of the message to sign */ +/* Again, the result code is optional */ +bool hss_sign_update( + struct hss_sign_inc *ctx, + const void *message_segment, + size_t len_message_segment); + +/* This finalizes the signature generation */ +/* This returns true if the signature was generated properly */ +/* We ask the caller to pass in the working key again, we need to review */ +/* the private key (we don't want to place it in the context) */ +bool hss_sign_finalize( + struct hss_sign_inc *ctx, + const struct hss_working_key *working_key, + unsigned char *signature, + struct hss_extra_info *info); + +#endif /* HSS_SIGN_INC_H_ */ diff --git a/src/sig_stfl/lms/external/hss_thread.h b/src/sig_stfl/lms/external/hss_thread.h new file mode 100644 index 0000000000..fbf572ad4b --- /dev/null +++ b/src/sig_stfl/lms/external/hss_thread.h @@ -0,0 +1,135 @@ +#if !defined( HSS_THREAD_H_ ) +#define HSS_THREAD_H_ +/* + * This is our internal abstraction of multithreading; this allows the + * "application" (in this case, the HSS code) to issue multiple requests that + * can potentially run on different threads, in a way that doesn't depend on + * the actual threading capability of the OS. If we don't actually have + * multiple threads avaiable (either because the OS doesn't provide us with + * multiple threads, or we hit an internal error trying to generate new + * threads), this will just have the main thread do all the work (and hence + * the application doesn't have to worry its pretty little head about error + * handling, or whether we actually implement threads in the first place) + * + * This is designed to handle this sort of task: we have a series of + * computational problems to do; each can be done independently of the others, + * and each problem results in a fairly short answer. All the children do is + * computation; there's no I/O or any other interaction with the OS at all. + * + * The general paradigm is: + * - The main thread generates a thread collection (via the hss_thread_init + * call) + * - The main thread then issues a series of tasks (via the + * hss_thread_issue_work call). This may spawn off other threads (which + * will then call the function passed); alternatively, the main thread may + * call the function. + * - The main thread then waits for all the tasks to be done (via the + * hss_thread_done call) + * The function(s) passed to the hss_thread_issue_work call will be completed + * by the time hss_thread_done returns + */ +#include + +/* This is our abstract object that stands for a set of threads */ +struct thread_collection; + +/* + * This is called to initialize a set of threads, and returns the identifier. + * Note that this cannot fail; if it returns 0, it's not a failure; instead, + * it's a valid return (which essentially means we're running in nonthreaded + * mode) + * The integer passed is a recommendation on the number of threads + */ +struct thread_collection *hss_thread_init(int); + +/* + * This issues another work item to our collection of threads. At some point + * (between when hss_thread_issue_work is called and when hss_thread_done + * returns), we'll have function called, with a pointer to a copy of the detail + * structure. function may be called by this thread, or it may be called by a + * different one. + * + * The passed detail structure will not be referenced after this returns, and + * hence it is safe if the caller modifies (or frees) it afterwards. If the + * function isn't completed by the time hss_thread_issue_work returns, we'll + * squirrel away a copy of detail (which is why we ask the caller to + * pass size_detail_structure; so we know how much to copy) + * + * We suggest that the application issue the work orders in largest-to-smallest + * order. The ordering doesn't matter for correctness (the API makes no + * guarrantees about when the requests will be completed), however we suggest + * this for expected performance reasons. hss_thread_done will not return + * until all threads are done; what we want to avoid is scenarios where all but + * one of the threads are done, and that last thread is working on an expensive + * function; that would slow things down, and the entire point of this thread + * library is to speed things up. Assigning work items to threads optimally is + * an NP-hard problem, however the simple heuristic of packing 'largest first' + * works fairly well in practice (and is easy to implement). The thread library + * does try to make a best effort attempt to preserve the issue order (assuming + * no intermediate malloc or thread spawn issues; in those cases, the library + * prioritizes correctness over efficiency) + */ +void hss_thread_issue_work(struct thread_collection *col, + void (*function)(const void *detail, + struct thread_collection *col), + const void *detail, size_t size_detail_structure); + +/* + * This waits for all the work items we have issued (via hss_thread_issue_work) + * to be completed (that is, 'function' has returned, and cleans up the + * collection + * + * col must not be used after this; if it was malloc'ed, this will free it + */ +void hss_thread_done(struct thread_collection *col); + +/* + * This should be called before a thread writes to common data + * + * We do this because we sometimes have different threads write data to + * adjacent memory locations; if the compiler has the CPU do a + * read/modify/write to the entire word (or however the CPU has memory + * organized), this could cause a race condition. Forcing those writes to be + * serialized avoids the issue; such a race condition would actually be fairly + * unlikely, but would be a *really* difficult bug to track down if it did + * occur, so it makes sense to go the extra mile to avoid the possibility + * + * Doing this locking also means that the working thread can safely do things + * such as incrementing a global [1] counter to report its results, should + * that be appropriate + * + * We don't bother doing this if we're writing into a malloc'ed region, *if* + * we're the only thread that will be writing into that specific region; we + * assume that the malloc infrastructure will separate distinct malloc'ed + * regions enough to avoid such race conditions + * + * [1] actually, automatic to the main thread; there are no literal globals + * in this package, apart from the verbose debugging flag + */ +void hss_thread_before_write(struct thread_collection *collect); + +/* + * This should be called after a thread writes to common data; it releases + * the lock + */ +void hss_thread_after_write(struct thread_collection *collect); + +/* + * This gives the application guidance for how many worker threads we have + * available, that is, how many work items we can expect to run at once + * + * This is used to decide the level of granularity we need; we we have only 2 + * cores, there's no point is splitting the job up to 50 separate requests; + * however if there are 100 cores, we want (if possible) to do at least 100 + * + * The issue with having not enough requests is that we will have idle threads + * (which could potentially do useful work, if we are able to divide the work + * further). The issue with having too many requests is that the requests use + * up some memory, and we'd prefer not to use up too much memory (we don't + * fail on malloc failure, however we do drop back to a single threaded model) + * + * The value passed is the value we'll pass to hss_thread_init + */ +unsigned hss_thread_num_tracks(int num_threads); + +#endif /* HSS_THREAD_H_ */ diff --git a/src/sig_stfl/lms/external/hss_thread_pthread.c b/src/sig_stfl/lms/external/hss_thread_pthread.c new file mode 100644 index 0000000000..b5f64d3764 --- /dev/null +++ b/src/sig_stfl/lms/external/hss_thread_pthread.c @@ -0,0 +1,298 @@ +#include "hss_thread.h" + +#include +#include + +/* + * This is an implementation of our threaded abstraction using the + * POSIX pthread API + * + * C11 has a similar (but not precisely identical) API to the one that POSIX + * defines (at least for what we do; all we need is thread create/join and + * mutex's, which *any* thread library should provide). I'd code up the + * support for that API as well (using the same base logic, with typedef's and + * helper inlines to isolate the differences), however I don't have a C11 + * implementation handy to test it + */ + +#define MAX_THREAD 16 /* Number try to create more than 16 threads, no */ + /* matter what the application tries to tell us */ +#define DEFAULT_THREAD 16 /* The number of threads to run if the */ + /* application doesn't tell us otherwise (e.g. */ + /* passes in 0) */ + +#define MIN_DETAIL 16 /* So the alignment kludge we do doesn't waste space */ + +/* The information we track about a thread we may have launched */ +struct thread_state { + pthread_t thread_id; + enum { never_was, alive, dead } state; +}; + +struct work_item { + struct work_item *link; /* They're in a linked list */ + + void (*function)(const void *detail, /* Function to call */ + struct thread_collection *col); + + /* These two items are used to pass the thread state to the thread */ + /* if this is the first work item for the thread to process */ + struct thread_collection *col; /* The parent thread_collection */ + struct thread_state *state; /* The pointer into the thread collection */ + /* state for the state of this thread */ + + /* The detail structure that we pass to the function */ + /* We'll malloc enough space to hold the entire structure */ + union { /* union here so that the detail array is */ + void *align1; /* correctly aligned for various datatypes */ + long long align2; + void (*align3)(void); + unsigned char detail[MIN_DETAIL]; + } x; +}; + +struct thread_collection { + pthread_mutex_t lock; /* Must be locked before this structure is */ + /* accessed if there might be a thread */ + pthread_mutex_t write_lock; /* Must be locked before common user data is */ + /* written */ + + unsigned num_thread; + unsigned current_ptr; /* There two are here to avoid O(N) table */ + unsigned num_alive; /* scanning in the most common scenarios */ + + /* Information about the worker threads we may have created */ + struct thread_state threads[MAX_THREAD]; + + /* + * Queue (FIFO) of work items submitted, and which can't be processed + * immedately. We do a FIFO, rather than a stack, so that we perform + * the requests in the order they were issued (which isn't something + * the interface guarantees; however it doesn't interfere with the + * request ordering we ask applications to make) + */ + struct work_item *top_work_queue; + struct work_item *end_work_queue; +}; + +/* + * Allocate a thread control structure + */ +struct thread_collection *hss_thread_init(int num_thread) { + if (num_thread == 0) num_thread = DEFAULT_THREAD; + if (num_thread <= 1) return 0; /* Not an error: an indication to run */ + /* single threaded */ + if (num_thread > MAX_THREAD) num_thread = MAX_THREAD; + + struct thread_collection *col = malloc( sizeof *col ); + if (!col) return 0; /* On malloc failure, run single threaded */ + + col->num_thread = num_thread; + + if (0 != pthread_mutex_init( &col->lock, 0 )) { + free(col); // IGNORE free-check + return 0; + } + + if (0 != pthread_mutex_init( &col->write_lock, 0 )) { + pthread_mutex_destroy( &col->lock ); + free(col); // IGNORE free-check + return 0; + } + + col->current_ptr = 0; + col->num_alive = 0; + int i; + for (i=0; ithreads[i].state = never_was; + } + col->top_work_queue = 0; + col->end_work_queue = 0; + + return col; +} + +/* + * This is the base routine that a worker thread runs + */ +static void *worker_thread( void *arg ) { + struct work_item *w = arg; /* The initial work item */ + struct thread_collection *col = w->col; + struct thread_state *state = w->state; + + for (;;) { + /* Perform the work item in front of us */ + (w->function)(w->x.detail, col); + + /* Ok, we did that */ + free(w); // IGNORE free-check + + /* Check if there's anything else to do */ + pthread_mutex_lock( &col->lock ); + + w = col->top_work_queue; + if (w) { + /* More work; pull it off the queue */ + col->top_work_queue = w->link; + if (w == col->end_work_queue) col->end_work_queue = 0; + + /* And go handle it */ + pthread_mutex_unlock( &col->lock ); + continue; + } + + /* No more work for us to do; post our obituary */ + state->state = dead; + col->num_alive -= 1; + pthread_mutex_unlock( &col->lock ); + + /* And that's all folks */ + return 0; + } +} + +/* + * This adds function/details to the list of things that need to be done + * It either creates a thread to do it, or (if we're maxed out) add it to + * our honey-do list (or, as last resort, just does it itself) + */ +void hss_thread_issue_work(struct thread_collection *col, + void (*function)(const void *detail, + struct thread_collection *col), + const void *detail, size_t size_detail_structure) { + + /* If we're running in single-threaded mode */ + if (!col) { + function( detail, col ); + return; + } + + /* Allocate a work structure to hold this request */ + size_t extra_space; + if (size_detail_structure < MIN_DETAIL) extra_space = 0; + else extra_space = size_detail_structure - MIN_DETAIL; + struct work_item *w = malloc(sizeof *w + extra_space); + + if (!w) { + /* Can't allocate the work structure; fall back to single-threaded */ + function( detail, col ); + return; + } + w->col = col; + w->function = function; + memcpy( w->x.detail, detail, size_detail_structure ); + + unsigned num_thread = col->num_thread; + + pthread_mutex_lock( &col->lock ); + + /* Check if we can spawn a new thread */ + if (col->num_alive < num_thread) { + /* There's supposed to be room for another */ + /* Look for the empty slot */ + unsigned i, j; + j = col->current_ptr; /* Do round-robin (so we don't bang on */ + /* slot 0 whenever we try to start a thread) */ + for (i=0; ithreads[j]; + switch (p->state) { + case alive: continue; /* This one's busy */ + case dead: + { + /* This one just died; grab its status (not that we care, */ + /* however that'll tell the thread library it can clean up) */ + pthread_t thread_id = p->thread_id; + void *status; /* Ignored, but we need to place thread */ + /* status somewhere */ + pthread_mutex_unlock( &col->lock ); + pthread_join( thread_id, &status ); + pthread_mutex_lock( &col->lock ); + p->state = never_was; + } + /* FALL THROUGH */ + case never_was: + /* Now, we can spawn a new thread */ + w->state = p; + if (0 != pthread_create( &p->thread_id, + NULL, worker_thread, w )) { + /* Hmmm, couldn't spawn it; fall back */ + default: /* On error condition */ + pthread_mutex_unlock( &col->lock ); + free(w); // IGNORE free-check + function( detail, col ); + return; + } + + /* We've kicked off the thread */ + p->state = alive; + col->num_alive += 1; + /* For the next request, start scanning at the next */ + /* thread object */ + col->current_ptr = (j+1) % num_thread; + pthread_mutex_unlock( &col->lock ); + return; + } + } + col->num_alive = num_thread; /* Hmmmm, everything was alive??? */ + } + + /* We can't create any more threads; enqueue this (and someone will get */ + /* to it) */ + w->link = 0; + if (col->end_work_queue) { + col->end_work_queue->link = w; + } + col->end_work_queue = w; + if (!col->top_work_queue) col->top_work_queue = w; + + pthread_mutex_unlock( &col->lock ); +} + +/* + * This will wait for all the work items we'e issued to complete + */ +void hss_thread_done(struct thread_collection *col) { + if (!col) return; + + unsigned i; + pthread_mutex_lock( &col->lock ); + for (i=0; inum_thread; i++) { + /* + * Wait for each thread that we have spawned. + * We're the only one that will spawn them, and so we don't have to + * worry about any new ones appearing while we scan through the list + */ + if (col->threads[i].state != never_was) { + void *status; + pthread_t thread_id = col->threads[i].thread_id; + pthread_mutex_unlock( &col->lock ); + pthread_join( thread_id, &status ); + pthread_mutex_lock( &col->lock ); + } + } + pthread_mutex_unlock( &col->lock ); + + /* Ok, all the threads have finished; tear things down */ + + pthread_mutex_destroy( &col->lock ); + pthread_mutex_destroy( &col->write_lock ); + free(col); // IGNORE free-check +} + +void hss_thread_before_write(struct thread_collection *col) { + if (!col) return; + pthread_mutex_lock( &col->write_lock ); +} + +void hss_thread_after_write(struct thread_collection *col) { + if (!col) return; + pthread_mutex_unlock( &col->write_lock ); +} + + +unsigned hss_thread_num_tracks(int num_thread) { + if (num_thread == 0) num_thread = DEFAULT_THREAD; + if (num_thread <= 1) return 1; + if (num_thread >= MAX_THREAD) return MAX_THREAD; + return num_thread; +} diff --git a/src/sig_stfl/lms/external/hss_thread_single.c b/src/sig_stfl/lms/external/hss_thread_single.c new file mode 100644 index 0000000000..d844385293 --- /dev/null +++ b/src/sig_stfl/lms/external/hss_thread_single.c @@ -0,0 +1,63 @@ +#include "hss_thread.h" +#include "config.h" + +/* + * This is a trivial implementation of our threading abstraction. + * It's used if we don't have any threading support + */ + +/* + * This requests that an object that tracks the threads be created. We have + * no threads, hence we don't need such an object + */ +struct thread_collection *hss_thread_init(int num_thread) { + LMS_UNUSED(num_thread); + return 0; +} + +/* + * This asks that function be called sometime between now, and when + * hss_thread_done is called. We just go ahead, and do it now + */ +void hss_thread_issue_work(struct thread_collection *collect, + void (*function)(const void *detail, + struct thread_collection *col), + const void *detail, size_t size_detail_structure) { + LMS_UNUSED(size_detail_structure); + /* If we were asked to make sure something is done, just do it */ + function( detail, collect ); +} + +/* + * This asks for all the work requests we've issued to completed, and that + * the collection object be freed. We did all the work when it was + * requested, and we never allocated a collection object in the first place + */ +void hss_thread_done(struct thread_collection *collect) { + LMS_UNUSED(collect); +} + +/* + * A thread calls this when it will write into a common area (so that no + * other thread will access it at the same time). No threads means that + * there is no need to lock + */ +void hss_thread_before_write(struct thread_collection *collect) { + LMS_UNUSED(collect); +} + +/* + * This releases the above lock + */ +void hss_thread_after_write(struct thread_collection *collect) { + LMS_UNUSED(collect); +} + +/* + * This tells the application that we really have only one thread + * (the main one) + */ +unsigned hss_thread_num_tracks(int num_thread) { + LMS_UNUSED(num_thread); + return 1; +} diff --git a/src/sig_stfl/lms/external/hss_verify.c b/src/sig_stfl/lms/external/hss_verify.c new file mode 100644 index 0000000000..089bdbd1ef --- /dev/null +++ b/src/sig_stfl/lms/external/hss_verify.c @@ -0,0 +1,196 @@ +/* + * This is the code that implements the hierarchical part of the LMS hash + * based signatures + */ +#include +#include "common_defs.h" +#include "hss_verify.h" +#include "lm_verify.h" +#include "lm_common.h" +#include "lm_ots_verify.h" +#include "hash.h" +#include "endian.h" +#include "hss_thread.h" +#include "hss_internal.h" +#include "hss.h" + +/* The HSS public key consists of: */ +/* Number of levels (1-8) (4 bytes) */ +/* The top level LM public key */ + +/* The HSS signature consists of: */ +/* A word giving the number of levels - 1 == L-1 */ +/* L-1 iterations of (i = 1..L-1): */ +/* - LMS Signature of public key i (signed by the pub key of level i-1) */ +/* - LMS Public key (of level i) */ +/* - LMS Signature of the message, signed by the bottomost pub key */ + +/* This is the routine that runs on a thread to validate an LMS signature */ +void validate_internal_sig(const void *data, + struct thread_collection *col) { + const struct verify_detail *d = data; + + bool success = lm_validate_signature(d->public_key, + d->message, d->message_len, false, + d->signature, d->signature_len); + + if (!success) { + /* Drat, it failed; call the failure in */ + hss_thread_before_write(col); + *d->got_error = hss_error_bad_signature; + hss_thread_after_write(col); + } +} + +/* + * Validate an HSS signature, using a public key. Parameters: + * public_key - pointer to the public key + * message - the mmessage that was supposedly signed + * message_len - the size of the message + * siganture - the signature we're checking + * signature_len - the length of the signature + * + * This returns true if everything checks out and the signature verifies + * false on error (whether the error is because the signature didn't verify, + * or we hit some sort of error on the way) + */ +bool hss_validate_signature( + const unsigned char *public_key, + const void *message, size_t message_len, + const unsigned char *signature, size_t signature_len, + struct hss_extra_info *info) { + struct hss_extra_info temp_info = { 0 }; + if (!info) info = &temp_info; + unsigned i; + + /* Get the number of levels the signature claims */ + if (signature_len < 4) { + info->error_code = hss_error_bad_signature; + return false; + } + uint_fast32_t levels = get_bigendian( signature, 4 ) + 1; + /* +1 because what's in the signature is levels-1 */ + signature += 4; signature_len -= 4; + if (levels < MIN_HSS_LEVELS || levels > MAX_HSS_LEVELS || + levels != get_bigendian( public_key, 4 )) { + info->error_code = hss_error_bad_signature; + return false; + } + + /* Compare that to what the public key says */ + uint_fast32_t pub_levels = get_bigendian( public_key, 4 ); + if (levels != pub_levels) { + /* Signature and public key don't agree */ + info->error_code = hss_error_bad_signature; + return false; + } + /* We'll use the LMS public key embedded in the HSS public key as the */ + /* key to use to validate the top level signature */ + public_key += 4; + + struct thread_collection *col = hss_thread_init(info->num_threads); + enum hss_error_code got_error = hss_error_none; + struct verify_detail detail; + detail.got_error = &got_error; + + /* Parse through the signature, kicking off the tasks to validate */ + /* individual LMS signatures within it as we go */ + for (i=0; i + * where: + * - Signature A is the LMS signature of Public Key B + * - Public Key B is the message we're verifying (and will be + * interpreted as a public key in the next iteration) + * public_key points to Public Key A, which is the public key that + * we use to verify Signature A + */ + + /* Get the length of Signature A */ + param_set_t lm_type = get_bigendian( public_key, 4 ); + param_set_t lm_ots_type = get_bigendian( public_key+4, 4 ); + unsigned l_siglen = lm_get_signature_len(lm_type, lm_ots_type); + if (l_siglen == 0 || l_siglen > signature_len) { + info->error_code = hss_error_bad_signature; + goto failed; + } + + /* Retain a pointer to Signature A, and advance the current */ + /* pointer to Public Key B */ + const unsigned char *l_sig = signature; + signature += l_siglen; signature_len -= l_siglen; + + /* The next thing is the next level public key (Public Key B) */ + /* which we need to validate) */ + if (signature_len < 4) { + info->error_code = hss_error_bad_signature; + goto failed; + } + /* + * Get how long Public Key B would be, assuming it is a valid + * public key. If it's not a valid public key (that is, if + * someone other than the valid signer modified it), then + * Signature A will not validate, and so we'll catch that + */ + lm_type = get_bigendian( signature, 4 ); + unsigned l_pubkeylen = lm_get_public_key_len(lm_type); + if (l_pubkeylen == 0 || l_pubkeylen > signature_len) { + info->error_code = hss_error_bad_signature; + goto failed; + } + + /* Retain a pointer to Public Key B, and advance the current */ + /* pointer past it (to the data the next iteration cares about) */ + const unsigned char *l_pubkey = signature; + signature += l_pubkeylen; signature_len -= l_pubkeylen; + + /* Now, schedule the validation of Signature A */ + detail.public_key = public_key; /* Public key A */ + detail.message = l_pubkey; /* Public key B, that is, */ + /* the message to validate */ + detail.message_len = l_pubkeylen; + detail.signature = l_sig; /* Signature A */ + detail.signature_len = l_siglen; + hss_thread_issue_work( col, validate_internal_sig, + &detail, sizeof detail ); + + /* We validated this level's public key (or, at least, scheduled */ + /* it, if it turns out not to validate, we'll catch it below) */ + /* Use the current Public Key B as the next level's Public Key A */ + public_key = l_pubkey; + } + + /* + * We're at the bottom level; now, the current position in the signature + * looks like (or, rather, is *supposed to look like*) this: + * + * where: + * - Signature A is the bottom signature, which signs the actual + * message + * public_key points to the bottom level public key, which is used to + * validate the signature + * + * Just go ahead and schedule the validation + */ + detail.public_key = public_key; /* Public key to use */ + detail.message = message; /* The user's message that needs */ + detail.message_len = message_len; /* validation */ + detail.signature = signature; /* Bottom level LMS signature */ + detail.signature_len = signature_len; + hss_thread_issue_work( col, validate_internal_sig, + &detail, sizeof detail ); + + /* Wait for all the threads to complete */ + hss_thread_done(col); + + /* It succeeded if none of the threads reported an error */ + if (got_error == hss_error_none) return true; + info->error_code = got_error; + return false; + +failed: /* If we get an intermediate failure */ + hss_thread_done(col); + return false; +} diff --git a/src/sig_stfl/lms/external/hss_verify.h b/src/sig_stfl/lms/external/hss_verify.h new file mode 100644 index 0000000000..7a29deb275 --- /dev/null +++ b/src/sig_stfl/lms/external/hss_verify.h @@ -0,0 +1,23 @@ +#if !defined( HSS_VERIFY_H_ ) +#define HSS_VERIFY_H_ + +#include + +struct hss_extra_info; +/* + * This is the function to validate a signature; return true if it validates, + * false if it doesn't + * + * public_key is the pointer to the public key + * + * message, message_len is the message to validate + * + * signature, signature_len is the signature to validate + */ +bool hss_validate_signature( + const unsigned char *public_key, + const void *message, size_t message_len, + const unsigned char *signature, size_t signature_len, + struct hss_extra_info *info); + +#endif /* HSS_VERIFY_H_ */ diff --git a/src/sig_stfl/lms/external/hss_verify_inc.c b/src/sig_stfl/lms/external/hss_verify_inc.c new file mode 100644 index 0000000000..451082f8de --- /dev/null +++ b/src/sig_stfl/lms/external/hss_verify_inc.c @@ -0,0 +1,203 @@ +/* + * This is the code that implements the hierarchical part of the LMS hash + * based signatures; in this case, incremental verification + */ +#include +#include "common_defs.h" +#include "hss_verify_inc.h" +#include "lm_verify.h" +#include "lm_common.h" +#include "lm_ots_verify.h" +#include "hash.h" +#include "endian.h" +#include "hss_thread.h" +#include "hss_internal.h" +#include "lm_ots_common.h" +#include "hss.h" + +/* + * Start the process of validating an HSS signature incrementally. Parameters: + * ctx - The state we'll use to track the incremental validation + * public_key - pointer to the public key + * siganture - the signature we're checking + * signature_len - the length of the signature + */ +bool hss_validate_signature_init( + struct hss_validate_inc *ctx, + const unsigned char *public_key, + const unsigned char *signature, size_t signature_len, + struct hss_extra_info *info) { + struct hss_extra_info temp_info = { 0 }; + if (!info) info = &temp_info; + unsigned i; + if (!ctx) { + info->error_code = hss_error_got_null; + return false; + } + ctx->status = hss_error_ctx_uninitialized; /* Until we hear otherwise, */ + /* we got a failure */ + + const unsigned char *orig_signature = signature; +; + /* Get the number of levels the signature claims */ + if (signature_len < 4) { + ctx->status = info->error_code = hss_error_bad_signature; + return false; + } + uint_fast32_t levels = get_bigendian( signature, 4 ) + 1; + /* +1 because what's in the signature is levels-1 */ + signature += 4; signature_len -= 4; + if (levels < MIN_HSS_LEVELS || levels > MAX_HSS_LEVELS || + levels != get_bigendian( public_key, 4 )) { + ctx->status = info->error_code = hss_error_bad_signature; + return false; + } + uint_fast32_t pub_levels = get_bigendian( public_key, 4 ); + if (levels != pub_levels) { + /* Signature and public key don't agree */ + ctx->status = info->error_code = hss_error_bad_signature; + return false; + } + public_key += 4; + + /* Validate the upper levels of the signature */ + struct thread_collection *col = NULL; + if (levels > 1) { + col = hss_thread_init(info->num_threads); + enum hss_error_code got_error = hss_error_none; + struct verify_detail detail; + detail.got_error = &got_error; + + /* Scan through the signature, kicking off the tasks to validate it */ + /* as we go. Note that we don't validate the bottom level yet */ + for (i=0; i signature_len) goto failed; + const unsigned char *l_sig = signature; + signature += l_siglen; signature_len -= l_siglen; + + /* The next thing is the next level public key (which we need */ + /* to validate) */ + if (signature_len < 4) goto failed; + lm_type = get_bigendian( signature, 4 ); + unsigned l_pubkeylen = lm_get_public_key_len(lm_type); + if (l_pubkeylen == 0 || l_pubkeylen > signature_len) goto failed; + const unsigned char *l_pubkey = signature; + signature += l_pubkeylen; signature_len -= l_pubkeylen; + + /* Validate the signature of this level's public key */ + detail.public_key = public_key; + detail.message = l_pubkey; + detail.message_len = l_pubkeylen; + detail.signature = l_sig; + detail.signature_len = l_siglen; + hss_thread_issue_work( col, validate_internal_sig, + &detail, sizeof detail ); + + /* We validated this level's public key (or, at least, */ + /* scheduled it, if it turns out not to validate, we'll catch */ + /* it below), use it to validate the next level */ + public_key = l_pubkey; + } + + /* Wait for all the threads to complete */ + hss_thread_done(col); + col = NULL; + + if (got_error != hss_error_none) { + ctx->status = info->error_code = got_error; + return false; + } + } + + ctx->signature_offset = signature - orig_signature; + ctx->signature_len = signature_len; + + /* We have the public key in front of us; stash a copy */ + /* Right now, we have a fixed length public key */ + /* If that changes, we'll need to investigate the parmaeter set */ + memcpy( ctx->final_public_key, public_key, 8 + I_LEN + MAX_HASH ); + + /* Now, initialize the context */ + param_set_t ots_type = get_bigendian( public_key+4, 4 ); + + unsigned h, n; + if (!lm_ots_look_up_parameter_set(ots_type, &h, &n, NULL, NULL, NULL)) { + /* Because we're checking in parallel, this may be caused by */ + /* a bad signature */ + ctx->status = info->error_code = hss_error_bad_signature; + return false; + } + ctx->h = h; + hss_init_hash_context( h, &ctx->hash_ctx ); + { + unsigned char prefix[ MESG_PREFIX_MAXLEN ]; + memcpy( prefix + MESG_I, ctx->final_public_key+8, I_LEN ); + memcpy( prefix + MESG_Q, signature, 4 ); /* q */ + SET_D( prefix + MESG_D, D_MESG ); + memcpy( prefix + MESG_C, signature+8, n ); /* C */ + hss_update_hash_context(h, &ctx->hash_ctx, prefix, MESG_PREFIX_LEN(n) ); + } + + /* It succeeded so far... */ + ctx->status = hss_error_none; + return true; + +failed: /* If we get an intermediate failure */ + if (col) hss_thread_done(col); + ctx->status = info->error_code = hss_error_bad_signature; + return false; +} + +/* This adds another piece of the message to validate */ +bool hss_validate_signature_update( + struct hss_validate_inc *ctx, + const void *message_segment, + size_t len_message_segment) { + if (!ctx || ctx->status != hss_error_none) return false; + + hss_update_hash_context(ctx->h, &ctx->hash_ctx, + message_segment, len_message_segment ); + + return true; +} + +/* We've added all the pieces of the messages, now do the validation */ +bool hss_validate_signature_finalize( + struct hss_validate_inc *ctx, + const unsigned char *signature, + struct hss_extra_info *info) { + struct hss_extra_info temp_info = { 0 }; + if (!info) info = &temp_info; + + if (!ctx) { + info->error_code = hss_error_got_null; + return false; + } + if (ctx->status != hss_error_none) { + info->error_code = ctx->status; + return false; + } + + /* Success or fail, we can't use the context any more */ + ctx->status = hss_error_ctx_already_used; + + /* Generate the final hash */ + unsigned char hash[ MAX_HASH ]; + unsigned h = ctx->h; + hss_finalize_hash_context( h, &ctx->hash_ctx, hash ); + + /* It passes iff the final signature validates */ + if (lm_validate_signature( + ctx->final_public_key, + hash, sizeof hash, true, + signature + ctx->signature_offset, ctx->signature_len)) { + return true; + } + + info->error_code = hss_error_bad_signature; + return false; +} diff --git a/src/sig_stfl/lms/external/hss_verify_inc.h b/src/sig_stfl/lms/external/hss_verify_inc.h new file mode 100644 index 0000000000..147308b23c --- /dev/null +++ b/src/sig_stfl/lms/external/hss_verify_inc.h @@ -0,0 +1,82 @@ +#if !defined( HSS_VERIFY_INC_H_ ) +#define HSS_VERIFY_INC_H_ +#include +#include +#include "hash.h" +#include "common_defs.h" +#include "hss.h" + +/* + * These are the functions to validate a signature incrementally. + * That is, we assume that we don't have the entire message at + * once, instead, we have it in pieces (for example, the signature + * is of a multigigabyte file) + * + * Usage: + * struct hss_validate_inc ctx; + * bool success = hss_validate_init( &ctx, public_key, signature ); + * hss_validate_update( &ctx, message_part_1, len_1 ); + * hss_validate_update( &ctx, message_part_2, len_2 ); + * hss_validate_update( &ctx, message_part_3, len_3 ); + * success = hss_validate_finalize( &ctx, signature ); + * if (success) printf( "The signature validated\n" ); + * + * This is in its own include file because we need to import some + * 'not-generally-for-general-consumption' include files to make + * it work (as they're in the hss_validate_inc structure) + */ + +/* + * This is the context structure that holds the intermedate results of an + * in-process validation + * It's a application-visible structure for ease of use: the application can + * allocate it as an automatic, and if the application aborts in the middle of + * the validation, it doesn't cause a memory leak + */ +struct hss_validate_inc { + enum hss_error_code status; /* Either hss_error_none if we're in */ + /* process, or the reason why we'd fail */ + size_t signature_offset; /* Offset of the final signature within the */ + /* HSS signature */ + size_t signature_len; /* Length of the final signature */ + + unsigned h; /* Hash function used */ + + /* The final public key. We need this at finalization time, */ + /* however they might not be in the signature (L=1 case) */ + unsigned char final_public_key[8 + I_LEN + MAX_HASH]; + + union hash_context hash_ctx; /* For the running hash we use */ +}; + +struct hss_extra_info; + +/* Starts off the process of incrementally validating a signature */ +/* If it detects a failure, this returns false */ +/* Handing the return code is optional; if this fails, the finalization */ +/* step will fail too */ +bool hss_validate_signature_init( + struct hss_validate_inc *ctx, + const unsigned char *public_key, + const unsigned char *signature, size_t signature_len, + struct hss_extra_info *info); + +/* This adds another piece of the message to validate */ +/* Again, the result code is optional */ +bool hss_validate_signature_update( + struct hss_validate_inc *ctx, + const void *message_segment, + size_t len_message_segment); + +/* This finalizes the signature validation */ +/* This returns true if the signature validates (and we didn't detect any */ +/* intermediate failures) */ +/* We ask the caller to pass in the signature again, because we'd prefer */ +/* not having to place the final LMS signature in the ctx structure; that'd */ +/* make it larger than we'd like */ +bool hss_validate_signature_finalize( + struct hss_validate_inc *ctx, + const unsigned char *signature, + struct hss_extra_info *info); + +#endif /* HSS_VERIFY_INC_H_ */ diff --git a/src/sig_stfl/lms/external/hss_zeroize.c b/src/sig_stfl/lms/external/hss_zeroize.c new file mode 100644 index 0000000000..f2bd334903 --- /dev/null +++ b/src/sig_stfl/lms/external/hss_zeroize.c @@ -0,0 +1,49 @@ +#include "hss_zeroize.h" +#include + +/* + * This is a function to zeroize a section of memory + * + * We do this because when we release a section of memory (either because it's + * a local variable going out of scope, or we free it), it's possible that + * the memory will retain its contents after another allocation (possibly + * done by someone outside this module). So, to avoid this potential security + * issue, we scrub the memory (at least, the parts that have data that would + * make it possible to forge if it leaked) before releasing it. + * + * Now, there's a bunch of things we don't mind being exposed (e.g. internal + * node values of Merkle trees), so we don't use this everywhere; only where + * it is needed + * + * We use this, rather than having routines simply call memset, to avoid + * potential problems with overenthusiastic optimizers. Generally, we zeroize + * an area immediately before it goes out of scope or we free it, however an + * optimizer might conclude "they're about to release the memory, there's no + * need to write to it first" + * + * For similar reasons, this function is in its own source file (so that a + * compiler optimizer who doesn't examine more than one source at a time can't + * eliminate it). If we are worried about optimizers who can be even more + * enthusiastic, there are other things we can try; however we're not going to + * worry about that right now + */ +void hss_zeroize( void *area, size_t len ) { +#if defined( __STDC_LIB_EXT1__ ) + /* + * C11 defines a version of memset that does precisely what we want, and is + * guaranteed not to be molested by the optimizer + * Note that the first 'len' is supposed to be the length of the buffer + * we're cleaning and the second 'len' is the area to clear. Since we + * expect the caller to ask us to clear the entire area (and hence gives + * us only one length), we use the same for both + */ + memset_s( area, len, 0, len ); +#else + /* + * Fallback code for pre-C11 versions + */ + volatile unsigned char *p = area; + + while (len--) *p++ = 0; +#endif +} diff --git a/src/sig_stfl/lms/external/hss_zeroize.h b/src/sig_stfl/lms/external/hss_zeroize.h new file mode 100644 index 0000000000..702d91137b --- /dev/null +++ b/src/sig_stfl/lms/external/hss_zeroize.h @@ -0,0 +1,10 @@ +#if !defined( HSS_ZEROIZE_H_ ) +#define HSS_ZEROIZE_H_ + +#include + +/* Zeroize an area, that is, scrub it from holding any potentially secret */ +/* information */ +void hss_zeroize( void *area, size_t len ); + +#endif /* HSS_ZEROIZE_H_ */ diff --git a/src/sig_stfl/lms/external/lm_common.c b/src/sig_stfl/lms/external/lm_common.c new file mode 100644 index 0000000000..e3eb56f0f0 --- /dev/null +++ b/src/sig_stfl/lms/external/lm_common.c @@ -0,0 +1,79 @@ +/* + * This is the code that implements the tree part of the LMS hash + * based signatures + */ +#include +#include "lm_common.h" +#include "hash.h" +#include "common_defs.h" +#include "lm_ots_common.h" + +/* + * Internal utility to convert encoded parameter sets into what they represent + */ +bool lm_look_up_parameter_set(param_set_t parameter_set, + unsigned *h, unsigned *n, unsigned *height) { + unsigned v_h, v_n, v_height; + switch (parameter_set) { + case LMS_SHA256_N32_H5: + v_h = HASH_SHA256; v_n = 32; v_height = 5; break; + case LMS_SHA256_N32_H10: + v_h = HASH_SHA256; v_n = 32; v_height = 10; break; + case LMS_SHA256_N32_H15: + v_h = HASH_SHA256; v_n = 32; v_height = 15; break; + case LMS_SHA256_N32_H20: + v_h = HASH_SHA256; v_n = 32; v_height = 20; break; + case LMS_SHA256_N32_H25: + v_h = HASH_SHA256; v_n = 32; v_height = 25; break; + default: return false; + } + + if (h) *h = v_h; + if (n) *n = v_n; + if (height) *height = v_height; + + return true; +} + +/* The LM public key consists of: */ +#define LM_PUB_PARM_SET 0 /* The parameter set (4 bytes) */ +#define LM_PUB_OTS_PARM_SET 4 /* The OTS parameter set (4 bytes) */ +#define LM_PUB_I 8 /* Our nonce (I) value (16 bytes) */ +/* The root value comes here */ + +/* + * XDR requires us to pad the I value out to a multiple of 4 + * This computes how long the field will be after padding + * That is, it rounds len_I up to the next multiple of 4 + */ +#define padded_length(len_I) (((len_I) + 3) & ~3) + +/* The public key just consists of the parameter sets, plus I, plus root hash */ +size_t lm_get_public_key_len(param_set_t lm_type) { + unsigned n; + if (!lm_look_up_parameter_set( lm_type, 0, &n, 0)) + return 0; + + return LM_PUB_I + padded_length(I_LEN) + n; +} + +/* + * The amount of space we use for signature + */ +size_t lm_get_signature_len(param_set_t lm_type, + param_set_t lm_ots_type) { + unsigned n, height; + if (!lm_look_up_parameter_set( lm_type, 0, &n, &height )) + return 0; + + int ots_sig_len = lm_ots_get_signature_len(lm_ots_type); + if (ots_sig_len == 0) + return 0; + + /* + * The LM signature consists of the type code, the diversification factor, + * the LM-OTS signature (which includes the OTS type code), and the + * authentication path (which is an array of height hashes) + */ + return 4 + 4 + ots_sig_len + n*height; +} diff --git a/src/sig_stfl/lms/external/lm_common.h b/src/sig_stfl/lms/external/lm_common.h new file mode 100644 index 0000000000..027eda2214 --- /dev/null +++ b/src/sig_stfl/lms/external/lm_common.h @@ -0,0 +1,20 @@ +#if !defined(LM_COMMON_H_) +#define LM_COMMON_H_ + +#include +#include "common_defs.h" + +size_t lm_get_public_key_len(param_set_t lm_type); +size_t lm_get_signature_len(param_set_t lm_type, + param_set_t lm_ots_type); + +bool lm_look_up_parameter_set(param_set_t parameter_set, + unsigned *h, unsigned *n, unsigned *height); + +/* The format of an LM public key; it consists of: */ +#define LM_PUB_PARM_SET 0 /* The parameter set (4 bytes) */ +#define LM_PUB_OTS_PARM_SET 4 /* The OTS parameter set (4 bytes) */ +#define LM_PUB_I 8 /* Our nonce (I) value (32 or 64 bytes) */ +/* The root value comes here */ + +#endif /* LM_COMMON_H_ */ diff --git a/src/sig_stfl/lms/external/lm_ots.h b/src/sig_stfl/lms/external/lm_ots.h new file mode 100644 index 0000000000..4fcf690342 --- /dev/null +++ b/src/sig_stfl/lms/external/lm_ots.h @@ -0,0 +1,64 @@ +#if !defined( LM_OTS_H_ ) +#define LM_OTS_H_ + +#include "common_defs.h" +#include + +/* + * These are routines that implement the OTS signature scheme. These routines + * never actually form a "private key"; instead, the signer passes the 'seed' + * (and public data) to form the public key and to do the actual signature. + * We do this because the LM routines are actually better suited for doing + * seed management. + */ +struct seed_derive; + +/* + * Compute the public key. Note that it doesn't compute a 'private key'; + * the signature algorithm gets that data when we pass the parameters again + * Parameters: + * lm_ots_type - The parameter set + * I - The I public identifier to use + * q - The diversification string, passed as a 4 byte integer + * seed - The structure used to generate seeds + * public_key - Where to place the public key + * public_key_len - The length of the above buffer + * This returns true on success + */ +bool lm_ots_generate_public_key( + param_set_t lm_ots_type, + const unsigned char *I, /* Public key identifier */ + merkle_index_t q, /* Diversification string, 4 bytes value */ + struct seed_derive *seed, + unsigned char *public_key, size_t public_key_len); + +/* + * Sign a message. Warning: the caller is expected to make sure that it signs + * only one message with a given seed/I/q set + * Parameters: + * lm_ots_type - The parameter set + * I - The I public identifier to use + * q - The diversification string, passed as a 4 byte integer + * seed - The structure used to generate seeds + * message - Message to sign + * message_len - Length of the message + * prehashed - Set if the message hashing has already taken place + * signature - Where to place the signature + * signature_len - The length of the above buffer + * This returns true on success + */ +bool lm_ots_generate_signature( + param_set_t lm_ots_type, + const unsigned char *I, + merkle_index_t q, + struct seed_derive *seed, + const void *message, size_t message_len, bool prehashed, + unsigned char *signature, size_t signature_len); + +/* The include file for the verification routine */ +#include "lm_ots_verify.h" + +/* The include file for the common access routines */ +#include "lm_ots_common.h" + +#endif /* LM_OTS_H_ */ diff --git a/src/sig_stfl/lms/external/lm_ots_common.c b/src/sig_stfl/lms/external/lm_ots_common.c new file mode 100644 index 0000000000..45672e18b2 --- /dev/null +++ b/src/sig_stfl/lms/external/lm_ots_common.c @@ -0,0 +1,99 @@ +/* + * This is the code that implements the one-time-signature part of the LMS hash + * based signatures + */ +#include "lm_ots_common.h" +#include "common_defs.h" +#include "hash.h" + +/* + * Convert the external name of a parameter set into the set of values we care + * about + */ +bool lm_ots_look_up_parameter_set(param_set_t parameter_set, + unsigned *h, unsigned *n, unsigned *w, unsigned *p, unsigned *ls) { + unsigned v_h, v_n, v_w, v_p, v_ls; + switch (parameter_set) { + case LMOTS_SHA256_N32_W1: + v_h = HASH_SHA256; v_n = 32; v_w = 1; v_p = 265; v_ls = 7; break; + case LMOTS_SHA256_N32_W2: + v_h = HASH_SHA256; v_n = 32; v_w = 2; v_p = 133; v_ls = 6; break; + case LMOTS_SHA256_N32_W4: + v_h = HASH_SHA256; v_n = 32; v_w = 4; v_p = 67; v_ls = 4; break; + case LMOTS_SHA256_N32_W8: + v_h = HASH_SHA256; v_n = 32; v_w = 8; v_p = 34; v_ls = 0; break; + default: return false; + } + + if (h) *h = v_h; + if (n) *n = v_n; + if (w) *w = v_w; + if (p) *p = v_p; + if (ls) *ls = v_ls; + + return true; +} + +/* The public key just consists of the bare hash */ +size_t lm_ots_get_public_key_len(param_set_t lm_ots_type) { + unsigned n; + if (!lm_ots_look_up_parameter_set( lm_ots_type, 0, &n, 0, 0, 0 )) + return 0; + + return n; +} + +/* Return the length of a signature */ +size_t lm_ots_get_signature_len(param_set_t lm_ots_type) { + unsigned n, p; + + if (!lm_ots_look_up_parameter_set( lm_ots_type, 0, &n, 0, &p, 0 )) + return 0; + + return 4 + n + p*n; +} + +/* Return the number of hashes we need to compute to generate a public key */ +unsigned lm_ots_hashes_per_public_key(param_set_t lm_ots_type) { + unsigned wint, num_dig; + if (!lm_ots_look_up_parameter_set(lm_ots_type, + NULL, NULL, &wint, &num_dig, NULL)) { + return 0; + } + + /* Total number of hash invocations: + * For each digit, we expand the seed (1), and then perform (2**wint-1) + * haashes to obtain the end of the chain + * Then, we hash all the ends of the chains together + * If we were to return the number of hash compression operations, + * the final 1 would be a bit larger + */ + return num_dig * (1 << wint) + 1; +} + +/* Todo: some of these values depend only on w; why do we need to recompute */ +/* them each time??? */ +unsigned lm_ots_coef(const unsigned char *Q, unsigned i, unsigned w) { + unsigned index = (i * w) / 8; /* Which byte holds the coefficient */ + /* we want */ + unsigned digits_per_byte = 8/w; + unsigned shift = w * (~i & (digits_per_byte-1)); /* Where in the byte */ + /* the coefficient is */ + unsigned mask = (1<> shift) & mask; +} + +/* This returns the Winternitz checksum to append to the hash */ +unsigned lm_ots_compute_checksum(const unsigned char *Q, unsigned Q_len, + unsigned w, unsigned ls) { + unsigned sum = 0; + unsigned i; + unsigned u = 8 * Q_len / w; + unsigned max_digit = (1< +#include "common_defs.h" + +bool lm_ots_look_up_parameter_set(param_set_t parameter_set, + unsigned *h, unsigned *n, unsigned *w, unsigned *p, unsigned *ls); +size_t lm_ots_get_public_key_len(param_set_t lm_ots_type); +size_t lm_ots_get_signature_len(param_set_t lm_ots_type); +unsigned lm_ots_hashes_per_public_key(param_set_t lm_ots_type); +unsigned lm_ots_compute_checksum(const unsigned char *Q, unsigned Q_len, + unsigned w, unsigned ls); +unsigned lm_ots_coef(const unsigned char *Q, unsigned i, unsigned w); + +#endif /* LM_OTS_COMMON_H_ */ diff --git a/src/sig_stfl/lms/external/lm_ots_sign.c b/src/sig_stfl/lms/external/lm_ots_sign.c new file mode 100644 index 0000000000..ee8f56b0a2 --- /dev/null +++ b/src/sig_stfl/lms/external/lm_ots_sign.c @@ -0,0 +1,168 @@ +/* + * This is the code that implements the one-time-signature part of the LMS hash + * based signatures + */ +#include +#include "common_defs.h" +#include "lm_ots.h" +#include "lm_ots_common.h" +#include "hash.h" +#include "endian.h" +#include "hss_zeroize.h" +#include "hss_derive.h" +#include "hss_internal.h" + +bool lm_ots_generate_public_key( + param_set_t lm_ots_type, + const unsigned char *I, /* Public key identifier */ + merkle_index_t q, /* Diversification string, 4 bytes value */ + struct seed_derive *seed, + unsigned char *public_key, size_t public_key_len) { + + /* Look up the parameter set */ + unsigned h, n, w, p, ls; + LMS_UNUSED(public_key_len); + if (!lm_ots_look_up_parameter_set( lm_ots_type, &h, &n, &w, &p, &ls )) + return false; + + /* Start the hash that computes the final value */ + union hash_context public_ctx; + hss_init_hash_context(h, &public_ctx); + { + unsigned char prehash_prefix[ PBLC_PREFIX_LEN ]; + memcpy( prehash_prefix + PBLC_I, I, I_LEN ); + put_bigendian( prehash_prefix + PBLC_Q, q, 4 ); + SET_D( prehash_prefix + PBLC_D, D_PBLC ); + hss_update_hash_context(h, &public_ctx, prehash_prefix, + PBLC_PREFIX_LEN ); + } + + /* Now generate the public key */ + /* This is where we spend the majority of the time during key gen and */ + /* signing operations; it would make sense to attempt to try to take */ + /* advantage of parallel (SIMD) hardware; even if we use it nowhere */ + /* else, we'd get a significant speed up */ + unsigned i, j; + + unsigned char buf[ ITER_MAX_LEN ]; + memcpy( buf + ITER_I, I, I_LEN ); + put_bigendian( buf + ITER_Q, q, 4 ); + union hash_context ctx; + + hss_seed_derive_set_j( seed, 0 ); + + for (i=0; i +#include "lm_ots_verify.h" +#include "lm_ots_common.h" +#include "hash.h" +#include "endian.h" +#include "common_defs.h" + +/* + * This validate a OTS signature for a message. It doesn't actually use the + * public key explicitly; instead, it just produces the root key, based on the + * message; the caller is assumed to compare it to the expected value + * Parameters: + * - computed_public_key - where to place the reconstructed root. It is + * assumed that the caller has allocated enough space + * - I: the nonce value ("I") to use + * - q: diversification string + * - message - the message to verify + * - message_len - the length of the message + * - message_prehashed - true if the message has already undergone the initial + * (D_MESG) hash + * - signature - the signature + * - signature_len - the length of the signature + * - parameter_set - what we expect the parameter set to be + * + * This returns true on successfully recomputing a root value; whether it is + * the right one is something the caller would need to verify + */ +bool lm_ots_validate_signature_compute( + unsigned char *computed_public_key, + const unsigned char *I, merkle_index_t q, + const void *message, size_t message_len, bool message_prehashed, + const unsigned char *signature, size_t signature_len, + param_set_t expected_parameter_set) { + if (signature_len < 4) return false; /* Ha, ha, very funny... */ + + /* We don't trust the parameter set that's in the signature; verify it */ + param_set_t parameter_set = get_bigendian( signature, 4 ); + if (parameter_set != expected_parameter_set) { + return false; + } + + unsigned h, n, w, p, ls; + if (!lm_ots_look_up_parameter_set( parameter_set, &h, &n, &w, &p, &ls )) + return false; + + if (signature_len != 4 + n * (p+1)) return false; + + const unsigned char *C = signature + 4; + const unsigned char *y = C + n; + + unsigned char Q[MAX_HASH + 2]; + if (message_prehashed) { + memcpy( Q, message, n ); + } else { + union hash_context ctx; + /* Compute the initial hash */ + hss_init_hash_context(h, &ctx); + /* Hash the message prefix */ + { + unsigned char prefix[ MESG_PREFIX_MAXLEN ]; + memcpy( prefix + MESG_I, I, I_LEN ); + put_bigendian( prefix + MESG_Q, q, 4 ); + SET_D( prefix + MESG_D, D_MESG ); + memcpy( prefix + MESG_C, C, n ); + hss_update_hash_context(h, &ctx, prefix, MESG_PREFIX_LEN(n) ); + } + /* Then, the message */ + hss_update_hash_context(h, &ctx, message, message_len ); + + hss_finalize_hash_context( h, &ctx, Q ); + } + + /* Append the checksum to the randomized hash */ + put_bigendian( &Q[n], lm_ots_compute_checksum(Q, n, w, ls), 2 ); + + /* And, start building the parts for the final hash */ + union hash_context final_ctx; + hss_init_hash_context(h, &final_ctx); + { + unsigned char prehash_prefix[ PBLC_PREFIX_LEN ]; + memcpy( prehash_prefix + PBLC_I, I, I_LEN ); + put_bigendian( prehash_prefix + PBLC_Q, q, 4 ); + SET_D( prehash_prefix + PBLC_D, D_PBLC ); + hss_update_hash_context(h, &final_ctx, prehash_prefix, + PBLC_PREFIX_LEN ); + } + + unsigned i; + unsigned char tmp[ITER_MAX_LEN]; + + /* Preset the parts of tmp that don't change */ + memcpy( tmp + ITER_I, I, I_LEN ); + put_bigendian( tmp + ITER_Q, q, 4 ); + + unsigned max_digit = (1< +#include "common_defs.h" + +/* + * This validates an OTS signature, but instead of producing a SUCCESS/FAILURE + * return, it generates the root value (which the caller is expected to check). + * It can return false (failure), for things such as unrecognized parameter + * set It also makes sure that the parameter set of the signature is that + * value (as we need to make sure that the attacker didn't substitute a + * weaker one) + */ +bool lm_ots_validate_signature_compute( + unsigned char *computed_public_key, + const unsigned char *I, + merkle_index_t q, /* Diversification string, 4 bytes value */ + const void *message, size_t message_len, bool prehashed, + const unsigned char *signature, size_t signature_len, + param_set_t expected_parameter_set); + +#endif /* LM_OTS_VERIFY_H_ */ diff --git a/src/sig_stfl/lms/external/lm_verify.c b/src/sig_stfl/lms/external/lm_verify.c new file mode 100644 index 0000000000..46b3627885 --- /dev/null +++ b/src/sig_stfl/lms/external/lm_verify.c @@ -0,0 +1,107 @@ +/* + * This is the code that implements the tree part of the LMS hash + * based signatures + */ +#include +#include "lm_verify.h" +#include "lm_common.h" +#include "lm_ots_common.h" +#include "lm_ots_verify.h" +#include "hash.h" +#include "endian.h" +#include "common_defs.h" + +/* + * XDR requires us to pad the I value out to a multiple of 4 + * This computes how long the field will be after padding + * That is, it rounds len_I up to the next multiple of 4 + */ +#define padded_length(len_I) (((len_I) + 3) & ~3) + +/* + * This validate an LM signature for a message. It does take an XDR-encoded + * signature, and verify against it. + * Parameters: + * - public_key - the XDR-encoded public ley + * - message - the message to verify + * - message_len - the length of the message + * - signature - the signature + * - signature_len - the length of the signature + * + * This returns true if the signature verifies + */ +bool lm_validate_signature( + const unsigned char *public_key, + const void *message, size_t message_len, bool prehashed, + const unsigned char *signature, size_t signature_len) { + union hash_context ctx; + + param_set_t lm_type = get_bigendian( public_key + LM_PUB_PARM_SET, 4 ); + param_set_t ots_type = get_bigendian( public_key + LM_PUB_OTS_PARM_SET, 4 ); + + unsigned h, n, height; + if (!lm_look_up_parameter_set(lm_type, &h, &n, &height)) return false; + + unsigned char computed_public_key[MAX_HASH]; + + const unsigned char *I = public_key + LM_PUB_I; + + if (signature_len < 8) return false; + merkle_index_t count = get_bigendian( signature, 4 ); + signature += 4; signature_len -= 4; /* 4 bytes, rather then 8 */ + /* the OTS type is expected to be a part of the OTS signature, */ + /* which lm_ots_validate_signature_compute will expect */ + + /* Compute the OTS root */ + size_t ots_publen = lm_ots_get_public_key_len(ots_type); + size_t ots_siglen = lm_ots_get_signature_len(ots_type); + if (ots_publen == 0 || ots_siglen == 0) return false; + if (signature_len < ots_siglen) return false; + + unsigned char ots_sig[LEAF_MAX_LEN]; + if (!lm_ots_validate_signature_compute(ots_sig + LEAF_PK, I, count, + message, message_len, prehashed, + signature, ots_siglen, ots_type)) return false; + signature += ots_siglen; signature_len -= ots_siglen; + + /* Get the parameter set declared in the sigature; make sure it matches */ + /* what we expect */ + if (signature_len < 4) return false; + param_set_t parameter_set = get_bigendian( signature, 4 ); + if (parameter_set != lm_type) return false; + signature += 4; signature_len -= 4; + + merkle_index_t count_nodes = (merkle_index_t)1 << height; + + if (signature_len != n * height) return false; /* We expect the auth */ + /* path to be there as the last element */ + if (count >= count_nodes) return false; /* Index out of range */ + merkle_index_t node_num = count + count_nodes; + + memcpy( ots_sig + LEAF_I, I, I_LEN ); + put_bigendian( ots_sig + LEAF_R, node_num, 4 ); + SET_D( ots_sig + LEAF_D, D_LEAF ); + hss_hash_ctx( computed_public_key, h, &ctx, ots_sig, LEAF_LEN(n) ); + + unsigned char prehash[ INTR_MAX_LEN ]; + memcpy( prehash + INTR_I, I, I_LEN ); + SET_D( prehash + INTR_D, D_INTR ); + while (node_num > 1) { + if (node_num % 2) { + memcpy( prehash + INTR_PK + 0, signature, n ); + memcpy( prehash + INTR_PK + n, computed_public_key, n ); + } else { + memcpy( prehash + INTR_PK + 0, computed_public_key, n ); + memcpy( prehash + INTR_PK + n, signature, n ); + } + signature += n; + node_num /= 2; + put_bigendian( prehash + INTR_R, node_num, 4 ); + hss_hash_ctx( computed_public_key, h, &ctx, prehash, INTR_LEN(n) ); + } + + /* Now, check to see if the root we computed matches the root we should have */ + unsigned offset = LM_PUB_I + padded_length(I_LEN); + + return 0 == memcmp( computed_public_key, public_key + offset, n ); +} diff --git a/src/sig_stfl/lms/external/lm_verify.h b/src/sig_stfl/lms/external/lm_verify.h new file mode 100644 index 0000000000..7f48767fcb --- /dev/null +++ b/src/sig_stfl/lms/external/lm_verify.h @@ -0,0 +1,12 @@ +#if !defined(LM_VERIFY_H_) +#define LM_VERIFY_H_ + +#include +#include + +bool lm_validate_signature( + const unsigned char *public_key, + const void *message, size_t message_len, bool prehashed, + const unsigned char *signature, size_t signature_len); + +#endif /* LM_VERIFY_H_ */ diff --git a/src/sig_stfl/lms/external/sha256.c b/src/sig_stfl/lms/external/sha256.c new file mode 100644 index 0000000000..fb18892a31 --- /dev/null +++ b/src/sig_stfl/lms/external/sha256.c @@ -0,0 +1,183 @@ +/* + * SHA-256 + * Implementation derived from LibTomCrypt (Tom St Denis) + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + * + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org + */ + +#include +#include "sha256.h" +#include "endian.h" + +#if !USE_OPENSSL && !defined(EXT_SHA256_H) + +/* If we don't have OpenSSL, here's a SHA256 implementation */ +#define SHA256_FINALCOUNT_SIZE 8 +#define SHA256_K_SIZE 64 +static const unsigned long K[SHA256_K_SIZE] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, + 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, + 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, + 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, + 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, + 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, + 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, + 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, + 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, + 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* Various logical functions */ + +/* Rotate x right by rot bits */ +static unsigned long RORc(unsigned long x, int rot) { + rot &= 31; if (rot == 0) return x; + unsigned long right = ((x&0xFFFFFFFFUL)>>rot ); + unsigned long left = ((x&0xFFFFFFFFUL)<<(32-rot) ); + return (right|left) & 0xFFFFFFFFUL; +} +#define Ch(x,y,z) (z ^ (x & (y ^ z))) +#define Maj(x,y,z) (((x | y) & z) | (x & y)) +#define S(x, n) RORc((x),(n)) +#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) +#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) +#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) +#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) +#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) + +static void sha256_compress (SHA256_CTX * ctx, const void *buf) +{ + unsigned long S0, S1, S2, S3, S4, S5, S6, S7, W[SHA256_K_SIZE], t0, t1, t; + int i; + const unsigned char *p; + + /* copy state into S */ + S0 = ctx->h[0]; + S1 = ctx->h[1]; + S2 = ctx->h[2]; + S3 = ctx->h[3]; + S4 = ctx->h[4]; + S5 = ctx->h[5]; + S6 = ctx->h[6]; + S7 = ctx->h[7]; + + /* + * We've been asked to perform the hash computation on this 512-bit string. + * SHA256 interprets that as an array of 16 bigendian 32 bit numbers; copy + * it, and convert it into 16 unsigned long's of the CPU's native format + */ + p = buf; + for (i=0; i<16; i++) { + W[i] = get_bigendian( p, 4 ); + p += 4; + } + + /* fill W[16..63] */ + for (i = 16; i < SHA256_K_SIZE; i++) { + W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; + } + + /* Compress */ +#define RND(a,b,c,d,e,f,g,h,i) \ + t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ + t1 = Sigma0(a) + Maj(a, b, c); \ + d += t0; \ + h = t0 + t1; + + for (i = 0; i < SHA256_K_SIZE; ++i) { + RND(S0,S1,S2,S3,S4,S5,S6,S7,i); + t = S7; S7 = S6; S6 = S5; S5 = S4; + S4 = S3; S3 = S2; S2 = S1; S1 = S0; S0 = t; + } +#undef RND + + /* feedback */ + ctx->h[0] += S0; + ctx->h[1] += S1; + ctx->h[2] += S2; + ctx->h[3] += S3; + ctx->h[4] += S4; + ctx->h[5] += S5; + ctx->h[6] += S6; + ctx->h[7] += S7; +} + +void SHA256_Init (SHA256_CTX *ctx) +{ + ctx->Nl = 0; + ctx->Nh = 0; + ctx->num = 0; + ctx->h[0] = 0x6A09E667UL; + ctx->h[1] = 0xBB67AE85UL; + ctx->h[2] = 0x3C6EF372UL; + ctx->h[3] = 0xA54FF53AUL; + ctx->h[4] = 0x510E527FUL; + ctx->h[5] = 0x9B05688CUL; + ctx->h[6] = 0x1F83D9ABUL; + ctx->h[7] = 0x5BE0CD19UL; +} + +void SHA256_Update (SHA256_CTX *ctx, const void *src, unsigned int count) +{ + unsigned new_count = (ctx->Nl + (count << 3)) & 0xffffffff; + if (new_count < ctx->Nl) { + ctx->Nh += 1; + } + ctx->Nl = new_count; + + while (count) { + unsigned int this_step = 64 - ctx->num; + if (this_step > count) this_step = count; + memcpy( ctx->data + ctx->num, src, this_step); + + if (this_step + ctx->num < 64) { + ctx->num += this_step; + break; + } + + src = (const unsigned char *)src + this_step; + count -= this_step; + ctx->num = 0; + + sha256_compress( ctx, ctx->data ); + } +} + +/* + * Add padding and return the message digest. + */ +void SHA256_Final (unsigned char *digest, SHA256_CTX *ctx) +{ + unsigned int i; + unsigned char finalcount[SHA256_FINALCOUNT_SIZE]; + + put_bigendian( &finalcount[0], ctx->Nh, 4 ); + put_bigendian( &finalcount[4], ctx->Nl, 4 ); + + SHA256_Update(ctx, "\200", 1); + + if (ctx->num > 56) { + SHA256_Update(ctx, "\0\0\0\0\0\0\0\0", 8); + } + memset( ctx->data + ctx->num, 0, 56 - ctx->num ); + ctx->num = 56; + SHA256_Update(ctx, finalcount, SHA256_FINALCOUNT_SIZE); /* Should cause a sha256_compress() */ + + /* + * The final state is an array of unsigned long's; place them as a series + * of bigendian 4-byte words onto the output + */ + for (i=0; i<8; i++) { + put_bigendian( digest + 4*i, ctx->h[i], 4 ); + } +} +#endif diff --git a/src/sig_stfl/lms/external/sha256.h b/src/sig_stfl/lms/external/sha256.h new file mode 100644 index 0000000000..a5de21c014 --- /dev/null +++ b/src/sig_stfl/lms/external/sha256.h @@ -0,0 +1,43 @@ +#if !defined(SHA256_H_) +#define SHA256_H_ + +#if defined( EXT_SHA256_H ) +#include EXT_SHA256_H +#else + +#define USE_OPENSSL 0 /* We use the OpenSSL implementation for SHA-256 */ + /* (which is quite a bit faster than our portable */ + /* C version) */ + +#if USE_OPENSSL + +#include + +#else + +/* SHA256 context. */ +typedef struct { + unsigned long int h[8]; /* state; this is in the CPU native format */ + unsigned long Nl, Nh; /* number of bits processed so far */ + unsigned num; /* number of bytes within the below */ + /* buffer */ + unsigned char data[64]; /* input buffer. This is in byte vector format */ +} SHA256_CTX; + +void SHA256_Init(SHA256_CTX *); /* context */ + +void SHA256_Update(SHA256_CTX *, /* context */ + const void *, /* input block */ + unsigned int);/* length of input block */ + +void SHA256_Final(unsigned char *, + SHA256_CTX *); +#endif + +#endif /* EXT_SHA256_H */ + +#if !defined( SHA256_LEN ) +#define SHA256_LEN 32 /* The length of a SHA256 hash output */ +#endif + +#endif /* ifdef(SHA256_H_) */ From a7e26d95451a5386b7726a614337a2db7045f24e Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Sun, 23 Jul 2023 22:10:34 -0400 Subject: [PATCH 08/68] Add 12 XMSS and 16 XMSSMT parameters. (#1489) * populate all 28 XMSS parameters * clean up * remove wanrings in scanbuild * change free to OQS_MEM_insecure_free * fix build warning * fix integer in i386 platforms * proper type for sigs_remain and sig_maximum * remove size_t in signature remain and total * make scan-build happy --- .CMake/alg_support.cmake | 28 + src/oqsconfig.h.cmake | 27 + src/sig_stfl/sig_stfl.c | 530 +++++++++++++++++- src/sig_stfl/sig_stfl.h | 51 +- src/sig_stfl/xmss/CMakeLists.txt | 180 +++++- src/sig_stfl/xmss/external/core_hash.c | 40 +- src/sig_stfl/xmss/external/core_hash.h | 23 + src/sig_stfl/xmss/external/hash.h | 6 +- src/sig_stfl/xmss/external/namespace.h | 14 +- src/sig_stfl/xmss/external/xmss.c | 2 +- src/sig_stfl/xmss/external/xmss_core_fast.c | 65 ++- src/sig_stfl/xmss/sig_stfl_xmss.h | 478 +++++++++++++++- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c | 32 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c | 136 +++++ src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c | 136 +++++ src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c | 136 +++++ src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c | 136 +++++ src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c | 136 +++++ .../xmss/sig_stfl_xmss_shake128_h10.c | 136 +++++ .../xmss/sig_stfl_xmss_shake128_h16.c | 136 +++++ .../xmss/sig_stfl_xmss_shake128_h20.c | 136 +++++ .../xmss/sig_stfl_xmss_shake256_h10.c | 136 +++++ .../xmss/sig_stfl_xmss_shake256_h16.c | 136 +++++ .../xmss/sig_stfl_xmss_shake256_h20.c | 136 +++++ .../xmss/sig_stfl_xmssmt_sha256_h20_2.c | 136 +++++ .../xmss/sig_stfl_xmssmt_sha256_h20_4.c | 136 +++++ .../xmss/sig_stfl_xmssmt_sha256_h40_2.c | 136 +++++ .../xmss/sig_stfl_xmssmt_sha256_h40_4.c | 136 +++++ .../xmss/sig_stfl_xmssmt_sha256_h40_8.c | 136 +++++ .../xmss/sig_stfl_xmssmt_sha256_h60_12.c | 136 +++++ .../xmss/sig_stfl_xmssmt_sha256_h60_3.c | 136 +++++ .../xmss/sig_stfl_xmssmt_sha256_h60_6.c | 136 +++++ .../xmss/sig_stfl_xmssmt_shake128_h20_2.c | 136 +++++ .../xmss/sig_stfl_xmssmt_shake128_h20_4.c | 136 +++++ .../xmss/sig_stfl_xmssmt_shake128_h40_2.c | 136 +++++ .../xmss/sig_stfl_xmssmt_shake128_h40_4.c | 136 +++++ .../xmss/sig_stfl_xmssmt_shake128_h40_8.c | 136 +++++ .../xmss/sig_stfl_xmssmt_shake128_h60_12.c | 136 +++++ .../xmss/sig_stfl_xmssmt_shake128_h60_3.c | 136 +++++ .../xmss/sig_stfl_xmssmt_shake128_h60_6.c | 136 +++++ tests/KATs/sig_stfl/kats.json | 29 +- tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp | 180 +----- tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_512.rsp | 14 + tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_256.rsp | 14 + tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_512.rsp | 14 + tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_256.rsp | 14 + tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_512.rsp | 14 + .../KATs/sig_stfl/xmss/XMSS-SHAKE_10_256.rsp | 14 + .../KATs/sig_stfl/xmss/XMSS-SHAKE_10_512.rsp | 14 + .../KATs/sig_stfl/xmss/XMSS-SHAKE_16_256.rsp | 14 + .../KATs/sig_stfl/xmss/XMSS-SHAKE_16_512.rsp | 14 + .../KATs/sig_stfl/xmss/XMSS-SHAKE_20_256.rsp | 14 + .../KATs/sig_stfl/xmss/XMSS-SHAKE_20_512.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHA2_20-2_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHA2_20-4_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHA2_40-2_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHA2_40-4_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHA2_40-8_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHA2_60-12_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHA2_60-3_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHA2_60-6_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHAKE_20-2_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHAKE_20-4_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHAKE_40-2_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHAKE_40-4_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHAKE_40-8_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHAKE_60-12_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHAKE_60-3_256.rsp | 14 + .../sig_stfl/xmss/XMSSMT-SHAKE_60-6_256.rsp | 14 + tests/helpers.py | 4 +- tests/kat_sig_stfl.c | 141 +++-- tests/test_cmdline.py | 14 +- tests/test_sig_stfl.c | 242 +++++++- 73 files changed, 5812 insertions(+), 324 deletions(-) create mode 100644 src/sig_stfl/xmss/external/core_hash.h create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c create mode 100644 tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_512.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_512.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_512.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_512.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_512.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_512.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-2_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-4_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-2_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-4_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-8_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-12_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-3_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-6_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-2_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-4_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-2_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-4_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-8_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-12_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-3_256.rsp create mode 100644 tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-6_256.rsp diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index c2c498bf54..aaf8ea6fef 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -499,6 +499,34 @@ endif() option(OQS_ENABLE_SIG_STFL_XMSS "Enable XMSS algorithm family" ON) cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha256_h10 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha256_h16 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha256_h20 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_shake128_h10 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_shake128_h16 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_shake128_h20 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha512_h10 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha512_h16 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha512_h20 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_shake256_h10 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_shake256_h16 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_shake256_h20 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_2 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_4 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_4 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_8 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_6 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_12 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_2 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_4 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_4 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_8 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) + if((OQS_MINIMAL_BUILD STREQUAL "ON")) message(FATAL_ERROR "OQS_MINIMAL_BUILD option ${OQS_MINIMAL_BUILD} no longer supported") diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index 3496e1a5f2..aef6c427aa 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -193,3 +193,30 @@ #cmakedefine OQS_ENABLE_SIG_STFL_XMSS 1 #cmakedefine OQS_ENABLE_SIG_STFL_xmss_sha256_h10 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmss_sha256_h16 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmss_sha256_h20 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmss_shake128_h10 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmss_shake128_h16 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmss_shake128_h20 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmss_sha512_h10 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmss_sha512_h16 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmss_sha512_h20 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmss_shake256_h10 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmss_shake256_h16 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmss_shake256_h20 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_2 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_4 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_4 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_8 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_6 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_12 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_2 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_4 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_4 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_8 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6 1 +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 1 \ No newline at end of file diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 2b68e6dd94..20bf641b95 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -13,8 +13,35 @@ OQS_API const char *OQS_SIG_STFL_alg_identifier(size_t i) { - const char *a[OQS_SIG_algs_length] = { + const char *a[OQS_SIG_STFL_algs_length] = { OQS_SIG_STFL_alg_xmss_sha256_h10, + OQS_SIG_STFL_alg_xmss_sha256_h16, + OQS_SIG_STFL_alg_xmss_sha256_h20, + OQS_SIG_STFL_alg_xmss_shake128_h10, + OQS_SIG_STFL_alg_xmss_shake128_h16, + OQS_SIG_STFL_alg_xmss_shake128_h20, + OQS_SIG_STFL_alg_xmss_sha512_h10, + OQS_SIG_STFL_alg_xmss_sha512_h16, + OQS_SIG_STFL_alg_xmss_sha512_h20, + OQS_SIG_STFL_alg_xmss_shake256_h10, + OQS_SIG_STFL_alg_xmss_shake256_h16, + OQS_SIG_STFL_alg_xmss_shake256_h20, + OQS_SIG_STFL_alg_xmssmt_sha256_h20_2, + OQS_SIG_STFL_alg_xmssmt_sha256_h20_4, + OQS_SIG_STFL_alg_xmssmt_sha256_h40_2, + OQS_SIG_STFL_alg_xmssmt_sha256_h40_4, + OQS_SIG_STFL_alg_xmssmt_sha256_h40_8, + OQS_SIG_STFL_alg_xmssmt_sha256_h60_3, + OQS_SIG_STFL_alg_xmssmt_sha256_h60_6, + OQS_SIG_STFL_alg_xmssmt_sha256_h60_12, + OQS_SIG_STFL_alg_xmssmt_shake128_h20_2, + OQS_SIG_STFL_alg_xmssmt_shake128_h20_4, + OQS_SIG_STFL_alg_xmssmt_shake128_h40_2, + OQS_SIG_STFL_alg_xmssmt_shake128_h40_4, + OQS_SIG_STFL_alg_xmssmt_shake128_h40_8, + OQS_SIG_STFL_alg_xmssmt_shake128_h60_3, + OQS_SIG_STFL_alg_xmssmt_shake128_h60_6, + OQS_SIG_STFL_alg_xmssmt_shake128_h60_12, }; if (i >= OQS_SIG_STFL_algs_length) { @@ -40,6 +67,168 @@ OQS_API int OQS_SIG_STFL_alg_is_enabled(const char *method_name) { return 1; #else return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h10)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h10 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h10)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h10 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h10)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h10 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_2)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_2 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_4)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_4 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_4)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_4 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_8)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_8 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_6)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_6 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_12)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_12 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h20_2)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_2 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h20_4)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_4 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_4)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_4 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_8)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_8 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_6)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6 + return 1; +#else + return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_12)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 + return 1; +#else + return 0; #endif } else { return 0; @@ -57,6 +246,168 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { return OQS_SIG_STFL_alg_xmss_sha256_h10_new(); #else return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 + return OQS_SIG_STFL_alg_xmss_sha256_h16_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 + return OQS_SIG_STFL_alg_xmss_sha256_h20_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h10)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h10 + return OQS_SIG_STFL_alg_xmss_shake128_h10_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 + return OQS_SIG_STFL_alg_xmss_shake128_h16_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 + return OQS_SIG_STFL_alg_xmss_shake128_h20_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h10)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h10 + return OQS_SIG_STFL_alg_xmss_sha512_h10_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 + return OQS_SIG_STFL_alg_xmss_sha512_h16_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 + return OQS_SIG_STFL_alg_xmss_sha512_h20_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h10)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h10 + return OQS_SIG_STFL_alg_xmss_shake256_h10_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 + return OQS_SIG_STFL_alg_xmss_shake256_h16_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 + return OQS_SIG_STFL_alg_xmss_shake256_h20_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_2)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_2 + return OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_4)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_4 + return OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 + return OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_4)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_4 + return OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_8)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_8 + return OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 + return OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_6)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_6 + return OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_12)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_12 + return OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h20_2)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_2 + return OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h20_4)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_4 + return OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 + return OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_4)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_4 + return OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_8)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_8 + return OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 + return OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_6)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6 + return OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_12)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 + return OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_new(); +#else + return NULL; #endif } else { return NULL; @@ -88,7 +439,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m } } -OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, size_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, uint64_t *remain, const uint8_t *secret_key) { if (sig == NULL || sig->sigs_remaining == NULL || sig->sigs_remaining(remain, secret_key) != 0) { return OQS_ERROR; } else { @@ -96,7 +447,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, size_t * } } -OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, size_t *max, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, uint64_t *max, const uint8_t *secret_key) { if (sig == NULL || sig->sigs_total == NULL || sig->sigs_total(max, secret_key) != 0) { return OQS_ERROR; } else { @@ -123,18 +474,189 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_ return OQS_SECRET_KEY_XMSS_SHA256_H10_new(); #else return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 + return OQS_SECRET_KEY_XMSS_SHA256_H16_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 + return OQS_SECRET_KEY_XMSS_SHA256_H20_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h10)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h10 + return OQS_SECRET_KEY_XMSS_SHAKE128_H10_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 + return OQS_SECRET_KEY_XMSS_SHAKE128_H16_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 + return OQS_SECRET_KEY_XMSS_SHAKE128_H20_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h10)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h10 + return OQS_SECRET_KEY_XMSS_SHA512_H10_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 + return OQS_SECRET_KEY_XMSS_SHA512_H16_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 + return OQS_SECRET_KEY_XMSS_SHA512_H20_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h10)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h10 + return OQS_SECRET_KEY_XMSS_SHAKE256_H10_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 + return OQS_SECRET_KEY_XMSS_SHAKE256_H16_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 + return OQS_SECRET_KEY_XMSS_SHAKE256_H20_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_2)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_2 + return OQS_SECRET_KEY_XMSSMT_SHA256_H20_2_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_4)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_4 + return OQS_SECRET_KEY_XMSSMT_SHA256_H20_4_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 + return OQS_SECRET_KEY_XMSSMT_SHA256_H40_2_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_4)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_4 + return OQS_SECRET_KEY_XMSSMT_SHA256_H40_4_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_8)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_8 + return OQS_SECRET_KEY_XMSSMT_SHA256_H40_8_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 + return OQS_SECRET_KEY_XMSSMT_SHA256_H60_3_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_6)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_6 + return OQS_SECRET_KEY_XMSSMT_SHA256_H60_6_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_12)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_12 + return OQS_SECRET_KEY_XMSSMT_SHA256_H60_12_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h20_2)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_2 + return OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_2_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h20_4)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_4 + return OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_4_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 + return OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_2_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_4)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_4 + return OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_4_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_8)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_8 + return OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_8_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 + return OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_3_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_6)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6 + return OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_6_new(); +#else + return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_12)) { +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 + return OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_12_new(); +#else + return NULL; #endif } else { return NULL; } } +void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL) { + return; + } + + OQS_MEM_secure_free(sk->secret_key_data, sk->length_secret_key); + sk->secret_key_data = NULL; +} + OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk) { if (sk == NULL) { return; } - /* Call object specif free */ + /* Call object specific free */ if (sk->free_key) { sk->free_key(sk); } diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index 6beeb8c24d..b2955d78ba 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -22,8 +22,35 @@ extern "C" { /* Algorithm identifier for XMSS-SHA2_10_256 */ #define OQS_SIG_STFL_alg_xmss_sha256_h10 "XMSS-SHA2_10_256" - -#define OQS_SIG_STFL_algs_length 1 +#define OQS_SIG_STFL_alg_xmss_sha256_h16 "XMSS-SHA2_16_256" +#define OQS_SIG_STFL_alg_xmss_sha256_h20 "XMSS-SHA2_20_256" +#define OQS_SIG_STFL_alg_xmss_shake128_h10 "XMSS-SHAKE_10_256" +#define OQS_SIG_STFL_alg_xmss_shake128_h16 "XMSS-SHAKE_16_256" +#define OQS_SIG_STFL_alg_xmss_shake128_h20 "XMSS-SHAKE_20_256" +#define OQS_SIG_STFL_alg_xmss_sha512_h10 "XMSS-SHA2_10_512" +#define OQS_SIG_STFL_alg_xmss_sha512_h16 "XMSS-SHA2_16_512" +#define OQS_SIG_STFL_alg_xmss_sha512_h20 "XMSS-SHA2_20_512" +#define OQS_SIG_STFL_alg_xmss_shake256_h10 "XMSS-SHAKE_10_512" +#define OQS_SIG_STFL_alg_xmss_shake256_h16 "XMSS-SHAKE_16_512" +#define OQS_SIG_STFL_alg_xmss_shake256_h20 "XMSS-SHAKE_20_512" +#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_2 "XMSSMT-SHA2_20/2_256" +#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_4 "XMSSMT-SHA2_20/4_256" +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_2 "XMSSMT-SHA2_40/2_256" +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_4 "XMSSMT-SHA2_40/4_256" +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_8 "XMSSMT-SHA2_40/8_256" +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_3 "XMSSMT-SHA2_60/3_256" +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_6 "XMSSMT-SHA2_60/6_256" +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_12 "XMSSMT-SHA2_60/12_256" +#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_2 "XMSSMT-SHAKE_20/2_256" +#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_4 "XMSSMT-SHAKE_20/4_256" +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_2 "XMSSMT-SHAKE_40/2_256" +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_4 "XMSSMT-SHAKE_40/4_256" +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_8 "XMSSMT-SHAKE_40/8_256" +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_3 "XMSSMT-SHAKE_60/3_256" +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_6 "XMSSMT-SHAKE_60/6_256" +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_12 "XMSSMT-SHAKE_60/12_256" + +#define OQS_SIG_STFL_algs_length 28 /** * Returns identifiers for available signature schemes in liboqs. Used with OQS_SIG_STFL_new. @@ -132,7 +159,7 @@ typedef struct OQS_SIG_STFL { * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ - OQS_STATUS (*sigs_remaining)(size_t *remain, const uint8_t *secret_key); + OQS_STATUS (*sigs_remaining)(uint64_t *remain, const uint8_t *secret_key); /** * Total number of signatures @@ -141,7 +168,7 @@ typedef struct OQS_SIG_STFL { * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ - OQS_STATUS (*sigs_total)(size_t *total, const uint8_t *secret_key); + OQS_STATUS (*sigs_total)(uint64_t *total, const uint8_t *secret_key); } OQS_SIG_STFL; @@ -162,10 +189,10 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { void *secret_key_data; /* Function that returns the total number of signatures for the secret key */ - unsigned long long (*sigs_total)(const OQS_SIG_STFL_SECRET_KEY *secret_key); + uint64_t (*sigs_total)(const OQS_SIG_STFL_SECRET_KEY *secret_key); /* Function that returns the number of signatures left for the secret key */ - unsigned long long (*sigs_left)(const OQS_SIG_STFL_SECRET_KEY *secret_key); + uint64_t (*sigs_left)(const OQS_SIG_STFL_SECRET_KEY *secret_key); /** * Secret Key retrieval Function @@ -284,7 +311,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ -OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, size_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, uint64_t *remain, const uint8_t *secret_key); /** * * Total number of signatures @@ -294,7 +321,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, size_t * * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ -OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, size_t *max, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, uint64_t *max, const uint8_t *secret_key); /** * Frees an OQS_SIG_STFL object that was constructed by OQS_SIG_STFL_new. @@ -314,6 +341,14 @@ OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig); */ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_name); +/** + * Frees an OQS_SIG_STFL_SECRET_KEY **inner** data that was constructed by OQS_SECRET_KEY_new. + * + * @param[in] sig The OQS_SIG_STFL_SECRET_KEY object to free. + * @return OQS_SUCCESS if successful, or OQS_ERROR if the object could not be freed. + */ +void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk); + /** * Frees an OQS_SIG_STFL_SECRET_KEY object that was constructed by OQS_SECRET_KEY_new. * diff --git a/src/sig_stfl/xmss/CMakeLists.txt b/src/sig_stfl/xmss/CMakeLists.txt index 83bfc2be5e..b4b3038c69 100644 --- a/src/sig_stfl/xmss/CMakeLists.txt +++ b/src/sig_stfl/xmss/CMakeLists.txt @@ -2,21 +2,183 @@ set(_XMSS_OBJS "") -set(SRCS external/hash.c +set(SRCS external/core_hash.c + external/hash.c external/hash_address.c external/params.c - external/utils.c - external/wots.c + external/utils.c + external/wots.c external/xmss.c external/xmss_commons.c - ) - + external/xmss_core_fast.c +) + if (OQS_ENABLE_SIG_STFL_xmss_sha256_h10) - add_compile_definitions(OQS_ENABLE_SIG_STFL_xmss_sha256_h10) - set (SRCS ${SRCS} sig_stfl_xmss_sha256_h10.c external/core_hash.c external/xmss_core.c) + add_library(xmss_sha256_h10 OBJECT sig_stfl_xmss_sha256_h10.c ${SRCS}) + target_compile_options(xmss_sha256_h10 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha256_h10 -DHASH=3) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmss_sha256_h16) + add_library(xmss_sha256_h16 OBJECT sig_stfl_xmss_sha256_h16.c ${SRCS}) + target_compile_options(xmss_sha256_h16 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha256_h16 -DHASH=3) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmss_sha256_h20) + add_library(xmss_sha256_h20 OBJECT sig_stfl_xmss_sha256_h20.c ${SRCS}) + target_compile_options(xmss_sha256_h20 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha256_h20 -DHASH=3) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmss_shake128_h10) + add_library(xmss_shake128_h10 OBJECT sig_stfl_xmss_shake128_h10.c ${SRCS}) + target_compile_options(xmss_shake128_h10 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_shake128_h10 -DHASH=4) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmss_shake128_h16) + add_library(xmss_shake128_h16 OBJECT sig_stfl_xmss_shake128_h16.c ${SRCS}) + target_compile_options(xmss_shake128_h16 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_shake128_h16 -DHASH=4) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmss_shake128_h20) + add_library(xmss_shake128_h20 OBJECT sig_stfl_xmss_shake128_h20.c ${SRCS}) + target_compile_options(xmss_shake128_h20 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_shake128_h20 -DHASH=4) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmss_sha512_h10) + add_library(xmss_sha512_h10 OBJECT sig_stfl_xmss_sha512_h10.c ${SRCS}) + target_compile_options(xmss_sha512_h10 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha512_h10 -DHASH=6) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmss_sha512_h16) + add_library(xmss_sha512_h16 OBJECT sig_stfl_xmss_sha512_h16.c ${SRCS}) + target_compile_options(xmss_sha512_h16 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha512_h16 -DHASH=6) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmss_sha512_h20) + add_library(xmss_sha512_h20 OBJECT sig_stfl_xmss_sha512_h20.c ${SRCS}) + target_compile_options(xmss_sha512_h20 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha512_h20 -DHASH=6) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmss_shake256_h10) + add_library(xmss_shake256_h10 OBJECT sig_stfl_xmss_shake256_h10.c ${SRCS}) + target_compile_options(xmss_shake256_h10 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_shake256_h10 -DHASH=7) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmss_shake256_h16) + add_library(xmss_shake256_h16 OBJECT sig_stfl_xmss_shake256_h16.c ${SRCS}) + target_compile_options(xmss_shake256_h16 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_shake256_h16 -DHASH=7) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmss_shake256_h20) + add_library(xmss_shake256_h20 OBJECT sig_stfl_xmss_shake256_h20.c ${SRCS}) + target_compile_options(xmss_shake256_h20 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_shake256_h20 -DHASH=7) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_2) + add_library(xmssmt_sha256_h20_2 OBJECT sig_stfl_xmssmt_sha256_h20_2.c ${SRCS}) + target_compile_options(xmssmt_sha256_h20_2 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h20_2 -DHASH=3) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_4) + add_library(xmssmt_sha256_h20_4 OBJECT sig_stfl_xmssmt_sha256_h20_4.c ${SRCS}) + target_compile_options(xmssmt_sha256_h20_4 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h20_4 -DHASH=3) + set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() +if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2) + add_library(xmssmt_sha256_h40_2 OBJECT sig_stfl_xmssmt_sha256_h40_2.c ${SRCS}) + target_compile_options(xmssmt_sha256_h40_2 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h40_2 -DHASH=3) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_4) + add_library(xmssmt_sha256_h40_4 OBJECT sig_stfl_xmssmt_sha256_h40_4.c ${SRCS}) + target_compile_options(xmssmt_sha256_h40_4 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h40_4 -DHASH=3) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_8) + add_library(xmssmt_sha256_h40_8 OBJECT sig_stfl_xmssmt_sha256_h40_8.c ${SRCS}) + target_compile_options(xmssmt_sha256_h40_8 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h40_8 -DHASH=3) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3) + add_library(xmssmt_sha256_h60_3 OBJECT sig_stfl_xmssmt_sha256_h60_3.c ${SRCS}) + target_compile_options(xmssmt_sha256_h60_3 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h60_3 -DHASH=3) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_6) + add_library(xmssmt_sha256_h60_6 OBJECT sig_stfl_xmssmt_sha256_h60_6.c ${SRCS}) + target_compile_options(xmssmt_sha256_h60_6 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h60_6 -DHASH=3) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_12) + add_library(xmssmt_sha256_h60_12 OBJECT sig_stfl_xmssmt_sha256_h60_12.c ${SRCS}) + target_compile_options(xmssmt_sha256_h60_12 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h60_12 -DHASH=3) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_2) + add_library(xmssmt_shake128_h20_2 OBJECT sig_stfl_xmssmt_shake128_h20_2.c ${SRCS}) + target_compile_options(xmssmt_shake128_h20_2 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h20_2 -DHASH=4) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_4) + add_library(xmssmt_shake128_h20_4 OBJECT sig_stfl_xmssmt_shake128_h20_4.c ${SRCS}) + target_compile_options(xmssmt_shake128_h20_4 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h20_4 -DHASH=4) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2) + add_library(xmssmt_shake128_h40_2 OBJECT sig_stfl_xmssmt_shake128_h40_2.c ${SRCS}) + target_compile_options(xmssmt_shake128_h40_2 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h40_2 -DHASH=4) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_4) + add_library(xmssmt_shake128_h40_4 OBJECT sig_stfl_xmssmt_shake128_h40_4.c ${SRCS}) + target_compile_options(xmssmt_shake128_h40_4 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h40_4 -DHASH=4) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_8) + add_library(xmssmt_shake128_h40_8 OBJECT sig_stfl_xmssmt_shake128_h40_8.c ${SRCS}) + target_compile_options(xmssmt_shake128_h40_8 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h40_8 -DHASH=4) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3) + add_library(xmssmt_shake128_h60_3 OBJECT sig_stfl_xmssmt_shake128_h60_3.c ${SRCS}) + target_compile_options(xmssmt_shake128_h60_3 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h60_3 -DHASH=4) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6) + add_library(xmssmt_shake128_h60_6 OBJECT sig_stfl_xmssmt_shake128_h60_6.c ${SRCS}) + target_compile_options(xmssmt_shake128_h60_6 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h60_6 -DHASH=4) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() + +if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12) + add_library(xmssmt_shake128_h60_12 OBJECT sig_stfl_xmssmt_shake128_h60_12.c ${SRCS}) + target_compile_options(xmssmt_shake128_h60_12 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h60_12 -DHASH=4) + set(_XMSS_OBJS ${_XMSS_OBJS} $) +endif() -add_library(xmss OBJECT ${SRCS}) -set(_XMSS_OBJS ${_XMSS_OBJS} $) set(XMSS_OBJS ${_XMSS_OBJS} PARENT_SCOPE) diff --git a/src/sig_stfl/xmss/external/core_hash.c b/src/sig_stfl/xmss/external/core_hash.c index 5df78cb998..565e571e36 100644 --- a/src/sig_stfl/xmss/external/core_hash.c +++ b/src/sig_stfl/xmss/external/core_hash.c @@ -1,14 +1,38 @@ #include #include -#include "hash.h" +#include "core_hash.h" +#include int core_hash(const xmss_params *params, unsigned char *out, - const unsigned char *in, unsigned long long inlen) -{ -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h10 - (void)params; - OQS_SHA2_sha256(out, in, inlen); - return 0; + const unsigned char *in, unsigned long long inlen) { + + (void)params; +#if HASH == XMSS_CORE_HASH_SHA256_N24 + unsigned char buf[32]; + OQS_SHA2_sha256(buf, in, inlen); + memcpy(out, buf, 24); + +#elif HASH == XMSS_CORE_HASH_SHAKE256_N24 + OQS_SHA3_shake256(out, 24, in, inlen); + +#elif HASH == XMSS_CORE_HASH_SHA256_N32 + OQS_SHA2_sha256(out, in, inlen); + +#elif HASH == XMSS_CORE_HASH_SHAKE128_N32 + OQS_SHA3_shake128(out, 32, in, inlen); + +#elif HASH == XMSS_CORE_HASH_SHAKE256_N32 + OQS_SHA3_shake256(out, 32, in, inlen); + +#elif HASH == XMSS_CORE_HASH_SHA512_N64 + OQS_SHA2_sha512(out, in, inlen); + +#elif HASH == XMSS_CORE_HASH_SHAKE256_N64 + OQS_SHA3_shake256(out, 64, in, inlen); +#else + return -1; #endif -} + + return 0; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/external/core_hash.h b/src/sig_stfl/xmss/external/core_hash.h new file mode 100644 index 0000000000..f350857d14 --- /dev/null +++ b/src/sig_stfl/xmss/external/core_hash.h @@ -0,0 +1,23 @@ +#ifndef CORE_HASH +#define CORE_HASH + +#include "namespace.h" +#include "params.h" + +// N = 24 +#define XMSS_CORE_HASH_SHA256_N24 1 +#define XMSS_CORE_HASH_SHAKE256_N24 2 +// N = 32 +#define XMSS_CORE_HASH_SHA256_N32 3 +#define XMSS_CORE_HASH_SHAKE128_N32 4 +#define XMSS_CORE_HASH_SHAKE256_N32 5 +// N = 64 +#define XMSS_CORE_HASH_SHA512_N64 6 +#define XMSS_CORE_HASH_SHAKE256_N64 7 + +#define core_hash XMSS_PARAMS_INNER_CORE_HASH(core_hash) +int core_hash(const xmss_params *params, + unsigned char *out, + const unsigned char *in, unsigned long long inlen); + +#endif diff --git a/src/sig_stfl/xmss/external/hash.h b/src/sig_stfl/xmss/external/hash.h index 5a3d750b07..076b3b56ec 100644 --- a/src/sig_stfl/xmss/external/hash.h +++ b/src/sig_stfl/xmss/external/hash.h @@ -3,15 +3,11 @@ #include #include "params.h" +#include "core_hash.h" #define addr_to_bytes XMSS_INNER_NAMESPACE(addr_to_bytes) void addr_to_bytes(unsigned char *bytes, const uint32_t addr[8]); -#define core_hash XMSS_INNER_NAMESPACE(core_hash) -int core_hash(const xmss_params *params, - unsigned char *out, - const unsigned char *in, unsigned long long inlen); - #define prf XMSS_INNER_NAMESPACE(prf) int prf(const xmss_params *params, unsigned char *out, const unsigned char in[32], diff --git a/src/sig_stfl/xmss/external/namespace.h b/src/sig_stfl/xmss/external/namespace.h index d593a85c53..468388aa3b 100644 --- a/src/sig_stfl/xmss/external/namespace.h +++ b/src/sig_stfl/xmss/external/namespace.h @@ -1,14 +1,18 @@ #ifndef XMSS_NAMESPACE_H #define XMSS_NAMESPACE_H +#define XMSS__(prefix, funcname) prefix##_##funcname +#define XMSS_(prefix, funcname) XMSS__(prefix, funcname) +#define __XMSS(funcname, postfix) funcname##_##postfix +#define _XMSS(funcname, postfix) __XMSS(funcname, postfix) + +#define XMSS_PARAMS _XMSS(oqs_sig_stfl, XMSS_PARAMS_NAMESPACE) +#define XMSS_PARAMS_INNER _XMSS(_XMSS(oqs_sig_stfl, XMSS_PARAMS_NAMESPACE), inner) +#define XMSS_PARAMS_INNER_CORE _XMSS(_XMSS(oqs_sig_stfl, XMSS_PARAMS_NAMESPACE), inner) -#define XMSS_PARAMS oqs_sig_stfl_xmss -#define XMSS_PARAMS_INNER oqs_sig_stfl_xmss_inner +#define XMSS_PARAMS_INNER_CORE_HASH(funcname) XMSS_(XMSS_PARAMS_INNER_CORE, funcname) #define XMSS_NAMESPACE(funcname) XMSS_(XMSS_PARAMS, funcname) #define XMSS_INNER_NAMESPACE(funcname) XMSS_(XMSS_PARAMS_INNER, funcname) -#define XMSS_(prefix, funcname) XMSS__(prefix, funcname) -#define XMSS__(prefix, funcname) prefix ## _ ## funcname - #endif diff --git a/src/sig_stfl/xmss/external/xmss.c b/src/sig_stfl/xmss/external/xmss.c index 401e0deebe..53ea10c24a 100644 --- a/src/sig_stfl/xmss/external/xmss.c +++ b/src/sig_stfl/xmss/external/xmss.c @@ -276,7 +276,7 @@ int xmssmt_total_signatures(unsigned long long *max, const unsigned char *sk) oid |= sk[XMSS_OID_LEN - i - 1] << (i * 8); } - if (xmss_parse_oid(¶ms, oid)) { + if (xmssmt_parse_oid(¶ms, oid)) { *max = 0; return -1; } diff --git a/src/sig_stfl/xmss/external/xmss_core_fast.c b/src/sig_stfl/xmss/external/xmss_core_fast.c index c0517cbb29..b3de5f17f0 100644 --- a/src/sig_stfl/xmss/external/xmss_core_fast.c +++ b/src/sig_stfl/xmss/external/xmss_core_fast.c @@ -165,6 +165,9 @@ static void memswap(void *a, void *b, void *t, unsigned long long len) static void deep_state_swap(const xmss_params *params, bds_state *a, bds_state *b) { + if (a->stack == NULL || b->stack == NULL) { + return; + } // TODO this is extremely ugly and should be refactored // TODO right now, this ensures that both 'stack' and 'retain' fit unsigned char t[ @@ -231,7 +234,7 @@ static void treehash_init(const xmss_params *params, set_type(node_addr, 2); uint32_t lastnode, i; - unsigned char stack[(height+1)*params->n]; + unsigned char *stack = calloc((height+1)*params->n, sizeof(unsigned char)); unsigned int stacklevels[height+1]; unsigned int stackoffset=0; unsigned int nodeh; @@ -279,6 +282,8 @@ static void treehash_init(const xmss_params *params, for (i = 0; i < params->n; i++) { node[i] = stack[i]; } + + OQS_MEM_insecure_free(stack); } static void treehash_update(const xmss_params *params, @@ -378,6 +383,10 @@ static char bds_state_update(const xmss_params *params, const unsigned char *pub_seed, const uint32_t addr[8]) { + if (state == NULL || state->stacklevels == NULL) { + return -1; + } + uint32_t ltree_addr[8] = {0}; uint32_t node_addr[8] = {0}; uint32_t ots_addr[8] = {0}; @@ -586,6 +595,11 @@ int xmss_core_sign(const xmss_params *params, unsigned char *sm, unsigned long long *smlen, const unsigned char *m, unsigned long long mlen) { + if (params->full_height > 60) { + // Unsupport Tree height + return -2; + } + const unsigned char *pub_root = sk + params->index_bytes + 2*params->n; uint16_t i = 0; @@ -599,8 +613,8 @@ int xmss_core_sign(const xmss_params *params, xmss_deserialize_state(params, &state, sk); // Extract SK - unsigned long idx = ((unsigned long)sk[0] << 24) | ((unsigned long)sk[1] << 16) | ((unsigned long)sk[2] << 8) | sk[3]; - + unsigned long long idx = ((unsigned long long)sk[0] << 24) | ((unsigned long long)sk[1] << 16) | ((unsigned long long)sk[2] << 8) | sk[3]; + /* Check if we can still sign with this sk. * If not, return -2 * @@ -619,8 +633,6 @@ int xmss_core_sign(const xmss_params *params, memset(sk + params->index_bytes, 0, (params->sk_bytes - params->index_bytes)); if (idx > ((1ULL << params->full_height) - 1)) return -2; // We already used all one-time keys - if ((params->full_height == 64) && (idx == ((1ULL << params->full_height) - 1))) - return -2; // We already used all one-time keys } unsigned char sk_seed[params->n]; @@ -710,7 +722,6 @@ int xmss_core_sign(const xmss_params *params, bds_treehash_update(params, &state, (params->tree_height - params->bds_k) >> 1, sk_seed, pub_seed, ots_addr); } - sm += params->tree_height*params->n; *smlen += params->tree_height*params->n; /* Write the updated BDS state back into sk. */ @@ -787,6 +798,11 @@ int xmssmt_core_sign(const xmss_params *params, unsigned char *sm, unsigned long long *smlen, const unsigned char *m, unsigned long long mlen) { + if (params == NULL || params->full_height > 60) { + // Unsupport parameter + return -1; + } + const unsigned char *pub_root = sk + params->index_bytes + 2*params->n; uint64_t idx_tree; @@ -805,13 +821,23 @@ int xmssmt_core_sign(const xmss_params *params, uint32_t ots_addr[8] = {0}; unsigned char idx_bytes_32[32]; - unsigned char *wots_sigs; + unsigned char *wots_sigs = NULL; + unsigned long long prefix_length = params->padding_len + 3*params->n; + unsigned char m_with_prefix[mlen + prefix_length]; + int ret = 0; // TODO refactor BDS state not to need separate treehash instances - bds_state states[2*params->d - 1]; + bds_state *states = calloc(2*params->d - 1, sizeof(bds_state)); treehash_inst treehash[(2*params->d - 1) * (params->tree_height - params->bds_k)]; for (i = 0; i < 2*params->d - 1; i++) { + states[i].stack = NULL; + states[i].stackoffset = 0; + states[i].stacklevels = NULL; + states[i].auth = NULL; + states[i].keep = NULL; states[i].treehash = treehash + i * (params->tree_height - params->bds_k); + states[i].retain = NULL; + states[i].next_leaf = 0; } xmssmt_deserialize_state(params, states, &wots_sigs, sk); @@ -838,10 +864,11 @@ int xmssmt_core_sign(const xmss_params *params, // has to make sure that this happens on disk. memset(sk, 0xFF, params->index_bytes); memset(sk + params->index_bytes, 0, (params->sk_bytes - params->index_bytes)); - if (idx > ((1ULL << params->full_height) - 1)) - return -2; // We already used all one-time keys - if ((params->full_height == 64) && (idx == ((1ULL << params->full_height) - 1))) - return -2; // We already used all one-time keys + if (idx > ((1ULL << params->full_height) - 1)) { + // We already used all one-time keys + ret = -2; + goto cleanup; + } } memcpy(sk_seed, sk+params->index_bytes, params->n); @@ -867,8 +894,6 @@ int xmssmt_core_sign(const xmss_params *params, /* Already put the message in the right place, to make it easier to prepend * things when computing the hash over the message. */ - unsigned long long prefix_length = params->padding_len + 3*params->n; - unsigned char m_with_prefix[mlen + prefix_length]; memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, prefix_length); memcpy(m_with_prefix + prefix_length, m, mlen); @@ -929,6 +954,10 @@ int xmssmt_core_sign(const xmss_params *params, *smlen += params->wots_sig_bytes; // put AUTH nodes in place + if (states[i].auth == NULL) { + ret = -1; + goto cleanup; + } memcpy(sm, states[i].auth, params->tree_height*params->n); sm += params->tree_height*params->n; *smlen += params->tree_height*params->n; @@ -963,7 +992,7 @@ int xmssmt_core_sign(const xmss_params *params, } } else if (idx < (1ULL << params->full_height) - 1) { - deep_state_swap(params, states+params->d + i, states + i); + deep_state_swap(params, &states[params->d + i], &states[i]); set_layer_addr(ots_addr, (i+1)); set_tree_addr(ots_addr, ((idx + 1) >> ((i+2) * params->tree_height))); @@ -983,6 +1012,10 @@ int xmssmt_core_sign(const xmss_params *params, } xmssmt_serialize_state(params, sk, states); + goto cleanup; - return 0; +cleanup: + OQS_MEM_insecure_free(states); + + return ret; } diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index e932f3f063..1fbc305b29 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -8,19 +8,489 @@ #define XMSS_OID_LEN 4 void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk); +/* + * | Algorithms | oid | sk | pk | sig | n | + * |-------------------------------|------|--------|-----|------|----| + * | XMSS-SHA2_10_256 | 0x01 | 1373 | 64 | 2500 | 32 | + * | XMSS-SHA2_16_256 | 0x02 | 2093 | 64 | 2692 | 32 | + * | XMSS-SHA2_20_256 | 0x03 | 2573 | 64 | 2820 | 32 | + * + * | XMSS-SHAKE_10_256 | 0x07 | 1373 | 64 | 2500 | 32 | + * | XMSS-SHAKE_16_256 | 0x08 | 2093 | 64 | 2692 | 32 | + * | XMSS-SHAKE_20_256 | 0x09 | 2573 | 64 | 2820 | 32 | + * + * | XMSS-SHA2_10_512 | 0x04 | 2653 | 128 | 9092 | 64 | + * | XMSS-SHA2_16_512 | 0x05 | 4045 | 128 | 9476 | 64 | + * | XMSS-SHA2_20_512 | 0x06 | 4973 | 128 | 9732 | 64 | + * + * | XMSS-SHAKE_10_512 | 0x0a | 2653 | 128 | 9092 | 64 | + * | XMSS-SHAKE_16_512 | 0x0b | 4045 | 128 | 9476 | 64 | + * | XMSS-SHAKE_20_512 | 0x0c | 4973 | 128 | 9732 | 64 | + * + * | XMSSMT-SHA2_20/2_256 | 0x01 | 5998 | 64 | 4963 | 32 | + * | XMSSMT-SHA2_20/4_256 | 0x02 | 10938 | 64 | 9251 | 32 | + * | XMSSMT-SHA2_40/2_256 | 0x03 | 9600 | 64 | 5605 | 32 | + * | XMSSMT-SHA2_40/4_256 | 0x04 | 15252 | 64 | 9893 | 32 | + * | XMSSMT-SHA2_40/8_256 | 0x05 | 24516 | 64 | 18469 | 32 | + * | XMSSMT-SHA2_60/3_256 | 0x06 | 16629 | 64 | 8392 | 32 | + * | XMSSMT-SHA2_60/6_256 | 0x07 | 24507 | 64 | 14824 | 32 | + * | XMSSMT-SHA2_60/12_256 | 0x08 | 38095 | 64 | 27688 | 32 | + * + * | XMSSMT-SHAKE_20/2_256 | 0x11 | 5998 | 64 | 4963 | 32 | + * | XMSSMT-SHAKE_20/4_256 | 0x12 | 10938 | 64 | 9251 | 32 | + * | XMSSMT-SHAKE_40/2_256 | 0x13 | 9600 | 64 | 5605 | 32 | + * | XMSSMT-SHAKE_40/4_256 | 0x14 | 15252 | 64 | 9893 | 32 | + * | XMSSMT-SHAKE_40/8_256 | 0x15 | 24516 | 64 | 18469 | 32 | + * | XMSSMT-SHAKE_60/3_256 | 0x16 | 16629 | 64 | 8392 | 32 | + * | XMSSMT-SHAKE_60/6_256 | 0x17 | 24507 | 64 | 14824 | 32 | + * | XMSSMT-SHAKE_60/12_256 | 0x18 | 38095 | 64 | 27688 | 32 | + */ + #ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h10 -#define OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature 2500 +#define OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk (1373 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_sha256_h10_length_pk (64 + XMSS_OID_LEN) -#define OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk (132 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature 2500 OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(size_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(size_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 + +#define OQS_SIG_STFL_alg_xmss_sha256_h16_length_sk (2093 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_sha256_h16_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_sha256_h16_length_signature 2692 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h16_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H16_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 + +#define OQS_SIG_STFL_alg_xmss_sha256_h20_length_sk (2573 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_sha256_h20_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_sha256_h20_length_signature 2820 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h20_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H20_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h10 + +#define OQS_SIG_STFL_alg_xmss_shake128_h10_length_sk (1373 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_shake128_h10_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_shake128_h10_length_signature 2500 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h10_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H10_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 + +#define OQS_SIG_STFL_alg_xmss_shake128_h16_length_sk (2093 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_shake128_h16_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_shake128_h16_length_signature 2692 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h16_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H16_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 + +#define OQS_SIG_STFL_alg_xmss_shake128_h20_length_sk (2573 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_shake128_h20_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_shake128_h20_length_signature 2820 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h20_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H20_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h10 + +#define OQS_SIG_STFL_alg_xmss_sha512_h10_length_sk (2653 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_sha512_h10_length_pk (128 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_sha512_h10_length_signature 9092 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h10_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H10_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 + +#define OQS_SIG_STFL_alg_xmss_sha512_h16_length_sk (4045 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_sha512_h16_length_pk (128 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_sha512_h16_length_signature 9476 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h16_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H16_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 + +#define OQS_SIG_STFL_alg_xmss_sha512_h20_length_sk (4973 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_sha512_h20_length_pk (128 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_sha512_h20_length_signature 9732 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h20_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H20_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h10 + +#define OQS_SIG_STFL_alg_xmss_shake256_h10_length_sk (2653 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_shake256_h10_length_pk (128 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_shake256_h10_length_signature 9092 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h10_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H10_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 + +#define OQS_SIG_STFL_alg_xmss_shake256_h16_length_sk (4045 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_shake256_h16_length_pk (128 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_shake256_h16_length_signature 9476 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h16_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H16_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 + +#define OQS_SIG_STFL_alg_xmss_shake256_h20_length_sk (4973 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_shake256_h20_length_pk (128 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmss_shake256_h20_length_signature 9732 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h20_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H20_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_2 + +#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_sk (5998 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_signature 4963 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_2_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_4 + +#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_sk (10938 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_signature 9251 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_4_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 + +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_sk (9600 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_signature 5605 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_2_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_4 + +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_sk (15252 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_signature 9893 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_4_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_8 + +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_sk (24516 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_signature 18469 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_8_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 + +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_sk (16629 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_signature 8392 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_3_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_6 + +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_sk (24507 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_signature 14824 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_6_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_12 + +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_sk (38095 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_signature 27688 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_12_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_2 + +#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_sk (5998 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_signature 4963 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_2_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_4 + +#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_sk (10938 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_signature 9251 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_4_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 + +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_sk (9600 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_signature 5605 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_2_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_4 + +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_sk (15252 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_signature 9893 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_4_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_8 + +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_sk (24516 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_signature 18469 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_8_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 + +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_sk (16629 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_signature 8392 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_3_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6 + +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_sk (24507 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_signature 14824 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_6_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(uint64_t *total, const uint8_t *secret_key); + +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 + +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_sk (38095 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_pk (64 + XMSS_OID_LEN) +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_signature 27688 + +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_12_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(uint64_t *total, const uint8_t *secret_key); #endif diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c index cfb6899af6..aa812bd22c 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c @@ -71,8 +71,8 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(XMSS_UNUSED_ATT uint return OQS_ERROR; } - const uint32_t xmss_sha256_h10_oid = 0x00000001; - if (oqs_sig_stfl_xmss_xmss_keypair(public_key, secret_key, xmss_sha256_h10_oid)) { + const uint32_t xmss_sha256_h10_oid = 0x01; + if (xmss_keypair(public_key, secret_key, xmss_sha256_h10_oid)) { return OQS_ERROR; } @@ -86,7 +86,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, siz } unsigned long long sig_length = 0; - if (oqs_sig_stfl_xmss_xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -100,46 +100,38 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(XMSS_UNUSED_ATT const return OQS_ERROR; } - if (oqs_sig_stfl_xmss_xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(size_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - unsigned long long remaining_signatures = 0; - if (oqs_sig_stfl_xmss_xmss_remaining_signatures(&remaining_signatures, secret_key)) { + uint64_t remaining_signatures = 0; + if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { return OQS_ERROR; } - *remain = (size_t) remaining_signatures; + *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(size_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(uint64_t *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - unsigned long long total_signatures = 0; - if (oqs_sig_stfl_xmss_xmss_total_signatures(&total_signatures, secret_key)) { + uint64_t total_signatures = 0; + if (xmss_total_signatures(&total_signatures, secret_key)) { return OQS_ERROR; } - *total = (size_t) total_signatures; + *total = (uint64_t) total_signatures; return OQS_SUCCESS; } -void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk) { - if (sk == NULL) { - return; - } - - OQS_MEM_secure_free(sk->secret_key_data, sk->length_secret_key); - sk->secret_key_data = NULL; -} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c new file mode 100644 index 0000000000..d613a4f9c0 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSS-SHA2_16_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h16_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSS-SHA2_16_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha256_h16_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h16_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmss_sha256_h16_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmss_sha256_h16_keypair; + sig->sign = OQS_SIG_STFL_alg_xmss_sha256_h16_sign; + sig->verify = OQS_SIG_STFL_alg_xmss_sha256_h16_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H16_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h16_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmss_sha256_h16_oid = 0x02; + if (xmss_keypair(public_key, secret_key, xmss_sha256_h16_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmss_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c new file mode 100644 index 0000000000..5d40092b9c --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSS-SHA2_16_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h20_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSS-SHA2_20_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha256_h20_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h20_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmss_sha256_h20_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmss_sha256_h20_keypair; + sig->sign = OQS_SIG_STFL_alg_xmss_sha256_h20_sign; + sig->verify = OQS_SIG_STFL_alg_xmss_sha256_h20_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H20_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h20_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmss_sha256_h20_oid = 0x03; + if (xmss_keypair(public_key, secret_key, xmss_sha256_h20_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmss_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c new file mode 100644 index 0000000000..81a1b85c5f --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSS-SHA2_10_512 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h10_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSS-SHA2_10_512"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha512_h10_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h10_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmss_sha512_h10_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmss_sha512_h10_keypair; + sig->sign = OQS_SIG_STFL_alg_xmss_sha512_h10_sign; + sig->verify = OQS_SIG_STFL_alg_xmss_sha512_h10_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H10_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h10_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmss_sha512_h10_oid = 0x04; + if (xmss_keypair(public_key, secret_key, xmss_sha512_h10_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmss_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c new file mode 100644 index 0000000000..b99b429fbd --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSS-SHA2_16_512 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h16_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSS-SHA2_16_512"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha512_h16_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h16_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmss_sha512_h16_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmss_sha512_h16_keypair; + sig->sign = OQS_SIG_STFL_alg_xmss_sha512_h16_sign; + sig->verify = OQS_SIG_STFL_alg_xmss_sha512_h16_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H16_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h16_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmss_sha512_h16_oid = 0x05; + if (xmss_keypair(public_key, secret_key, xmss_sha512_h16_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmss_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c new file mode 100644 index 0000000000..8c618b8bd7 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSS-SHA2_20_512 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h20_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSS-SHA2_20_512"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha512_h20_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h20_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmss_sha512_h20_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmss_sha512_h20_keypair; + sig->sign = OQS_SIG_STFL_alg_xmss_sha512_h20_sign; + sig->verify = OQS_SIG_STFL_alg_xmss_sha512_h20_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H20_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h20_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmss_sha512_h20_oid = 0x06; + if (xmss_keypair(public_key, secret_key, xmss_sha512_h20_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmss_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c new file mode 100644 index 0000000000..efc4c6ed5d --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSS-SHAKE_10_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h10_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSS-SHAKE_10_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmss_shake128_h10_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h10_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmss_shake128_h10_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmss_shake128_h10_keypair; + sig->sign = OQS_SIG_STFL_alg_xmss_shake128_h10_sign; + sig->verify = OQS_SIG_STFL_alg_xmss_shake128_h10_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H10_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h10_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmss_shake128_h10_oid = 0x07; + if (xmss_keypair(public_key, secret_key, xmss_shake128_h10_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmss_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c new file mode 100644 index 0000000000..948e29b597 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSS-SHAKE_10_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h16_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSS-SHAKE_16_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmss_shake128_h16_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h16_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmss_shake128_h16_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmss_shake128_h16_keypair; + sig->sign = OQS_SIG_STFL_alg_xmss_shake128_h16_sign; + sig->verify = OQS_SIG_STFL_alg_xmss_shake128_h16_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H16_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h16_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmss_shake128_h16_oid = 0x08; + if (xmss_keypair(public_key, secret_key, xmss_shake128_h16_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmss_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c new file mode 100644 index 0000000000..9e9d330da7 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSS-SHAKE_10_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h20_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSS-SHAKE_20_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmss_shake128_h20_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h20_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmss_shake128_h20_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmss_shake128_h20_keypair; + sig->sign = OQS_SIG_STFL_alg_xmss_shake128_h20_sign; + sig->verify = OQS_SIG_STFL_alg_xmss_shake128_h20_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H20_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h20_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmss_shake128_h20_oid = 0x09; + if (xmss_keypair(public_key, secret_key, xmss_shake128_h20_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmss_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c new file mode 100644 index 0000000000..e96c5da22a --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSS-SHAKE_10_512 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h10_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSS-SHAKE_10_512"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmss_shake256_h10_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h10_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmss_shake256_h10_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmss_shake256_h10_keypair; + sig->sign = OQS_SIG_STFL_alg_xmss_shake256_h10_sign; + sig->verify = OQS_SIG_STFL_alg_xmss_shake256_h10_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H10_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h10_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmss_shake256_h10_oid = 0x0a; + if (xmss_keypair(public_key, secret_key, xmss_shake256_h10_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmss_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c new file mode 100644 index 0000000000..b90fe2cc79 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSS-SHAKE_16_512 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h16_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSS-SHAKE_16_512"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmss_shake256_h16_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h16_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmss_shake256_h16_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmss_shake256_h16_keypair; + sig->sign = OQS_SIG_STFL_alg_xmss_shake256_h16_sign; + sig->verify = OQS_SIG_STFL_alg_xmss_shake256_h16_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H16_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h16_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmss_shake256_h16_oid = 0x0b; + if (xmss_keypair(public_key, secret_key, xmss_shake256_h16_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmss_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c new file mode 100644 index 0000000000..53a88db04b --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSS-SHAKE_20_512 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h20_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSS-SHAKE_20_512"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmss_shake256_h20_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h20_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmss_shake256_h20_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmss_shake256_h20_keypair; + sig->sign = OQS_SIG_STFL_alg_xmss_shake256_h20_sign; + sig->verify = OQS_SIG_STFL_alg_xmss_shake256_h20_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H20_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h20_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmss_shake256_h20_oid = 0x0c; + if (xmss_keypair(public_key, secret_key, xmss_shake256_h20_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmss_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c new file mode 100644 index 0000000000..b5c1df16af --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHA2_20/2_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHA2_20/2_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_2_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_sha256_h20_2_oid = 0x01; + if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h20_2_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c new file mode 100644 index 0000000000..2bad4a33a2 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHA2_20/4_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHA2_20/4_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_4_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_sha256_h20_4_oid = 0x02; + if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h20_4_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c new file mode 100644 index 0000000000..c1a0243e96 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHA2_40/2_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHA2_40/2_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_2_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_sha256_h40_2_oid = 0x03; + if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h40_2_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c new file mode 100644 index 0000000000..9835724a5c --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHA2_40/4_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHA2_40/4_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_4_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_sha256_h40_4_oid = 0x04; + if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h40_4_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c new file mode 100644 index 0000000000..ed223acdd7 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHA2_40/8_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHA2_40/8_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_sha256_h40_8_oid = 0x05; + if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h40_8_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c new file mode 100644 index 0000000000..de9253552d --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHA2_60/12_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHA2_60/12_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_12_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_sha256_h60_12_oid = 0x08; + if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h60_12_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c new file mode 100644 index 0000000000..7e54ff760c --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHA2_60/3_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHA2_60/3_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_3_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_sha256_h60_3_oid = 0x06; + if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h60_3_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c new file mode 100644 index 0000000000..49d870dec0 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHA2_60/6_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHA2_60/6_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_6_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_sha256_h60_6_oid = 0x07; + if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h60_6_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c new file mode 100644 index 0000000000..5a66fc4e96 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHAKE_20/2_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHAKE_20/2_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_2_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_shake128_h20_2_oid = 0x11; + if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h20_2_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c new file mode 100644 index 0000000000..163689fc33 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHAKE_20/4_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHAKE_20/4_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_4_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_shake128_h20_4_oid = 0x12; + if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h20_4_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c new file mode 100644 index 0000000000..9e59b72d19 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHAKE_40/2_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHAKE_40/2_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_2_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_shake128_h40_2_oid = 0x13; + if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h40_2_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c new file mode 100644 index 0000000000..4dbd11f836 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHAKE_40/4_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHAKE_40/4_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_4_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_shake128_h40_4_oid = 0x14; + if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h40_4_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c new file mode 100644 index 0000000000..91223579b6 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHAKE_40/8_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHAKE_40/8_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_shake128_h40_8_oid = 0x15; + if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h40_8_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c new file mode 100644 index 0000000000..e480d2d5e7 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHAKE_60/12_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHAKE_60/12_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_12_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_shake128_h60_12_oid = 0x18; + if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h60_12_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c new file mode 100644 index 0000000000..3904bd43b5 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHAKE_60/3_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHAKE_60/3_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_3_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_shake128_h60_3_oid = 0x16; + if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h60_3_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c new file mode 100644 index 0000000000..b6cf53cfe0 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +// ======================== XMSSMT-SHAKE_60/6_256 ======================== // + +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->method_name = "XMSSMT-SHAKE_60/6_256"; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_pk; + sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_sk; + sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_signature; + + sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_keypair; + sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sign; + sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_verify; + sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining; + sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_6_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_sk; + + // Assign the sigs_left and sigs_max functions + sk->sigs_left = NULL; + sk->sigs_total = NULL; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + memset(sk->secret_key_data, 0, sk->length_secret_key); + + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (public_key == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + const uint32_t xmssmt_shake128_h60_6_oid = 0x17; + if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h60_6_oid)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + unsigned long long sig_length = 0; + if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + return OQS_ERROR; + } + *signature_len = (size_t) sig_length; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t remaining_signatures = 0; + if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + return OQS_ERROR; + } + *remain = (uint64_t) remaining_signatures; + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(uint64_t *total, const uint8_t *secret_key) { + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + uint64_t total_signatures = 0; + if (xmssmt_total_signatures(&total_signatures, secret_key)) { + return OQS_ERROR; + } + *total = (uint64_t) total_signatures; + + return OQS_SUCCESS; +} \ No newline at end of file diff --git a/tests/KATs/sig_stfl/kats.json b/tests/KATs/sig_stfl/kats.json index 8be3ea457f..7ed8350ad1 100644 --- a/tests/KATs/sig_stfl/kats.json +++ b/tests/KATs/sig_stfl/kats.json @@ -1,3 +1,30 @@ { - "XMSS-SHA2_10_256": "e71e6a390fe09c275e0fa0996d938d554d01548da229fe159ccab48e6525ae8b" + "XMSS-SHA2_10_256": "4ff9ea00bec98f790a5b5e96ddb8441d58e646d679a47f02db21085c35a006f4", + "XMSS-SHA2_16_256": "398ef810276efaeabc84780816950a9243be0b37122f33db556010a5ec606a8d", + "XMSS-SHA2_20_256": "d695061163e3a5124222a6d3202f1e397cde65733b84d700196a9c55b7d721a2", + "XMSS-SHAKE_10_256": "b5ec13a0eceb7cc1bd14f2288557b7dcb431c3c930ed8eb2d09be32eca52f722", + "XMSS-SHAKE_16_256": "2875eafcdad20e964c6abf4d90bdb73e1ab47fd2e636ed949502fff9f77ea94f", + "XMSS-SHAKE_20_256": "7e78a5792165d0ba1484f4cca60985373be475fbf1047e58997798b2048f5048", + "XMSS-SHA2_10_512": "791840f9f015bad6df9138d2ced1690daea746f65d54826ce85a6ba38211d16c", + "XMSS-SHA2_16_512": "c060814c9e029d9272c8942bb3f9a5ca46cf361e59c16bf70065476243095196", + "XMSS-SHA2_20_512": "c5684bba5d53983cf3c52b45ca0b443a38102573cae4aeab5e4a911b02b0fe47", + "XMSS-SHAKE_10_512": "edd6ff8923afdefa3ad7b5158f2adc90eb58c377b847c5c35508546a7ea2ca3c", + "XMSS-SHAKE_16_512": "537540146232f6647c215e32ae057fc9cf3e83932a6447953c7f9ac5d38eccf0", + "XMSS-SHAKE_20_512": "e803f3af92cea3f8004a94484f8f666b306fa353c3b09e9e0763b63f7f9b20d6", + "XMSSMT-SHA2_20/2_256": "da52ae24ebd6fb3ef85a80d83357835164a292fd8c0e83a32c21d386969d5c0b", + "XMSSMT-SHA2_20/4_256": "eb5a0afd967f660714b1b9bb6a214f348cfeb06e474048c94d6e08de183b78fe", + "XMSSMT-SHA2_40/2_256": "0cb74272d179eaefc180303cfaaaed13093268ead2b6e3d066228b64077609ee", + "XMSSMT-SHA2_40/4_256": "16a7047724db2ff45999a4e95048bae3bac5d645986d6670014c53478412b4f1", + "XMSSMT-SHA2_40/8_256": "fff5c6a02f8995342199155052ac5115af6340ff9e729a1609c815c891797111", + "XMSSMT-SHA2_60/12_256": "2e5869150c17da8c13094b66a94a94342d62d035fa63bd972757f3eda2c9c248", + "XMSSMT-SHA2_60/3_256": "04b10f0320cd77b8094b1116d67085b38a0d68f02aa9b0ec5938a511ece1ef6f", + "XMSSMT-SHA2_60/6_256": "0ea5be22f851a84e1bbbc21a84dfb5c5a5d2f5d636dbae49e1e092e6ec5833f9", + "XMSSMT-SHAKE_20/2_256": "5893c3acc4ab1448510888ca6c6f483d1ed247028900752d11d2ec9dea77356d", + "XMSSMT-SHAKE_20/4_256": "eece12452652dc37d1600b39e4bf589ac12bee6d5e5025845bc06c7e5321669e", + "XMSSMT-SHAKE_40/2_256" : "c5a539dc3cd7af4710362c3e9962137e33e4061099bb2dd0a03eff862c9cd01d", + "XMSSMT-SHAKE_40/4_256" : "b25c826e97d442ade70dff6e7008e95c099d7cde6f533fb9059299d9e1ff200c", + "XMSSMT-SHAKE_40/8_256" : "cf301b7d978d5c0afcdf3300ba97d829e2e5f737cb449968b19b45f05b987591", + "XMSSMT-SHAKE_60/3_256" : "09d26df5e911e98e71ef73a1ab6f224964d4a7beacd8071b4c7f7d1930a537bd", + "XMSSMT-SHAKE_60/6_256" : "0692a32e318d5c3ac8631120910b783edfed4cb7ed69e3ffa29f83aaa34e27d5", + "XMSSMT-SHAKE_60/12_256" : "1a05ff4a4fea850a5fe5c9e976006577335eab0494e1759fe217c2f33f5a84e6" } \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp index 5641aa1e9c..ea0bef3312 100644 --- a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp @@ -1,182 +1,14 @@ # XMSS-SHA2_10_256 -pk = 0000000157A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -sk = 0000000100000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +pk = 00000001B901B8D9332FE458EB6DE87AF74655D0B5AD936A66FDB6AC9D1B8CF25BB6DB8404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 0000000100000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94AB901B8D9332FE458EB6DE87AF74655D0B5AD936A66FDB6AC9D1B8CF25BB6DB8404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD09000000000001000000000000000000000000000000000000000000000000000000000000000000000000 count = 0 -seed = D260779A680342EFB7D244B1333C2FC9884B85CDB7B96F8EEEAF5FC7FBDBABF9A0AA3F0E7238F97142BCF1C561731CFE +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 mlen = 33 -msg = BBCB0A3E0F49152C2D8022F5AAB8AD5E80E81934BC66D468AB76F141D4E741937D +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 2500 -sm = 00000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA70105CAE69218E377931AC690634219BE00AE5320712465A2B736772BA10311D81DD6E16DE90489D3963F80022BCA055736187CA55BE285B83537CE987CFECF1401D6B7DFFDA5087F9586D35A22FC8B42A3FA29A2A5F4BE53E17A9CB8D42942B5E187796E96704F8CC77119F33BAEB06B1140A484E881C4385C31F5D7D16C842E348320D1CE3556DEDB800385B782AC949821203199969DBC2F2652C256E91157096E07E49BE3133DCDD305CBB4F2077D5DE4D29C431A2968F50AB5501512524666CA7B2268C159CB047FC54ED490A963C2A7A4E936C407176C1DE9142CF8BC0CD4FE2AC3C011F531564A1B93D4BB59867CF655C9F170C5BDC6A62D93562168EF99760160982B28667681DE3D81832DA109CE5D6D3E919C459063AAA6C58D1AF2616C4198F41A8969C0F2F67DE6417390E170912482D75E5E18EB1CCA84E6914765546E3452E1219F438FDCC57D3AF82DCE3DD8B69E58FAA28B1983BDA064CE1DBA6886F23C77B2FE6F6A1427FE94649C25E1366079C5008F7E6E9DE0EFD7E8792BF1EF0948B621D309BA771BECA0592BD5D4D23AA8BD0C469D5C7D5DF396D1D75C17F8C5D632A753C32CDCCB1A3896C2C54172D1871737319A3C326AF497D7216A6CB1DF7AAA231912F2AEC85392DE82D4648B27970075EEAE2BD1A6A8A7A49B51A973B852799338E04C136EC1CB3F84825C35A7CDE243C5025B36ABD240D4698438E9323E310E320EF0833677E35A6D02DF5838C26277241C354ED9130BA6086E333168D84664AC66BDF26A3ACBC4B4D67312564FA30E94B3B7C22A1D9F4A2DF2F8458B0715E3670EBEA3B6F3CABEF3C4282E821A2BA2F2B21D16F1D130F56BBAA8CC6F5EDCC37148BB069D3404288D2BFF211193A839ABCBFEFA3069F6101A45595AAF5CDCF3F2565C14BD5AEB26642608E029600F5F973EA4952EBB78C74E0A6D5B9BCD4CE7C9A3BFD982083885AD7F92B3ED09BA1EF566A1640DA41F49325320727B0D0ED87B3EF4ACA88E3C698627C67D9E9EA656F3D66E369320CFF7D2958E9F66CB5379F66C8E69DBEE19350CD95A84055592D46C2C42606EF6B4EF63B31269665A7F2B5A00B492D60C9FAEC0FF5057D9D50D858DB86B85D902681FC873F8F865CAD7358B5EE4169CDDAC13307900AC1CB241225283861E0B871D1A56B2F433367341F7718C80AF69ABA1C359C91B4271E7A46E86522180DBD9ECB3842AF76F7757F50F243748E7F13246533B1D90CBFAD3185B781B5388C2FC0C36D08CEEAC757245ECFB9BEF58AE28F535601FB4379DEF650FB39E1C00C072E8E51BF8BE96CD88C66F2EDABF4DD04263A0B02B56196DB9106A62D98C284C839B1B4D19C8FF0FFAFAFEB732CDFFF7B5D7D65E5D4DD3D84C631439CB133033A27561C1271EA45A509AF7995511A09F2E294E8B33CE0B64EA29322E55004A7E4FEF5EF089080BDB3C2DD2AF979F46C4715E0602DFC16E8EA9FB7DD1E47A872900903B214EE7A1595C3C254F598B7460DB51FA12204A97B280E83AD0F796757D6C9E7CC6BC53F8E17DF6AC34F8450566E9E4DBD4FF2FAA4755577DFB8E90229F5B15F418C3E290AF21754336F25254BAE436E9C6839D07E45D56A0821110DBF193E1E95448A43EACE60B461F47937072A051B4C3C0D17489E393B47F2290269F171E22C571364B7F906B79C69668BA0AF81DF30C3D4AB906F5E47B50C0AB0143E9BEDF247A0EB562DB0898C104A6CCECE457033784C2640FFBC073E01E354BF068D3416B2FCC5837309FE2019CDB053F42E63EA1B1683898C506B89C6B2D390F745D3A14FFDAF9AFF26F73AE79CBA225D9A5FDCFE9CA7041D38D991064AA5D32D5CEB0A97DB58F3B5FE894FCC983F71662F4EBB6C067AF9FCA95222229AA497F8E1F9BCDDE0C59216068B0B284F148306974E3E8D785615CDD5002357D423103F02F490D3CBE413D0C9A5108444FBC85048D14AFECBD57FCD6A863155D62D6B4061F5941E989F1C10869047F82BDA5FAA6BAE01359F5CDAA5474B2EF78C4A3499D95FA85106849AF8A80F439B30DEA0D60D187F49BB5C26B05A14822D8F257C4110A2684FA444630777D6610AD8E6B08D0ECD0433B9077DA8853E9F567358300FE457B521C03B89C7B77CFBA948DB2A6BF87FDC39F1C349EFC00C17356298DDA38FD48095BAAF5B346DE3B1CCF91018785869FDD98EF8F7C12189DC13D473458228851B48725130D439AE5AD57CC700A27B51ED54380D80D80E5A770EDF368A56762E7CB037D59E73D311572411A466B7934E9B9292332F73407951CF9294CD541D4ADBC9CB624C3ED57FA33F67A72BA1AA9BB8DC95FF10B8DB6F23F996A31CA87D5DC0086BE4FA7BC7EEDFCC1D32D6D84A99618B6998FCB4A791FF9EE0855A4A7C6B5C4796E9E213C2DA5B205D5255C71B6F97D5067E5A8A579664AF2C73D5A949FCD43B36DC423E34BCBD72575D2E74DE56A97A5440F84BC2408F10E8DE519C3685D4AE28F395C52615B3B03F5D4C45D9D2C207B74734CAFA0C924822DC3E495B496C892C7556446F14BCE82DC2AAD295A65A7E6C4358311B04882FCD05B066A46B6A98FB3C2AEC438247683AD2A2DF295EC5D42B638F91E9E67DFC4B4A33831BAFE5D1C8CD6AB95A431A16D3FAF05080B1DC25B8B882BD29E2F8BDDC1407E493C5D5DB11423AC490954C66A924ADAD04842DE902ECFC37436DC6A736BB2004784599EE80ECB66B2EA06224C5961E5DB97AEF1EE4CE7D0A70C61BAF568023479601A7CAD8CDD2AE929D0C1AFA811FDEAEC6216E74516036E7E9E0E2A1E169DE38221869E46E6EE4325D37102ABE9709356223F80A4D259F45AD260AEFD801B8052A55E9848F9976497A14475D98DF3F1EB9EAC832F44C0981BA49037C116F6CDBDCF0FF043B96D225DFDF54CD890408F824CDE256CE8788601AE0705140253EFF336F060DA6855A3403EE9833C898A9E602401EF67C593A8AAE02C5BBBF8383E68C71BE4583B423CEC8E3D7CCE0C4652A9FE6097AAD64C5FC1588AC9CCDEBA3C6E435AF86E29F25399BD4EC118F665E4CC9D59327F129CECA4F359EB0547BEC24FC3E7D74B1125892F02AEBEDD1AB9A7611C4FEE5ACBB9BA8634169DB9AC73BB0704D1F8F6098CA76F2FA504D8825564A30A1D7E6E12690DE34C0521FE70D15714626DEBC8008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 0000000100000001061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD +sm = 00000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA7010C534B0D4C6FFDF4DBFE00E72405EFE83BBCF19AA2030A8CB163808482B6376FF8CE01FB8090F4842896A1EA5E9282F35CACD245A4B9DE9FE84E9315851D68A72B3ECB9F440937C8BA4AC3F0429246CBC2777E8B92D84F4BA49FAB89465FCB0FC8017E582746F531B4697925154A22E2D6A0F1B81913438000C295153D7ADCA8F852C50D360F65F887479E9631A2CA30FE3AD92E7BF648643835F4F8CC081A6C951B83B77608A08C021821DA61962CFCC8E97D75441921D39C5AD537543EFBAF0345DC70826E6E950929570C72E51619600C58D932A72657B19AF163E0B8F7AAF2949A5EB26C517909E0E663E36753491182975206009107509DFFC898D308B903E84A8B29718BF7125397AFF5467D53CF8F36EB945B6B98D48E81C0174A0E03541D24369CF8EDDA4288FFA615D16FBC7355CFC0966BA9256E5B8A44DA95760DFB61301B10FD3E82436E267DB089773E43B984297D1E0D395DCC77FCFECCEFEBD4B80B3F241872EA251DA466CA6C5324346F4B5E6886654A86592641A8C32AC554261B2D9130462C976B039E593F873AD1712820FF3E723FE57F137751AB3CA8B5B20D28D1B9384DF1D710AC39FAF699989418B7856C2034C695A693ECC336EB472DE5049C743089529695B028F2F72BE0893E59169E9A2376C64BC5CCAC5482E5A6E9C88D710A3FF8F23C206B09D314BF50568228B1BACF1CE330D529BD3793D7C7CD9EC770C111D9681D6F1B97D908CBBD436444853FEB47F234D31F5E92B9E0465D67AC0FE48859126BEFA7F7D121A67C2C2970B37B8081B4E73C5A21A41F60160A61FAFBD48649A3D2032C1679A67F348E3E25275FCD9AF650937FEB0A30F25878CEED7D6CA693518B5A2F5418135EA9316EFFDECDB1DFFC9EE3A62EFF0E66F3D05BD9D5F8679B536BB6D39792B28DF2481A6EECB9BEE40B11A10D39A90EA1AAC47BF956FBFE9B0427B599B9BC024F326515E71615419423FEC3F19F621D49B6EED59F129A6B1411B7B1AFCF073095D57B03F25A16F946ED716BF705F567A151BE85B8E8195CC2F070BFD482702182B8A4A43ED942F6BD3CBF9DE7E8AEB17C41E1C009C94FF4A2050E3731088B75474B38DC52BADF53C7DCD3FB98D023649FC4799CE060ADDACEC7CD4E656074E631C1CB8AEF88EFEE0817C2E3D79E287F4510E48DFB7E23CB49D6FCA39A1E0F471F16A8BB65AF02150D059036D00386DD287BEA4D52FB263B57AE5ADD901CADE838B1D7347D9E47EAF6456148C6C4E44B0FA3DFCF5C9CEC2D80AD509A65AEF0E3E663B7F31BCA437311BA799D4C2ACC138F85D73CB40792FF03F8F20427D951444990CA3976A71368A7DC1455E880722F06F02163BC712E852A914F22E5675EB9B1C6C8B7FD20A8880AD2EEF97982C065C937BD3639357E4C7450CBDA0B51CCA8E3E078DC760FD99EBF646B82369576539B2BD5B2C866ED5AE94423A5CE18C685352398D01C983F080D7BEB8A9243AAA9AC1DDCC1B058B92BEAD301E8F3B8F5EF71EEE7966302B44D2E26D2A02393713E5D4D3FEF42196FAA368274C78C2932D22840ECA6018CE7D16B19A0727CB1966EB28B57D137C5264CC2E627F24A3BAD50EA4F75C7BD8998709C01ED5ACFFF0891934E94DA2CACCA212FB48BE3F9EAA310547E73C388D881F36AE21EFEDD23744F6B07C5D6D2776C191ED41E607316F61BBEF7A20E1A03150AE833D18952AE35188FBFDFA55C12A388836717BB2BDD97E89121C56C3B53E8198242315C9E438512E0C8354A3E599CB7217AE688647A72985606BBD0720F6FA5C5B6F70E88234EE54C6DB0A41106C866564650829FE4B232635B06B18240C9F86369C75B2F7D237211A380C43F95D362E0680D9EA2CA47E1DC8C49703E22650B765F847AD86BE25A3B7630D640A0097632DF13F600E8A025DD9A1FC67B0EB09C1CA9FA3923896927DEE1E3CC0C81F4B82E43B89CACC69C9B8ADCA1670F7D4E50DB7BCD94C2115E75F2BFD2336DA5A304D0F3455927360BF5040E95D1454106F2A8A7CD27D5510E7B5BE7B5B9EDEFDC3D4249D655C51F4C1DBA0F359BE4769AB66EDBC802824E9AB866E8EEAA2FEB1CC855F0A745AAC84A610DF0238112C6519F8E7346C45331A6036F84D5B6250F4B5BC0A2A6A31DAF9C60EB13C20CC649A18E27A6C98B82F08E21706A8BDF338CC69C1679D25ECFF733A721211C1F6DD28091AAA9C93B047EFCD2C8A55F2DA65E616F07DCC0F44081D4E359C1688A00F062EC925D24432862B547BB70F2AF126A3DABA5C918B224DE444B8733E6FA601B3D349307E94583D0EC976AEDA2B90972324B3ACE8C7B79A67723AEA037E12DA9EFA9CA9668A4F5FDADFB9EEE13398921F5023E354A6894825431DBA7317E6A6F69F0E77294BCD02D7616E75AC31EC528FC070B8C34027C4E9CD0672903412FCA6B723650D56AF562069312FC7EF1891A77E1A3F29D810C205EE212E75863F3B8B1ED216DF888ADD07AFF45F1B5C01196329311414797CD5F67FFC54AAD04C803FF7E83C2E8BA224CE83695BB7916AC42B1861F5CB527FDBCD82DBFA31C5ACF981D8414203837504263C96A0015841FBCC721F96D50A86D6E096AB54AF9980F06CEE6341C78D6583F6BAE8081B3C44B0F10FB7300874B5011FF0F97C52F975A31355884C2F12B6FFEE20E8371D38183C9D04977BFA037C9BD4DD7F7CE203FD7FAD3852B3C2AE9D078ADEC70DB1A7140EF1114EBB03E8DE03237E0A27FF510015AC76FCEFE4EBD4C3A1B6C67DB2A82FE2B1BF18723DB0F29FE4AD47B2EEF22AC3C6661CFA7DA7476D23B470FA2E0441B6473EBD291791F09B4ADA70A5286EB05167BD59BFD8C46427413D60692382EFB7882F60DC53AAAFDF2014CA7D27F8FA93C187A8371B41796557AE739912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70D3DB184EABED83E30C11C9BC62F3340923A0082B987EC45CC7BD1DB4B2B15E8AD3EAD74E96D8C20D85617BBEDC0BDAF8ED48B7EE8D7C42990028EC0669AFC0861C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A remain = 1022 -max = 1023 - -count = 1 -seed = 4AF2A48BFB8912E1209AE0B00C0B52CD84183E9D2B0D63E1C9DC7E3B2920874CBBABDEBD47BF4CAA5E19B4C6BEB96D8D -mlen = 66 -msg = B81C782E781F6D005B891EAF89527B7AF65AEE14E0B668EAB7A1EC5AE188B391A733B7707E42A7AF3699ECAF1A43453C2CFE0ED61233CFF68F35F4A84ADA949812FC -smlen = 2500 -sm = 0000000196122FAE790CF4FA6D9055E159003D223857F44B3EF248882A415D76FA26BFD2892B42C27F464D13FE2026F5F1CC11B7BEC39DDB84E55A8D02733F9DE45D12F0F78174CE816C9BF2021400FFFB8A957696D2C91B8EE32984C1A7FED7D76B76E3C3877DBD912B9D53681EC0E601947D7AF1F4285EC10CEDB10156CF3B5DBE57C29056EFA6C16B9C3AFFA2835DC3395DBB7962BE6E9FDFF0D4EEAA5A7C40126638D443E00E6282A0278BCB076FB14AE295627CC9D4CB0E4C48A3D9D9394EC889363EAA2382263BE9D1B8C50D744212910B83F4180FEFE601102F1AD9AD3E592BEC45B42789D9C5949A6178226C21581388ABACDDCB988F2FFC0AD98A21DB0D728EE8F7E4E19111DF2EB74436E3CB14792B4C3FE691C27889337D984F82BBBBDB9D2A54B78CF70BE8057908959247FB5A84596DE7ABB1DA1B28BB787064F79A5270A249DE499C6FE8F6DB84B93A12C93563B658527E99786306CB3C32465127497C42E38DAD8F7E592B8585EE77AFB3E70D7F188D1AB0C9873E5005FFB4C360FA74FF8E0A6E3493EE7407D8CE5EA12310F6F51BFBDDB7290BDE558FB6A2F5317F4D11412FA7FFEF45465012D531D90EDC3A62E2EFA07CF58B3B45B5BD8431E7DBCEE38783F5D4757A0AC26D4E5C7F6A94F71BA1AC2F4DD8E9927D0A06792AFF259C2A413B678CFE937A0F3D166761DC7A6F3EFB029C8D4CC735878178BF5E97D06ACBEFC607649F48131D8C35A23278C61A333C969DB3E938011B5FF54A5A46A11392127736DC233186381B84A4A3F7B88D88A5F6519DC83F049F7C57E8CFA439187BC89CEF18CE0E53F6B79BE3DC9575DE0F16EEEFA2619D53A2D2D09078B1D03C0034D8BACFC6B329AC9969B3702AFFE04A94607324D40EFAFC0FA6AD7F0A14D8DD252583D34916D83F927DFBDA6ECDBBEB1D6ED96E881A931D7A6582394A06A53429FD4A6D0E155B533FDC73F2C8A7C7408E56CF3F318CDEA142480A95F6C398BBDF900FA09B386B096391D060F5CF6BCD2614F61E40B3E84AC0BC08FD2AC9D7AFDBC5CEF821810ECB9DF964E3391A6C869DBC59BC75575C11B75CA9C106D76D3AE2636F240B7D25F71772829307F80F6FA5C8000BFD3693407F367A7BD122EFB12493C558A4FC17DF46B892CA14B2D696AC154DA1BF51A274A35E55A8D94A0A8052AAE2C1944347CB57ADEEA0429FDD5D846F9258226A7E3B298F3E687A04B2686C740EDE8DC7A1E447A0792FF49139C33BA99A42A0E760225BFC882DD5BBD1F517126309B438F6813D411048FCE5F2C997E321CA9B6C3B16779034416B1718D962D0CF187E15FA6FBC668C7FFCFA6398D0B58E7FB4504D7623F465E6B657A8A2C4FC8FA01C94F54A3D3E5A29341248885B570B4E4D3900F82C21457782B08AE1C7798405A1CC0EC2CD22120B3EF25F41714804ECD9DB406B0D509D064888E8A2FD3DABCCE5675A3FEE01F4D4F22D0F071AD6E4D907EAB25B0E4C7C5DEF8A5B977012298F6969B9D0F515FA241701B390C605FE982BFF2A5D1375ED026686835769E1B988706A3168AD81C3FF4B394E178999FAF7E711EA6F72CE64CB7CE3ED5E557515F6C0D135401B70C687F97445AB03F49EAD2F911A5C1C21C2DDA9FB2D4A8001F698DD5C54693A515E3FD9205FFF4CDB297FE3D82CFCE9077261758798C7E31B2661E4919572822216A14496F65D6318458C1D758C413A84D4909B1D330E37B8D6CDE30DAFDDA5966559C35D1E79DB90B8B5D0D64B6B74F4781A15E34B0CFFCAE7655CD9C5FDCBD855E1A597A22F82152CE18463F1F71B5E343032BDAA71C3DD5EE7F3E5EE157390DCF4AEE17C7F204B548B0D15412B03AFE4A0E733C3D0CBEE8B2B23854DCC6D98FC7D9FF63E841210541946A048127763FB4D7BFA43EE2FDA7C52A07F1EB2A7CB3E06D8E98CAD68E1AF7C60672C35C410EBC0B7CED72E6C88FF5B2FCFD1AECDD459BB472D0CB20B4CB53102F979F5743E1F1949E30C3DC04A91625844E5780DE2E9D855EE0E03850F123BB8A092D6F4F11E9303354AA49758438C653D52EBDF36EB20FB6B2678E756907ED51879A13A4E233D61BE862DC85D8C8CD04643F783030BD4798C1BD1DFB54706E79FAE2DE8D2FC28469F74B141A571ED0C1950DBBE941965D0EE3B17DE0BC0AE16F98A72CE97B51A37C0132E051E7B2AD221926D68851F3342BD398AA5CD779AA91F1642CED4F81520255B2AF51F6941EC7CE3732553AB201756563DEBED7F6A567306E93B2263CB7B6895863ED6F1120069218A9A2BEFB5AACE3B87B5701E5CD6785E8D0D1E9B5AF7E3D312E4DF0051946B8F29655725F018A9A6315EFD2478B3AC2DA543E347A83A672A7D1C0EF91B31C154E8B57AC643D1BF4A787B53D5FB34240F0072B44E86F8BAB01335AA56D21B3F9DFBFCD10BDF2E51D0B56C1811CAED5B1F8EC8226C54EACE2EAB841B9CD9C4CF876ACD6F7030D9A6BAD21FF3D6316429B2A1AF4552576716AD3C3A8FD36CB54B6C395E43EDE8B5DF0F24927A2A46D209A5B595F4CF60F487B7C138BF59D1265AE0A40F476FBE9D4A49EE24944D5999C748E2291DF06379BA1A1B372566A19F0A3188CB1F5F66821C3B8B974CBEB27BDD80AF162ACFA954BC2207A825A4086ACD0110C677B06653F3E8D34024A01810087E55740AC10EED1E104A839EC2ADF4627FA659F4988238F25AE00B756BFCB2660A0F840DD96EC3093B3AEBCDF20EA99345FD75AE8609C4332B1A436C93B1CCA940C523FF3CA2C4C22B1E60FB7778301FC9A6D0107475433F96D086E3AF105660F7AACE01CB697BC2F495C71ABEF7B3077C75F4AEE329EB5BF9E8AFF82261C0676734C1D85312E9CC0559E26FFC2382C2E123E680F7A22F3AE9A508B856333E36155B5706A7D94596CD131AFF869168D93E45632C9F04E96479532273069D838618B606712A6BBAC7F28275B4636A32D20E677BBA12BA75286545DBE61A9D1DF7AECEBA0896017E9129CE5364A76C1E9EC4AED8E903DA3599BCE44EE44C9E3CEB67870D7D3F815B1B83E8E655A57A167C9AC6AF4B36601C726D78E1A6AA7B3A73F81CC0C8543E67883AA525DA0B828D91ED510E6EEB29AD92649947FAA463EAAB93583CE2BEFF1308D4B1125892F02AEBEDD1AB9A7611C4FEE5ACBB9BA8634169DB9AC73BB0704D1F8F6098CA76F2FA504D8825564A30A1D7E6E12690DE34C0521FE70D15714626DEBC8008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 0000000100000002061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1021 -max = 1023 - -count = 2 -seed = E7D9E1A1D2B81EFE0556C01A7386489B692F4669717A09BB491A7DEC9893F44D2758E633658AB5479168CC719711E2ED -mlen = 99 -msg = 955F970C4CEA3EDFBA0CDCA55FBF59EDF24663E837973E11658FCDD8307A9101FA2E13C4CB23F588EFF1A5201C77E9F734EAB8C76A7C5DF78A6DD8DC5F17DCFBEEED73C7B940F6D4B711CB8856B2E1653D246506DAFD05EE812D6476B53C920E0ADB6F -smlen = 2500 -sm = 00000002C8299416D392EA9885BC2583B1AC67F96AD84D563D0C301C02EA868E744C7BA3C1C7DCB7ACD5DAB40839E3945B0784FF1AD07B1E52812722E7E525CFA0B0615721FCE84472139AFAA7E03AB9D43D62C1C9F71FF0B83EE68E13E96E2D61F27BAFA1FBF91365E6E2AE524E2781040BD0040AE61C59F2BD111C6A67F4F348F25710EA652F452FFDD770306DCF94AAB169F987EAE7F7FB2617A492F9DA54BEE07689400BA5C77FBF6EA54D933F8B84D82664CBCA37FA896294DD3CB06165DCC1CC71083D74D6EEB4C0CC84864C038A52E7BCECBA7E026E4F1ABD3AD53A24F4A0F6A56DF3E0A45AF1F015FB39B04D695ABD9767EEE724D542DE41C23CE1360A69C6A0AECBBB5FA37B67777B066276DD82EF020ADCDEDE2087999C418351EFC54FC1787855C75DE7041402F8EE569D5AE49DADC3E7501F4FC1D9C7AA685E9647BEA04075EC25C3D1C4DDAE1DAB5DBC54A403B7B8B1BBB96751953B33275CFD3B1EB733292E94B32648E31BD4C6591E9705A09598C9C3F9B1FFCDEB10FC9A47C6D4B6B5E45493CC706FE39F27EA164F88DF41E164A16AE2B248E547F4198BD08A5530B5E54089FD91B6F93C533AADC2FE8C1833C8C364A047809E733036A632A91B9EE037FFDAB49021952A3808C4B8E3AD4CCCC7DD28B61C51897E4A5E0A99EC095900D5AD1A2C15685A9D8F56059AC53EAF595374DBA8E2AD2929F8ED6E1C6304831A9D6E3BE0AA1B5681C04D2E8A0300231C121CC1E92B9526D8E797822A7C5718399AFDC5306A868C20BC0F54DBEB95FA711EC79E53F0E1320FAC24BFADCEBA31B956370596A49A071C7A766EBE2118D73F2E39EB59E78BE49F74765FA0134C9B73DCA1A839FB9CC70388FE51E18922B67CF4D08765084E11CE5D45AAF87DD932AE5647C5AC2F88CBCE3FAF67C6035F40781D219C01B84A6728BD4DCD1B173C91FC69798EF1E6EC4F6E8C48A1ED68B917B7D35F3DDC88553F816A4C0F084F56E7D245430F13902459AD609E2EE59B0CDBFC46B823B0922EE41373AF43702E9F093972EE41CAD6F128317B718E87E1FA6185ADFD4C1AFEC61083E3BA5A0D22CE367FD25B98BD3A660399CD4D8A7F608C4BC0CDDE993E57EF92C1FD6EECA542D94FDD77BB0A4B1B99CE7D7E53347B7CCCE13FDA6F8F458DED1B91CAE8CED28FF8D7E39C4F144832E3223E874507BE3AB9718F6240DE0A18CF2DDCD2786940DA86517B3CBE792D5095707ACC08758CBBC307A263FA31A736F6E61EB09EF6BFF82BA7A3273B619878568D62E21D1F15A758E1E83DDCAE6BDE013494DA308A55B5B1E2FFEAF690E04BF725A3C998250067D6320A9A61B3156A5F2A4B4D53BECD0169A0C10BCC0494C2B51BA2C4904CB6A36F7D302810829CBD03E11A8BEDFE4A1ED70FF1E28992B0BBAB3BB43EDD2BBEC8C943E9382B47E24E442264060C61A826EE9812EF305EF83DFA429B7BB0DAAD700AFD47C91F01D046B398B877FF896B437DEB2D4489016CAC266D5B970013229EA33C93909B75ED6755F2FE72E1E3C90613866F85862E70227320B98A4183C4D5C04135A54987088FB17B56D1868102D1B928FC2801ABAF7B05EF137427317EA41BC44564C7BA0A4D7B1A11E494FA15D2915C5AF412AC1CE800A713528774E7B3A74FE03B83F4E30E85570F8BDA6274CF673819B6D43A4B5723B6F06E5B4C55A0D87A424816817AF489E51E8ABDBE6401FAF4732EAAC864E4A6CDD22976BE385E2EE95613FDC2743A7F9A1D60B57C364A58F4F49D414C419671852CE004CF21A2A612BA8157FD0BB2A8A2B630583AC660AF8D220C628BDEAE4973CA3BD6ACCE2193EC091E5F39B7BF0F6AE5CDCC606DBDE2FB25C81106D1B9096D22BC5562B1FD0459BF4DDB6DA835C4C63056D93EF434A55A09CF08053F05FC36FB05425A34E0203B17652B243A2330EAF2F3643EF9A38E3148D71A6B1DA95E4ABCB40376E606FA666623A2597D537B30B0846CD393CFFEF276D91656137FB596E9D9906265764B37DF4725C2BCF0E6E3BD3CFEA76CE098151FACD13AF3D43DBF1E0046ECEEC801CB1FDFB9DF6EBC5117199D98E8C60C5693D629B52334342A4605CF12C7DA172C094E6A48A74A1601F057B3DBE7D5EFB8699339A0EA6DE835507F830C3F36F5B7BAF338E3CBDFAA42E79DA29CBE2C64431890592D97485BCE2608E8B34788A17914CD59B485FFE5297BD2860AA661EB69456862EC5C68C9F5E365F90C1E42BA3B0AFDF3AF05859929EE65DEFE3C54117C05931164C42C6598C85F48D46F0AD243E59EAF0165439D934A56AAA3EEC4B123178BB2828C4F1A19484D3B832E1D376A3BCBBBB13DF1F792CF11BA16E2AC13A000431B48050E581D31696F40D1BFB3C17E98E240F2F8A49D0407E42C80169D19B37EC4046D3D60A15310DC58781060C0B53380667B7B0A13128789C0A9C83486C25F244C1549E80C7769ED738F3E00ED937CB5910B8DCF67F9EB7AED39FAB6F5C7EE9FA05CDED2148CA9E3DF2DF81B9643DF4538FD888A1BF99BEEA7378EA6B6EB86868514A9EF808FF1071FFF8D5D48A2BE6AE9D2404D9AC87D394B3A533CCE8C4A656DC649975BA1CB7F631F210BD285B0FF1BB6874B2B81A9848AED264BA8224889D65C0C64FAA546A6ECD9BC5674FAFC959C1418C0A3662A7DFAE6BDE9DCCEA5B5BDAD952DFC7FB1B969078189F691578B0F5F30343311CF6C1E629CC292A1746104BF422EC21422C15283525D9A3ACDCC9014366F20E2E17BB6D3039DCD8395C61905C23B540F4BB01E817E23FC3723E4AC95FF04BDBDBDC7D70AA1621E7C3AA13E9AC66F057EC0DC6CCF460F969CEEA3002206B2BF88093E28C24F70F1704FAE79F6521951C5B714AA2F0837A179D7B6B49C438D4CE5A8DFC8D660735C1FFF405E406ADF6EEB8D01172B4CCBA596DCCA0C1C92E50AC42D6C5F2E440D25C796456B756D4C857B0E46EDFCA5B5B648A9662C16AF94EFBCB1511027721DBE0537176E4808FDFA6A226E5552A279DE132C70DE7504A5B61A036A86A67EF126FF6F609A4887B589F12FD447180A82EE1BB355DC3216777E0A698D7BF588226E4D442E50847743F3E300BFC9EECC8C8888F69FECF8E95A015A5998F0E1BC3B4948C0EEA76004F507747FA63CDF4A10E802DC40928F4192B84EC2A9FB98D7DBD6AA556098CA76F2FA504D8825564A30A1D7E6E12690DE34C0521FE70D15714626DEBC8008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 0000000100000003061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1020 -max = 1023 - -count = 3 -seed = A344668712D7FF31F511B249BAD15D46C184C9D38442540190DD21E5E784989C56CFB7CDA3336E290F1344AC5AFFFCD1 -mlen = 132 -msg = 3472BE99A4F7CD9261B7F97B0A846790A252CF5A53035D4A6A31B5425F0852F0A63E630D97CC57A455EEF0FA171F7A06C0454D8D3713D47638C01BDB4855DE167C33019780B5EAB0D521E80F536D354756DB0D253A83674F74BE657B0B5681E0696C4294C80B712743EF9AFEC9AE6424C8C8A1810D4BB010F47FEC835AF7F65B40586CFC -smlen = 2500 -sm = 0000000368D0AF9AB3B4981A5A3687839F654ED9958EA0B19666AB0A0D13C7ACA213DB148F827E8E20518BCCBA7D22ABE71110838318A6A5FAB7278330DEFEE172F470802774094D528C66BF6CF628E256721F18E998AC89E94F4CC64B87D4A7B33CBD2EF85DC2FEC2584EA9B7A65C674917AA475663107C608FBF993520F53E87966D52C2C13C93E7B84AF63F2ADA035DADC96B0E4B3FCFA8C1C4F9C3C96866D0ACA6C7942A9C15EC1D25754A12E86B88E4903A1922D10C6378DCFE38CC7ADEB898384718ED44C328936A0C0254B76D6B6E2BEF0175B1C1CB700E724DC4CADEDFAFD35C7D054E351B7AF0E82762710952790318BE12D2D860E8635E7803A1222D4ABF87EA0D656B659D634F0454A730BB92D5E80CA6446BD798021D6B6D19FFF79859BB30D70D77144591CB86ECFC91F3236AD24176B2E8FD36DE8FED94344B3D6DCE6C136830E439ADB5C558B5DB23F5531C07DDE74EB158774D566B086EECCC5C5A7EC0EA44F1996FE3A9D3B8C39990CFED6E9D9A29B8360672B0B9F3D1B50F66775868B7EB8E94FDC741D21B7DF68E9404188EAA65965944F2036EB61F41F504D3796A154024CA4CEE846F948D67A13F820F045B4F92576749BC63692A1C184F20544C301255510F4F869721362B71D46A1B3FC103C97D16139770A8FC3A5304D7B0A82BF68518B8F6246DB32F6A73E787C6DA515D788951132F3DA9C6854599F0B97612F0D26A0AC31B0F28C87509FCD1B044E60322181263AA54DB4E2DAD046D81973EA7FD836A66D2826947DAEF5BB7C9646605E245F4AE8C331D39C585E5912D09A596D5EB66B9DBCF3765E9DF7F79BCE194FB3788A24E22210171FB985E573FE67488A941D7141B041038EA1A1E2DA34898EB8C0D79290657222ADEB49B5696D0211B9B748FEF3CF99FDF7F9FA234F5ED38BCAC44A716AD831D1085CD7CED7AE5C24B2A3C28FBF0970B4C367FF65D650234E1ADCB9BF8D874C66B66AD48DD35D01703F8FDAFEB791574750946C6BEFE20E3BB291294153BBC0D4FDBB05801BB271C4E5D67E7CBE825F03C458065B60C4E30F645BCB7700EBD90400C80843D83F5C70E3B0A6F53BD12C6525D3E37AC18274714D5CA4F9FF0D5A199A679C1B361E845427623375CC168C626D7770F23FFD26BC8121F1F37914D9C6F7758D06CA02129433945C4C975BA76FEDC0EFEB4E447B81D9333145EB86212387381C20A8AD70209008A2EAD4B56A0BDC84B706FEC1ABE2C60A096B83E345405B64EADD4786238C59303E195C5C8DE499696CCE53CD1A469E06EEE0916EB84A04B46B7809A92B6664F97483091B3F239E14D947190CEEAC71B270A1CB730886490CD8847053B9DF24F82D7A857DA3DBE952349556469BB4AD4AD70156BD1D64AC13D822F43DBA949C54CB47B0E75D116E96CFE87BB0E5B21D643B45D143F5977AB27F53BF4724B3CAEC8DF9B158A2013943BB524D1956DDBFEEC65B49CBA2306CDC188A0F18D38728E44C13ED3D309FDF4E8D33F33308273B955620686B057BA2C84BCDECF0AD37C19B4960C5B1B06D89F151E437E8963627EB667D41DF5A1BB89B271E3A5DC2DA0541B13B1212FB2578EF75013B1BFA40944D685041E82958A195475E95132C8B17BF2A090D54B00558773964B2BFC8B1EF89FEB193F0A0646C32FF4CFF26B3EFC3770662A75C3BD7D93FC58C68FE89CEBDE9B4E8C522A81E9DFA925ADCD471E27315BE08E3FD414A558ACB91D0C8BFAD659F1C45D2BE45B1B62CCECDC048EAA7B386F90244E3C2473DD550A3FDF5E1EA3DA65E789065918F8C920586AE31B8DEB3BF6442DC9FC09186CA79221850E4CA7D42CA426DBE5544E0CDA7CC27DFE210739C5D2D5A0AAD80C0F3BFFF0805F71805B5C668CFED02443CDA7A36F8FD317D8E24FEDC58385E31CB94BE00B84F5CCD188A6F0762E4F2CFE25DF4136F70892CAF5AE197556EC733C161661DABF09C3C3CA9F600E23DC9FCD9C843EA4412B2A6E0C5FAA0E67755453FC72DB4024F6A6C09ECEC00FEAF0E8AADA220317902A734CA430C84E5699DE750674A9F7CAB447DBB937E431018A050ADF6D526246767F7CB0DDF8D63BF122831FDC1686670825CA16A261534A48E712D0A5E0E68A77265EFAD238D63310B616E036C198F73D88EE6FAA0A7352A108695DC86C0CB4FEEE07719B876DCB7604C180416F6057E32455A0D7C8920DFEC3B91B9BC873629CA3D001467059D66C9E2EF4F31E2C92178C27CF24B9722FFE355C32A14951B75D53D8ED8FFA99693BD41AAD51964F7E44AD6477F9D2CE0DA2DF930AEE3904338222C51133132B0FC497A1F0B822CFB2DFC449E10F7D5B080B89920B486518FEA8AC14CF572D373A823EBC0733206DCCE604450000CA95838163BC0DB200509110E1A877221F3CDFD74DCB4895AD12AE02F30352627DA55CE4FCC0752BC84D0D88C702A030952D6A7BB43FA817D2DDABC20E5D49E8B165F2A828E1E8A0CD2E65A56287083F88F11E6D6FA76255EC84E8554E607B7F427E408A5BDF93436F9F45C2C5E850E521E12ACE3CE6964859EC4EF0B3193C3FEAF199B7B1C52EFC3617231425954F781AD53472D1312ED78A9B53C2948C2CC281E74EA8FD843265D296A0053F28EC6EE9D02BA1634A3E0A7A62C316E691CA98D5948880EF1A4210030964892AFF3E326AC29526AAA79AD83A65590F223B7E102CB44F49A2BD383887385D9FC294E5FACF72E7D358E212819DCD08AA6C0CBC366CA970DB76EE5F2FDBD89F84FA7766BAA12105E26645E9AA93DA0015C16A8C67D8C53263E83D276770C393F8807C2FDA9000F3237D50A0C246EDFEEF87157AAE7173344B0E562A10C62F252AD8B31C25EBAB7BD44F51A70FE560D6391374ACD07BFD372EF6FA019CFD1F938AAA6A243942809F13952161094F08DCA33C02F988217392F69DF32B4F8EE75AD6BF0EEB02C9A8EA177DC6C87B51B59E4CDB39C1C8E7269444E362B3755BEE8D8F9FE6D87E68B2452B2CE2B06A25FECD41D92EBB2C8F98C2548623DB4E4B37C486C85EA8F078772D5A679D6F08CC187675911260EB42DB4EEDB7D7B0C385EB20D612A9B8A8A9A515C8D5BDDEDBA678A89F26DEEC24B5AA0C071B27554573250CEEA76004F507747FA63CDF4A10E802DC40928F4192B84EC2A9FB98D7DBD6AA556098CA76F2FA504D8825564A30A1D7E6E12690DE34C0521FE70D15714626DEBC8008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 0000000100000004061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1019 -max = 1023 - -count = 4 -seed = 2629FBED0B88DCD29C3E7553B2B8C209455EEFFF7E8A3EDBA39BB1C2B4F3F1B0DAB5D1CE55060B1FAD562F945433DDC4 -mlen = 165 -msg = 1911306403C3C794EE57605D2FE311F4509324371103F69724087A7247687CD25FDD0C97319D6315E262EA581BB61987D5AAB33F331C7A7B260E92285C168DCECFC70D164D7A23110A165F456F22256A77AB7F0C5E5A69C91D7551ED437ABCB9B3101B8BD794D1939F372BEA8C5586BA15528BC4E4FEEBDD9904DF943513AA0E01FE67DF25E8F3075FC2EECB775DD2BE8D9D3EDFAD05762DD0BF1C228252BF2BFC7AD6A8A4 -smlen = 2500 -sm = 00000004F5577C9A22BA344F5F1F043B0D44721479D551BFFC0E507537E00A68CC13F73953A1229456CE0BCC2CB8E307B0117CC4166ACAA913EFC07C79D90CF54E2A8DEC96C5FF3C062CE9D634B0A1A562E7013733A934CF4B40DB2973F82FEF1C39532CF1D1A3A3E8E388AE133EF365C8F9F70CFA87DF5DCAD0D4295E0D8B6DDA3C83D729D7C1BFAF88C369D8C27564B2463171208AF1968F0C996613370B95EA9693D8152DF3B4A2D369FED6CD83DE8F81F7DD4BEB3B71A1441E3E6F37C5596F5BECACA70F7281762869CB2AB90D62557847B0AC6BBFB9486F471EE680CD8EF8E5B8B983BB876EDDDBF042D55BD96B0B6E7B29D51735A1F1319A10F5A007B98C3901D20D9734B79191DECBF5A19DD8508E22286E56373E9BD62C32BEBABF80617EE842F201A486FF8210B929BBADF6598B117D59CB623B839C93E87E1353279BC62203DD32C4838DBD0134577F633201B1E2368E517A33DF664CFB9F8B965A1B47DABEE48887D08FB2AE7586FFF0D4DFAB573F3003AE1F92C4A8DF5E992E123E38D7F980CEE7E2EB2B89CFD25BA8C8C57858A7B18118A7F57688EDFE98EB053B168140375439F281A55A610FF6C82FCE9580D66970862E149012CF4FD56F9A6899DC7A9EAB77D3514476B1D99ABC7A4F2B94EF04264CF810EF6EA9F8CD8098727AFBAD99F9DE5A4D6BF0D782FE0BBC47DB266A1699A70AE9BD276058A326A3B48E9C90A0316B774A766AE6D4518EDAE4D54560A554213C6121D8073BD1DA2D3B46961D6CA5B56AFC3CA5C5652B4A66B08D7CA9175F8D7E9368404079660BED6B7EF7AF0AC1AE89D102F0FF62C6FB8197DBD91AB2C61A041ED2E151583CBE57B99BD3645C5E2B0CB134BC7F313DEE1ACDF05124B69BC23E229FBE6328A5DC96F530481E397995B2B1D4F2E1520396EA226E00DF7158095212059B009A595FA280D074A8436041BB7878E3A50FF7EC5B7DA6EA5B60F733A8F43F5B8014DD403320F899A22D147228847BA65CCF10CDD8EDCF1B386D4F3B32663D4328562DBF528726261EAA4ED1EA6EA25039879A334D522C4ED989CDCB7B16FFE382701301CA6F3249450A279F04E9141C77E96649FA91972B9621AE55F7FE20DB34F886BAA0DB045E27AC8CDA897B64BAC0C730E616D11266DA4EFC8831B3798AAD9F3B5A9B338BD570A65542B5BC6280CFABBFBBF91D72915F5EAD42BEAFC9EF37AE5F676FC71131490BBC5CFA1D31F31BAF268B0956ED80EA6EE67CCC24E575EF2F405BA0AD453E491BA7BCF8D64BC9244C5B7B5A5243677ADDACE8743F75ED78D1D639F843380967CBF6E1B28A89B6F9F2B6748D993A4FB93BA0792DC331BA9073227DE2AE187A4118F296C95554B7075ECBD798327963322D1BC1F53B96551B8AD04C0F5106F02D6175A3DF5759A88EC1B3E9C4A93E5E9C662D39458F809FED357733F0DC98F0EB1A129DBF7AF4506CA23FE71C99C203AE1ED1D1F845BF904120EA102010E7839C789FA1EDDAB2C119AC31C93AE0FBB043D349C5800C795EB296095B296407C735A4398CD271AE3EB82DC844A33BAC423FF061D1C8AD83F1A5F277E87C9257612E7DF97169EC5064CAD3EC5D6023EA16AB0C86ADDAF13AB379D279F93E2610AE1E857DC769558335BF490DF208F8FEC57EAD1040F4DF3CAD9E319F66716E3DE25C81ECC797E73F7F520083D41369B16B5C521C0A84BDAD190F6E7BFEAB0640BCBC5339B5102441578C533E89982246D3A05CE329D203B3E9ABD016126DC3CC80116F5B9E6524A37305424F10280B3E14102548326C940B7CCE9A272DFC170DEB86C1BC48817D8D307513070EB341D0FCA9E9C17CB4EEE5DBEB61A2D503289EE4BBB7520C2E934E9BB15A2476BF1111A5D0F6573DD92B28C7DFDA5AF8F82C813EF2B72AD81FCED64DF903ACCF98EB33B8F71787F4DC780B5E3E3855B407C90FAAA62B210B23935F826FEEA939014C11EBC14083FF149354C4137602AB34673E8FEA7A0820302D4306BDA77AB22C414A7C0ECA857F9014BC4CD80249653EB51A36B83572CA45C9CBA732F93410F7F01E1B0BBC705A66C7625BD701C7D2A42181945416196B8E9756CC2D43F4669001505D00E025AA8E1B3BA8BA1EA2F062C70FAA3F6B254ED8E3A28EB72DEFC5204C76697EF6D95FBB3C94A63E5D8CAA1ABAD7C140D8C8BEDA8FF2F3B5828D26E63C680D5D034C59B0CEF85EE333AE73CEDDB2200F7551A0692D03A93FB23BF54CADB3EA26C06E016B632A4999750ACEBBFE52465F9B84618D445FB24BE42EC349CAA9608A2BFF39609F076C44388F654868B167480575C8AD72DE99BAE9CA3392F1718428C259D2F60EDDDA26F8D09FF8FAA2DAED50AFDE4063EDB37749A1E172A435EAE2030AD118C5953BB9329BAF06B4CF6F8A391D1AA908C684EF5FC855453F29933BDC17FCD73A282B411DDA3BBBCD3B3DEBEE0AB91E627203570CD3B8459872849984F72E3DD71ED762DDD7F3E32252F6B339D18AD5D0A6B5D9D2DB81016175A7E42529DDB7F15DE23CD75A241624C5B9C91749FA5CC9800CF5FBA04A03FF97FF67FDEA4F728653A6407110CDA74F2E5AE159742AE0620D1405213B6C101823FA07D454DAD1A0355BD592BE6EF059AEA34923587A34A9A9BFB75CAF93C400E2044C852FA6A9A8EFAF1A0614A06352E6DEDCAB1A10E52A7B29ED5D48821788DF5C5C12431983A9D1539A4D914DB99F5A3C8833C91140238AF60DBFC0FD7DC60E99DB34763EA9CF1BA4AD306A3B6ED36286B681AF9D5C215DB0216852A6FBBD0EC828FB756E7A2285251B490CBB4273F9ACEA149BC878383D01200C9781D063E3932A847A223F58582DDA86F2422C0CA1A991CA1ADCDB41B97DE0EB6C24DF2400626719D9B99B78B66696168E6209FB4C31B4089AFED7167D10512200BC1133590A8FFEB4861E0E4D87648DBEB9446862663AD4570877A84E8CD6755CEA8EB7B79B0B21DC390176867215C7032BD92BBC7A81B464737B62AC6F7BF5D92551718233A7DBE37EC33B1804763C025426A6778757E004E043FA9F5C89A8044992762C3734D092CF23D04EB8D9F665055FE6A256E4DE0795896F08B1B3F04E10B5553476D48EA669EBF6A5090A83BC1A00F9596E70E6F751B0A3F7C0F30D15B08B42EB0D30A5C1B528078FA366959BC1D592D86E3555A4820740E272AA2CD85C8E05202C13B89A93260496DED8FCD03F614D953E978008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 0000000100000005061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1018 -max = 1023 - -count = 5 -seed = 13E884A522FABD17D2E055694A6D931C6459A17FDFA40131E19788DC572A47056670439565685510E54B3BB94D67226D -mlen = 198 -msg = 3A46A3D825C949B1E8E68F01B523B88347F0F249F6BDC0129A11CD46F11DAB4C11CB14FCD062A67A76C0EF2798D3586968EFBC619DD949ECBA08099B3A55F6917DD922DF985F769BBC53AA03D93E029DDE2B19FC02147BFE4B4756A560C75DEF13DB7104D5A6A238ABD0364A3B3EFB7A50754528D75E47FD8349B0D88569FCAF3382FB8C6C23CC52BB87B75454A0AFBAEC15F2A19EAEAD8C8FC15668CE37C8C1BBAA75F705B9804F2C942880C01C170D8CAA3C3743A91D569837DD84B50569F52302F8066600 -smlen = 2500 -sm = 0000000549F101925AB0FD811DF00BE2C75202021F2CD6DFBC82A8B38FB3A288863E316D4089B9994A97AE8AFC236A3C6B933AA82BF624CDFC8275E3D738E9F8B70B9F28705F444E6BA204F90AE9765DF09D51F8FD493B16385FB50C264D7FBEFC02912CBB280C74523E42361691E4415E749A27F3DB2F9E7145E9FA37A41E31316D5AE4AA386427D27F0C6989EAA280FBED66B67B3BFE1FE40F4C2B3C6829EFB834F0194E36A6D5B827747380A96C03FC8D21BE870FD98865BC822DB92A43413511AA3A0AB5EB2873A5E59764F5314677CDAF139B586A0FBD262A9C1672784156CDE6D5B933E36A67995B12FEE129EF362057ADD48C9F1B99251EA903975CA2D25036E74DC518F519A5182961B92256C810890595A156372328DD4DB4BA457A4CA4CF38B2F88AFB1420B5B63D295D38ADA7D44D7C818F7726CF566E5211E421B8DDCB20C265AEEB830AAFD60ED271067EF5B551A448CA78BBA817067D97D83A0696BCFEB6AAF5DAF64856CB08228CB09EC185C4ED7D6B331D49AE6AC8CB359D93B0C4AA7818C9B53B5B3DC7D08F4706EDEB62777707C0F322065B9A8AB683171115821677D85ECC1E7ABFEB6FDD609A7D1CE0CA13564E5723908FC997EB8B2D5C020EBCC82A09F3A03A49D2514003EAF26BEE005699C461069C7248DC80B903949B4652347FFE0361400DEC51D4513E48D4CA655A72B42633200259FFD2C00FF686F9A3678ED5BE780A1273CDF2DE1CE1BDD2EC627289D2407C7883A50BD752193944D927F9AAE86831475BCB5C933F053C46CC441A8007F4461397AD391F0E5BF9C40545FE403A7C2B82E25FB43578941554BB92BF47858AE719435DFCB6E34BFF2D018BF92C0A5F4DF75DB6F0BCB1E46B68F7ACB514CFBE11D2093DD8E966180EE009FEF7DC83B9E7D6126CBFE1172D32A74C9214D8FA7BB438B8225D213939151FCD463FE7AA412B0E5764359E43F2C8844D56B04ECE2CD254094DC351A8063FD892F4C04916DE2FF996E91F9C3AB7591F16ECAA108890F5AA4907BE6A99E5537DB234B5CA31927AE36835FA74F596A0E81D52DAC70E10AA0E5405D49136EDAF38838C37F2F76C195F7B3550E609FE6C8BB34038C0105EFC2469E367437F9BAA60B6B34D50584B4BD45AE85944A639734DC8D7FA21CCBED43811F9C593DBFE64DE8D7BBFEF68AD641137B40BCA3077EB58A632A09BB5EDA3C27EDBDB54E5AB1D7F430C9748C700BF4DC00E8820EC4CD825D899E1CFFC8428DF6698C0BA957281BF123A3EEA5F4110B32C36DFD114F54F3C89EC0475C46BE27A72D049D5F959457852BE47D7D88F91D5364C0DBA8A18AFF9CE8D7329562C1E89A7EB7AEA5E8F0039D89CEFED8A3E4BF04A201522C6EE71C17CAB5A93A063EDC4A3065372F089D7E41B435738F61C0B2E5F93DFE69B83F2BA25E2625DD27EE25D2777BB5472ACE985A4294D6A6496E3A99F02E0475F9A3ADB55E58A5B9F4B8345D931CC0119AA1820AE167DDD88423D632A563DBB0B22BF72105879594E5B09152324803258E981EFD9083FADD7E581F42AA9FBB109D63DDD83FD5635C58B9B8F3A53B8A2278BC7E8435CCF8C7E713552AD0A92854137F2F564CC9D659168CD8FF073623843957A342C9A78B4964A22DE1B1D72625F9B9F2F6C74FCA632FC09EDD8EDD2A5B846CDEE8ECB9CD932F16D6E3F23C0CA047A3F3E53B0BC18F442656AA1E271CF61C8A13A0CFBA7641A5A09713D75DC732CF9B29A73CFD5BCDD8F8ED2E8F3A1688AFB539CFF010D49641D753CBEB055985369F362C6D310C5FCDD2A270A2445E9CD5C8990BEB3A34C7C5BDD350CFE136E165C21BD7BF78FA4CB9174AA23F925D9824C2505E08A1FBE1D090E366D1BCD42978C6B48E855EB4A9693A3AE93C22B673695519976560C84188D3353C2EB5C864B71A3C66489DD368D3A83376ECA99AA7FA83709A12EF6FC1E6B82FB70FA258E7171761D963F2CC8CD2A4D30A1FBE73BFB606CA6114AE3F9D038FE259FDC1E5C552E49C21694D378EA54351313DD8740CAD5E6140526AA7EEC0627ADB8DCC5096425270CB32618FE5C6F068E934EC222248F80AB1718AF9E0E737588C1BF08F7B602ED635E060809F02F76238A7743774FCB1E6361FE16D4EE275F70A518FCDB1DEB675AD29873C78A651018B125FE05B61A124A336739CC0A5033A3E83FA87785FBC3C0BB14BDD143465505BDBF9FD96F3FFC6BEE0999CA1D857DCF6C6CBCE8520E7A5D095DB288FFF07D9B98F579DA18A374C1CE1C59A73AA409A8BE98B90415168FB55EFDD97EDEF5AEFD8B3B78F98565F1964CDBE714D1006F97F3D0DB5463974AF951DE47059C5F1215C7CA8ECFC34C9AEAC679C849E39AD4FF2C55D9917AEA1802E326B59D46538841333E6B3BC210D8217F4CA0F6D27695ECFC02EA7D24A04A10373FE455FC22B805147592954131E2F898B04CEC953DA2284DB98AEE5C19B4F9F527D8172A63AD650BACB3EB29097A171C1CC63CF98D01F0A36A3B2B74B683F9F5D14390A864461D1DD8E5E125C76C367A6FA5102C2DBC2250874DC395DF8D2B94B5627EF2C4242D067006F44544763F30A76D956B9E34EF0BA9FA7AACE7E15941DDEB407CE208AC58C82681BB9308CE30BA4F0D1CBE55174771EF0ABE277FD38C0C5506625D7F5B0CD361BA4BFEFFAFE08B9283A00267F71F5689F0D7F1D281C63A06003718881FBD01F425D7719393653D22882F039656D33EDDC4AFB3B15921D85D5896CC2C50085874D62AFE96FE98830A294F102768CE4D22548AB1C8E854783243A88C401402D7643C091CFD48CF6112E056AF6A9AEECC897F6B9FE951547CC633AE8C3A60C7C1DFAEE5A11908BAF8C77BBC92D851B52A7F49C5AEE0A3AB47FB65F49EB80E5E93453A022B0DF239BB99070BFCD354E2F7490841785AAA58F4655A1837E30A710BD43BB7DFB1A390D53E7D557E2630256989B4B945DA4A4FE88FACD5BABDBF179A7543C366E07BB0C77280613105CC9AAC4093E8A277130907AD172CFF1DC09C00BDB99687EBC2D59076E8E23E9CAA773C686AB2BAADE15865663C4D94834171FBE5A670FEE2FE269FA8394841FF6C2A3227E8EDE85215C74AB6A8C66DCB3B1C709614F01DE3EF6AE6F751B0A3F7C0F30D15B08B42EB0D30A5C1B528078FA366959BC1D592D86E3555A4820740E272AA2CD85C8E05202C13B89A93260496DED8FCD03F614D953E978008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 0000000100000006061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1017 -max = 1023 - -count = 6 -seed = 473EE54361C6786036B3540D9307B3C09FA9C85FA8A210CA9FBAA3690FCD7A0D9E64793F20E9D2D40F6426C0C7B7CC3A -mlen = 231 -msg = 8A2290A20898F46A2F922A0F9E2565C7E5AF20868E6C18D7D4F659C10F0A3FA2FC4BFB6BB19E9E09DADBAEE668F8A2FBD29B1591AB80738BA63EEEC291073B9DE0F5D44B53952C940DBECC8CFEAEC7B598135BEEAAEB2A0DFD8D55F9F51A10BEFCEFF594E74BF6FDB972BF4B9B514A03A5954C6FB09FB0640CD854ED6A9E62B4E98291C3DB7D2E19EB730A865CA6239869868F512BB38C4020FEB9554B9F5631E5A5ED00562B6A665CEA045CB66A5B7437EA4E2E55EF70656A9BE301CA3577CE909BA413A8A78371A493FAB5E89FB8D836E90F560857670E3761430A9364ACC32D7005543D8541 -smlen = 2500 -sm = 00000006EE07C35A8551A62496DE1C658EA679C4EB861964165B282F6BE686038253E3AB824C03BDFE794D985AF23AF4FE2C7D99E7B937CE00A56EEF7FB838EDD55B8B6F0F2351ED5A4BCA9A6069484DA843D459877DFDFF32CDF084A375C0AF4652683D10E44DEBF3C18F1DCC249934E0D3820BB77879ECB9569C4DDC24ED1AD4F7E8C8F3EA59866C2B1CA98BA038C06EBB90AD8D55C54D55C494DBC18B6CD68A92FD6250535E0470B9EB2BAAAEB5E138FDBED73008F6D78CA8AAC316BACCD9D26BB3D438C8E92E702F6DCF48B8BC696D633DBA5DC00683E55C823B14FEA4B3B515A78FCAAAF5E4ABABE932375B23F22F63128A331320E773B713A26C2F60787A82001DD43CD62E536F48B3EC2057E543D5A4269152FBE28B8DCEDD7D7E0619A29E17CAC3CD37B0FA7578739680E529225F1F339F4728145BAB14C18DC46C0AD95F20B9655DEF9749F7CFDD61B9B463A113082C3CC27524DED08D7E973CA017A6A783AA6B6593ED9BAA72026CD8F448D4568EDA5B5356EA1FA7383E6BE65C1C99506763CC75BDAC698537D492C6125A1898F336D4783337446A90DD492AB708FE436B28C94666C9575345B6E624E08D037240E93624C07B2A8A8D00A126783ADC599ED686332C26D8CE020490B8FF89DBDA3D922E30011436454AE5B56925BF0577BDCC9FA13DF431B2DD67E465CEB310470188850C4974CB29C49AE1DCAFEC474371973D863790FE4B5FCD5D1B6385F8A2E4D89D0B4F0C1B66F614633CA1C70E6B965FB35E287FEEE7C75C49EE8E779A3163C9088089D490E4F5499C5E7645253A193FE04FECD5DF49C1773EEFFD87C8D8E27C6807F66A1FB2F39A130B92281F37A0F5FA33D948E02EFA3F95AECA8E30E69F81AC0184E79715FBECA388468ECD41F93E518888ABF3F889617B27701D6A90B8C4C316E01821FDA25C675683AE08BDCB221D7D07E8F5886DDCFB8EA909A140B0EC9532170885AA44D8431A6AF7278B00F4BDA9E361592A552BA719C8C2D8B4789B4D7032DBC1BAEC2D54B58AA294926EFF7897A17DCF62C17CA8AADDE2CA9D535E17C45941F570371B0FC251B71668BDA3DF52F974E8D39E9588A3EFB5D67FD81E120E2FEEE49DDFBEA48C792E427A5BC2E31BA4486BAA224AFD29F8B44C4460D34F5ACE470B11830361102A0676D4F367716F4C337E33F599E6B109B0106E74C4F458AF084C47E52583239386656E9FAC487EFFBE24539F83B398D643BDE10E38F399C45C5768748D1D56DFA4958A33B0DF1C853DDCAFD31E4CCE279102297B3834A26BF59AF85285A6032BFCB9C47F11FAD42111FBD3BB84D283EB72B2484FD6FB10751444E10ADE45FF2FF2684D332080DA03A2B9C7E60D0BF3386DB98EBD745273EA8A4BFE54DD1021C2547568A4C4EC8E217147A6E4291BAC5643962B5D61105568E50A2A068422B2D555EFCCB2D940DEA1E0C675B910B799635F7C492F53BFE784094B43156632994123B197B1F616BD776A205600D43F65AEC6564AEFA1490D1FA688AA10111CEEAD764E4068BD720D9F6F18A78A99FD5AF3936252BE3DCCDB6A23B44713C5BB5F0CE37E32B114C86A2D507CC6AE84A1AD7AE601D4711BC4E249D34533A291E6FD309DD2CD9AB11CFA8269F7A1F898C3FB54AFC0E889A477E8FF06FCAB49039FFB0DC278820C1B51F7E3C57A2D5C23D832EDFC0D7C744876CD001E8E21CD4B286F0EFCADE9763B810DFFF6293387B07D52BD5375F2851D9BA3BA1A9DC61EB70245B4E9AF46E271D9BD896D1178FC22D37A0DC42ADF4326A4F72D2A77F796944F32D667C4F943F14CB764E68734D4F0BB8F99B13948539BF208228027F38C0CEC77C3ADE11FF923D55314245A8CDEC403A86351001EB1E1BEBCD967F2AACAEEDD7E35B67F0F21BE2FA970B6D26EEA7E3C0C1CAB7CEB667DFCF98EA04926B2A537CC6057EB2B87F95E8AB2104B0F0EEFC7B987033C83884FC1E6D29B4225EDB6A927DBD431B38BFF224D25D5CDAF99640F2EC6B68E93CDCF7ADB26309F76CA9361D07C7192FD3DE39F7A2767D55A32FB2BBDA1FE11A432BF156B3EFBF3B621665C01F2209CDA6F2F6AC96C7C11E335C54BBE223D241A7EA222BB901FDCE1D013BB65127A4B7F3CF582A2806EB91A2A04FD0B358F3D4440D92029AAE45A3F5E4D421EACE412EA318493238E05221716F5B540130B57EB0DEC4ADE20A973EFCB39358B1AF7991EFD5A64E36F49FE66E85AFAEB5D109B39450B6E2F7A30208DAC21B5207930ECF97D6B4145DA66D97B720F10B1893BF2EC59FB1A4A9B3F27ACF7ADD9523357F4BDF58BF6927089A45906AC41666FF9D07C5F01BCB6AAFB1F143785BD4757BFFD595870973C0EDF20CB138398D4D2FB3C6BFAD43094B4D54E304B2589036F56CAFAF88B6E2DA1D2DBCB6B9836A2C4FE0AFE5740A26DEE961FEF5127E6314B22CC61ED2629A65F75453C79937600DBF35F0D617D7915BAA4315702A01AC6ECA674642A5CC4B9C9F0DB03C5E4BD0A81EC25A45103DB65A8645259FAF50EAC96DE2338AA4716C5F90281EADB561F14C8E5FFFB31AC72BEDC927111EA074A607292D2A1BE66DDB1DF86BFCD22731BDD08F2E74AF0B501C25EB78A499E5A0D8EFD8162D2F971B8905209C257A82B2A1EFFA3A71217A2D81726D27F3168573D4845633D39CC9D8C6BCC7E9E5A6526D304B115EA9EE7F9DE39E3E5C37E4B66C88AED0FDB581D9D02B86353CC7BB1D9033B4D68AC47340548E6B3765691EF0B08C6396218D196479E8A481CEB342C2AA117BED03120634C0BC0A851EC74BD8E0EB5771966C2425FF6D071AEE103686C3CB97EDB304863A1B7A2EB65AE0914051582D8F1566B65ED24EF89D3E77E72E3347B04F625C95AC5C171F475A3224F971F642503C86EF42ED2625E80F5DEBCD6F6A42317197FC85B7ADCA648BE20140CA76D6983616EF1E4C6B3F7D7546663527AE4CD6AA2DA20B2330CCDC0C19C002CE42767065F53B59D196F5EFEB930C4F575ED9BF16B75F6FE0AE739A129122CE1AD8DA6DCFC0C095D2188633C8F6B2F56593A0A4894EA8F7468B5DB974CC4FC52028602378DB8A0048A871DDF234D0795FBB5F90571D976650ED1AF81B7DF18DB27D59E76D5458129C80F3C1100AD9366CED92297A33CE6FDCB5C59A66A40AF9D17F670CA861BDC8555A4820740E272AA2CD85C8E05202C13B89A93260496DED8FCD03F614D953E978008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 0000000100000007061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1016 -max = 1023 - -count = 7 -seed = 55897A15824CE06473EC510179AF2AD3CA03B55B7B654EC9AEC393C34BF05660AFBF6B553D3412A59C7E6C8D2F9B1DA8 -mlen = 264 -msg = 962F0F7A3A6771C64F3A6A1E12200A2F73D884FFCF600456D8BAFA0181F67E807971005B2CB81328151570971CE98FB1AC42CD1A2DE020FFE42ECA9C2008873074272042E6C8CEBFAEDCA2687D7721AE9FB94C692FC344015AA917224CCD579913BC415E4412E713C0D75594E414AF8008A27B5465771C2C134C326FC902FDDE7DF59CE13D4AC1DEC6CBEDFD49F03FBE569A3D8895E93A5CC222818400DFB40F3213C4D4CA879C9B8BBC5C511095E9AE15284988826604F48A9CED36519FA903D617CEB821F5B2BE249CBC9AAEDBDA3C62CB9B0E351C95BE8DE05D934F7AF3E336308D9D3F550A8A755BE060815F8CD070F1E7A3220B0C05BF7429081033E09C2101177698BFB515 -smlen = 2500 -sm = 000000075FF58A8D31442A261E6AC66AA4135E434F09ED7F1B7BEA9060438E4FFE7550B11731FEFFAE1F7670606B1B808BDE9EF5CE855A3BC0A876B9BB0BAAD32FC65A945F106F07023485956255F8A8C53166427FB74F73F8A2E54B44F54035993CED96088A7BC0E02A9F6D48BE225FBE7E4F0DDDA995C2E674A51F3C23F6FBD14509E6E88DDDA39E7668EE9C269F94A582B7C874EB415B85F90E37B5A6F0588287732CDC59010F052B59036CD379582562E27753A24093E0805C4C0FB9D7886328BC1ACEAFD216EA7B9D38FA97F71EB3217F4E67771F8599E4152CD25B64DF752AD2CA78D8047A8C3A7BA0A1ADFB0B36BD7C70B53E68BC8DBEEF70E255A613058D1228D3A66E210783230E3396944BB5265CBBD9FBF280BA65259CFEFFD2C1A73AFC24C06BACE7A0F391943EC311989FC54C2A48D001F8017727C6A1CF686B983AA10E60B1667FB0F05434285F24AD37F702C5270555A772AB7FD63D81CC2DCD2A088BFED73E4F705140ABA5F16BE1A5E3ADF0D57E1C0973916ABE4C6B87CADFDC6C20803BA6BE08E06E2EA2AFB2C409F864937A3A1F11E2E74CE0C2E9395F57B9F2F8A45DB9F6CBB29E8302AED637B8583C35539AF80CFE945B7B42533ED2AC67A23FC8327056BB50063140286585475289EC61815B73AF54834C2BD016745EBF78140EC5A1F2A20790871960A3C3E5DD3C006052BF3062762207369CF4420E6E10AD46C2EEB6DDF685185CADF5BFF8C0A624AC2BD0B253A7AFCDFE7EF58A74D31D9E22C922367B5EB709BF0DEA0D2100D99B9C45C9047C181B00977FDDDC61828C3CBF486F9740CF834C73AEF270974AC1C6A1DD064B7D0E592E408ADFD89C1703A505FF612AA6336C48F8A313BC3B7F0C5A7E2EAA53C5921A8CF7E785AC969B9E6A270277407FBBCC4E12BFC2FA475597EA2DF27FFCD4B3FB13D5F0A7A6FC7EDFDDA60EAFAF1D6010E20D775E49A6331D1AA90DFF0A9C6DBE9A7295F06B33965FCFDD65C5D5009670116E6FC2665865CAFA4614745F91B00EAFD4CAD0E5B60134BECFDE85074181E7E5D6E88EF6372B54145CAFE0D749114F67F4F6CE9892CC463CBB41D28E6B00DBEA29167E67FD10CB66F5A86AE6B240375293A61D31FAD2A9CD83B4372052DEE199983C7EA605574AFE235F512E8A369D6803C744B271477C42666C1F6D7F62B8796AFD2B20E881A250750EAFC85C9B9D878FDAD7D213B06CBA1606F6F9E757E25656A36E8649BA1CF23F66D3455D000B6690A3150AFBA8A246F14E934D670050A792973B42C49866CF4D9D1E02477D3A6F30C2D8861B46C3082941A77211F89ECEC545CD10241911E383FF05F65C0293E0F5F7D459339954E522F01CC219BDB80EB87DB871B426BB2D8D9A2FB71BB31AF9A9565DBFF52D27CA5C500628865255028093066F928463BB78C24B039F9C77520621FBAF880148A25F9FF262AD73FE1195B32C9CAC4C11E4B794D606577C32C58AEE7EA0BED17FEF0AC62CD9D5C3CD26AC00CB72455E37D6E9D0CD953BA2C055A6C9EDE3177E38194B9D8ABBDEA35B563E4FECBC7586FC065A6E69D18915CAB3912A9E41850FB837D31B2080EAFF8599FF759DBF67B8B236AECFD2EA7377D7D1C33EB9235158D1CDE56113736156792BA04BCF40AAB95A386D7D40AC57231B769EEDAE23FFA35DE8C0D86E6A45D08CA10B376EA95B4D41C5AB9F7E83E874C438147B0BA166146825A98525CE012F0D1448D064259BF17B3D1048F0E21934FB8723410466358DF677832693CA1E70531A960196436D7188597572B4D45B0657ED0393E02BBA2B4B1FBD1E182AE57E289F3BDEBF716B83825C1691CF5C45A9CAC1F7EAFBA71883777703AF3441B1E3EB5F18D1F952155B4550B9A5C7811F7A4D99AF6F76EAD52E89D8C8A67CBB330F4796A08CBC26EAD8EB9EFDDFBA6D24C51E2B14963AECE698264AAF3B7568F5F408B4D3F3E958C3EBAB5687B31298E92802ABB3FDDAEC811CDFAAD8A255D454C3D16BE06ED4A9A508A3C1208B3B711C02090227FC1597328B211A7017ED46AF836FAC35901B58F6E0AE7164071837C5DBF536EC40CCE73D062E13AB8E420A073CCA65A908CD64E62C5ABEEDDF49C83782C120F8D5EAB3C9940D8A5A27D72C62E2EDAD8D34E9A6E28C4EF88AA6BBB4BC530B9F6D48678D63DBCC817626A0BB5ED1A7FC2B039928D4879732A5C6E3BE506008DA61F7BDC2535356FAD462B28604A2DF5F93B56B76E799017A0D652E7CD1B76A7AF256AE56E9F1B2DD8177457A204EA51C2165DA70A262D3291E5B500249114E5D4EAADCE28E43AFDE8D923219426DA704A32F3C490203353F143196D0F76D6C3BC5D2B8679982E9DF6AB1A69FF0A48C94579679A6898A42E3B902467FD3F90ED13F8F34172FDA06550DF19EBDF355E35DD192611E09C16414702A6BABC3A46D210D39B216F65F22A3EEEC77DF45919755A1C27AAB1C985C66CFF36C2A83FBC21DDE858C530F519459982D5D6F3A283876DEFC2994FD13E53A227941FF0803603A0D68E95472BC442F147CAE9CB0DBC3490265A9CA4A93415BEE3CCB3012ADA9A2B54B2770C948D30F02BB71B5D8D3A149FB93A848459CE42E65F00D71AAF3CE838DD97153BCACF4512ABDDFB3157FA091F4C92461F3CA79459E188727316A5FBF3C1824C4155DE949657162BDFEB664ECFC5D079561589A44D2EA95202D8C06C77EB87C0D9CF59EB9FCA86EFA805F9536857997FEC12E9F212A121E25F11706DC4497963306B9F30707A9DF5D80C4D3FE92CA9DE57A81D0E3A93C494B9A681B5AEC35298FB6273B9D9860ADD35C90A3AEE088746FACC13178382795D46352FD7A59D02108B83D40CC143FC6A950520A1231ECCB8012D97449CCE14836FFA75C19D20B6A948E0CB6EE2F75328056BA00D5EFE28C107541403D881284A7D920C43EBC8B1134572B7ED6CABB97D282B693BA678D3A397D29961169A00D2F0D2036E83A9635E17944EE4922CA3B28DE5B3D3244754A9FC8B5DF913EADC8ECF573013D2E483B404DAC46A85F664A3D482614B3D504E1D1F3D83BC18759C78855D256799807DC2F4338AA29720392864A3CA81CDB32C8A1120D3E2D0815F6D77F7A00AA5ACA394AE30BDB9FC80F3C1100AD9366CED92297A33CE6FDCB5C59A66A40AF9D17F670CA861BDC8555A4820740E272AA2CD85C8E05202C13B89A93260496DED8FCD03F614D953E978008662075DC657270C6763E95569B87A7AF41D07585CE0E5A95DBACC5384E3131D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 0000000100000008061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1015 -max = 1023 - -count = 8 -seed = 798BB062FA12450D432D9692C51C6A9A837AEF567604F01A67935E28CA16434B5DB2A5B74D45661491CC0495440FA989 -mlen = 297 -msg = 289AFDBFA80F8CA4613060AF98810A2184FD3ED165F4E0AF7FF0FA6E830493C99055DB441377C1FEE9FC7D0920A77BAC8650DA3B9A35D4306C2367B3D482EFFF21C28CBA4E2F7A89CAE8A25D5AB269DB6E43E791074999039589E5B38925EA263733B97D9EC5EA4F8C411EB2ADF10B22F3A65E1FBCBEECBCF13B877BA8A7FFE187807D222C73ACD352EADBB59176F9F0EBC7DF20CA7E46F5CFC9330A68B6F45A71A553096165D70DCF2398EFB4D8005B3701D6DF4ADFDBDAD30CBA98FC8254D7A1A0DAF653BFF68B6CB72AA2633F7539772F0872348759AE0D45571CBD3621EF06F1151F18578CC04FF6B7E3E938DA1F50D6E6C82DD0C6ACD4C36E84BCCBF5A4629942BC20434DE8B6E68315A5C62DFC2357F75911634C40E2B9B4DA89F515F9280EF86620939B369F -smlen = 2500 -sm = 0000000842B446CDF177CCD300BCEFAFB8133B67EE9F6DF02088082EB873B63125391DFDE96DDF21B58DDF08B1E0E813D21723DE5861C656C71D87290B1287B9B22F0CFFD5F63BF17A33F7D4DBD56ADFF47C06B9CB73B39B867D7075B92FFD38E38990EE4E29CF5EA9EFF96FB792E2D8031D60F422748B2DE49260C0D34E93C315E19264C6A0487438A3D1073FDFD74EC015D051D4384DEEFE689D7880BFA573EEAE2E3A7CFA65477167BAD6D2FE3FBEAA431FAB155275498D72533121800E2F231A662FC1F439303F05295328BFA0AB68B196414311629461F6BAA615B0A0E92350063BF58827C14F47B1D18606DCD093571965306A7628851D1A653B64E1463FA7BA83F468676371DC39F1F27F13C41AF42814F6409C00B7C4693AFA77F01537A286970F8A0A59800F827FE8541E70C27872EFA23DB0641713454D1A3C9E595F3E74C733F1180EAAD48D1A19FAF95B88A0561A05D296374273AF651DA94C4F852185D957E308672C760E8D08027DA54B47E7F38F215D85D43C515F8F19628B505D37F37AA5174549D57F6F3D42B6A5C51BA7EBC7FE0DE9B7935982E91AEB697D952499DDB4BA855A2F9215A72235DD9449C7F1CC4B4E646ACA12E0204476146618A0E4BD8DC7434016CE03A7430BE1E8EA827A381486F50F680409AE081EA67B8C703878A5445FBD0CAF5DACE16B9CF90C62A257392B20A44806EE3E8B60025A817BCB674E8D2FD2E6BF4BB320EDDB4007EDFDF0FB62892548D310218D39C974E12064EA28920F0016A6E2636BF6D524E0912E2B64DC3EC7636ADD0A20C81CAE6C3BD62CB872634523C7D6CA8DDED004A967CE50795687E4CC41335E9A8AC976C95A270317DB7D96E6CB596D9FE594E669C0604798E453CB5A9CF36E4F4974DF1660CFE562CB63B96ED122A9A9B3C38E5015E64CC3AD37CED7C2192AFFD1A4A6BE234C6E60EFEB7F33F25A33FF5A7A332657CE759EF5B81CA28C1E497FF9E4CFA1F003B8F5F1E8FCC07E8ED6DAC6C06D2DFBBF86A463E9B71F2D1552DFFBB05755CE4AD2289EB1BA4B9AE3E56395509A65DD521EE58F06D0B4E40C772B702747F36E7DBE6CE7EEE4A1E79065E590EF37A2CF6E1CE3A88909701A70765BB1CCBFA94AE20BBBB96167BD93DA33D79DB3815319DC3F38486E64AC42E371E6EF0CCF14FB4B2B6205E89F66FE2A572ECCCF85881E6363271B58F434E38FEA4B15013C95B8F5867A09AF06D592939FABDB5B96ADD3A179D366F99150E3DFF63185569F2D862D412073B9DD13655B8AF0D87DE06B2809191D1EC754FA7342D5383EB2C7E702080A133B51B7C630CBCABA758AC54A015D53DAB9D3ED19C4ADCA361F153CF8C4CCA568FCF0367A8CC348B6C2AD139859443F6F0CEE2B6B354727265CA14F0AA2271A96F4ABD72B8954E103AD1402FDEA2390C07D1830C142A0AC4CD4583B31D54AE3A64F668FB194767EEA716AEECCFB8951419E328201F781382A198C9635400A52FAC59710273FDE792994308B7E3856C21C5F1227A3438FF54A40F4D9A29918BE7639C83D06341FACF62FDDDA8AEF74FEC6FA3F09433E6C3C5D0A5316178DC70441E38A12D8BA742FF49F5B8D3971A0276C53DA416FC6ACAA94BFAA1B73C5FBD59057E553BC71A7DD537CCD02FB22C9AD9EC122AF040C7F8F28A53686F841C84F0630E1F694872EAF34C80390D28F934A9D47E6E5FC367B187E74F2E698569A484244645F4A714500890B0B9FCC4E1130DA1D4F03F7550D625C3680335C2882D188DF4F6835B9549F1A4D33AB7B028561B43A860F4094CAEC30C81E1F073E9A1483B846B0642FB037CCCFD505065D855EFA681EBDAE286B337B8C472ACB6C310BC608C1637B01D3A1578C2B9FE032B263EF2E0C42190EEE09FCDCB555803566473114D1B05DBA7ADD15813F6023FD82AA25AA1F6AB1EBABBFFCD62FE98F83A17D7DBA719041CFC155C09B05B1E0D3D8909B1A892542FA5B31F90839AFCB68A80070DCADCAB8249B0BAF81E8D0466D9F6CB118DA6B80697F4366153FE94A53600361DF10D11D1937182F02E5832E4AC2B95AEDE0418736BBB16A285BE7B9473BDA4EB2B2665E255C6EA18A8B07111F09E9B057D5F9176BFCFDBF3E3E073143BB33A6744DB9E973130A7D7BF99F148A526630964617E4D600EA5E1A27277AF646C909AEDA2BE16BBFE7CBF037562819C4DE2AEA88CD6BFD18F69D86D37F2321AE06324D5248956964ABBF93F9B0E106C692319DD7742406F98550E5B31CF170D6EFCE0CA28465258A2D76559663F1B7BA77C340B7FE06C45988A5CE8B7B1EEBB2411F1ED856ADD6E7EAA8BE6895534D3D0BE1CE385CC416F06EB27F5C6C69D01EF1A81F4E3BB6EFF9B0F3992D490EDCBC6960F5DAB0081557D385821D08BDEDE73CDF33A9AB3207F72C85B9BA229546724DF96C87AACEC40CE3A89D414A4C2DB9F9950843F05473C6BF0A69A7AC5A366F6B4F612D71A71669A8BF4E3668003F2CF25E0C1297F5B8293598E6A7FA1299E3A5E383215A3F41BDFEC4CB9163BE8741EF08DA132A934F84164D05F4175122BC5152CD651D697AAEF291F8D1A18DD49AE8622D0DC49EC77FA23FA51B3760F6E684AAC5B949729DCE376553B16082C70BD43848584A56F136D01BE3B80B4AEB9B4BAC518F17CF44ADF14B618DD04059F55D666A7BC0AD6747E2F64C8B25F55A4DC0B178FA14E80EB6A8C6CDBBC5FAEA9BF0750E6463E3C1262E3EEE072EC95EC3AC8939DE5F4111F734FB0347D743F1EAA67DD4189B92BD8F37B2B62EA00636F48ECA262BFAF0238DE48D2D0EE04865979682741E96C05DCF28BBC40D9A7A95EF2AF8040BA3F44E72FD6E04887937055AAA644A073CC82782214A8B9948ED942283FADE73D3E3E7F14105AE3FD1613DF6BE5CBBA99008E5E4A61EB0D57400FAA7A150CD1F690C3C3FF1CC695CEF8FC746DD836025EEF5523960E786F7DA022C9E4FDD6F810DA35C9A71BA26B8BE68BB33814A5D5B47088559D4CE3C910B1A70435755466E86B74E8FAE08AC7910F177D5142FC7742BBF0A738BF76E9E72FCD7C2957CC74F299285CF21B8A71015182678FFA04F377490152E9B4BA60D4B220F04EE5A38902E62627C12B696360CBFF4C016C2896B09E62DA088FA83B58F5C0F0D645FCFF2AAA1305F5A46036716C1464372A0437EC5E25D80AC6815CAD5B7EF29F71AC68263246E725C21DEF39E6DD1316C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 0000000100000009061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1014 -max = 1023 - -count = 9 -seed = BC4285C7804C15AAAA7FBF25D494E763DDA04B15414E1EC6461BBE0B7C6962A625F087B9DA019F277CC038FACA1CDBD8 -mlen = 330 -msg = 8FFC13A7F7C0C6C20ED56AAD2FD44C9C053DFEAC4FA62446A6FA4CE691F347C89D0BACF62C54DF754CBA2591209EC1619960E6AC2612EAAFAD3D343ED32AC1233DC00FCD88CA2AA8152F13B1FF530840B6E10C7BCB4E1022BFE82F468458A45967834E141709019361BC4F6AB67326884FCAB2E3EE3DFA174B9862C078218F8BCB5718784B36725ADF2907901147AF25B621DED9521FFBB2270F2A3C98EA901EA9BCE0764968EAD9D4FC027515B478B670841A4B61DCE9FE882242FE22F3830A9BE0B546287F6E0CEAEA92002654E7BB73FAF673D4041B5880584E1FC566F90FB2FABCB3DBB2CB30D66610B73EDFF23C89F20B6BB1B3BC71C17133F64966FF9A8404CA350D2DC953736B731D63E204F50B1D5F44F27E255F8FB508892A369F9F8272078A1E988C6C105C9D37F44619CC46E7430759C67AA7B131D23B2D405C3ACE8076EDFBF21783D2E4 -smlen = 2500 -sm = 000000094E8205284069747FA1B604DAAC8F1E8BECE4756454AD65441B745B5948618129E48E5AD2C080DD21C422723EA55CAC647B30EF0A0ADD4A68ED6CF5F1AE68EEC8A5BF69C4922F886D35EC8575F036FE13253B2C2433399BC92FB4805B108CF0B810E10CE31E16808A7643AF1DC74CF71BBB9065507148629CF9246CBD6D17ECB5F12D59E88410F0F6F04CEE6F87795DB6FFC1B78D43AA1C90C54FD44B7FADD9F76C93B1FFA7EFB8185ECDC6D11A1742BE67637C90B73073DB977FA393F50B48491F03A34E9811B87116EF3F91A563F7D0799AA6962B0BF216FF3C20B86062AD1F37ABE3CB927731541F9EC9ECCC74206E1B7A42F8BD8622E92914B221C2FE884EF67E56DF122DFEBC8F3703ABBC9E038A5CC8FA5B67DAD5F5942F9CD17067B06D28669A5FFBC4A05FFC0A771BA537F922F08DE9F8EB42B28032887494D4FE03E8668F6B6F919E681F5880A273C855A073EA44890B1A410334EF24C0D25B3EEA3305EEC8793BA12EB6B076CF52F8A86DD9100F984D700969EB78ECF034DF14E3AFC9C1C2A9A37346F89480D540F72AE127E7476E95641581474966AA07B76092548FF20E4170235D597E149F0B44F17B751BF082AC74E1EC74C4CD9474E37FD587B7C50A8451EF651079B7C8FD9BEEA5BB4D6C58C6EF6C5F6D12F6868C355753C9606837AC660D3C54E9113E0DE0FB750D1C86801346B1B89F06710D531319D2D49385C7080BC6321AF6F6F89FBD36399E2E3B82BE93B0DE483712DC5D84C2DE999BA81CC850721ECE18BC31C8F39DA690D338B24927124D0F2C40C1AA5E50FC0C22D52BF200283A153E146E82C1F583BD291A3AC3B07FDFFAE57B3E4AE9CE2A4679BE9602DB5B666089359C4540D2FB8AE0031D5D8064E45FC9083B03112EEE7370676863752BED12C48E167C9FF0AB1DB5D30F2DA3C6866FE436406A7793270A6BA7BC9C859808BFD5C642C592AF045793E9FD64E5744E51E043D288AEEE79CDEBDCDAE181F3E93A3B202596754CDDF4D18F8E6DCB1414345893C8C634430CE5C3F3AAB7F02BA0BFFE16C775D062F04A43412C0C380C823427605EBDD6726FE33F43DE8FFED4BD73ABA600E550B0E710F77D8B0B158AF3957D19E2A70605227F5C13BF7367BB4A6456667F5F580F6B303536F29D70362CA4DD30DAA727F8E74006F4397482EFBF1A6C30641F720B1D772231D706B4DE2A72F1EEE2D31573238A995C22F2EB2EC5B7CE61084C88063808C4C1D3499038D7CEBF37F6C5EB9710872F24C9806BD5DFF7E079537DDC64CBAA9EA208ABE23F7EDC5A7791CF7600A6F85780B70EE9412165FFE815F02F74896ACA1EDA0DCB593B74D6D48CC6E1053B5372D767D03B4B5B4041686BDAEC4F42F2C202649CCA404572228DABA2D04604AFF5BAF85EB871B8B5C82E03BD992FA2569DC8E1E4CA9041B755A94B9E4F06F7A662EE53D8A0B019D05497FD6032D9E95C05BB59E9F9458B4389000CB46F4190A19472C4CB51D873AA1A6FF6CA591E938E25E4C898319D850E0FB8C0DB6E983155297734F0243B9DE56F880D8DCB191EB9F9CFF45CFB9E1BBC92FEDD297A3811FE691D8674B82F437891F8AF6054AC87AB48EFE883FFDCFAE21F26E1BE134B53AB544F6E9DBE06938C0C466CBAF170FBFA7EAB618357635A83411E2CDCA0BB9323EF54CCD4128D639D80B127E7729ABDC04989B06EFEFB7C87BAE7D48EA599B7EA627B98A6317BE3D70824C25747FE3D2347E01B0CF7D3F389434DD167D703291DA0CE89097F339806CE37D526B7859FEB93E6E176ACE8F6A038AFB424BE1384422278141BD3EBBF890F3E9028CC7B770B9E8928ABD210ACDE38A31D38D11DBB6B9921D915C61616B9014170AC5124B2E4CC6C66F94906682D29946577EFF47053D28BD6488640C65ABE97C8AC8F9603E1EA89E082CAB6BD13C0D010DFD8E69211CAF3FAAAAC255365E928C47C88FAEEF61A27312C50FE10F21C719445389B00E7DBB32863F90D1E13014C6267B1FEAA1D3615F30AA72CB6905A5A9E78A9F406CB1774C5BB413D73D183B3C3DDDF7D608AF61C1459DAF34C99191A3A9FB3D99F3C45DAA3DD6CE8D4FB4991F367C00540BCC233AB6545BC7BAE87B319A1CBA5A8C17D2F3EBAE53008BDB896ADA1105B17B340E28940900865DEC2FEE01652B9FF9261A1660D8B2BD82044B4F224FC3281CB8DEAF17B7B06D5398467D9655AB3A0A77EB7C3FAD129C16037B0FD3750AA356106D26B11E9ABFB1A73DD9C36BA2346B38ECB00535EEBEE63A3C0436CF70C974D26FF28C580C88509907F68AE6332461880F839644B37D8999E16418E2D0152925CC0F0D63C87F612D30404FDBB347A932432037384FE00A6D0E9B0B97A99063FE2BFCE1FF51AF5CD593F6E4A2F82845A44F174FD8647774260944DDF0D006ECF6EBB9FCA61FE5B5D6EECEF44E4187EA3E9AC8C17294740E5B016C7DCB10E603FEC2C3960F3A83B41B84E14705129894B682AC1A52FC190CA10CA3218C5BA67A6A0314F6F059435A6D3B6E347219243E33808FE0E12F188BC30DE394F5AD725421DDA0EF686282DA121461BBCD039EEE6D500BA10BA92078BD4A3A44B9389F7778114BD126FFABB724ACEA754DB959624D8167A8FBB90BA4F38BCDBE3CD172F4972B189F1D08548C4AF7F14D9C405FC5831BFE59D13716CB9B1941DA438EF93E6770DDE04386DFCED416B3BB9A911DAA57423E0DACA2B93A2839AF26F1D3B49587A46BCB694A4323B08E8DAB4FC80E94B80319EC849445530339BABDFC4131275444636526496420453C5E917894C9F6459492D6F7F24728C83FD45D0F2BCDFBBBDD718768D8B83BE2DCC2CE080F3E48973BBE6AA1577858C9AFD2AC2FF2066562C4EB88ABED1F284A6D40982F4F3A2C2CC9A34FF7F30BA1FFD4F629EB8A3434FE46C523F903FBF457860F50F2D0ACE9A4D7E2FDF5E6EE7036C5DE8EF9CB7270E93D5F84E5A097417C2194BB54534B66D1A1761B165B6549EC8D7AAA2BAD5775C3C5CA78FCC38D738772746666765F8909B8327D3427F0F8BCB815D5BCAB5621B4FFD0AFD5F2DC983DCBCBBEE1622FFCB09748081B59F493821B467DF8B22B2652F4E3D112C38A15CE733E4610833DF3F16C2896B09E62DA088FA83B58F5C0F0D645FCFF2AAA1305F5A46036716C1464372A0437EC5E25D80AC6815CAD5B7EF29F71AC68263246E725C21DEF39E6DD1316C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 000000010000000A061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1013 -max = 1023 - -count = 10 -seed = BEEC566BC26E2DC13FBA54ACFB667A5C77FEC1BFFEFDC42F9131F1524FB0F71AABFDAEFF6894DBEAC6B89CE3ED236239 -mlen = 363 -msg = E24DC9F0A986B4F5A349DD1567A80B7C1170C980444F715998681BFFC2417661BF0B503E11D2BCA8D135968E6F07FF0144308AE69E55F4CD663A3CEC5C5D84D00E5C0FB2E458CE22C7E41761852CDA6EC268A8FC06E76D1E4F03A90A6FA9D1502F6F21295106F3485C9B3A1DC6C40C8E304DBC55AB2B90F6E6DDB404D8487D736E5466243F0B055B060287DF589D66B88C6DCF6D2FC8E88DC20BC9D693BE9B9744C31D181558289C3F2406BDA3CD3FFEE90249D95214C7D77E1A9927123335573E952FFF9A8D3BD66E020AC1FFFE5C1921DD7FF6B48295B6D2496376AE1E98CDEA032BCB8662A915301FBD014224CB7D899CAE2889FE0D673E0B55F4A56C914DE868D61775D3DC92366524F606C9E279ED231B0662ADC50A4161C19149830305B9BB38AA2606DA23830C3951386E63DA6DC2176F48B2ABB26619833074E95391323F0EE3B6151B2FF463EA3CF3BE55C2875EA93586AFF0CDB4B43DC7E8A156510B74E566233066EAAAF845 -smlen = 2500 -sm = 0000000AD719AEED657AB07C7C37DD7CBE31796106E1FD0448B52C745F3773B1D50910E79EAD6FA89925264FFAC1873AC0B4D744E5F0A51D3DFE9CA072561CEE80760E69933415428EF853336DCED466E4FD65EEC9D9F361E8883129A682149E6D96C071586DC062FD19FFE475FE59874DEDED58930E7DF5ADABFCEFCE81B1C3174FC2C0E32E286DCC466A672C9045508DA5E4A6AC78C8D1AD546D069AB0F33AFEC74539652D3F8F9426CC4A5B3E73FEEA8C21F775D8B723AB587207CCAAF744230BB44F7797A963353D6E0EAC03D072E4078F097B37FB8BC0FC83D8F1CAB838EB9873862751E67166F04988ADA52B4025523B5063DBF2CEC43FB19E5DAEBE09654694D5FF40DE664CEE993D9D5E407A2097E5817AF42433A63F6A9B8C7CCC77B0B459A8AA829D6D900949C7CDB3D2BDA3D9F2842EE570F86E6344AA35D4E7082C8A9F9D4CF49D66B731CDACF75F6E3D22E1E9A8FB5BE26C512C280E1DF08D6967DEABD487E5FAF709E753E29A9639EF57B8EA9B45AE707B2C7955A2383CA90CD5B287879AE1232ED73A3B3E8EEC33A42A3FAF56217AA2AD9B05CA2B25CC0F947697469926EE97A2C54D00024B9E1E1E41B62AB63F4CBFE6A1566E85976BD113CDBF5A32857ABB1609D21A43A52B7591733E0C9F72EF6F5723838F16303563930ED35FB2400984B59FE13A8B156AAE6F463F428AB90C867DCA52191713668D1F7D81B9D4C9027F2BA691F3ED6B68466CE6AEF9798554EAC31AD758F24F2F25D36CA9452658FBB70AAFA9D1E969AA2D99E5F2C95F8B2ACB75ED02EA71BDBCB935E2E4FDA5E40CD437810FF824FCFD4979099584A4C3C8C1B50E00F19736879D25F35D135C7743477DC01F8F722FA5E302356582CB65A242EF7BE4AD511E73024F65EC0478537697F98CBE4DC8DC67BE9C14C224F6E0263578882822B08905389B92C9C9CC42CD0E680C9968F6FDAC42089471C8AD79D94EDDC54AA1EF469117A9A69352F7E191A23E6878E575E9CDFA20B554EE736989A95BA228903AF625C02886F5FCFF7AAC3AC091F35B3DC2B75A66EFBD144547FC5C60BE0A3E25EA1C2BB31EFAE728BE70BA224140C564D1E5DC2FD9AD95578F7BA901E06008B929774CADD8BF8B59BCD73AFA8357C765AE0AAC542F89EE0B91D095467BAE38CB09AD25B19485780FF7A1CACAB02C04067ADC82750F4F10CC041EAE21D661E993265F19AC7E84BAFDA92785C8DAC4E68B08080EF0C6A193C049B8280EA9B36D69268840E3F2967E56AE5F10FF2B0DD087EEFFF4A669FBD29ECA6E6EAD8BB4A410651141075B95C0EF198A4DB1962919A12EC994738112EFEC20C4B80755B9E2A529E727AA345D77E6ED5D2FDD0E3C6F007EA46289528F9EC43AB064BA941C33428F6DD44049C0FE1E047C566AEA77A9B7790599637F8D009E63EB07EA142136F103B02F0C8C18268A68F2716C9FDD30D4FE657363BCF45773BA8899CD207C7ADB06CCFE023251DBC7D16AB06A8C83677BA461CBD9AC99A3770878727FDC198A886267F4068D298A24E7DB244E7AFDB84BC911A1AA6522A472DDC3C8F7181871FD9AAC322811EA172DB1EFA784967ECD11D4B1C677214FDE6833F5F18C69E46D5870487B557DB91D97CA3E1C85DF74B9B9DEBC8E8A067F59938AC93614D3F55A174C9038054FC3788A42EFD8E412F1FC27B7C3BCB7F035FFFDA4346304F3F4530A86F2F91BB48BEDE554A97F4BE765DE44FCC5B6CE5E0BAC23EC8392799049A1BED546D3C99390B153A1084DDD4E78D8F908723BDF8149A18AE593EC9226EF1182C9F5119E2909136C04B220F1D5B517B6E031E1D0A182564A7279AACAE12D9A1F180FC9F98A902E13A598988F32F9B36AB34C04EF0AEA3CA9148515C27B0416B46AA4E659A6139C2313961CDB7BC94A67F0FAB92AAC6DAFF04457C93C303764D03C893E06D5078F1803241A5ABF45B4D543E860475A93A3058190C1330501C4991E436DCDD6AF534E50210CD45C09577F951E2C10EEA286A905CBDF6431FD627EFC3EF88EF524DF80A95FE062F65C859E0B40FB4D842347FA037B28B02DED61D9E65AC77DA20DEB236C1E5BF5BC4EE34B1DD200221FC9BF231D7223D25D8877E794090A88C87C70563AF05C150421464A0D324E0C673835163FF86DC8D95741DF4D793C00E7E25508294BCD0D1039AE2C38CB4D0709514C4905ED2A5187AC8B289B567D3AE59620E4517ACD1675A2548E6B8EDBD0CFA3006DD6774757BCDF684F7983D6D5E7A9F73508FE6A25F8487BB6EC8A9610B480C8F11E5A6E60300213348CC172B7724BF5AEE19A39EF9D98BE5524A349046CB3E381A73E2F9EC83677BED29B47A759C73E33583FC278FA35D328A52A2CED5A30AB1DCA0219D58832D22AAF4E20A8DFCC848E4E1DFB11A74166EE19B0BE943B00F8CED64F86B537221CE7B13F3BF616CCC8A8690668305550D4318FBB8AA4D8F2B7AA0F15BFD13EFD90F64D16DA924163FCD8C7EB983B66361D9A0C81B14224EBDA2941096082F551CA8106D85BEAEC1A08141C4E94866C51CC0360B0C3816930C8C1A22A682754EC0C92B7909B9A6363DC0432ADA9ED300CBD7EE17591FE27A17C6FB9821F95669C47DFDAC6FF8BBA66B5C59B4FE6B8BC7CAB52D5E63A4AC372E89BF12ED7F92B8517E4D749E9705A8A29E592F27E41E5121CEC6D1751224B15010BEB0333F9ECF9D62AE2BBBA821A4DF8E5BAB730A238DC2E88B6AFE89EDED65A563A6B99335A99973057596D66C6F27E0D09D24C025C5853C2FFBE82AD54A86546CC4616A7F19746293BD4E90C3F8A903413FE2FDA45EC6C4F3E2F306510D592442D08FF4B2952C5D75C987364DA5801E5A64BA09761ED1A6653C6EE9106C3D5E0BD5A592896B4857271AB4BE38CB489D981503E7F2123C53D46BE9358C51C218F6EAACF5A2983B8C4AA04D34B56A16F3DA944A51280AD282EDA076F0F20B5237CB2DA1667DBF06F5A2BBD471F52EB1B89AACABE9FA1CA7A1B33BB904456256E83ADC4E8AF144DC1C4822114793B558534842DE033536D35C51DE23218417D3C99D30D994B0ABD740DD423BA73FAB5CA570F37152B0A3EAC6A98B344548F790FC0E51343E31FCFEE5DAF8E7EB4D1A3EF935750C2CD15888F03DED5904065F4CB00EC42F7106F41F11E69246E59737AD06772A0437EC5E25D80AC6815CAD5B7EF29F71AC68263246E725C21DEF39E6DD1316C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 000000010000000B061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1012 -max = 1023 - -count = 11 -seed = 66638FA3A92FACE1BA5B311362842ECE73B6EBE5637EDB3E16B0EBABAAC6BA9335BD63DA0253518A6B9648BA490AD60A -mlen = 396 -msg = 942D9CEE1FC9325A8E6456194FF3E1ED7562E19AF59C7A0F7569911EFC22A89EEAE8831E66B528797A6DED2E0AFF50933AE425245953BF95637826F3483F1E8E12E12BA8D6A42D320235405E422ED3522F25F630AEB0A63635AD70A51CBFEF6DA246562A10529B3DAC58C50BB08F88469987DB5EF8B3E37BC07639E56058B93DDDD88E9735B3632E37B3DC0146E3EE9A55F29DF71DA5DAF7A14CDD8276F363F3E1E4C6DEE2BF623DE44F0C96DD03AB00BE02D5BB90C61B870E3CCB41ACE1D1FB5902FB1FB2F866E92CBEB41117C5C5C0D367D20D797BF09E0C8EE934209351A149A306E34A62DFF428687C6285FB3682F94FE3C6B1C28F1F0537A60B4C9D71E2B01DB08DB7A033E426C73C86A061345B0596CDC6FFFFA005CCCA8C7807BC293D3E14D5881D6099103C98449640AA2E806592D345781D81D6EEF1CBA823E0DA1858C3647CAE811D7FF87B9E08C7AA1E2EF8ED615AD32B744CA253B6F172636A964A1E2719CF7DCCADC61569DAE0BB1A37F4A942EE17762586BB9A9BDE8B66671D50ABB592947337AA71D35EE1 -smlen = 2500 -sm = 0000000B455CEF8ADB9FA246879773E4AED4C367473AD23FB89C5BCAFB1BAF65F9615D4408268EB928B66B1709C9A932AD9A450B20263301918FE23671583B5674AF03A96A38194A098992E96D278B8B68F9B56451652E5C7B90F3A8FD0DE39BE575675EF6D1ED6655052DF350B420E90A070CE2592CE4B832969A07B513E3C7A8F3AA8F025A596591F339E09EFF624D89F97C65E131E0289DD0B34286DC38AB98A56B09AFC9B14A5A2DFEBAD49D476A2F8829E881591EA506C3AA5B1A91F7830127437078E74288A6237956BB16E90BD69079E19792A01CCFF507DF31D99CC6AB1D654A133CFB22A9DF43D1C427B2079EEFA43EE6F2858683E90440ADD529EB1965298EABA124DF53A0C4B1E41FA0C0FBCA4E52ADE2D0D19EA2090390F4608518EE8B3B9FB051C9466F601684B6109B2533A6A3E2CB7530F49EC9F1E1271210C90CB3F4B798ADD65CF9033077CC4DD74549FC87D2744B1303F3C7406330A40E4546BD76B979E9EEB8AE22DDEF7A2B2A3F5EC9E8289466FE038C1EB224ED4CC8248BAA09827E2A8E08ED2E64B233EBAA973D459DE59ECD7A4E47A36D12CC86EEAC6D2DE57AFC79BB41177F6E7E0853F8E2D43DD9E206F242501794E73F049A046522434E35FC255BE32996A9A67188440C78F39309060FE62121D5FFC0CD8DC91F220403049390212DC9A0BF50D1D58A3D4E5ABBD1CC6D50020FBBD7AE31683E01648F71828594311B45C60EC2272144C6D8548777E74D79B5F83C4AB3E26F1C05F99A3CF59F8E63CBEE6E5BB2A10F7B9512D6BDED02314516526854DAC0349897B9DFA3FAABE9A886C6AE8281FFBA9E71FC4D35DE35B7B456C7C6B95BD4BA0DCCE93323F055890226E95F267F03B166509C3788184BAF6B3236BC674190B2D3ABF2876717D90324B6A7715CA39B77CDE920E7E39F2DBED6A4FE6AF3C5AF8BCF555B0F77FD63F9FC15E622323F8D0BEE79450F367250B5E77568C5E650B06346AD938FF4345833B98CDE075CA1D4F36EED5A0CEC89F6A2E33D22B64D0A4C39780E62A21E4106DFDC3CCA753F659F3CCB9FFA760EE79FB6D6ACE22B8FBFDEF1F1D297860E07D726C667BB13653A391A839AD24DA7FC889C194879D4AA22E3CA7F7929040F8325FFEFD805B769B02F39042B03B04B4DAFCB23C360A4811F70E7F95DC20CF5E0FE8D5567A96D95896BA67938E5458685527636DC1CC38389A25A1EF8A44D04ADB2113613323637478C6992466AA02BA69462D85F8FAD94F3228A9374B26FD050BF0BDBB18502C5507C74C40850FCC6BBD9A771FEA0772B5FDD7EA346867A444AFACBF6F2FA4C781E8C49A1FC4B3CA4068F737FBADF261C25B264C2FD8B9623E55941534EF53933BBD2E8628CC0DE5C60B472170B204867623AF8441F84486240114D164C54F316A6DB6EFC6A35BC7FC1A06A17E9E5B410E26C67E78857BFC6FBD8A4F71F9F81D8DD85958B486EF132E983BFFA0EE4E2F2D13600A51C331FE58EB164F58757A0649F0D0A0CE7665A6A099856EFE3150C3AA79299DC1DD4DFFB0E939611A74B69D821E33CECD5FA2F012F2D40E494085CC3DEFED33E101E5240F7C2116BE78D3843EA1ACB017D27888D76E17654A3F0C9CE653D4910C09F883B8D4A7A6DA7BE70B3356EE4F253C583C086A6ED94B0E87CA9BC0DEF3AD297C76FE001EF31B028DFB7A1D430B7F569EFB8EABFEEB09063F0ABCCB87A66D58230D947EC0D3F233457FA206FEA765837168525F5B70095EBE76CF3F5FD69CB65F7DF3917BEC3D843F39B65789A28ECE4ECF35FD54F9D5881CFAECEEC601589C17C227477836EB11989474CE24B64956022E16ED7275FB32833E22AEDA33E89E2810F479E886F2B42DCBB1D4F7D662BEE7AAA6C942C38AFFA6BE24EDC48E2F47131D7CBCAD87C639969B2E58E71005393294A1FB75CECE19DBB87F309D9989D3F1D98744608AA73B53887660E22BFA6087678F52A636F5A0DD00EE1A40D721ABFFAC571852F5301A71F23DA7F2D21B49B36C4D0E85D3BA7A9D15A5364B799F696EE31701A6F53F22D2111F025D4919C6B305304AA180FC6551F7A9997D9A5A242692DC8C146B282FCB864062119C89050DD8952C563D336A2D00560A5C5EA5A1DFDC8273CEE2B9546813198F011D9C7D640A7D75CF036445E58E566A2434CEB19EF8870E190E9451D537E0B5E4471446366834DB65649F58DB535152061A5BD598F9D940F299B42775290719DEEDC87CE332EE592DD40E687B5D6A19E68CB24293F3AAECA1B0059CE264562190DA057A230C98222A0664741B63D570B195A510B5DFFEE9831C7CDB05936F0EBF0A9339324D1E42BC9157216D5F61C177D08C620E2F997259C7323143F0B968EDD22EA9A003C8CB3A74C2481B3596E64B261129B96F345B4927F144C6F1D744D88FCCCE76368B915C75D09089D9542C0CFB45A770A0EE5E03F6C4AF3C49735317136E25197C589958D0155F97DA3BC054CBCDEC2730A8B4D680CA67C358B887285BFF3EBBB3EB6379EE79E2BA86C7887C8EB4983833E48C9D1BD56E1013969C7E040196E9AD08980284760CD737FD46AA537D8B1274DD8267CC7F82889B1AB9B2F6CE75FDDEEBB7315B710A1A2BC6D286832E2FA6E0AE88B6AEB5CC99E99567E5CB106FED3747D132F1AE277DF8FDAD615328E2C7F3CE2BF4B1D75B9E6E6B68758FF634158D3CA893C49070FCB5F5D0C491334537BF3D33723E09996843177A77BA37A268D63CC95B36AD8F53BD9CA859345DC7A2535E488BC4D5C2B889F1CBCF242C35181121C8997734A0E614038FF6ECC1C15F9BC6B1F4B3F40DF1D612A1633485AD2A8040401F1915405565F4716A5CA159B7B6EB09A7EBAADDE2E5DA3D936B2CE5847CC9BFF737A2978F92AF3C5B907B370E49133D6E162B89BFCFF176965497A24EE4A6C0C6FE05C544A4C00D5352F6DE408D34DA24248EA94601201E6C0EA92B2562E030B16AD3E3C391445D3EC63591470D2E9896E07C7A17FBCCF45D69B1C9BB1BA07B6311FF2B97C620CD0AA0E500222E7F17C816BF5EA50F85302F198830A7E4B47A80896290F8DDDBE63E1646947C7EF5ADA43249E35DA580A61AD34EA9DE90785B144564C936090F2C725C86246723B5750C2CD15888F03DED5904065F4CB00EC42F7106F41F11E69246E59737AD06772A0437EC5E25D80AC6815CAD5B7EF29F71AC68263246E725C21DEF39E6DD1316C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 000000010000000C061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1011 -max = 1023 - -count = 12 -seed = 495AC157AF18D1563D6A03CCFF53807D532FD46AC67A624D433DAE418CD1E0F5FB76789EEBE1FE0A50279D28E411CFFC -mlen = 429 -msg = 0FF7A2C1D92BE47802CFA7186033B611FFC9C4C385F016D1762A79ADE356C85E9D81F35F5B3095927B855C194DA184B90A54B6241B8915A5F989130248E28A92C9A7EB5A1C6FCC96432C4DB091C75923BECA9C4666320D955EA2AEC268E47DB6735CF0297B9BC6E4A033D413A3CA7B7BC6B8393268AC91DAD4DA427DBDB14A20F16CFDC9CA0E7C904EA182F060BF6458147ABBDBBAF69C631B9DF27330F8AF63122F32D0099F5CAE7FE0DC3AF91E8FBAC3591B5A8B5ABDFCCD714F6643D4D3D65C6CE7C73194A8A3193FF8DD2AA8ED8113548C0BBBBE4C68F96BEC93D799B64149B010EF776B191E6246498B19286B8D53D67CE09D5CAC398917B46D8530EE55B67BF8D4D00164A519288D9112309713B9EEDEAB11346264221FAF4BADCA7E6578B3EDDE6F37EE9CE2C2CCA03FD61383213C2252D35178918476B7A1B9E6FBEFDCDF1B3F02BA60562EDC5B68C6AC6FADFC1CAE6E9C267DEDED7ECFA507F277C18F80FE0A9E160654F1F4234E5EFCA51D9754C12CA0C5E96395835F3465E6AF793ACA81DC57EA044D43DED72BEFC8806DCFBEC917E89DD816A48CC726A39EA8EDA3917744EB45C6B4C09A08636D -smlen = 2500 -sm = 0000000C6C944B219F09B49DC2CED1253423D44E077C7F3DAE0800CA631065BBE52798C4E653D169BF64C7079434812664FE304668BBADE2BBBD8C134B28B4329FFE9FCAC65DC99709926439D826FF40E2C01197B72E13FE0DAB97E60D22F788827FAC992C971498927E62ABE5111A3193E7DB4D5A4686879722F82267CADDB672D312FA2FB88AC548574C251C89F00A567A3AB4EF5437FF1234AFF5682C510729F2AF387CC9BEC4D6D6AEE5F3BDCEE55A829AD0374B536D3CCCE4F94F8A75EFEAAA529AD3ECCCBFD7029F6B78329126C085FA15EEBB4C5A791E8A836C95D2E1C48D009BF7564FF869B4C45DBEBCBF87670A848B6F7804E27F253474941B4A5FD08B586F9F2D4AED97E8DF5786936675D8CFC9CC45A7951EDDCDBC419045B52782870CADF2577CCB2223BC4CC133162771F0E0735F141367F8EEC344AB8D73B919BEBD83183E4BF93543C748E80B298CB4FE81D079E1E9909C74F131FF4198DA648625A41F32DFAC5840F0D0C6746652F2B0C296CE736C4AB8C6B57BEB6BCAABCA9F4670BED8C3412419D1E3ACBF1D1A2AAAB6D6B2B7228D0610A08E6A7A1EFB8A7FC310E4168E9ED8281E08AA6A6512832149516586453D8F9E635E92AD9291929A0FB7610C9AB1701E220276F121BC687287E685F662FD9F01253DFD824B231CC969780567B1A0E861C1A29F5496EAD4667F08242FA7ADD1650719EB2164E86A14F4CF10EABA980AC33D84BE707EBFDD335046C0768CA319D2415528627CCA6449250B9F6504A160B41C205C76C1C45E087A741D7AEB880007EE9C119C5B8BA623B6F71BA290596FA4E9EF7856601E334F1851CCEC5234507E67CF917971E6EDA51DB86D6CE3FBBEC887DFC71E4BE3ACDB7CF3C10AE6FF1972B35F829421CA8426C7D6B54B8C30B1E6D866B626B099BECDFEF1FDBD3FC9BDE733E80E5C27416D8199890949D067C0B92F97B8EC2D7FD1869A987BE954919D340B4A3429A5D8AB13E1033506566DB3CFC50AA2DFC801718342B386F53FC4BE889CF07BD42E153649C03BF5BA87460572DF176E682362070E78486DBC7CB61C0782A64E542CC4D15850E6F80B22B45BD3E974E23CC819A855E195125A876C435562ACC5E6AFEF0359E389972BA7DD42E5F960737C2451B1345F8EFC8078570E1FF80BC6E3195DAC526F70649D44C6737B7391DDCF241D8AC0CF5551AA5BCF85E54350B89E0CEA57B1B7A4A1EA3DCADAA4AA55D432928813DE1635412954A152CE6D8CD8AA7A017A968C41415DB6B8CDDDFD762DA1829825E0FE303F3FAAFEA07E65A322F1496A4D648582FE7AC25EEA883DDA11894CCDA6AEAD9E57683F819D99CB64FFF21AB68D21173ADE9FA7BD5FCF92B5F880D7AB500E592DC2918C15131FBFCE891C9132504A9DDAE33209066ADA28134E843310D7B2C0066D446C00002689174401B4D9307DF58037FE157E7EE37406275510726E3B8F298A65A99509D2DEA839834BE87E449BC69903832FE827DFA477424F5F33524398AB14D5280F9289386C33B3D4791C62F44E81E0DEADC13B5E7C43E1E56DF769E7D89D3BC981DE0CCA1D682930512F9635D597D14A4BDF554CAF26F86492195EBACFCF921F464E07CB8BD184AA8686762C637AB309F5F8A2BAAE48450809BEE33112380576DF9A864A8434C10C6A93F8ED326D2F105DBE2F011717B25A5B622E85D286ED9085AA4492DBEA368D90D52B7EEC7F004C8F1D667525954C53B2A95FC0107D8309ACF865F12D1047DF7AF7017F94FA1AA9D1B45946C6D85DC849F6ABDBD393E0B8208576959FF757CE2D4E7018B78BF38D38DA114CEF8120C4B961A02834EAA331727CBD0AC79156C787740DFFA4D1610AE7DF2E1F7AF47C68243B44459AF8BA15A2504971297D40B70976A1B76B8CFF2E0FA5158B209FF5F78F2240C4F83980DD24426AD934AF0E0B6E5A6667A018E4D2B41DFDA509E823673BBB3CA8D39F38332386DE2048C002718361CA171ADFBA0C16F23B8F43CE7C3D9E2184101BDF3EE15AAC0878587C480816AC9B37870FC07B8C9A1F5666658882BB8C724296083298AA01CBC1E714431A37922D283E06F4E7D6E7F0E359784D04B686D8CB70E082424C2E1219FCBBFB17FD9A3564179D5D9791E9FE3DE6DEF0579470F7CD9175C7A3DF64B16E8434AF8F205A23075BD781195C96180B4E756C1B13A009B91F12039A447E58ECBAC183F833668433F244FEA2FF946F0642996387D1AE09DC932AFEDB10CEB0B25385F39587E55D3BCA8D42F570703998807081E107DE538256DB2A9EA25CA355EDB5C25E3A2E7E5CFB9DBA44675005924B7CB5BFD4920D337CCEEE50755B4A30B25EC29B4D4C656165F6BBD279591236FACD816BB685CEA3844A6BF76A24ADA1915653F47C0AC9859113DA4DB62653370CC2F39CD693E4DBE375C3099FE0F0DDCD1F57334501B0DAB3EAE9C10984B48670C483E20D8067AED50F93A6C4582703FC61DE0816EB30D10D904726993381E17487FADDA620AAF2415A2730F8819D81D9412F308984AB15006CE3015EA65420979AC0A253069454EEA9EE629152E004506B2B1B647AFDA1A3F5E25C83393A43768C18A984E2127D1C07E44C979DCD04D005ABBF1094861A1D5C28262B0A40168829D4EFA346F2803E6615C676991E6A5C90F27AE4B8F0C8FA53B8170D96C0517B97FC46CC1DA18FB16B3248CA0EB03DD4A8125732B5B94B45F85D316EC5088AE34A3603F33FC4FFB1DA574617A7957435E29C292948CB23DC21BB1326C91E65CA869330DCDFD50CCAAC8CA7F161402AB7044B33626C898C5299AA9ABD8BAF3ED559FC097C74774693C6BC3E8A3752590DE39AD836BF4AF6BE77E65639629787F6C9A4C314DED81358CED733443BD057230140C6ED6692A8386CDECED9ED6BAB06B58D66EF260237455AB56A8C6A2E2EB200B35D2FDAC16827CA6FF68D4791C9E654C85973AC8C62629ECC4B04A4242602DCC1BA4ABE256A26D95247BEF9F1C201752EAD7DE44F0D4A5CFC4EC5E04E8D778A1A874241E632534F4BD6B961421F198F87C8D3097267E7E45CF63DAE7F4ACC35EA8FD2C559B7C3EB5601EC90E1380A002DEA4BCC54D083A5634F8223AF145B35306EB9DF25BE2B95A2A28182D717A05E0798BFF294A94E29A13626EB6590C9BAF810C977A9E37C574540C6BD3EEDE15DF113D2E8492260FEEAA8049ADE7A99AF98CFBB7C67F06C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 000000010000000D061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1010 -max = 1023 - -count = 13 -seed = 21905954F5B96B48D223480BE10EED13A16F59C175072AFC3FBF0B6A69939917E07EA5D998523CBED0993F9D5C5F603D -mlen = 462 -msg = DE4F0CEFC7B6A7A83AF41268C268EBDDFD5C01366509402723283AC6BF6EBB5330CF62190E4ED61F8C232C9DD0DABE0628782029CD7BFC67765EA0167294CBC6EDD7C63829ACD5D09447AF5B13AB605FC51CA16044336DC888AEF43C7312E38BEA5E4378E7B260E01A9566FE2A8B2893429BF5B4F5A755EF901EB19BB2E6365FA83F11BC1CC5BDFE57E2A009340A034644AD8A72B467430D42AF7DEE753572E00A41886D971D4145A8D0B7540A63D26BFAA06BAFBA4C46FC5672047C56D7D5BE1E12F50AB0B3430A815B43901FA2BB1921956492692A6943E6035099D509CFA0CCA8077329786962ABD134909643BBD89D7A5F81A8F96CAA93E80BCC35BD75AB6F7CC43F1563EAC9FBCC697061C7FBC391E55AB545105B70555490F10C86D0B0ACBE5758B06132530E90D9F35B3E23C1E42F46405BB54D485B8A78264EA8E612A4332FCC46EA04938465B94298900129231E974159CF5359C6BEDBD7CC4CFCF0E79DAFD0738307105590AFC8F076AE6F026B9FCE281727D1DA9D3064BD534810EF08E05181F1496B0F014F7F895D67465781A905F3B90CD203C78442EC4F289DB7814763473FFB29B60645FDDD910C35F5D3AFAAAF516AB5060CE9AD57C616D15D90F8277ED658A6D2089535E437 -smlen = 2500 -sm = 0000000DA2F4E9C5D816C4EE8E82A8DA08F2EF56C0A4DE60731B6548C230E3C2764A98BF2F099D12D167218EF2502301F410D3154F2960CC92CDFA4FB623626985FCC7A259A095ED95F09D6BA7B67D525D1AF0A55060859E7F5EECD5627819D49CC76D6B7B264D36308DFE13DE699BABCE8F88F1F3FE4C4E89FF0D39E22F408D95EF787C760A340776B92481B995A52129A592E92EDCF5E080219B74D191E5D0B8D6905A85365DF865B59A883B7401D3061FD3462731FA25731428E1D6F0CC439439500A979D4D4DE8F2C9F3C75F9AE87309D77194A5EDA8F1602B0F5D323BB07F40ADDC72AEE9AB8D9970EF6EE82CAB84F61D58E4B2CBF01FCDAFC77F8BC46F003699A0F66E46FF3200CD0701660BE454FCB98ED1EDE0492D74C9EA98EC60BD6DD321E46AB34286DB1DC6300FBF34A4AE8D3725EE416117E2366B0A85D55516F236CDF34ED3302667F80F6EBDA13930F7D1F38909F98330D0F309EA024CAA1C5E62340D8AEF9BC289498763B3E322A938DEF14463D1DD761CFA1F3224DDA5828A0ACD682D670D72C50E2138FF4D6B4853CB64B51CE1DC1821AC1E03699849C4A6C2EF111AE893ABD703AD453D6F8DC042E482BD14D41D3FF261C1134E12FDEDED59F6F6C2D1242DF2AA2C3F0F4DAD14065C7DBF26FEEC5E863FA38E06A4BA51EE5D59B44052583F12BE9709551278D78825D2860E23C1B191ACA3DC53033B65F629779A762C6DBFBAF0E0DF785744DAE59FC6A4305BCA4811740D5C4B0C60F8822FB248BEC3827F34D9C3E9C5637D17678E43078E5A9C39435BD5081194690373672C78E228FA5116C59B07F9D7ECA7ADF828072CDD9880FADB36A7B6E3F3823690DB4029DF45E94E9E1784F7EAA8D8C2C338ABFA8EA67D00037902D4E671F2D8A9291096E3C0759E0348137DE00B6295592EC311E13EC42A3B8E35C3DAFF289B8A00ECFC8F8C05BE60F4D1679328199AE9CEAD6E0653D582D745463C61BA11E5C4E7329CE08BFCF96B879B7241A975FAF8DC09FAA11BB332F40C38AC643D3B44F0CAC2DCD600C2A73BA91652B9CD89D9FE606436D9CAE225DDBA8673487C7DC91D49CDC9B03F63068A4E4B2E95B565492188711A1894F597D04369FB9CC3FC0577C81F4ACEDA050C11F8F8A671B638E2CA7CCBCF5E7F18E1A878171F2E00D2ACAEB7C91334BAB49A065BD4034041B7B064201D846C765EE0C92D03C5964F6193D2D11653D755246AAEE62200ED21327E19EC2A66DECD6B480EABB59CC574DD9E8BBFFAEBC478428B0F78E335300C4322C4351E5AD7E9C2B673947EBFE42BB874F8158A880C4ABB59E4A48D9A8C2C4718212F9DE0BD0CBD55447EBA4F93DCD2DCD143E5A66E16FBA34C0AF0FBCD14F9F50A6449E8F9AEBFE1EFA63C4473D38499DA73337FDC50DAE7EB38DE5DDC00952FB38DCE1B915C0D160B85A9146BAD1D2BB53152B4DD3919609279F59C7791D65C66330EB4270CD7CBAA68342DE2517B3D69162349B66AE62140487C07D0957FD5FC54A0F4C05FFD62BAE733EA6891B330D3DE39BAF2401572E013A7F1F696CAC53402DBFB4CA425252DD990CFB668B95DAD3B85189EB971B691BA54AA3279E696EDCA00E5CCCA8BD60C9FD948309AB867767BE58155E49AC8C2C780C4940CCBC30559E71DE7893CBB6D6E45D40C1013FFF2D81A146894021AF7005BB6D2BA35ADBD5E1B4AC529598459FC86DCC011FA72AFF832DC6F5B8813AEBFB793195C95795B48764FF59E352990C328B0474F8E0D888F014218A82A3EFA5F58F80540908EA060B26E1E96A81872C285AC778049DDEE94EA598195ED878D11AE6C7282A609826A59B365D374873CB5EE3B5577179DF51928B0976200EEFAF020D4B3E9D3190BE44B50A4D91EB3DB1C1FE0F01AFBDAA39F6277C8F06496E1F2B6FC0DF2D01BB8C7BC94427F7A3731A3FACDE421B2B080CCDB009B228944C9F663B25813391EF7472DB01AE8212A1FBC274A41623013ED6056E64B4AF1BDC3F3571C6A9F4FCB560C1F621316A27288FC1B093447FBC1E930C823F5AEF8C33A57FCFE8E3E08E41DC861D3F8A4F30AB624413396DC4D414F2EA4EFFBEB3A03F6496533836094ADB2427826A1D289150836788045F8640F5D0F600A56F4956AB85DA0D31F206CF188F1630A1810916C6ACDF2897B54964391A975AA224F6870B5EADD1A3C56C51A21362795BE240977187C7231EDFC56CE71F8B997D390CC7E3343755EDE9FF3794A875451CCBA634AB6761B85ADCB56E28E5483E7AA9F017333D2EBB1C3B40EBC330F5A46F03117D9059351769C88B8BF03D90BAC63B4EA073CE2D3C6C5FF7A67DFA8F6B27858668C1056E8020BACA62EEA224BDA4257DF3B7045D8655A8361B5195F150216D8EB045E4047916FF03BFE8FAA6AD5F789E881B1D8434D3ECC06CFB46E4D25323E74605DA75BEFA5B5B796C6A3587710B1A03912332C84A089E055A4AF938FC1325D120E80FA2FABEC57FA3EB197CBC7E0548E2ED397F1ED1A128AC26CC4B7F9EF399F2AF01540463C929C6483EFF1B55DA0E06F574EB3C2C21A55199C37B35FE5F8C2CE2C4276146F5E96CC4F0CA9B36B40AAF426FB2F6345E7245233928F13EDA38A6BB2872E590919D99497D4430A89AD2830E9131B46C41C51547F0A908A753F79B7671EB69F5DA919A987B9B8DBD0098A2F1B3DA8CBEFBD5AF73FA729DC9524989AF8B0853CDFFE345DAB39379D401135E19FF844C4AA89B3C69BD72FB57160CFE28E6F927A00BF94A5B9ED7A0C78977381B24B93A4C6E5893652D6B2C8B9BA89D3BB074325C328FDE52BC96322715538235BEB0890DF1567A473117C8F48A425BBC84327E9E0882AA128828B6862EF11CC54EBFD80891404C83C86F6376B8F3D009BA9C02675456F534C75BF0F6D1A52AF39CB1D10945A5A3EEAAB9C0F331D41FE855CDD5F2EBC18AF5B79E23078BAD54DD8E67EADA8700D96979BF7D121FCA304E81158FE2B181EB4A1EAEDE044D99EDEA7AB8D9D8056035D9B1307FCF23E5354CEDD51FB67BFBEB92DB445E92C1EC813B68A45CD1FCF0BA2EA0DC42746951161B77480E3E13D811B1F8DFA30E90EFF64C7B9F0A129BF4085A2F11F537EEE2E04B80C3B93E101A0FAD94B2B95A2A28182D717A05E0798BFF294A94E29A13626EB6590C9BAF810C977A9E37C574540C6BD3EEDE15DF113D2E8492260FEEAA8049ADE7A99AF98CFBB7C67F06C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 000000010000000E061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1009 -max = 1023 - -count = 14 -seed = 5B9F2A1DFD877CBE4E30BCB6F022FE142E1611189F83AE628D64EBB329AB0D9C66461CB73EE17E69F5B637CF4886BDD0 -mlen = 495 -msg = 971DA327D2195078632898AF79691F8F5F93189EF0807714096D27480E82B1F0B884AD43FEB3151AB6B7261A501416AB982BF9F2234B8199F89EDDCD56E160E1825E79365625A979FE157E9FA937926E7F12C4B5091EE6572CF8D4FB9FB8E1090BEABCED73AC36B35A5020EAE0134A3291CB10A05C3EF778038702843739E59ADA2C3CEBA6353B482C5F80E751E10BF13DDACFC6C0E3FDD09B21710ECE846ACFA1305074ED4328B90E65B1FBABC53ADFD964A4527CB1B8101C30A41804A5EAB9A00D135C38C52EB5149B6655B60D5A1AF50E3D0DBDF63A035924102495B46327A063292503F4D72BEAE063B577B57226175AD58DB98AB164521EA9C21A78D2BFADCC109B78082FA4AB1FF3FAA2B768BE3FDB1F929B67010944DC3AE6941877F599B478B03F0C267616AEE949197CF7D230EFE0930CD01D6D4E0A6A628068C6006B06C75F2DACF6027D5A2721B34A232A73DADA62A1721F2903983A5A04EF8ACC4C5E29114A9BED0BBE492C1972212DF08D3D2D8041E5658A42442821044AC7A8151F621BC88A56B53E84B5F342154C1109716BDF877A631EDF7BD64E5FE45A0DD40BB58C91F9DD5005736DB32DB3B57B9DAAC0ECCB66860689F5C1F6BF9D5115544601260F22A90EF77B340DE9B4C7F38250528D57140EA5FFDDCCA4C4254252CAA34A4DBB9F643B18ED950DC89A06 -smlen = 2500 -sm = 0000000EC2BDBED877538AEAC597717A7AFBEA0D0954ABE8A2E303FD5386BE09B9145B0C4F5203CC3771E11D3EBF99F8CDB84B8B59940B570676EA55FDF6996BF8A8EBC5293080B32CEFD214031A7CE6C9A239751D15738EF36195812AE0553CA5054C8DACBBCBF686C371801CC80544E9BE47B1E01090090D7BB51B52DF71D91417FB922D6235B34464CB75D6357A9FD3FB19789C78A1B5445265157A8F58C97083C9A3F77E1CB62F400722ECF9EA9607872D3C6A12925EA7F4D0FAE1359D3CAD5B84BAC51B5E18DC6F915D9D3877248331E841CA5E2A9E5E22ED89FF387200E50F52CCEABD27D6826EB2287DB82D7EE520391FD597B6E73139D84BE3C1378B822898C4A8EC07FC922FFBF9DA07B3A08A3CEA274606F312AAE564D581E8E2E7DFC83C26D7FB29C88996A6363BFDA2115931D23AFA9E1345B9D8DE542FBB8AE1A883EA2C3DD893029D9DDB7320E0B8CCD1E864D04FB2A0F88F8974FC26841D212F70F7714EA7676B20C0EDB14F3551FEDF6A6F9A81C06F5409791E02B2152E90B3647D326890361887E005819E758367695243C60DF2CA9611B9836478290A82E471494336FA2D40D2C5768047EE8B2837D82E232F8A52A5F28D79A5E0EDF59E8FB27FE189BB5B0F3E8F2112955DEA9435CD0E8DC59671930528016B04B05864D309080A6A142F0ADA36AABBF0A7565F08B7AE8F893D0E724DA5DDEE68CF6EB05DD8ED5BF327B3F681FCDB708F47894072B5A60C1FC4DA918A8BF40E01A1B85D546A9CCD65CA4C45EC66B81D15BEEC0BB1114CC87C8768EE0C1787EFAEF0B623754DF068A9530EEF7E4A19434BE78605C5230F8351AFB855920EB056BE2A3C38AA1130479E653E93869E556170CD10F9A9820E6B6A17BCAD164A16E0AFD1F57FC7C517AEE878241675E44B8F85ABD1404E4C55F17B05C4D3E3E6C7197B1B90CC1C770758BDBA381E61BBDC0E4BA9E36FCD992EC1FD2A8E598CBB9F6374A3665E10DFD38E1087998DA2875594CD5712639D28F4614C3A5238FB611ABAA56ECD0D80CA77AC229B6B7CF9F0678A4C9ACB41E232B29BE6A7C3973364801E1DF151E9B947F768CB76FF97E4C7F00902FCA4D83DCFB51359F01C68314BE71B7311F4A93AD651014F35BA773E27EE81E38018FF840FB5456120021B04B9CD5503D5829A7394EB0FAB8E211BEB08DD5063CE686B34CFCDF0101F29CA63D1A6AFCE6ED512B3D4E06DEF655C1E70C09072911F6ED8E75B35A466941CD98B91927A59F89D4E417B4457FF686CB305BE08A9FCA46AE7B3D0515374A3A15CEDCF67BC0ADFB84605471C5D17141D89B4930B8D16309FC3FE1B4BE671671C67761A2A65565ADFC7BBA5EBA03D46675DC407511A8AF49055628E47BB8148F69A0DD542AF9A8ACAE95042D2173FF559AB30689BF2DD6CE2E9BC177DCC38954F5019B7F9CC6D9B6966D6B5F3ADEDB3CE772A017DC98CFE1C3EEEC6CEA804D9A862CA7CBA4F3CE71D27647784840F22DB7DC1D24FFCFCC73CD086AC0C2F5CF6F090CF508BF802C397A53EB393B6A8E3B890615C690AC84C7111BDA73D772AAC3D3A85A23A10299C98D8CF31A96F75E69B00A1C7E73A5DF7F5E5156315D60A26D2620720EB7D2D1218328BA7CEA44C0E4F67F5390CD395DE53A2A1284B643BD496D4622739BE6D6D20967E6D295ED74753859E43762105686FE56BAE2BB7D7DFE92148123BE34FC191A3A095ABEB7D62D9276986F6A6E5E491707750CD9397315A8E0A116E730EF0DC1F872DD3CE6C7EAEEB299016940A49D6D858E1130B4BC0DBEEB28DCC45507477E149AA8F89165494D20DB95960788B7056F3C300664C51B6E57AFFB185760E7CFEA4E0950A6087327FE90B85525EAAA477EE77A3E5CDDC7BD7BCF2E0527B04BBEE19531131335F280406CF18AD9755ED995F5D7DFF50C2843719A8A65626F978D15F738019C5CF0E9C83639EED862E518F29FB0D70D80A3C36E565AAE7BBB04BA42809C591002BA8D1B7FF8579A1D50761A10A0CCC32219784A7C79DAC25CF1495B2409D5743D93CC3371BBBB66D1CC54CA6B5FDFF6F55AF6439CE48B2B54420214147E247AD6AFE0612556F092C9A3009DCD78D322374D111B8097AB516402CB129CF3CDB02EC6F86D85B67B8E3C46637A20CD853E0419DA7351803B6B716B143636C6B67E911508FBA163FD126C895E916FDA1E61652AD18B5F875CD954CB401820DD4B33D42F6AC6EEEF32FC6F002F93A02DA8B94996676D189C1EC49DC3B50883300654904C3FF42EE2204AFC09F10FD31840DFC03C6F1DB94E9B4717A81BA75EA6414E25EAF1EBB07EB10A06DC8F6E998C8BD2B4FC11B0A39132787BCF8EF204325CD749CA55C0C0F181C860506422AD1533DF054CE2C4A14336CFC2F491D8898881C7BDEA290F03B592F41803DBFA4242B36A00AD5679A4B399F6BFE5CAD3651C20864278C1E21108FC5C931DD609DF0C862DD5580D143122B31752EC50166449897AB37CBD781A38FBAA8AEC433CFE069375345000C149664AD80A49A42D63E6ABA5EF18A7D5BF3DB41A2AC6F37EEBE6EB51D6A33DCD0D8696060CCE1588E4F5FFFC9FDD71D77841C999E305A89FCC77FA47DBEF546787A18D5BD3B245069E12BFD01EB979D661194A65B9F63B2B618A924BF6EDA90F10457A10F90BD0D8EC793ABD8826A7858691A600BDCB889CABAC8D6DE95D68A2AFC1B6A7D62286302D6C639BAF3BB56CC040D33B0187220708B7B9FB9B61EDB2919585F39171A084EBA668007357DBED95E8A9F4E19B91CCFEE25DCFD85CFAFA286A77451934373B5F100621C794E375F6E69F6DFFAF61B9375EC5B5EBC8F0AECA1E2AA2437D0DA7331207270FFDFD83CD40C3EAB2A4BD452DD5567FE4794C74509A840815F12EF9CD26DBD164B677FA61C06CE7280C7A1A9D2570081161C15CE3F39183F8D7DEA87966BF87E191261E810A4E476A29E8FBAC4C51BEBB86630CE74538E9161F05E001E7AB2DEDF2C4E85957B0E9DB53E2190CAA2513CFBEAE419499E68303810DD604475B2DDE732DCC42FA8BD29FECD128393E422E35D9ACC7BC70F43787A4F755BE4A04D21DB18559FCE2F8C54EF3BFF39348DA5E63456B063063786637ADA04174AB9B37257E6024EB56767E439125B55B23CB29B00820BF6C9F81CFE63392A76BD3DC57C574540C6BD3EEDE15DF113D2E8492260FEEAA8049ADE7A99AF98CFBB7C67F06C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 000000010000000F061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1008 -max = 1023 - -count = 15 -seed = 6F41B5F7648FBC1B70F35CED64B3EA95E04EF08CA2C96D8AA264D85F1556C15B295E98699431B072AB2EB621390B6BC1 -mlen = 528 -msg = B0B98E653197404F869906E4E247A0C65C485EDB719D0F24508F55E2E6B2F10247C431B7D02E7107375D6E3DE9F289993C5C082026EC982D0B3998448E4E82610A7EAC8ADB3C2BB1FA3FDCA3ED8151CA94DEEDCDBC6022FCC2E89C2CE89D3C3DDFF2BF86C3AA47FDB7992E1DFED195E2AD2DC46D8E8D67DF6C7157B85E941DA8A703040741DEAAA88FD97642B546C40A135E5D184403A218EF425069D698D9D2B765FC7DBDE46661644F616DDEA73FF9E0ABDBACE39A00DF1802BADE7059DEF4E2FD622DA13154612DE5A74EE2B38EC29D3F4C8AD96EFB347B29B77902E0020919C32E698EDF88816F4D8E55F6EB84B273B879D51AF6DFEFDCEC72113EA9947E7448C2D15A56E748D389FA84C94F8F67DD52B5AE6393EF4B48ACE2B45F4A47007F33CF1C40F0DD043D964B403104290FDCDF56AC39DD3BD28F7AB3EE8BB455CDB0E9AC9129363E8979B53E34320C6516F6861D70AD47A605A13D00E59506A6FD48D8DDFCFBAEFA0A3FC6A1D4B8599D440EE71AECF85F3456098F361C3BCD1562C8537CDA207B1911E33C58CDA460A7A349528DDF8B2AD41E979C858FEA5BE70F2147316FC92103D6786A75D1B3D3B5B18C9DC0A702710D3E4EF0AC9BE325CD0E8F1AE09ACFB0CDE162153CA8E894AEE6B9059AF9BB37150FFA76C532122531B3DBD4D323BCC10F3D0FC7E814C6074B9C5D9328510415D7DD236D478D3F349D5338DDA8D4BB273C8D0290664D6661080B -smlen = 2500 -sm = 0000000F6380E9DD17D8D82C80034710AFF3D2405CDE036AE70A8708C52A514783B2DD9212717E6AD1CD1A850658EDA7D055CF04648DD80D6DA435DBBD4140B90DE079C064D1FD5611B0F5810264A148DECD4E62A8554FE38D50E43CE5F8E1D72723C12134BDFA3105F5D90C8D21FACC87EFF761589B23AAB9DA9154E7E252ED30AA186221D640903E2A7D2328629B8E7C2BDC9CA34886171ADA9E8533C983738A84A2982797D8E200BF43FC145B4F4897D06F3BFA36D57146777A34ED9A331BF33028A1CA92C0B24E849A3217EA488BD91743A44700928532C0953C227CB2D55589A8F340AE7ADB2C032A35B79E35C718CAE4BC28B3DE25C031116DB97C9542E3782AD56511A9D5403A93A06482A84469362E83F35EA57660602E3E0A37F0173CE0DF978678609AAE4EF9A413E09A78B1F29534CDB9087B494AF99ED2FABDADDD2341EE50B9CDB3F70C3C04225599FC5BEABE0E4F1643685E5F2D9DFCD239E40E9F26AE5BCB355845BF3803B7A4FDCAA5CE632740C32B6988B8EEDFF960F9489C4A45CB5147A69658D73B1591B6C6867BE801E95EAA2F6881370EF61D17CA8FEEAB89C3914C7095AF2F119820585193CBB91F70D5408A623C518B6EC2468937C3D9960E217B79BA016809ED28604DE75C9FCC65F77503FC95CBFE6415F4C06B6750A88387F8AF1825C982369AC1B97CDA8B96CAAB4EEA9C4A1771427A64DF8F9F8E2C1DD9A2106D16216D1411D8F3FE17C191729A75075AF3001721472A311810E26471832BA89143A762DF88E00C3F958DF6DB414602AEB08E97A4FCE7219362EF3800EC2B3BDC1E2B936D8F4B1E4F2F65F2A40B404E397765181CC40D0BE334793D827F5151A66CA637E5914ACE7B72C7DF2E20841CB2CC3DAB8D00C30E7392F146B55770D4AD23365373C4FF113255C9DB98319A2ECD5B2CA74216B623F1E3AC2351B322C2F8296677E5A1C6E499019087B2AED8B8F7634F4BF74454B65DF2CEE89C3BF4458A240F2CDE6E5D6598607303746F22A5813DD284E458C1875A23738D2D061F738C45875CF1C09895424AF5B16C444935DA630958D036FBE7E8112307027410012162EF755B11A9A717FCE491597659C1C7D613917A3EE153C0DA747BA30979A75DABC39CE1C4DAFC9B8CA4B9CAD9389759564DBF6E5C44338DA26AB20BB89884ACE11C23C80C772F338026D679BA493BA54B43EEBC894FCFCB82037CA9B87610C3CDB6B40FE2A4D0D994736E41BFCD52B1E353DCD1F6A936D46A088658F29AEF70E52CB10B7C9913161D534DEDB19F3052642B2FBE3B7F13A9DFC90ED2F31CB13E40851E63477EBCA17AE8DD57162DBD50229E53CE2F7BE182BFDAFB1CBF7411BF81A6347D36EF370A80C214BD810DCC51AF6D41339450967BB1D64C83D291F6A83A34DFE75F8EAD9BCE44A1C35D63B5052DC6D1453BEA470CC4A305353E5AC54316FAFDE70CA0DA16DE0558F99ADAE0817EF389DB33520A86E1BA5AEB53F9AECC98ADEF00D191EF7366F35A95FA5875D9E9328B8B60E7F55B49BF8D813CCDD1ABD4D06F44B09819A2E8EFC61EE12DC83A5D46A2B673A8B985F763CD7D1A396F7E0ECEC0BFC0D4916946B68C6CAFE5F2B45F345ADD145ED25BA9BBDAF5DDB7EA6BE3B8E89D7A9837BB55851AC5DE3F0ADE35A3C5E1E39561FB850D238ACA632997059755FC1F5C9B7A58479CCED5251F39811885AB916CBAAE4698E8F6CC67D14071317FA79DABF2F3C9098438BFCE22F64EDCD49EBF75FCB7CF0D5804821B1892F7F417FF77B2C61020A1DBF66561B351503E8DED31427B50CA896A2BA37627477F33FC50CB0E51107ADD6391C5290C9CEB0AEFB837EE3BAE99FAE78C2215CFD10E008BD0F26490DD5A1ACC9727405EEFCE6CCACFC4F291D9CCFD726957477487E3B64200EC4FABB79A38BF7E1F4B00FEDE43C28D1E7A0EEF3B8E1639436DE69B53A13EF5267837A28B1E0788E736F08C5DE95BCF030F9B24DA8616218B983D22C20C6A5C4436EF236C6DBD6AED69D86F5BEEF250FE21FE4F75630C2D77D39FF35C205363A40A7461B12E2A52BF0BDF70FB8C6879D2A00B8CC6B44DB4F7FB8806DC5D80CE9AA2F72268BFC256848618F25C46260D013D3F0B0D2139B63829F1D616CF4D47749CFEA5E5336539214FA73F1048C0E012CB702B4D1C0407DEE769A4AD046480EC020E90622A2BF1BB6480E52E8CD6EA4AAB9F861FB3B9F2C8853F3FBB397BF7F58ED6EC2033FE0579ECD921C24B03A446ED3BC2F7C8B93D59E52EBC8CA571A6DA8AD8C4B2DA83C0A3EB19B5439235097CF87710D9378FAAA12EC6BF5AE6E36D3DDF2A4809CCAAE552E41F404006785C9BF30A7EAB3AA5CC9C9FBF7F8DFE93A356993D3752FE88C77E9FA9B40A2B5272855B8C7307119946E5577037E2382EC700F57B8B962DECDCD2AC7D6C4EE1887EB9EAD542753548A60BFE6FF83F8F9D8950B82C4642FAFB58C152D69F5E993F762A86CB9A13290F07AE77CF788361E5013B3D1EAF5174D4184AE7BF8711EA50B04163CB4CC7EF645A2822BD5ADFA0DEB85D6E1CFF105B1BC96F2C0644DD375E5078B8E3F7A0962C54BD89121DE087243ECF73588938F487F163CF333E5B5212EE3E71264D21A3965785F09CD97737CF0FD3206347A33DC95A7A31BBB2FDB52C0988A35AA3EF74EE257C3096FB0AC40CF11DCB91C09E1A19B86F57E20FC6C1B868D10B990BEFB03C975A0E010D131344557C8CB49BD1351E166B712B351771D7935E5A26BA1DCBC7832D467F6B8D2BDC69078E1AA40D236700EFEC54E7E7D26C67B2167DBE76C9F529F28CB8C2078EBFDB364886686DD3D251C6F060C1971504984D33AAFA4503043339A494FA48165B42CF153DF2DFB6B5ABC2716DFA6FFCCDC60C49C82D27773B0D7E6194BD5840ECCCDD59C776501F7C2793F726FBB79C7E174689BDD5D47E50DEE6B1FC2DBFD7A968A57DFFB2D646192DFF2B4AB63A284A9FC4583FBCD0128BF3831F579BE0F2000E31C7C98C43104304CBC168F60AFF77E65DE4BFB716B9F3619688945BEB34ED112E619B017A744A9AE1624A3DFF9E935E639D9DBF5700D99575A8681F83BF86EE67ED1D9E75F03622149FBAE8E916A1DAF2255304CC3676687257E6024EB56767E439125B55B23CB29B00820BF6C9F81CFE63392A76BD3DC57C574540C6BD3EEDE15DF113D2E8492260FEEAA8049ADE7A99AF98CFBB7C67F06C6ED9028BCCB791AAF3D679BFA20D6CF6DF982D4A166AB137796D648D6388CB31D08FB964E185527B3D7C13580E52A30F40A0B9764BD9CE61BBA6263CFF9DB0199DA11AC26B56F08913B30427020DEFE45B5056D2EE1A5DD1CC4866BD30016F748C3DCD2899B4A8AD108B686AC2985260CD274286B6BED29F2A76F058FD406471C5783FCA881501FCB5736BFB1155A501CD674620F158AE7D857F4F440F126C3FE6FD472885A0B99AE949CED819F6B3E91D5EFB5A62B47F3C08BB57F3A66482146F7AD3EE350C510732349F62CB0D57100A63E4DB00D053A58ACA49ABA4AD11 -sklen = 136 -sk = 0000000100000010061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A57A2329C502273655AA85737E957C7FA379A71BEFE44012B5249386CE2FD0BF64E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FD -remain = 1007 -max = 1023 - +max = 1023 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_512.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_512.rsp new file mode 100644 index 0000000000..c56266bf30 --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_512.rsp @@ -0,0 +1,14 @@ +# XMSS-SHA2_10_512 + +pk = 00000004E219A0AAB2C8F4054939A56A419E39D2B91371C6A2A485B21D749DC399E0E58275A69ED6A400A7C1EA5A7B4EEFF0DB2A7E742C062A847DDBA24680388DDDBFC14D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE +sk = 0000000400000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A4E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FDE028B6F5724BB039F3652AD98DF8CE6C97013210B84BBE81388C3D141D61957CE219A0AAB2C8F4054939A56A419E39D2B91371C6A2A485B21D749DC399E0E58275A69ED6A400A7C1EA5A7B4EEFF0DB2A7E742C062A847DDBA24680388DDDBFC14D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA7662A4DC4B05165A87B8D0064114CD7836FBF0E8816843C48A8FCADBB6A7FB88801F98928A5E5B90C63DEC0EA0FA3395D402190BCAD7718FF534030A15444CF7658E15BFE22A447F3E23F7CD3B21642364F858C75968120262406989789AA6381C6C7535C2EF461B882A555A1BB43239564EBA5E7450722069495EAF1D3A396C45CA714A94B1C38E13E94E14249A8CBAEEDD0EB6A1F867221D94D164CF5D47DB5C759708AE19D193AC01ED5DD678BBEC27E908CE04E5F45B13648FEBCF66AD7181BE682028A9F3C137E962B292AE5A1D8A661085461D378100FFBD3737C4FB6B436A85B851F5F823A0BFA2F981E2C0379C626F2F813B3CA1708CD9D844A8044A917DB24EAD379D5A34E90E3546AC2D9121365D162CAF65B3DEEF566ECCDB449B1CB773057B21BE4F54E6036E1923FC486AAA69AF01CE1E29A3C89F78DF91A71F1145A92FB5C12BBB2D4E43210A60286263F56951307B13956F7BC1EFDEF3C8194B815692D4B71BB74DEC510CB396F1D903FB30BF8FA8D845915B74A537CEC2F5BD6CACC6E0896A10B7FDAA6D1412CF1B29A2669A3BFBED70CC9A6D3F8E782C5AF72DC54E3D1EA0F88BF2BE93E0EB4479DA07ECDC18885ED58D555F8BE63A483C6E20A875928081C31DC62E49E550D608A6EE22480FEBEC0A3DB64056A63C772DD0C14B1D2A8EDFC0D3A799B008B5D7C63D42D1848C06F43A974DBDB5334F237E6C21481E12170947B7CF9EA5E81D7400F79936FB292C1E1910F016AE190BC1514559E027FBD2C85DDB78A3230443DF8D1F35FCDC73FB189353361C7A4C819D3FFFA3CE11E6237664C8FBD8D0AF7AEC9C2C47D0DF15B588773520C10E0285F00299584CC25D5BD18DDE6DACD091C1CCB8318F830C6051D181AA29F3863B0859000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B589FD94AB5C37762EFFA44AC2093812248300D072E964594FDE1E5EBC7987B59EC36D4C0C120E76872FB77366F2C5B18B86B9139DF28EF7D44E32FECC4C804F010000000000016B410B4BEEFE73CB8F4D4C3ABB7DF62F132C01D90F410AE51281E0C5172FC3762D01221D015C100F93020CD106AB5DC052522C419A0FD67AD1A5EE9D5FD62E180200000000000121D1E9B1C034C0E95BEA3582EBC57F8383D0F6D1DA068D3ADB5B2B6237AADEE9A89B9F772A990889B143707CDEFCD05608317F599099BCDD2EDCA4B7CF410EB403000000000001C23E183353CD7FB42309F34D450892A84D2E250627D82E72E4A582BFCA8BAD10D4F5A2CBC313BC02333F65E8FC8BAB87A19EDD304EC7F7F85AC8078CFA3ABEE7040000000000011E2BAE00E2D34A2B2CF6745FBEF9D552837C3DC63720847E7DE3094B58785B6043AC7DA8CCBB7CB127C7B0C7A974607349D30D61CD7F08BBE092A3F9C7BD0FBC05000000000001657D3C7D66C12770C0BB75D4F5214C4B194F841F23B240ED784A12295B734A173AE89D8EDD857516ABFACE192FED90D2CBF6254B4DF0CD8C0D3F7CE520B0FAA5060000000000014567D4BD416073A25CDF242C18DBEA42908A4D6F0F15266EFF60569D4C458758BFEC8027BDB07730ED08E3A23D0540D8B90A140E06A28CBB64891316084D93FF070000000000017B8C7C4EBC5F897F112AAAD0FE18AB8CE4360565BAECD1075FED846955A14048C88B6B5C1A065F92AF55BFCBB10C7C46B114C80E9A36CC3BE6A245F466351B7D080000000000011F81CA34F234A41958ACAC3BE7C53450FCCB7E4D785F18C94981FC721F4CFB851AB0550BEE14A4DDC57D2A9EA06065395660BF32D43B71FCE388DC6F33795910090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 9092 +sm = 000000006686539E267711CC53D8B185DE1BEA3A8484A81CDD6B6B0E46CD6568189E74C033347FA34BA7448CD4D56964F49F730BDE52ED29F39B1CAE52DBEDC90A0941564695221F5431496845B1E75D26B6B857E2611A6451456AE84936147AFFC7C7B2D2C1E333FACC759EBED3AEFBCB300486A32BB292A7F5331B29C4CA9D53EA76525BF71D5A3E48FC845FBFC5425860C9A12823F207A63C137A2F354B763989905F589D19E88325E04DAB387A43728A4F541C50FD01DCC2A7D84C6F18B6E97EBAB3CC292356AED4291FD4B69C3D557CC1FCD2964C9CC149D630EA9C2E77275C448894615FBD360F62B0E244B1C000F1975FA615DD6A6DD56929E69F80F1086F533631B97B3061C60CB3CCFAAA690EC0F4D9C3A99567C975C87A589881F548C5F1BD93EC0217C975EB40B2A715F44E2A70068D27B8EB36A6BEFF81E312438EEE5813EF919C7FDFE95C078BE095A07A41E468AC98C8AA215C6C976DC94AA462B2DD38EB434E35A03CB016FA3DC81C1D8E91E41FC43F71CA3BFFF5B5ED792DDF10BF542E2E0161113497B31AE7D795C0B9DFFB62E809F587779B6FD7B1DDCB38EF48A449BE87FFF3D39854CB01E9F97B36ADDD4B2D8C4562C45AE61E527AD277EFAFAA5E69FD57EEAC4828EE99DBE12234E48A253102FA3FE6298ED6FB7572BA4FCE73F55E90CBD9F6F0D111DAE055BE32913F0275722C5EF30C2A1E10D6D6A783C2AA2838C5A6192CB37077B5A1AD2074C2A24F21854C91973F186FCEEBB536B6EF677311DDDDABCC839947F681ED60691910FE67C017A449B91D4F2BB342A9CC5DBD62C2EAD8B2DE02150CD5B0D3327B7D2BEED3415167D54F73AE24BAB4BF906C1A056A1392B078CB74664CAE461FAACAF60FD0C6A7925CEDC5FE1DA590D0C52CA558F6750C7A75A8F66C221421F154A3A0DB9542AB5555890176CE1345DB286997894FC57EB5C2C3EBA0A4C6E8C9D7C637C56B034057C364C66F3EEC2C6DBAC1080BE9C26B16610D007F303C4B9B7A329D17000CFF3853EA3F9D56A5315BEB2313265CE888B790F4F6E16E53F6A75DD689FC246F6E9675748F56FC883F850EBF452AB50D70A21F6ACA9CBE83C7452B8A05EEC284B49CB92A4FFD1ABC8FFA72CD41273B4D0A0E91DBB3B321F507274EC896231A24B3CA654405654E449EC9F0ABF7FE8182F7098A6DFDD2889BDBECE91F5E86CEBE4CEBF8EF098C05A5895040E89A2D24730373D42A05DFC4E9DEFFDEC1BE8EB34AD922C94F80075F0BC540B1587AA961E1B668789484624BB34E0F1D2C6E163EE3DAD3E9D8A608F267D2BF7CD4CA356915B3792EC7B2956CB5335E1630ABC7EA438C7131FBA2BF91E4E7E0E54D3DE82934C2A711F4DAEF7D4EA9062E659449D207EE702945ACBA58A9DE4B8E9514A130561352A04B1923DA060D90B0EB3C654C540507F745F0F24065FFB8D76C0C5B326DA7C300F3E2BDC6DBB570C85850C88E0996753DB70B1C9201593B3A8E6ABC9D581604EA41D9C7109959DB8E8882265C7F8D12F24702F9BDB9BB4AF388C55C02FB49B4FAEFB98A25886B558D4C3492048BA4DABB55680D5F5BAFC70BC02492283183BEA8127ECDCE84EBF441C8AEB01082D07CFA9DA4C9034C8F4A509FAACED436450317A7DB7DAA434D927BEBD2AAF917B2E6D434511237E31A7B04E7F3E6C5FA38087E274E5B6BDB334F9D9F6ADE18AA9065FF72F09CDAE4B3BE7FB1CA862C78B0B8A9B8031297629CE35DAD8281075CD7D250557ECC3581AC93F62001020264F8E93FBA0FC322245747EC7076288748AC8D13F18AC5A3AF4884FAE075042FB85CF3C0DD3449575E0066021BE65428A2976BDE033407039D548D9EB6DA7D02B2CD6556B12362140950B80E378D44E4B1AF627BF715B7F36083F6B899B4D09FD639E47CB04541E6A306894AD18BFDE42AFD2BDBF2B61A78E98DB066BE125999FD687A324F16E0452119E9B7085799DB594891A9D631EB4A955B5B0F4F4773C19006EB10BA46D8445640074FECBB51649B6FE90BC1C63503018A37400CD476CB166A6A2782EE1680495B2E11F5EC5BFFA5FF196C739CFDDF7430331E71CC5686366E753DCE01F186ECF2AA9CC1BF911670165C06319EECA4D406145735FBAB797A794C3C58E998827A076E23DDCF473ABAA62E2C5BDDC6DDF55DA550BFFC23BC4895F223F904064AFFD5D5E61A7B64E29E3FAE23CD6FD9619795A1314587D124F3FCAF3569206484848932025D8F638102A4F25644DC1F62F13AA1262C5C55679AFE8E1F7BF340ADAEFD97221D46FBB8702B2BB5EBA511066C8E9F159F52431ADAFEDABB476DFB8E836F153B08F3BD4643B9FCA0A954DCAEB7194661EE8EEB97781695D64EFFE2301189B28BD7C2F9E64C32E263C99C6BD804AEDB9127A60EC8489973F99C782D062679F3F604ECDF2460383BC369DE103D0736DF1A0868D6037F68F091E0C741442DF88E14E8EA615F5E8646A68EE301E551849F580EA63BCEF034B847C47B373602465E6FBAECB948374A3D64410717B19A240DB023B16B6BB0B7BCF1D63987106F171B53DEFCA63A7E0652FEAD5584FD17F54F50AF85E1D87FFE5CA116AE1664CC9AD25B327362D9857CCF6169BCFF97A95B1583B8E20B7BFA4814BF5D82F00F07961107B6063E8CCD453E1A622A7BDE9C4C6B97BA3A41057AF2D7098CD4E829C34A80AE24846D8BC92BD7489B854831DC7A4956D010988AC9B2135917188810FE4D94FEFDC59F6954EA289C444813ADEDA9CB435B6C470C0037C21024FF67B7B7031E87D8F8774CD6BC926318982544BD6FE38C09893B929C9F8B7487D51614D1FBCCEDA56C1794C943A36E54225B729D63855471F2AA9A514D567F61B9E9B4AD4A327E6B113CAF5C0A22D26F74A507B0EC1A67965F0978C608B70E7F6D1646E7F89D2E70EEE62852C69618ED8AA136DB1E75D4A687A62443A82802EB270F1C91E97074F3A12C63FDF3BABEF882F934B4BD0C2468C66B1C6E37F8CDA8FFCCFE109FB291FF10163AAD73721CDB57A5E2CE8CC41467CBB125E3B525185F8ECB34C4F4675220CD92836BE2E420F24BE023F22594B5E3F5AF06CE056C8EDFC67B49808AA9643FB1160DB9D455C38071F49555D3FE9A7890DCA5E2047BF23E904D07641140BE0142DC90069A86D98A280D45A88C7E54B6B0660656A5C40018C9AA955F5CA9F10A10005C735C90F5B2941043AC88271B241AF7EF66218B4B74E41579BF64C812F9502DBAD602FC7894000F3ED41946FB81DBA9DCCD666125E9A4A5AA7DA1B8E5B8347E1964D36F6D0ACCAFC14DD8B5DF301A3768F5EC7924982E1B57D37D019914A01EA0B7B1652EBA5C15A6843CE712C34A1AA8842DCC9FA570A6883857EB260BDF01EFDD4F233551D18F89B585993A92A3DE64CA9A0EEB74A7D91DB9E0FF5FE1E035C97EB8CBBC796E22302FACDFF89231FA3F77E72EE189894071B376D0113BAC1EA0911D3A5E24D638CF8BF0C8B92B0A321B7E4557CF465B88102F98645EA37E58DC6664DFAF870E024A4D9E84C8B913EB467D8252BBC8F86818EB2F9D03EC70B4342CEA881278C516382DC79E27B4EBA9879AF2DFEA6CB914AA98593C52CC7857A877371F871CEC175AA5E72285023F1A59BB072D9B2912D974A26B4B57A6B772F9CD7334A3A66DA86DCED932119C5D57106FFDC51D4B7E10B6E94C343A90C9C15D078E9D5A66BA252695CB27377607E0968C93D529E02EA881A2AD58DB81863B0FAE8B45252AA6F742E04D310D82FE58B7E6BF2D0BF8A7D714F7352BFBFC3EFBE050F75E60222CD694496EBA04C85B7DA12A33ECF4325A392ABD40458D087DBC638BC65270E6E7E5719F14AC7721541610F2724EFA0473CC320023013DF549C8DBBD5F5691450E04C26202F5666F5130154012204FBD584E84D821EBA36CD2FCDCAE1C4BBE8BE5C9AB1983526743838548D107810E014FED68387355106C3B39A9539F2C24D318DD5F1B0715E853E168C809BCE684671411C783A766B7307675CA4D04B0DD86442B1744ED1B8EE018F83D9D68B4FCAECC66FDEE75EAC379E19D0DBED5C3473089EF153433ED2B5587C22C3299898850F7A872BCD7A064A7F8211AEB8175668B1402E79729AFE8F4EBB2F147DEABD1E0234E5056F5D1DA522752639E200C12C166D5A442071F190DEE7670941E2F0C59C05F1F1EE8C6449EC731082CF56CE8DFC8DBABC019420CEB0975CC90E59F165B156FDDE09152FA049386C57EBC64DBF0ED92181C6605B0EC442B5CC242DA32C1716B2FCAB0F64F6C94E7E8053CFFA1B5329D7DB924DF329BD3AAC38A29DBEE3454E1FE3D79A6EA6877DE61518DB7D79BE808BF2D6D12AE400E94866A8E27D2F4FC70D9CB443F8DCA23113E32C1497EB0E61AA22594817739E8F954A39CDE8B6B1A543CBD65286E2DDCBD0F5FA3A6A28B28036210ACABD9EEDF4B006B94DF3631B68A824824162C1A3A1E3288924B834F21568605AD9543CF93919467A90E61C49F5EF5EC30DF4FFA1EF2C8CF59A7EFA1446238D9E23C3B5A42809BEC365038F526DC24D81AC1DCEAA429678B3A019C12A772B3AB24DF707A1E9D83FEFAC76668A9E234FDFE197101FA2F74EE80C9F0CB50CE2EA40A19D618EB82699E032B417810765366BB2DCCC2B41081699F01563DF24D65E6FE0142E9AFBEC6366C1C027864ED04D3C3F1EABCD974A2C842C640E46024FCBC33B5C94494AE26FD0CCDE2A62DCB2C63D22AE6F0CC2D107C78B1C4B0E54CBE78573B38785A0CF94839C6DDB6218C234CD351F3813E119DC05765C450DAFD64BEB915E7BC6D09FF6B756949615CFEB5518F19A7FFD3C36078FD18CF782D5FBFA41AA86ABF35E16079E71886A63077763203439B75DFE4E5CE50F97EFC93030C80ADA63754D8096271224D1EB627E3FDE3F54E2D566535C5D33F2485E686D4B56B0C674BC5D6EB60C81488344A32BFB02FF5A309FC45088769B98930C32B2A9F269EB83E3AA3E0CB0FAFEACC1EE2BB5366C6787E89D46155687639CC5B02EC4681977761B43191E5402CBFFA0573D63041029C7D14F33BB2BA687208F18A91AA8E22AAD4E86CE927DEEE97256EC3CA81B71738B4BCCF072234047F5B32E44D030FEF18D9509CFEF94B447ABA3CF4878DCF9C0FBDE9DD7738D91D5AE94D1583504292E5495945E3CB6B202674261F4D1911468E9C95B6BAA96FDE0EBE07EEB47C5BF9ADCFE3A276F79C84CFE48D3A5A9A2BFB656C8A9A87B76A602508018DFEC14EA398A05022C87D8FC0969EC627F4FFAEB1F8242D31B82CBBB11B4959307B3D5DD0376F3E7AA40FAD8E2FF8DBF5D0AC1C9F90405B943879D5633041A05942A6BF60B89DD7ED5BC14F1C1658C4CF226DFED57C8AC5C825BF5409BDC051F8C83506164836662C94CCB33EB665E90735DA8132850BC22BCEAA581A42D97E45884C03CBDA6113587454CEFB86EB828BE506E20FFD3A4BD3F0BEEE7239FB57CB8EFFE15B421A049D5A654EDFB06F17EF56BEB8B7E9F0FF2FFE632AC59DEF87DFD32129479284462B108D604B665EFEC0D25ACC19CFD6EB6356E7CE960EE78553A56D622D3B2838F49510940221E87EA2B308F4DA54915B3D61C95500A3073A2E4B9B34DF59C8111CFC5F6E03B86E339C806CC0A4128A7E47F6340737C8A3004A2626E544CAEAEBAED62EA3C45801ED8711715D6B0A85A4C005CC39629D894C1C590BEA60BF5AB5B02A9B76728A6E7F72F7C746265D51FA1771ED9D2FFA4184D4EE985BB95235DED9FC782DBACB8AE478797CA856EE48A24941059B4CABAE9D48E1C4AB18F419EA94224485ED860D056AE7D5D0D00E9AC97470A30D805CC2176895F3F80F1D8EB9F914C6F86C6E870EDD24F0AB9D0D1BC03B4A6CFE770CAFC641B4BE6222CABB3BF68DA88AE2822BC27255ECB02085C7E19C4BAFDBE27C05FEA7B8E3AEF255164A84697D9C7E4E540C01F6FFD4E7566922FED1EB49DFB029E350CAB96EEAA30567500EE1C5C04FFE0F2564098798446351894219168368642ABA593001A47584DF43742D652659CCC1F1BA0FE7C21797859AD752423033EC5871F5A1703D0504E20B458677C4C4740D9181951412512D0C0B5A32AB9C33BA1C9AD9CCC303021ADAC2091500382D42149A0AE666ED8CB8DA412E52D2FBA633AE5525EA0FE81DF7FFD071C39EA7AD445C01F9B0847226C84973B024F3A69AA22D64F477E130DCA563037B7CDE81B11498EBA5850B5C31E2873EC2A4423741EB539B66580DA833E487A3ECDD6EE957143534C156407EBACD74408888066EFBBD69441277EC843C45B39B3E0B6E2F936D2F8EF15F45075982618BA5F983806E7919BD4D59582282C16AF1221980B5510A38DBA62A587F6D80F4080ECF7819B5EC949B2856FD2AF0DE295274718D859D64FFB280C63546D27C98873505F49D23DA88DF5E3052769C28FDCD40E0FF72893DA4244E492FC2EC940D407344A1A4EDAC677EFDAA1582772990C3DCD904B3104569F93989FC13FEF43F344AF7C75621FC14C448FB778D681F506671E5D03D24016424B2BF10CBDD9495E7352F040A48F46FB33690DE20A30C0ACCCED872430F7A277B4278BC83939E90B07B4B548E4D541491EB8B997C17825EAF3DAAE1F5E308099617F30955E3EE32AB8B029A6D72EA42A2FCF33077620AD4FC58CF7DDE2BE8D6A62B9466291BC7286096F14E8BD2D11C73AF7D92D2CD31DF9C18307AF432E933635CA06153A8DC47870BF5FE0183AA8AF5687D01A8DEC21957E57EA27DD4BA80ADFB48B2ADE869BD76D11BB4FAC2A74984397FC8D65E641A8A0DEE95CDE25AAA04EA13D3007A031F80AB9AFC73BB27C60F256407715DA96071C8197A8663CDE5DC9990FB29A1EC9AAEE667BE58C4EF1017534D07C1CF9028754AADC687D760D6410AA1FE5E2A6A4C35CA7EF3BB3E5B4DEF14FFD7903AE3570175C4C75E65C09DDB262724AEB97ED9735CDE139B74ACA9A5D7B1463D6BDD900E73E8D1AA1AE534AEDC0B0ADC0634D6AA682AAA4C8FC2EBFB97E98478FD918AD4B24B4CAA246D328187047E8958756BB05E80E4CAFAC794BA6824CFB30EB09EC7786BA7CBDC468A7ABD66F6D7D62570D7B2CE612D4A781663D2FB9C5BA533F6931FDF374D77681CDBB92B2E0ACE313023857010DB8E401FB36365BCC03E91E78F4959A0BA59348BE988805AC9585172CB1AC5749644900832A67D493F54E0D898E7606276073226B5FA8036437067D193C744C0115F5C71E345A48F96A4A7B10E58D79B9A0EA10C545DA202CDA1B4AF08A968B218E5C43AB295740FA5D36D9B611932B9E0682A1EE6D5DBE228FE90E9C7E169748261E1C566EC82308884DB143C3A8F199B814F706CE6F7C612B26EC1A01ACD713CF758C1682D15262280F0CE056A2FE81D6A4965B6E66CC8CB01C7193C9AB5B17159724D0917AE84C28BA3525DBA96691397BD9238483AA3DDA24C3334AE22EC9A47FE426B3B08640E6B6347CA91AA4384D1B27B323C8C9B363A162D27BBAFB8EF81CDC90B309DE38FAD663F00C0343A8D8FDBFE6F3455BD288987C3443AF79DE32D86735339B9828478BF5887471663B2D20CDB0C92D87F27833CF08D628DC834210CD7A9C852B58C14B894E24C21B380A1E44937B6E831CF0DB2BF88799A2532A3383C755EACF3970ABA6EFAE0D5825B7DF122F6A7B536CCEFFD000C2E61A519412B6C60966D4ADD9DE24F94F771348E043EBD2A25599CD72233B9744EA63F6C94424A4AFDC10B30EB857E423C4B19D41CEF442432E433A6AF71629EDB05E7809FC011FE3DF16FC6A56B83AF09EC0169A6D17B318C27BB074DFDF0C4D817679551F0080E7A8D1D9101B63FDDDDB2D1CDE21770CCE0A0EA5ED402AFE65311A48249D2A49D44C10B7CFDAC28583C67CB6430DF02EE9F84E430C88522CF1016242CD0677EB43F077842B5267A638C551AEA6931D182D2D3C631598B247FF93964C59B0EABB99C4C9941E641B0023B8AA5F3F93C17FD684B3F18996E30FBB8D3D7798C37BACE0F096F04BF1CC4446549B49931107D2F86C66638AFBCCB22CE50D7390CD38311EF7A9D50734A7021D872B87E8B60AAD96B0F12748F7BF4EF8C9BFB515A5B017191E9079956DDEFF3CF016DAE35C99D3FBB755BB3A79E69EA78F4576B9E05F35DD7CBCBFF369822B9322BA2B05337A17930AF87975EF0CD380B920CA86B6C4B7C4238A59F6F03E8AD55EF1E6AE8FB04663D7327FAFF924E6EE53476C449AB25A236C98523A7067A93EA0C54EE9468B9F79DE251D99A95C1AC1D7C78B56FDC43369418DE381B78CC9C9E478E64D904391F368A188444E80F3C001BDC93459ABFAC1E229C7905DB266ACE93C2AC4614AC777663E448EF8DB336AF6A937CA13E325A2043BA5514C3AF9CCBFFEF3FF635658808CCC58E2FD1CA58802FFC72E386E777328A79D163298E1DD66603E0396DE534A4AD7D3A19C117E7873777EC8735A910E4177B0442D9294C4EAE3246E87B95F437335AD6930D4D1D6547065756BEC9EF32188FCD42043BE04249D920335B6E34D944AEF7C542F18333280557DE060C94CC2F93079741811FBA2930F038CD4941BEB47984CF3DB2F3E721AC15B1AC979CD933EBE8EE073D129888C9B871C87303889897A8B9FAE58999AE9574C53F3C024F9E1587DF95A820B3886A4DE641EEA0C2A17DC347CB16ED3D4BA5BDF45EED7222F6714DDB16F4343AB65FE27E27A47D18D82CF8003332F59DF37976DDB719AB48035169C6AF53DD2EDFAFD2512CE3B73D53859455B456D756CBDBC3EA9E1E869EE96002CAA7EB6ADD8D9C0201AC3E88332A531D509A861A95BF04F0EC5867AE4CDC1B5B0A056DA596BDA426545829EB5C2773AE19951D346A9C62DD6EF1C031A4D659FEE60472619BC1DEF82F9183B7D776F5FE30F625CB1F41054C522E4B983013203D7F55294B79C878B069A9A86E195CE477B71B53EC98B482F5072F9B442C32316CE3E6CCE64D0AB79197D439D4169FD36BA3A30A9F150821821B395695B7179D8937B264A6AE4506A9599F73998967C824F444CEEBBFE3CB587412FE39C3F5F88CCA164CD050EDF18CEE52BF1FDC4B33A2A347E82720B49707737278348DCB509A488823BD2907C60F0465CD2710DD0041B53BE0D1EEDEE5C6F39A02226BDC3FA56409AA98990C1D6E62C324797D910C79AC06DF3D956CF6788EEF1F70B267348C0E5C88645059E631E17EBED5D365A0C16BFABD6FB9DB2BF9FC078C7DF6187EF616E236D4DDC816332D10DFAD1601979D4CD14EF177FDC5D93DDCE075E0CF0081E5EE900E00B5B58820BF0FA5BCE0FD9CA38C6E2CDC456376DC2326E99DACD54592756C2A5F651131C084ED369C94654F44669E1A950F16FEB85EA106F752BFFE23AC4B089F37A07D3DF7CED35602F57DA407F9D60DA3B2D110005D0C27927967B61A3D3B16F4F0AF9EA887D9CC9FD812132E60254F1B3AD778202696F7084388AFB30AF25D61DE9B7CD3D53044524A832BE78D058A68B17BDC981D4773C5FDE404362A368272CDF08070EB738D7AEF2B8B5519BD005BA5140E230C2AE07A24C4FC0B22579FF144DAD576466D6CF76C2CF3C663F5E8E1F423C2F516954B1888096333826079EC2743C737824220E68221A15AC03DBABD6B73BBD6565D9B3B2FAD2D107ADA8759030253C4B7EE6721FE96850B07E962322F6D47BE10711FDCEF278DA39B6588EB45FEA241875C0BAD85FEBF38FAE94358BBC673D57138D1B09437F963C20A764DC35D73FD7CA0CE1B44F28E4FD2731FDB75B9E3001E63A4623811141747F410903ABF5A914DBC9D60ED5C3E59443D569DD33181B33869F1E00ADB57C61FF5F74E5F3F8C0AB974F7D5E9AED105E35DC112F50FF03461C19E2E456FFA22C3DA25491396837FE35064CD5AC5F8BC453E0E86736CDBCD997913BA652B281B814278F7772ADC3081EFAEDF51946AE741AE63D3863CBDDF78A900AE829F97F63B4155EAF0B245843A5962C62707A5B57157747BB6D20054DC9A49D0AC4D1E5EDAD0FE3303055B8667D773DDB4DF9B72F6FE2E2FA58C2E7A4C3D6C9053AC3C4B7E4E80A54AF105F88AFB441106E38D3143B7AF5B70447D1F96AE8FBC7CA4D7FF9764252125C2739963273D2E139640DE66F878AC3793DAECE33FB1D05338FDFAC98E051D2613FD4A4817ED459FA7B05CCD6C90A6110AD8A01AD594EFB2FC2DAC88AD30737A55C475149505C341E9D77B3562DB46347DFFD2A9DB8A68124026D9E9D9A9997AF40D70D3A922DF54D52845B387DD8C2E4623CD85659FA7F25ED157C79337C99BD9173FEEC9D14B0C8D18881BE0BD2D639A7D2F3BC5628F9574E923D74489CA281CCAB138B54F75870855923206B9E8BCFB6B41F46B7953E3BDA5A8E8A233865593A41F393C05594FEF6AAD0D21D6969BACD767AF83E2C05A524E0C5B2EFC01609C5F7AFDF6A2CD90BDD871475B703544AE98A4DDF412084B0A8CAA4321007D12DA982338FB3311238E26C35F2D5C7EED3E4BD6F5F932C42E0A790B17BC5C974BE06113B70D9B34D7BEF5B5D37662A698F8AFD529A703EF92686C27018828D114A1DA99492698BF66F2A801E8C97BE82786B458429DBF7FC1D90390B438E6B91D021FE8DCE180BD28F5204F373CF45BBA390AB9E3977FAC6AA1B680C49832F7FB649EAEB80058FCBD1E4E67B7F4A065E7D80CFD90146B2D0BFEF64ED0AC34E4FB1AC2F1CDD51D1A3A10F99AFA145CF94E374929C139BB64D5B143C1FDAF309B15BA0A57686F2BECF7FF886CBAB80A3886D94B2C99BA026E1963C6CDA0E50D4242A4F78D4C93C171F47A8457FCD3BFDA4CFABD771E41015EF13D6479E6FAA1EE63BA568E7DFFCC7DDD98EBFF25C16C53DDD3122E1F33C3A18C6D4081076324D50EEC28549F3EFF9007726BD7CAA24004C778BDA91B88DE6175CA3A9D26C0074F3ECBD8A5E980B41CD46E571E1A462596816A711E816DAA1F373FBEBC98461A05E47E3C082FE88DC300C95AB4112CDA18BB7956FD530E68CD8C916457ED0CE6734CF72560A8B675C0AC8AEE7DF585994E5FCCE96917E2E034E07D6EF7114C74BE2F799EB98D1BC78725FDF26AB22CB9FB25FDDF7F8A7B122827564563E400EFC7FFE34602E577EE0427892BE8D5EC42BB4764C4CDC0C779FC057F7CF8411CD966F45ADEE37853B3C988DD739FFB5126C760323D83AE1AA97D979D9DB3080033208B5DA3CDF7D98445D336949B28BBB27C282F9B0779FF04AF813E5DD203E0EB21C32D9CF2B825F150E853D4906C960CB624EF33820290DBAE1EBE78E60888DAA2D72B865EA952BD21DD234513019551BE865506BEC1513A187682186BD5C482ADCF0AADEEB83D05601CD570CF0E406E94F557A3F8DE99EE903CFBBDBF2C50B3A33FD6BE722804D2D64FB91D6EBDF5BD762D78C86D1AC2976A85CCFEE7CB3CA718E706C41AC8BB41BFC2888AF84E7E3A6088087D669098AF90EA6D92E9BBBB37EC26C1C9A705B11C71A442D32ED65BE2D79FA73C2F99690A21A627891F2BE7FCF340477AFE57A6FA2E827D05FDB3A4AF6A49388FC062D7F24FFBAF8AF61503124D79EF179D32CB6F717B854F11B401908C700B8E4A38337C3E76C33525A93525845C614F39C5B7310BD07A88D7FA99558DB3292B3B5036F85A046FA38B040544ABE58C8DDE9F86362D03557FBECDE436683C5BBCD58A497AC07F7E7F3B62B2AA8BBABE4250F4C418DDA374DE6988F843B7F71517B385A9A1CF02931A0D9DADFB417722E17910530EF488309474E6D9DDFF56A5DDFFA3859354FE34B93FFBFB0E7B1822C832230DB644CEBBD319B2D8C4E2F689642852B34F2B1253BB58EE9B7C62B757E6382CEBE47BF5CD1D26F0ABDFB5AE5356F0944F82BC00B52BA61EB5C603B7BB0EE768D763B8ACABA90516914D5C73FFE5908E753F498EC7E28BC3ECFB69D8EDD76D313140FE218F3AD55BA76F3CB73E331BB762B7F7F92F75C2CDBAAA7662A4DC4B05165A87B8D0064114CD7836FBF0E8816843C48A8FCADBB6A7FB88801F98928A5E5B90C63DEC0EA0FA3395D402190BCAD7718FF534030A15444CF7658E15BFE22A447F3E23F7CD3B21642364F858C75968120262406989789AA6381C6C7535C2EF461B882A555A1BB43239564EBA5E7450722069495EAF1D3A396C45CA714A94B1C38E13E94E14249A8CBAEEDD0EB6A1F867221D94D164CF5D47DB5C759708AE19D193AC01ED5DD678BBEC27E908CE04E5F45B13648FEBCF66AD7181BE682028A9F3C137E962B292AE5A1D8A661085461D378100FFBD3737C4FB6B436A85B851F5F823A0BFA2F981E2C0379C626F2F813B3CA1708CD9D844A8044A917DB24EAD379D5A34E90E3546AC2D9121365D162CAF65B3DEEF566ECCDB449B1CB773057B21BE4F54E6036E1923FC486AAA69AF01CE1E29A3C89F78DF91A71F1145A92FB5C12BBB2D4E43210A60286263F56951307B13956F7BC1EFDEF3C8194B815692D4B71BB74DEC510CB396F1D903FB30BF8FA8D845915B74A537CEC2F5BD6CACC6E0896A10B7FDAA6D1412CF1B29A2669A3BFBED70CC9A6D3F8E782C5AF72DC54E3D1EA0F88BF2BE93E0EB4479DA07ECDC18885ED58D555F8BE63A483C6E20A875928081C31DC62E49E550D608A6EE22480FEBEC0A3DB64056A63C772DD0C14B1D2A8EDFC0D3A799B008B5D7C63D42D1848C06F43A974DBDB5334F237E6C21481E12170947B7CF9EA5E81D7400F79936FB292C1E1910F016AE190BC1514559E027FBD2C85DDB78A3230443DF8D1F35FCDC73FB189353361C7A4C819D3FFFA3CE11E6237664C8FBD8D0AF7AEC9C2C47D0DF15B588773520C10E0285F00299584CC25D5BD18DDE6DACD091C1CCB8318F830C6051D181AA29F3863B0859 +remain = 1022 +max = 1023 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_256.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_256.rsp new file mode 100644 index 0000000000..299c00ae9b --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_256.rsp @@ -0,0 +1,14 @@ +# XMSS-SHA2_16_256 + +pk = 000000025E84310CC01CAAD0B2B1E010C15F6691FF24977EF626465F5CAC2B015342A52404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 0000000200000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A5E84310CC01CAAD0B2B1E010C15F6691FF24977EF626465F5CAC2B015342A52404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD09000000000001D5DA3370DA40FE4B2AA8D93A4C52E009ED16134083746A63365266ED868E33160A0000000000010EB7A75A56A1497F0FC1FE5B3F6B396014CC9357B7FE8A6D2BA1B553EE3518610B0000000000011B23B9B57C09E7B440346ACFAAB7028D8821AF52CA85D5CEEE66FA4E95B45CA40C0000000000016AC8FE7754C3CBB4F71F8514603EAE30A764437F404409A1283CFF4B7159C0F80D000000000001CC6FF52DE53BEBD4E1D3DD11D0BE5FFEB977CA63FF2ED1099705AD3D5BEB1AE90E0000000000019B6C3951BCA1748DC7B89630F962DEB3937A4F8D15BF5634741113C38D2699F10F000000000001000000000000000000000000000000000000000000000000000000000000000000000000 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 2692 +sm = 00000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA70104A82ECC99EF0F9172F36D2B461A6515DC13666B7F1D917746E7086F99C8F1A63E1C7E5A339AC394788015AB12B3532C7ED27D1BCE2B1F25ADC96165F6104861C3DCC2B150E1DD088C95AED7DBA928946BCC8351DAF6136F7335FA45EE8F4651CB9A6E98D556765100FECE8CCAE704D7AE90AEABE735C2FF46DC9FB302D2A1F4C33F371ACC4FA552FE83C254761E140E990474A10D5D2119D90AC9C2736BA2992026D11473619FC9D1857C50BD2ECB693FE0DD9C15EEAA100015D58F2D8F936E154B5C932078BABD1E9A3E3D7B876174311282D3C02D8463E268FB1542D967EEDD01DA7D0ECA0E3257F84C2813FD01B211B495B9191A48E3CFC34E056844855BD1EF463F5D1F9E9A8C7FBACBD29E2726EC1AFA11522536678005155E1CCC5562A8C0D1AE450EA842EE72F236381AEF42F2445DD5B9CB2A791B1D95240D10FE14A3343E73C5FE2CC524A7FD21FA547675C86F6C8D4EADEB1AE29060EF687EF65344A45A5F1033DA0B50A5529AC43435DC3A8BBBC986F1ACC1AD60CC13F9BB26A1F99DF207BA4E2C7B1A4A0BD8B5B9529F705C1C323AD93B7F67D735958A454CC7D6927CB165E25F6C4811F8D486A34DAC2C8A920D506682D747BD6496258BB4011164FB8F12A3E984085401E73A96C5A0B7A661F6D9288910CCF1C1101E0BBB68646191DCEFF06EAE14F3762FA5C231D3D57770F230802C2188D108FE326778A10980AFDFCCD50CB32C844771C1B5DF2054A7F9D19FA28F461E81EDE49B2D780FB3FCF424A28FB9B2E88CD08E4D4BCC31E1BD06481E817980FA8A40E74D0CECA78B87452100271944681A77667368E04F077001DD9B1454DA4614F631A83335A8C5B1F83087C603CA6D731A4AE32346FFBF5BBBE7FFCD206304CA468789748789EA6620D7C8AAA5D10EA029C3EAF78675E35C29A598CB5624FF0ABCE0548CD6C9DAE3CE9BFE4665EE57358DBEC0D157880889597F245FA042D00FFB56066AC873718FB1BD12E0428923AEF51F55928C8DA0D632382E3325E4CC5C6A3EBC4776C9F6520EF2C6960F0129A707F90315AC1AB035A7BA0D293A6400C30D363DF000F53D309FCB4CD455AF4290FE44F8FB76B6C32ABF15BAEEF44136CCD739D96CC95B0DC0EC8186125075F21570A6440A5967CFB83836BBE0FA463C0B6692A9C6D673038D17D343EF79BA50ACE3835F6216C3943470012081600FD81FE5B31B604E946A2328C40E977558DBDECCB8D643E07A573A9CB5DB4518877320FBB4998BFDC59FEDF2EFBDAEA4058725054A1317CA755D3BDD4780AF57F3B76649B3675DD9DD95A16F5CBDFCE00CADC229C2DD7B4E32D6EF82B346C5900BD03164C1896A4640F8B79FD7241614D2FED6D1E2E5795827F146C2158BE0A39E9556BCE1B08B774531FBFED5012C3F1DDB0C27A8503A43AD652AEBCF8E6F904EB09F30AAFF35952227395C3151F2927727015BE31E6A03C994E8011B555AA21C792E806511407B653D1CFBBD97D1D4CC87BEC5E436487DD454363E2E87AF3C2AD4590B98E9597885A533623BDDDA308151FD4902D8BE5EA43CEC046E62DE367D9C21F581AC2EF46EAF0F0E10438D4895C49FDD3049A23E32561BCEAF00F0C192BB9B2426CBDE0CC3E6186C3228990D0C0703BCB923061D0256CA76F9A75429F35CF416D6A93FE80E8C771DE016EB671CCD86B9B221CAF0C521F58D8BDDD226514234C6D44554A5943C782FFE265FEB6309F643277F09495ADB42B4C362E1EBD6790AEEB0C5329F797809B1A99E617BF85395C38D7B367F2C2AB5E26A156437E7248DF2E9F2F6170493DDD3FD0A0CFEFE8577D87D69AA8E668F66279BE02DEC2D05BBA330A504C68A7E81709454395DB2C55345262308C2443E6D245675277291C8E6718B222332047A841B2EF96801D464F6EA1053BF96F6E69F495D45535AC3FD4411C27FF7DEE1A7BE429B3D9A386E40B99329DE24163911705BC3137F0C728AB5848532999315D7DD980036E8107AC3A68691D840FD37C6950FED7E43C79CED8DB06685476979EB357AEFCBB1CE969D9C37505FF2EE6B27F8FCED566180664EAA36D867E2C702C6716A8EC826FAAD00204EE915AC2241D72BD22B8C46387703E5005F5A2FBACA6F84D5B6250F4B5BC0A2A6A31DAF9C60EB13C20CC649A18E27A6C98B82F08E21775133C937E715F8EB13518C059EDF4585E7446408D2AED56F1AF125187E172DA47D9A150ABAFCBBB6BD37E68B51E1E3B76A88186784096804E0CA23134BDB161B70F2AF126A3DABA5C918B224DE444B8733E6FA601B3D349307E94583D0EC97649EDFF2BD44402B649537B4A3AB06D71227E40BE5A484B47D7364A839A4730A09D12310A297840646C5828AAC63A9C3D416A375BFD3CE0D4A35C24762B458CD70B23AD28725612F5FB98FF740AFB457915740084644120ADD17B445078AAF541C08E140C4F0E8E005322F8AB6BAB5DF2FEF6DC1EEF9555B3FDA2C9354130A171A704637AD2E628163EE49D33FFA1530ED03F0A3E771B74CCF546BEF58EF21DD1522538D7ABA7F4A83155F8567A89BB7E052994F9E491025A37F3229BA80485F66F0BFEB7D77B5227DB43AC1360C86DFEDA86872B28FA47CE1C78A4DA2508F2144D5F353F6EAB57CC363587735255342964CCE7ABFB619A8072054867C554D4474EC48C059D2384AE7E36865F8DDF0CDF3C1B34C9783169B23CEAD96903024CE5D0B798AF6C9717BBC5DEE4C9150E8B271E12B53D2DC24D62BB1B522696BA13C595EED0091E7B3E7B5E50DB3DAD2516992EF120B950C8A22C5D1DC1959D8A6DE0E31E568B1B105DF9711B589CCEE0BF0A8A4597AFB9D07663D1FA4FE307488CDC692382EFB7882F60DC53AAAFDF2014CA7D27F8FA93C187A8371B41796557AE738D2AE42D887D10EDBCABE6AAF951E0A070D881879332064C99F8527A5EFF252439DDC6270CBF5906FC144DE1CBB74B260E8615FDB2903BBACC7A30DA76937CC982BBF293AF6DE61315DE00A8D15148487FFC0BA96489AB359231EF31202AF53CC22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B583 +remain = 65534 +max = 65535 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_512.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_512.rsp new file mode 100644 index 0000000000..ab807bc996 --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_512.rsp @@ -0,0 +1,14 @@ +# XMSS-SHA2_16_512 + +pk = 000000058AA2D66ED8FC46C0EC0504C56F35B897EEE56E6E022C0020BA1B38E675296297D99CA20060E4954AD137D640B279CD2903DE768E1FBF6A412EA45B5A33EC55D54D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE +sk = 0000000500000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A4E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FDE028B6F5724BB039F3652AD98DF8CE6C97013210B84BBE81388C3D141D61957C8AA2D66ED8FC46C0EC0504C56F35B897EEE56E6E022C0020BA1B38E675296297D99CA20060E4954AD137D640B279CD2903DE768E1FBF6A412EA45B5A33EC55D54D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA7662A4DC4B05165A87B8D0064114CD7836FBF0E8816843C48A8FCADBB6A7FB88801F98928A5E5B90C63DEC0EA0FA3395D402190BCAD7718FF534030A15444CF7658E15BFE22A447F3E23F7CD3B21642364F858C75968120262406989789AA6381C6C7535C2EF461B882A555A1BB43239564EBA5E7450722069495EAF1D3A396C45CA714A94B1C38E13E94E14249A8CBAEEDD0EB6A1F867221D94D164CF5D47DB5C759708AE19D193AC01ED5DD678BBEC27E908CE04E5F45B13648FEBCF66AD7181BE682028A9F3C137E962B292AE5A1D8A661085461D378100FFBD3737C4FB6B436A85B851F5F823A0BFA2F981E2C0379C626F2F813B3CA1708CD9D844A8044A917DB24EAD379D5A34E90E3546AC2D9121365D162CAF65B3DEEF566ECCDB449B1CB773057B21BE4F54E6036E1923FC486AAA69AF01CE1E29A3C89F78DF91A71F1145A92FB5C12BBB2D4E43210A60286263F56951307B13956F7BC1EFDEF3C8194B815692D4B71BB74DEC510CB396F1D903FB30BF8FA8D845915B74A537CEC2F5BD6CACC6E0896A10B7FDAA6D1412CF1B29A2669A3BFBED70CC9A6D3F8E782C5AF72DC54E3D1EA0F88BF2BE93E0EB4479DA07ECDC18885ED58D555F8BE63A483C6E20A875928081C31DC62E49E550D608A6EE22480FEBEC0A3DB64056A63C772DD0C14B1D2A8EDFC0D3A799B008B5D7C63D42D1848C06F43A974DBDB5334F237E6C21481E12170947B7CF9EA5E81D7400F79936FB292C1E1910F016AE190BC1514559E027FBD2C85DDB78A3230443DF8D1F35FCDC73FB189353361C7A4C819D3FFFA3CE11E6237664C8FBD8D0AF7AEC9C2C47D0DF15B588773520C10E0285F00299584CC25D5BD18DDE6DACD091C1CCB8318F830C6051D181AA29F3863B0859EBE1763192D55AC1F413982692F909485720BD4F9B15A9EA968A63EE3F4A698AC73B58112D644CC2E1EFE05CAB29911A95C103284C83290F67B83587BBE7556294C5225374477D7ECAF9AB5EC9460765E6A40DC75A84EC417263C50D22FE5583FF9626977B8826C06E160772D6B0506861A86633446A807183935350D91EEB5D37414CF3BA477AE353761B74E05BB6DC167E86FD20D1EBDCF5C7F6AE3C16116BF9CBB6B67BB564009B597CC2CA1B16B7B3B484C6B172A817AC71985522092AEC980B2FF393DEAB2A375CA8C894A68CFE3DDCF7CC0D468B43C6531A58723A8BB14E201B277155AE268D6A3D15933778611288CF4B0BF3A33C30C1A77AB39A8E6770125995651FA889FAB2B28C87DD556DD7260ACB83D691E2B9DA5880BCFBC2EB079B0D42F673A8064710EE9CAE5913E37500A2BF7FD4B6BB409F511117323CEF7EB39EF1BCD8096E4EE0F5605D58361BB74E6656935E7B075F389DC49BE4973B7C6EDB05DD051E120406EBE62FE8A1DB88A91CDF152BFD790E3AD2308C12B755000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B589FD94AB5C37762EFFA44AC2093812248300D072E964594FDE1E5EBC7987B59EC36D4C0C120E76872FB77366F2C5B18B86B9139DF28EF7D44E32FECC4C804F010000000000016B410B4BEEFE73CB8F4D4C3ABB7DF62F132C01D90F410AE51281E0C5172FC3762D01221D015C100F93020CD106AB5DC052522C419A0FD67AD1A5EE9D5FD62E180200000000000121D1E9B1C034C0E95BEA3582EBC57F8383D0F6D1DA068D3ADB5B2B6237AADEE9A89B9F772A990889B143707CDEFCD05608317F599099BCDD2EDCA4B7CF410EB403000000000001C23E183353CD7FB42309F34D450892A84D2E250627D82E72E4A582BFCA8BAD10D4F5A2CBC313BC02333F65E8FC8BAB87A19EDD304EC7F7F85AC8078CFA3ABEE7040000000000011E2BAE00E2D34A2B2CF6745FBEF9D552837C3DC63720847E7DE3094B58785B6043AC7DA8CCBB7CB127C7B0C7A974607349D30D61CD7F08BBE092A3F9C7BD0FBC05000000000001657D3C7D66C12770C0BB75D4F5214C4B194F841F23B240ED784A12295B734A173AE89D8EDD857516ABFACE192FED90D2CBF6254B4DF0CD8C0D3F7CE520B0FAA5060000000000014567D4BD416073A25CDF242C18DBEA42908A4D6F0F15266EFF60569D4C458758BFEC8027BDB07730ED08E3A23D0540D8B90A140E06A28CBB64891316084D93FF070000000000017B8C7C4EBC5F897F112AAAD0FE18AB8CE4360565BAECD1075FED846955A14048C88B6B5C1A065F92AF55BFCBB10C7C46B114C80E9A36CC3BE6A245F466351B7D080000000000011F81CA34F234A41958ACAC3BE7C53450FCCB7E4D785F18C94981FC721F4CFB851AB0550BEE14A4DDC57D2A9EA06065395660BF32D43B71FCE388DC6F3379591009000000000001FE9BB64389A416997D68A9C5451FF9E3E78396632F38598E5345173954CBFEC8673FBB2AF02559E05CD20C58416401806095E8E1C2857DDAB16D1EE0F3E190DA0A000000000001614A2C14DF18FC44145D5BF5D800B784E33E3A9CFF914651EC186AFED8DD7B7BE9DF850F296C864358A76F3746114A0E8C77DC4275625349967A30017CB236F00B000000000001F9DB099C3387CCED2252727351924A10457131B3BFFB25244647716F38397BB534828F09AE38D601A810D11DDD56B5EE1DA23E2FE2DD430E40465C7D6B2E0F9D0C00000000000105E33C911412FBDBB9E20A3ADC0B7252641A464D05EA7033F487C212AE41F3183BE15D981076DAB6BE2E3FD38B92902A67949DD0DA273D580B0F486C5A66B3E80D000000000001E66DB2720E5C55537B360D0F774F1CC73246C4145690C3EAB8367194A83269B7AB01804478CADEC9A748FA6B2BBF7F33D13C61CCC88F19A0BF16908E0B0BD12C0E0000000000015F9CF8DB14A3F181CEC637BA72FBE950458F42346F664729CFBBEEE0A492EB07BDD134095EB0CAB4FA91B361999C9BE0959B55087B34DB128EE3FD6C02D7E4FA0F0000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 9476 +sm = 000000006686539E267711CC53D8B185DE1BEA3A8484A81CDD6B6B0E46CD6568189E74C033347FA34BA7448CD4D56964F49F730BDE52ED29F39B1CAE52DBEDC90A0941562F22013107A0B9A812D3763286B6DEABDD26B7D975D267CA8D98F7A4EF9158E8CD7254464071BC8456847AAF9C54BAF4164E50E45D0417F3E9C05E9C1FE81AAB153A5F0C71B1159C1481EACB9BDB9EB4DED57C56BF48661F4775A35225DE9D2EE101EF5B13D4DC507EFBA53E65FB539793ED8C45E5FE4763F0CAC9A29C5E6685571D9AA4D3365B9B1014A1927E25870871F9C8C0EA530BA455B0B2360C24B1839019549E1862D3AB46C728804F06859D2E974B49FA858282D752079D80E0420A9C94EF9DB7050E9D83A8AB5B37763812080A80FE3514AEA7C767AD2C637E7DD267A27B2ECBCCCA482C11CBB111846DC6EFDF105181DA3453CC3342CCDE25FFB2890779D5F57790F1339B680C95ED5FEA0B4E0DD7B8071149CD9432E9F2DC0D451735247973EAF1F284C8E0E4E09FB49A659505338C62CA09DB6A820D9AE34C95418FC6F5B22273C55A5A4523C7ADDAE31CF57D12C4F7A8472A5F3292A2AAE44AC57E22D3F2BA2104EF47CA54788A1D754230DA125501428804B85AF0D296A8301278114033F8B9FD1BBF20FED474C486FDD6598A5480E3F3C46A5D432930C1DCB43711B63341E31CFDC262F53BB4E355678AD71FBEBA8D6887D67E7CE3ED994B961B8EEC3659BDC3251EE7E92BEA91B17A8302ECE53EFB4571729FAD476EC91E2AEA3EAD3C30730D3F9D454B44C843B9E1859F8E420119B153F83BBDDA898961B77BF6D0845BC513419C529B3CC2EB61CD813633419E80C461B9F46187ABFF24D359CD067C1792B41D2A7001CD548F8E6BB1BAFFCACF72D29D5675356238BBC2F0A0AE53850FE21ABA0B9912570EF03454D3548411E9C2E2DF47FA81A08336CB05044958E94D96006B6B80346FD722EFDBE4509BC4C27C779EA9CE3FA6D4540A5A30852BAC3D98E69F92319B4CE434112B9E046E80AC8C98AF74C0F75C80E0E55FE0F54F8D1BFFA66BA2FCB3B39BF957F6C35F00BE5735481503B311BCB51F8085303054C88CE780A72CD3A41FF87C89FC0C0D19B5F14555B99B813EA0046FA9D421287C14472602EB5836875B43EAF674E37D971DC563A89399440960BC748B244AAF9D8744E1408EC8E0818371808AC6F10CEE8A4CD6FC25B5F616B4152BDEB86B4AB037E4E1BF59F6AFFD7EC15A55375111D8F8F2FCF710941DD0CB532FAE810F87613AF8B853FA559F4B7F61024A9D73E531BAE8FEAE72AF55A282EFE6108AD2DB94FEC5E3D9C6E052B9B67F5AF7C4469E00A21A91BED53DB2541037D72C1AB3EC8C8933E6D65A458A8A5A57744583949653BF9E771695B7C8D30EB9A1B57D15BAA3F89D28315138BFAA88DDD261EB3AB17EB6F3C4A85065934000B2F7915B326DA7C300F3E2BDC6DBB570C85850C88E0996753DB70B1C9201593B3A8E6ABC9D581604EA41D9C7109959DB8E8882265C7F8D12F24702F9BDB9BB4AF388C54A0AD6AB6B60641551B31D77CD08E99048ED64D16659D9B65BB8ACB3895948EC2B7CF30870B25E4381E550CED893B3BA2713FDC8F14C58EBA6F2CDB2FE3B2BB0310A51F954624BFE8A8139E9E37D329FDE86A56B1E3DA98EF9C3A6F654AF4E2E89E8BBD2271ADC9129C21AF4CFA132B4196FFECF5700C963268928C92BCF513CFC081409A6714C353C36A5540E163F57AA0A57FE68E2AFA78F331AB752173F3921B49E17CA30FE44412A904930D1BF967E9BD4BEE04538B02EA3058D0BE461FF6641F3A5E2B393972AA0943DA5DC0DE745567F22B02F60798D647A71A59A141E675EAC27961F95BCD87FF5C196F08766ADDA7F43E73EFA570E51C89D0A596D861A2B1731FBEA4D5D953E9E699721BAA76F564C39EFA91B1DC10F78BD396643AC730C45519FA0247B58ED7A0A4FA11342EC4789348C4FB12CCA3608E22B7EE96173C19006EB10BA46D8445640074FECBB51649B6FE90BC1C63503018A37400CD476CB166A6A2782EE1680495B2E11F5EC5BFFA5FF196C739CFDDF7430331E71CC7383F41DE05AB125B74D8F25C445B975C4BAE944F94E73A60D62C87EA33D60AA7F55DD3CBA1947848AECF5F01A9F253201356E02722D0531128893FD2ECB735D9BD46B778D1D00C245F38301F71B90D96C1359753921556A9AF55478B971B0FE8D8B284964A625D4322E90BE82C9067445E5469EFBFC33FA904261072CC196842470BA810566F2D5B553E7291CBA9A4FF8CCBAA223BC0D0E8044FF34795ADC85ACD048FCF710D31641074EF233CCA6611603F87BBCC47E20A9348CC567C7E23FF84C766A49B7BAE6A59F59AF957721AFF84E83539B8C683149A5787CFC4C05EE82C46340E64C486217CCC83C57C2C9226EED64EAFFA9923877514B46AA08FCB446DB1D731C742B8A17C6A652751C94387DDEF68C679D1ED0845026C68DA6B7F3E36CFE1B02898DF0EBD98FE88EBC2F3F569CAF8F11C2D66027B4C4A1440324843622C2E7D450E98C437BC5E66F02D3524F0FDA9FFC063C7DC91B56A48C2943D7D04B674EF6494105BD5F4BF79D4179031580E5FE9974E5EDB124493EBB0EA947119C50C4EEBE1A7E9EF3CF77C2AEB05E55FB902A867A353A635AF798F74BA88B9A8996964BFA72DC73DE5290966FDEFFC94EA8E767F9C977BC27E50290F3E0D9423F3BCCE545D594CF0B4ED7BA966F0BCDEA0172EF7CA8AE732BD24AAB99BAEF03CF970D3877DBC1F7D9F82FF63F316D7547463129BBF08604F7F21DDEDF5A3758EC8DFBF104738CF062F712D64B6F653484DCB6D8601C5FEF58EFA234BDBA6FB052F5254BFA7B7212FF8D6D03A03AA502F797E100790A3499185CC8BDD5BDEB0978C608B70E7F6D1646E7F89D2E70EEE62852C69618ED8AA136DB1E75D4A687A62443A82802EB270F1C91E97074F3A12C63FDF3BABEF882F934B4BD0C2468C6A036DDC3493F2311294F01D09CE5AA36E5A7AA830672F45EB2894A80E5C1937BAEF259EBF97F61780A84F31DF608E126ABE26038708017FD2588656AA416D24B89D52D80739EFD42A8FBCCE76C155BACF1B514C8B8C3F7276424A52CFB8444E548DB752EA947DF2CC1DAF29490FE79A42FF2D845E7A491ED6861ED64AA868A162C70ABD4C04B0C8B1BA523AD0B6E8E0EA210166D6213B94CE1275CAA2108DEA7BBAE6017963FBF7D5F7801685EF6750F6BED988D0C1FEF24FB9B75FF7C95A8B6A9DCCD666125E9A4A5AA7DA1B8E5B8347E1964D36F6D0ACCAFC14DD8B5DF301A3768F5EC7924982E1B57D37D019914A01EA0B7B1652EBA5C15A6843CE712C34ADDEDE75F42A117A14B1A9D9EC75594333A3BCC41D95099F30B7293AC6A76B535FC09AF856FA8BCBD2CF72770D48120A3FBA021BA64D685D58072257FF93A7331243A8A7C3D6507BFCC58E7F76D28FFA3EE36BDDCF6E389E9DFCDF813315D720773AC005EF78E77F093FA5E6FF281E647B4BD982AC33591B40BB2F2E2A37BDA9CFFBF08B0A1954FEC592FCC0A5C15D07ADAE82739FF85CEF18025B93C6AF3ED72D63590D8FBB6B7CC0EF87DD769819DD5A6E60630EEECD4BF4296F27D4F5058E20CB33E5B172442509EE7BCD817CA7C67F263D4F3BF41ECC6851986D74E49C1AD0D2C97008EBC070E122F1B19DF8DA264BA46BBE734F9B08A154167755B2A3089EAE043E9D1A4ECE5F5D1C0C080963C1DA98AF78A665FE477338F3F0B36FA7E2AC73992F509EE47C11FDDA16BD612DDD81FB9427C5DA2587154264BAAA4654441B46400F0481AEBE3B8A744B973169CE5A06C78071821E8E644CD5B66573991C6C0390B2B553534DB4D0748FB63DA09112D58D75525D6F73C94BD93CE121BE678FFC625D9241222CC785131D42D8B36BC5825654BAD71E7896CCA575E3A66F948EFDD54BCB2E574B39E456045BF1D8CF7327100917AD670336BBDEEEC25277E6DED2BA4B77D91CEBCBD247B5B91CA02888E208498DFA03EFE10C25B94C8F5BA3BFA5CEE079E1AA8A07F109B4701706A3F96BB3C049382417EE0E08605EF08B06D62AA092592D816631AC7394250971E2E56218B0320FCCFF0CBC0B670237D1D1479AB655780CD7E41D2D1582FFCDE1528CAB79AB734DCE747E58483C4BEC989818E91AB33D5E8BD6E080B8EF7437B9D5C7ECEE65EE24E6B3940E4EF18CF7D5A9B217A9A2C058A900BE7129B628E81E009F3758ECB3D278E456432D5B6A3EB800E10BFF7DCD958501CB055F8A20F5579DA1421F43F593B7F2F8BBCB6D90805AA9A9CC5E2456F530BF522FE5FEF9E38295AA45D6CD8BEAC16D5152B9505DB546924DC43644753A7A151C5711E00D534A288D662FA4EE5C6DE546C203D4C37192AEC06F52A9A1AF4DCF6A86A32D78F214823D1F0EB76B297C1C7B3DA933AE8D6405E3486C1284310237BBEF96CE1620D8BEF7C4035D1E01CB1A67AA4E613EE471CD9ECD14DACFF64C986CBAE45D3C39C1E2C36EF9DABFAC020014AD281DF4673F2F4072047F9C881CA03DBE28908646872A48667042EBC119D9D162C5343778C99858950287015D6128C884E4F335E65D7FF03B6FC7D954E7413B5619888474992800304D1C9CDBEABBC7466200AE6075DC257698C454A5C2DB560AD172FFA64E38BA5A8382129B23BD52432D10A2977683DA4A91546AE242CFBB5AF9B24978C4AFC3F2CA44543DA40D27EA7CE154844F48EC6C90684587F0EE3BA0654F8530D2A47182F6EBBC44B5585BF16653D6C81866C6C02813FB92E9E4B6D39D1F022AE14FC2B55ECD93DAC6595BE2F372A1516D1A4E6131E72AAA49019B359E4035C864F829EDF26EE08A45E9C252D6F76AC45DC63EABBFC641E80AF149DBE1E53F1EF85B66D3B813C2BD444D6E0DCB5C59E2978BFF9F4A60CB9C6AE0A9ACEFBCECED54ED592EEA9C9B0F9BCC9356A3D1EB7271329EBDC30BC8F8EA72969B03FC5AD6042DA3DB87C36C00A7F0CE9F28305E2BC72972239C61C973522DA519EE286B388A0C6AF3FDC3A09BED2D38CDFFA16AF6A517F6B73621B136C2C2D8E67FF6314D2DB42C6A3FFB19C74C0637BC530A56F8DF71FE105DE525BA2B24071A2CAFFBB0D37F8F5C3EFB5B34FADBCBB9DD2C092A0BE9B4BB0AD03ADACC8D06CAF6A980C8B66DB154F07BF689C3E9306A6CB6694AC8588CFB5F42105214FB51C576EE777608A051D9FD3850B22CFC2EF1F4C3A8D659AE6F43E74A335A14459F7ECB60CAB8A90294D51571BBEC69283E957B055A29B5BD7616510E8D782B7C25327FFB042E9B00F8793BC7268C0B92411ABFC2830042AAC561786D93178C6DF6051E5B520E8BEEDB629509B0B3581BA16D27A84EA94D05A8DD3F9CE73EB75027CF29D3AAA5FBA10F88CCA732D15352AA09E04E0BFFF2CFA60A41207D7C9D07B7E3BB1D39D93C4127454CEFB86EB828BE506E20FFD3A4BD3F0BEEE7239FB57CB8EFFE15B421A049D5A654EDFB06F17EF56BEB8B7E9F0FF2FFE632AC59DEF87DFD32129479284462B826A56E7F957C82037D1D753EF996155A8E13D8E4213BBCCE88B3713A079FD4CD25E611D857F347639367B25D9771969FBC13BA2161D64970695977BE8EC125927FECB9DC34EF4097CCB154B41C3098637CFFDEE46DACDD83A51DDF20CD4F2DC12582C937BCA1F33E311E40F7A35A98A14917AC8BC2934F2F3E68410C893E2B02A9B76728A6E7F72F7C746265D51FA1771ED9D2FFA4184D4EE985BB95235DED9FC782DBACB8AE478797CA856EE48A24941059B4CABAE9D48E1C4AB18F419EA945395F3B2530ADA8996D2C6A77D18D7E374E994BFDE761C04FE235DD6CF3AAF57E1FB12CD0585A74E02147E3D4814634EA9D82C5A746E8BD611C05EA798DA659D03F5B5F6D77BB8ED9CD99CDA42B176351633FA4C06BDEADF1867B2DA7D68D5BD5F915EE4988A16C8472450A47EB217310E79327FDB829A5B2DC0878026BEE398EF0E4CC70CD96BA57463A5B596FAD237E47C4923DB8E3EE9ABC263733FDBC34D05B3C0A133681AD5F50D817BF674486B8E3C3CED4654D4D93E2B8BFF92AC9FB6DEFBC1982DA0F50CB14F72301A25E3855602A6E8BF915509E4005AC69D7BBDA193AAE56A95B72774D3177A0988007CE34C97B4F1DBEEB95EA966E51A9FA7EB78AF76F7CA88C869459A5837D3F05821C7C5BEEB0508738AACA46D0A2FF361E47538429FF845488A14653D34B4AF836DCC39E1DFE62EF9700D7F6D01C3C5EBD31C87B03605C0A6903C8AF70AEDE6BBA5238426E92A7BC99C68B2601F25EFA92A72BB89C4BC86297EC8E67FF2B3E6BE96D11CD7C500F380C1E3EB68F7EEC1C16195ACB77CE9FD9E7E2D48ABF0FCCD27B1A058CD74E969DDE90D004128ED790B2E40F78BCDD3F630E4C01424EBC58F5C020A92BC81D6887DEB065B6252294B5B7F458BEACEE6B6B8313E23653C80C4C532CD2E515931E6452EE883F6B124642F9657328FCCBF300DC2567E2118B7BF394143C6D1FDF380F92EE15C07BEF9C18A4054EBCE1ED59AAE8318725EBDD388948BEB3BAB282228C743B3B0A62AA7B64C70141BB187C77852C4DF2B90387E4E3670E2AF35E3D969E7A516D2FFF28C7C0799396E5A7FBF936293C3633ACBD50BEE1BB396E04D228D6BCB5F1CE8FEC6E54069593FA0DD244B61D017DEA5007F2ACEEA73C208E7129912849B398D318DE57405AE4D82CE8793AAD854DB0755CF659AA3A0EE83EF6AF166D81383A3CE1D5C0917074517C9C68002E584C47FA0B6188BC5C9263933222D7E106499F98B42B39973A65CF611CF5C9DE267487DBD9E19529A4C02321EAC4794A43070D8CD97E7732EF97E53621D203A5FBE0ED3D3C5DB794083784744FBC4E66D7114559BD343A53A582CAE18A8451122F93BBE34429E7B2284F1274AD7933F26ECB2A81C8D5DC60BCB98C9BDFD7D6170585D4813E93DCFC6133EC18794ECD9BAEBEC7DD31D80BCE151B61CE42DF11EFD55AE81A115D073F7414119EEBFA05E73D43A2D8FCF1CEC1D7FD9F0D3A1AAC4E5945A1D8400340D7E8B3F1701DD57CBD4261AF00736BC25499356F02E5BA7D0F19475F7397269186697D33A9BF4699F1EB385E08059712615E3C1F6A03C0BF8959A78E3960F7F2C51C6F0530B217879721431260492C1B3B7F9D074DC62E722798C9804AA83EE2779C73715AB5B78F8639D8D30F9D54671023D8331EDFE4718C78D79980A446F533F8556B16BCE1A1C09C607C2626525052986F3818BABD08ECFA78D7C11FA71519AA2DBE8A3B34EE82AF05ED10D089F7DB006F6D92AF90FD0962F8EBCFAD63D5BF41D3A51AD570789ABB8EC53B37C3904D7C914B83FFA8206C968814F82EB25DB9893FD427DC0A9A584270E306BBDB4EB6853EE37462F4EF562AB2A26B6B520A18D52489C566EDDC1BB61574D20E2A17B55D142A77E3DE415BB98C6E39622DB30F3EE02C62E405A5DA0DE9B07FE58A72B61B60011C752C01FCC1245DC3049691A145558AF755BDED22872431B0FFFBB7C2A09F61885053A19EE8589E76CF218A1CEE5710D962EAEC8F9C463936AEA8E4168407CB8AEE787A2C5FC3DA3B9D7F2C6985D1D812537AA348E2403E5C0A2451854B4619F634EDC83A193EF6A48921EC9BB4DBA821C890659E2ACF30ABAA37D70483F3B808A8F64F477E078AED9F6A87D2BC23D2AB079251AC645B75BC1500351F100F771348E043EBD2A25599CD72233B9744EA63F6C94424A4AFDC10B30EB857E423C4B19D41CEF442432E433A6AF71629EDB05E7809FC011FE3DF16FC6A56B83AF2E13E895AFC2502186964EB95D68FA0B39D11F78DF7D4C5D0B65DE97B352BBF256F41DE84DE4E399ABF4614713974D0364349E2C465C422BC09C779166D104BFAB82AFAAD2001C6AB97AA598DD9F8D9F17CF2AE19802E3DCC3542A04FD158A8A4961E7333AF64127F6A08B378688DDA8B3BF53EB0DAC1146B18DBC3FD1718E3E7E07821A83F6AF9534809168DE9C3D4EEE7283D4B012B18D119051D0A942C19B79236E427FE1027A46E0F1FDE1A68F45E36D4299E8DBFC690BB470457A854B8A86F9A235E8257F66A1DB0A704A39A78652E5928A95FB4C1889DAD77CCD4BDF90A6D330D0E6067C3B319BE5EFE2D4DD1B562413394A983DF3B4F989F74D0B3EC7D8A11865F3AC62F9D84932886D24FE3BF135E66D7F0A27D00EC010F88E0951A2B67F0BE92BAEE3687DCEF1AB008CE6A289560E90D41BE20C1E9E83C07D04F073938EC45416626FB219C7CE32DD9ACDEE512CD1E2A64B48B2846D97D3F57355BC68A8BB28336BCE8C1C33267BAF2EBA5CF9623FC4EAA61AC506148214DA6AAC02C8CE3441C8564260F3374E4461799C5FFB6A67CF34F7C1CACA39591D0ED86F6B1B5BA45ABBF6A4488E669B281B5058F92C89023FB0C482E0B245052B45A63519CB6F30486343C8BDA9F47651344F15C876AB8CB40FD8E694C24CE5318773D6BB148A67F9EF7722A9F4E1833CEFCE62C4ACC89622AFF50CAB1101906402B2F91BA0C4EF9BB59FE5F49C65B2F993F999C212ACC148CF04AAD8D5910DEF892441A3F91D5289D0F2F5166506E6EC068F2042E69746BF2C20F0463BC40F0A4DF6AFB6577666E4B60E5DBAB251340BDE082420A0BEBA2D3BEED60D17EC30C7DE6304359ADDA83E9E86A9A5DFAFC8AD72256209A8C6E34DD0907BD6BABD698F7748A908534FB2A986BA65B1DEF141CB0BFFE420545A293BD648836D22C4B072EB60FE3C1E4524540495B5D3BE99E170CFE6C3CA4C3B72252A0D4127A3BCB1DB74818BD259F0293F161FCB8CDF54D957F7AFF6118452CAA20F38DF881FE306C2E918BBCF4D6E4776658BC27FBA1C88DFD1FDD80D72A4FEEFEC07F78F76FAF76A3B9803C6FB8BD0CB2588D1766F4A930D9DCFDA7E1639FA0ED56E5D7742F6F55CE9432C57685DB5B7199BDC12756C9BEA29E22A6F6FA3B5F8BA2B301FB3D9E129014B757F21155079B3FF1C5478BFD9E8123B9565F9AFCE4C0E75C7C4E19AFD397F2FD5F9CC2A3FBC7447AF54E6BA8051A0CF5F35DDE7E4FA4238909B202C9134D36CD7F5AD05EF5D671854F39030784B7531B757E8F9F4F710A4E714E2A97AEAADD6FE9A1DEE57626BB2A360383D014FDC273C11A18DC52A59D7D0E7C756D6D48F1394E25A5CE5025222471AAE0AB79A9667DE5CA3D97D11E2A8455A77ED842744C5CB5E3E810B543ABE67063F04E6BA5388C61B8D6FFF48971E7D16F1D519DF56279CE71768AA7EEA14B23A420FFF3761968279CEB896460ECBECBE5785E33AE248E1B309CA20B7F7E70AEEA065888A2C20088D0C686F7F566811FA6D4B0747786D5EA1F91AAF7901F6185EDB3E0F21C611C8E084BF7594C3AB0837429DE9ADAECD98EE324708DC1CDB1EF927F13463472253D413863F7E89DEE36AA8CB604CCA4ED03030551A1E448EEEA671C8FE8C7A9A88C3BC7E8F0F06FC9202FA988E04521FDB25ABC209D0A134B0D2A84032F503B1B0FC206077349A35AF71349AEC444427E398BB33F4DD668A709DC6704CBB40CC126683080FD9EBE5822333B72D71B4BC4E15F7A17634A5E414932DF52EE6EAAB1E2CF2119C0F4D11E8D38907F7B3307E655DB30087AA2901A4CC6EE4D15F72CDE62F429E2825F5B7C70572D98DA4ED88F56CC1DDEE36D09BCA15FE29ADD81EC74CD0F9DFC2AAD2CF50D71454AB4E04F3A8763E3EBD3F31FD22656A0A846925DBAFD0DDD107D9A86AB28D8E7F8D127CA642BCE5D010562B3F2D5F47014DAD1A88DAEDC54C3547560EFF5E764A20966B860273D35A686FEF539575B8898C3ED6984E0BBAA6FD5E8BA596CE548EB72CE5F7A7E53022CBF8BEA53EADC6EA1F4D4EAFDA59807B939E02E8417342CCDF07D00DA329B3FFFFEF94B61BDA2495816C551AAFFF946D2E3C0B6721584620FC264CC0293316411AB56EB337F613326C456F2D59318D45CE4C11B42A08F2644940EE91DB6B709E07DFF670EFFB7D6B5F74089B44DA284571AE0AB361E233A76A099DCDBE955CBBEF8CCE129A3CA380E8C45D3879C65DCFCCC928F0E4233B8B6BEB60C5EA34D691BFCBCE45E469510F3FE1C5A37C93AAB390B352790849E7B17A36B420E9C8AEA845EB671A2C9649264425B9F2A953114FA75B2161D9EC058132C4FBCE3587A24BD8C2671E2B8A1D29727C283A43B88D270FBD9A7978D9FE6EC869F4D9340321B6A283891010F801AB780927F7688B5FB73728CCF39291329C6B97A445587C0A1B1AF2EC8CD86CA83A912B6AC359F9B569988CDBBC22F5591F81FD1F97C205BADC0E62C390E8426C35AC602ADB498EFC1E8A589134349F2D901ABC7637793E2DBDB6A84803A6A5516ABF3BD2C4076BD44F7E8927D29F5D618DE1B5CCEC5A16C57D4DBF5741EAAC41008312B14000E27035FACF21B175075FDB9B0CAE9904FA41AE4F19320A1981B1D4D092F62F84D404AB8688D0A614D18AE93FEA9C5211B9BA81C573C4452A405771D7A88EAC32F7AD29EA64622EA20C9D9239D4A064651BFEBD64F9938961CFB26E832053F17FF9D6DD2F0F463E2BE1BB92BFACE323B15DD68927C4365A08798728B1326E43CD8496D30207B0527AD68E02CC16E56B8BCCD23DF0D7C5E3047220BF7ADDA607F4EC540F47A1FB0FF28883070E2CCA49A42D364646D826D34131B971378C26081B861AAE59EBB9B714FBBEC97F5A3E0622D02BF5704FFC48AF154DD5A952CF43830C8C9931F2F0DA2DE2F94140717D3C9B427889D2FC2394710F501E41FA5DDCC509391FA97784687A115574E60F723B9CC83A68280BE41B5014F02A3486C6F5F249C430C1E1DACF9A03C410174A386F6275CEA5E101D53E7025971E7226693DE2CD39395EFC763A9E52103F00E7F0CCF2C7EA45AB213D3F37608335403E6551D2D896621EA9678C68EC2395E86DD2011EF70915CD9D10AB88C52AF27FD0067630F7AE9BD0504951C9316504373B2A60F155EB1E49119480746B79B4D4A67A5BF39912C69411737D16BF3CF8BEB29CCCEE94D309979F2B757A07C440FA9F53BC9056ECBF6FECE40CC20AD9DFFB3CC0E16B0E4D7BB9389D610A965E9A351F03F7B2F35E141E1A67E75F1DE81A1C941A41D6605D0EA8F1D9D47E93D2F65ADF67D96EAFEA77342095E82BCCC81606908AA41404CC36B0F58FD0943ADA9571259C253236973C1BFA8F82A519276089219706E5092CD4A940EADDBA5FFCF52D699F30CF5CB4B1B6392D9C33D00CF632333A06EA1ABCDB2473F65835BE2D3E703DAB2E469CB78A0095561589EA0B114A6BEAC3B1EDEF9764E2A4159194E0D5968FBAD672332FFA3E6E3A82FCD08E8F7443230F2AF4104C3D8537E1FBC1057691037DE846EBB6426354B80BC635C61BF2B9411569BF5E339AE82276D400EC319A2E575A39CE1A662EC3581E428D4E74D285EC5E283FFDABEEC19A1130AF54691E5479D4BFDE9E5DDF4D1AED4A8BF69411F9F6720542BBEAB7870B8E1BE43361BE2C017AAD2C10915686E506E872523E088B80E0CB5AFCF340477AFE57A6FA2E827D05FDB3A4AF6A49388FC062D7F24FFBAF8AF61503124D79EF179D32CB6F717B854F11B401908C700B8E4A38337C3E76C33525A9356C31A70691496A56A0AC6338ADACA88AB590597E016D913CD21A91D07AFCCBFBC32C6BE8B19121EE42FF926B8F55106D15B7B6301E6B0E456EAB19366F057C9FAA8BBABE4250F4C418DDA374DE6988F843B7F71517B385A9A1CF02931A0D9DADFB417722E17910530EF488309474E6D9DDFF56A5DDFFA3859354FE34B93FFBFB1CD2F2E1B4C72CE4A762DEC2EA1B0CCEDD01D81B69DBB663DEEA0CCC04E0CA9017162A72F288BECBEDA8D2FE3B2C31859C3C4B7E06ACE1543A1A8277C08BA6E0A5EBB08E14CFB334FEB3AE84F99538DB994FFB3DDCFA5B7DE509FA096233A13EDFA21C59A49C3B33420E148701403C7FFA694CF5C5B45BBE6CE596E60414A6EDAA7662A4DC4B05165A87B8D0064114CD7836FBF0E8816843C48A8FCADBB6A7FB88801F98928A5E5B90C63DEC0EA0FA3395D402190BCAD7718FF534030A15444CF7658E15BFE22A447F3E23F7CD3B21642364F858C75968120262406989789AA6381C6C7535C2EF461B882A555A1BB43239564EBA5E7450722069495EAF1D3A396C45CA714A94B1C38E13E94E14249A8CBAEEDD0EB6A1F867221D94D164CF5D47DB5C759708AE19D193AC01ED5DD678BBEC27E908CE04E5F45B13648FEBCF66AD7181BE682028A9F3C137E962B292AE5A1D8A661085461D378100FFBD3737C4FB6B436A85B851F5F823A0BFA2F981E2C0379C626F2F813B3CA1708CD9D844A8044A917DB24EAD379D5A34E90E3546AC2D9121365D162CAF65B3DEEF566ECCDB449B1CB773057B21BE4F54E6036E1923FC486AAA69AF01CE1E29A3C89F78DF91A71F1145A92FB5C12BBB2D4E43210A60286263F56951307B13956F7BC1EFDEF3C8194B815692D4B71BB74DEC510CB396F1D903FB30BF8FA8D845915B74A537CEC2F5BD6CACC6E0896A10B7FDAA6D1412CF1B29A2669A3BFBED70CC9A6D3F8E782C5AF72DC54E3D1EA0F88BF2BE93E0EB4479DA07ECDC18885ED58D555F8BE63A483C6E20A875928081C31DC62E49E550D608A6EE22480FEBEC0A3DB64056A63C772DD0C14B1D2A8EDFC0D3A799B008B5D7C63D42D1848C06F43A974DBDB5334F237E6C21481E12170947B7CF9EA5E81D7400F79936FB292C1E1910F016AE190BC1514559E027FBD2C85DDB78A3230443DF8D1F35FCDC73FB189353361C7A4C819D3FFFA3CE11E6237664C8FBD8D0AF7AEC9C2C47D0DF15B588773520C10E0285F00299584CC25D5BD18DDE6DACD091C1CCB8318F830C6051D181AA29F3863B0859EBE1763192D55AC1F413982692F909485720BD4F9B15A9EA968A63EE3F4A698AC73B58112D644CC2E1EFE05CAB29911A95C103284C83290F67B83587BBE7556294C5225374477D7ECAF9AB5EC9460765E6A40DC75A84EC417263C50D22FE5583FF9626977B8826C06E160772D6B0506861A86633446A807183935350D91EEB5D37414CF3BA477AE353761B74E05BB6DC167E86FD20D1EBDCF5C7F6AE3C16116BF9CBB6B67BB564009B597CC2CA1B16B7B3B484C6B172A817AC71985522092AEC980B2FF393DEAB2A375CA8C894A68CFE3DDCF7CC0D468B43C6531A58723A8BB14E201B277155AE268D6A3D15933778611288CF4B0BF3A33C30C1A77AB39A8E6770125995651FA889FAB2B28C87DD556DD7260ACB83D691E2B9DA5880BCFBC2EB079B0D42F673A8064710EE9CAE5913E37500A2BF7FD4B6BB409F511117323CEF7EB39EF1BCD8096E4EE0F5605D58361BB74E6656935E7B075F389DC49BE4973B7C6EDB05DD051E120406EBE62FE8A1DB88A91CDF152BFD790E3AD2308C12B755 +remain = 65534 +max = 65535 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_256.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_256.rsp new file mode 100644 index 0000000000..5fb1e18f1c --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_256.rsp @@ -0,0 +1,14 @@ +# XMSS-SHA2_20_256 + +pk = 00000003A7FBDCA19FC30ADB13F35C92F71086094413263CD71A0570C9C2F250CBC2842704562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 0000000300000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94AA7FBDCA19FC30ADB13F35C92F71086094413263CD71A0570C9C2F250CBC2842704562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5832CE029A1A95FFCBD5C8B157282F7364E680C60B252C49483FCA03529693B074E0D2B1F6DFD6463B974DE6829A616F20C839B0D2B8BE5405623B5B722EF22F7A3BB78E91315F715D9DCDB0C8639CB8A90685BEE7969671789047083CACF24FBC4B601B1B23B2E79E42176B2438CB405BDF46369F4DE5F411B2ACD32BEE3065DF9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD09000000000001D5DA3370DA40FE4B2AA8D93A4C52E009ED16134083746A63365266ED868E33160A0000000000010EB7A75A56A1497F0FC1FE5B3F6B396014CC9357B7FE8A6D2BA1B553EE3518610B0000000000011B23B9B57C09E7B440346ACFAAB7028D8821AF52CA85D5CEEE66FA4E95B45CA40C0000000000016AC8FE7754C3CBB4F71F8514603EAE30A764437F404409A1283CFF4B7159C0F80D000000000001CC6FF52DE53BEBD4E1D3DD11D0BE5FFEB977CA63FF2ED1099705AD3D5BEB1AE90E0000000000019B6C3951BCA1748DC7B89630F962DEB3937A4F8D15BF5634741113C38D2699F10F000000000001F21F01A1F02A9D105C71E89A189791BDA7CFB7BC89003D2EEB2AC6E7DBC26814100000000000019CD3ED9E3D49C10FE36B3813045F452DD0B3CEB702EA9FD3DE2289FEA46C9E41110000000000010CD4EC639F5FA5159D505EFD1215E62E35B38AC9A8B36077EB263B10F5BB4B741200000000000111A178357024706621EF264E4A66422A6F5B9F4C24A35579CB17DC686277D05913000000000001000000000000000000000000000000000000000000000000000000000000000000000000 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 2820 +sm = 00000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA7010C534B0D4C6FFDF4DBFE00E72405EFE83BBCF19AA2030A8CB163808482B6376FFD2CB50DDA1EDFD708F002ABF07D0001C3357A70F6511884C4185790EECECCC578715C21A26FC1E7A951C54A30ABCDB7EC71AAD92F2662BC900F9E9A93054CF39B9A6E98D556765100FECE8CCAE704D7AE90AEABE735C2FF46DC9FB302D2A1F4C3C0901B0B16F96846F8196BA6E2E8BA4375B3F5FE010A02661EE3374C1B28A76A4A8879EF91C329714FFDF118CF5669BF7BD65CBDB738CF6A8636F20F399855E5BA4B0955661EA3FC882D9D64954405502E2BEF7D3063D36F993460D2557C7977DACE2D6D7D9A77DEB151610372F7DA0C73F7B2A737064A6C62DD0CF4B69F1CE4D9BAE3589B525734E92F3F8D4D2AD9091B6C82F7C0189D3780AD854BCF3CD62ECA5F998274C2E153FFF3CEB473D81B551AB5F85CA351B4BC225D7942733BC8DA6EEF78B8184B2E355CC338055DD2A26DD02B1A0740CD15F6CBA4EF429254DBCE0CC4F4B00DBFFBA622360B091DD6AA817423484ADF53F5D8A30E3D4164F539899DF207BA4E2C7B1A4A0BD8B5B9529F705C1C323AD93B7F67D735958A454CC7D4290DEE03A74DB1B3A62D2EC10EA3C3EF2DB3375893598133F36B5B8F2AD5929164FB8F12A3E984085401E73A96C5A0B7A661F6D9288910CCF1C1101E0BBB686FC03DC302429EA2768093BA3B43C542F272E93D15A190426830A92526E5251912FE8153DDA93C92A1195701DAB2D2A22C9F380DD4984645384692FF8721D549A4CC74ADF8A5C2BD5DE48F6A923D8FD37E36377639AD73D1C7AE721D0152DE0E73844FC867FC8C029E657271B738EFCC1A39C2A64EC5DCA96D89BAD4C407D4F0CB226B913ACD451E7C65BAFC90021E665C24A2EA208A16D92E9C27BC18B9D59B7FAA8FD4A12AD43A403062FC7003ECC756E3E26F8B1BA47801DAA46173063E37823CFA4B1481DF4C88093941CB014F54D73B5058ADD52B6A0638C8F3341DC13235F18FFADE0EA5601EE831BD587A8EDB72F96744AF8B08AFF190BA55D0B25D47F33F84F17D6C15B50AF1684C8F4044CA7BA2CC196C7F3CC9AC2603194A9A536347F33972E57BD89F4E3AB7977CD3220C0D5E54911F17007973BAEB9C8B3DBB95D1483FB4C281E8137940969814A5B6FE7D1057E1DCFB7AB61415E94AA4338F0635813AC5FC9767CAB6C9B71F63D372BA40AF511C7259875386539636DD45512165EB3E72F1046CBFF94254043D879CA0B64F7BD7AEC79F5F87C11DE3DE80756E9FA3DFCF5C9CEC2D80AD509A65AEF0E3E663B7F31BCA437311BA799D4C2ACC13818BDA90266F7A362B61CFDDE0523BEB8866B829512E9B625A90898DCA3DBA0BAD32BB3F2B1687014B418E277BEF2F73A6CFC6016578227EA1A56E5F7655C68B27E3B486B3D2D5EDAD5390DA570BEC6613D901E5D75A913978DF9002D8AF64A9B4E6BDB7388057A17624FC600F3031D016E61D17E3E6A9B2771E2CC466B2A17C425E4F21F65131B4005AF392C685BEAB2FF1E5E4E886E1454DB240AFA0319449B4F3DACFC2FAFF74844BF8128A3B77237211ED11362BA8A6F87C6D103A23A7D6628B57D137C5264CC2E627F24A3BAD50EA4F75C7BD8998709C01ED5ACFFF08919C609F8F74BF5303C281E4D8D1488EFB7FCBCF8AEC5C4B26330A6CF6E4D798C1FA4FC6DDFE7FBFCD3C4CCC352F28FFFB9301C08B0731F472F6CFDED99EFFBDCFF23AD4839258197D6706C3551375B3F7359C6A8403C9BA07CDAA348C82E896416D74BEB3BDC53DC8CBD2A281340B78F7635419636A3C38E9D5515CF8A035A439D322FAC7F9853AD29B44EAFA7AA9A4ED2471B0BC91B4E1FDB7E6A80056C0F264CD1E0837F2ECDB1EC864CF6565D6F9ECA34C9B961B278867E8ED627C1CA3F0E05A841B2EF96801D464F6EA1053BF96F6E69F495D45535AC3FD4411C27FF7DEE1A7BE429B3D9A386E40B99329DE24163911705BC3137F0C728AB5848532999315D616AE1EE474D3F1C1DD7BC7F282E6DA92731914758830B8AF74345719259AC8366C65C61697E08F06B61AAFB4C247C6FC8412F815114AC9C3D9172C1B5CF22867D870CE2534C0C2A163DD971EFB7226AF5B9BE4351DE6AAA45F27F9B2CB0831FB8C51B0C6412F36BA064FEA5ED935CD8FC498C92D651E2C9BB0A294D35E87BE8B94C03E5893DFAD17EB8A15E5B131E62A0924331F3888CD95D68D0541171EFE3389CBEC636344A6AB01468843A94F56FA7FC1806448C09DA99219B5B3FF5EEEC1397B66DA61A963FEAFD805408782D911B79206BE9A53D04EB1ADDF69988D97437FAFA9FE1D707144A2290523A7D25AC1BB6206AB824556519D2B909E4D04DE8D8D35A0398398CFD1A6A4D5B8B9BAC3A42A27B05E91DC07C8AE10BB4636D08A9D08F444A61A465254F464EBBA190A6B09EF04567EA727CF57713F381DDD9FA8D431BD19121BCE533E07068AB0500B15488F2F60DC3C2BFE4CBDBD849C873D2036743E7CBED5BFC1F8511489AED9E0CCC0FAD5D9F1805544D2A20F56AAD3E0058522538D7ABA7F4A83155F8567A89BB7E052994F9E491025A37F3229BA80485F6823B9A3781C1CC42488414DD491B2F80FD91E049E56AFB0D3823E66A6A3FCB1660641E4368990B3D05CFA937C51BE7692B36F007281321B5F317242030B2007DEFBA495E0499587494A9B6E4974C37F5C006A34FF102A23985FA9F660326DA39E41C65227E6F51D5EC56D93D19E1D3279F668A13A2B3599139B265111473D5F8F0B23E656D7E2729177C18213323818435F2951FAF7288F66F9B7B6ABBFC9617B0191CC9DA4EDE34F511E0849E7C27115FA6EB6C43172DC2FD4CB1AF4C27A4A6874419356CEE67CFA51989ECB77328F87F18629E63A6732C5BEBAB4DB4BEA3E19912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70D982818E4AA66E926983B45F64AA0172AEB48B28DD4994F24311F28B2577791EF712689DF5DE30ED5313C773311EC605B8E44C297ED4AAC95D3B1DAA8631F7786C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5832CE029A1A95FFCBD5C8B157282F7364E680C60B252C49483FCA03529693B074E0D2B1F6DFD6463B974DE6829A616F20C839B0D2B8BE5405623B5B722EF22F7A3BB78E91315F715D9DCDB0C8639CB8A90685BEE7969671789047083CACF24FBC4B601B1B23B2E79E42176B2438CB405BDF46369F4DE5F411B2ACD32BEE3065DF9 +remain = 1048574 +max = 1048575 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_512.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_512.rsp new file mode 100644 index 0000000000..92b345dd0e --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_512.rsp @@ -0,0 +1,14 @@ +# XMSS-SHA2_20_512 + +pk = 000000065711A97061C93B4FF7199D48104CC42415C4634EBA3647D8E51BB1ECB7D4C455418BDE977F20460E48826E531A7A59E7DA8746D7AD5D80CD059D8007C2E890304D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE +sk = 0000000600000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A4E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FDE028B6F5724BB039F3652AD98DF8CE6C97013210B84BBE81388C3D141D61957C5711A97061C93B4FF7199D48104CC42415C4634EBA3647D8E51BB1ECB7D4C455418BDE977F20460E48826E531A7A59E7DA8746D7AD5D80CD059D8007C2E890304D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA7662A4DC4B05165A87B8D0064114CD7836FBF0E8816843C48A8FCADBB6A7FB88801F98928A5E5B90C63DEC0EA0FA3395D402190BCAD7718FF534030A15444CF7658E15BFE22A447F3E23F7CD3B21642364F858C75968120262406989789AA6381C6C7535C2EF461B882A555A1BB43239564EBA5E7450722069495EAF1D3A396C45CA714A94B1C38E13E94E14249A8CBAEEDD0EB6A1F867221D94D164CF5D47DB5C759708AE19D193AC01ED5DD678BBEC27E908CE04E5F45B13648FEBCF66AD7181BE682028A9F3C137E962B292AE5A1D8A661085461D378100FFBD3737C4FB6B436A85B851F5F823A0BFA2F981E2C0379C626F2F813B3CA1708CD9D844A8044A917DB24EAD379D5A34E90E3546AC2D9121365D162CAF65B3DEEF566ECCDB449B1CB773057B21BE4F54E6036E1923FC486AAA69AF01CE1E29A3C89F78DF91A71F1145A92FB5C12BBB2D4E43210A60286263F56951307B13956F7BC1EFDEF3C8194B815692D4B71BB74DEC510CB396F1D903FB30BF8FA8D845915B74A537CEC2F5BD6CACC6E0896A10B7FDAA6D1412CF1B29A2669A3BFBED70CC9A6D3F8E782C5AF72DC54E3D1EA0F88BF2BE93E0EB4479DA07ECDC18885ED58D555F8BE63A483C6E20A875928081C31DC62E49E550D608A6EE22480FEBEC0A3DB64056A63C772DD0C14B1D2A8EDFC0D3A799B008B5D7C63D42D1848C06F43A974DBDB5334F237E6C21481E12170947B7CF9EA5E81D7400F79936FB292C1E1910F016AE190BC1514559E027FBD2C85DDB78A3230443DF8D1F35FCDC73FB189353361C7A4C819D3FFFA3CE11E6237664C8FBD8D0AF7AEC9C2C47D0DF15B588773520C10E0285F00299584CC25D5BD18DDE6DACD091C1CCB8318F830C6051D181AA29F3863B0859EBE1763192D55AC1F413982692F909485720BD4F9B15A9EA968A63EE3F4A698AC73B58112D644CC2E1EFE05CAB29911A95C103284C83290F67B83587BBE7556294C5225374477D7ECAF9AB5EC9460765E6A40DC75A84EC417263C50D22FE5583FF9626977B8826C06E160772D6B0506861A86633446A807183935350D91EEB5D37414CF3BA477AE353761B74E05BB6DC167E86FD20D1EBDCF5C7F6AE3C16116BF9CBB6B67BB564009B597CC2CA1B16B7B3B484C6B172A817AC71985522092AEC980B2FF393DEAB2A375CA8C894A68CFE3DDCF7CC0D468B43C6531A58723A8BB14E201B277155AE268D6A3D15933778611288CF4B0BF3A33C30C1A77AB39A8E6770125995651FA889FAB2B28C87DD556DD7260ACB83D691E2B9DA5880BCFBC2EB079B0D42F673A8064710EE9CAE5913E37500A2BF7FD4B6BB409F511117323CEF7EB39EF1BCD8096E4EE0F5605D58361BB74E6656935E7B075F389DC49BE4973B7C6EDB05DD051E120406EBE62FE8A1DB88A91CDF152BFD790E3AD2308C12B75581541C17666CCCA89933F0BAFD5A0D93CB983D087BF3D1D8F388D22F6B09BC3418FB7AAB26A5754CED0B1F20E1DC38A0426E818B22F34C296DD19DBEE2F1E048C65EA766F8B9EAF074792D83B2C35D363CCCBC4516C9F0FDAD4B07A3DC3C44A9D27368A57F7C52E75500763BAF2CE58C0B9520E1CF94B584D0D9223312ED434D305314718BBBF41BD80668F2D6ECD82327BBEE9FD960898BC7227727341B863F9664701B3F77A1E01155063FF685D613EA39DBD04F12F9E72C840A286A1DB44E63C1CB55527BF3238DBDEB31328477B9089683B1F07A3A0034660ED39487C43D1DB76757D3F0A1D0B52C26E6713D66CE20A818A113D19E5A312C5127507A3C410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B589FD94AB5C37762EFFA44AC2093812248300D072E964594FDE1E5EBC7987B59EC36D4C0C120E76872FB77366F2C5B18B86B9139DF28EF7D44E32FECC4C804F010000000000016B410B4BEEFE73CB8F4D4C3ABB7DF62F132C01D90F410AE51281E0C5172FC3762D01221D015C100F93020CD106AB5DC052522C419A0FD67AD1A5EE9D5FD62E180200000000000121D1E9B1C034C0E95BEA3582EBC57F8383D0F6D1DA068D3ADB5B2B6237AADEE9A89B9F772A990889B143707CDEFCD05608317F599099BCDD2EDCA4B7CF410EB403000000000001C23E183353CD7FB42309F34D450892A84D2E250627D82E72E4A582BFCA8BAD10D4F5A2CBC313BC02333F65E8FC8BAB87A19EDD304EC7F7F85AC8078CFA3ABEE7040000000000011E2BAE00E2D34A2B2CF6745FBEF9D552837C3DC63720847E7DE3094B58785B6043AC7DA8CCBB7CB127C7B0C7A974607349D30D61CD7F08BBE092A3F9C7BD0FBC05000000000001657D3C7D66C12770C0BB75D4F5214C4B194F841F23B240ED784A12295B734A173AE89D8EDD857516ABFACE192FED90D2CBF6254B4DF0CD8C0D3F7CE520B0FAA5060000000000014567D4BD416073A25CDF242C18DBEA42908A4D6F0F15266EFF60569D4C458758BFEC8027BDB07730ED08E3A23D0540D8B90A140E06A28CBB64891316084D93FF070000000000017B8C7C4EBC5F897F112AAAD0FE18AB8CE4360565BAECD1075FED846955A14048C88B6B5C1A065F92AF55BFCBB10C7C46B114C80E9A36CC3BE6A245F466351B7D080000000000011F81CA34F234A41958ACAC3BE7C53450FCCB7E4D785F18C94981FC721F4CFB851AB0550BEE14A4DDC57D2A9EA06065395660BF32D43B71FCE388DC6F3379591009000000000001FE9BB64389A416997D68A9C5451FF9E3E78396632F38598E5345173954CBFEC8673FBB2AF02559E05CD20C58416401806095E8E1C2857DDAB16D1EE0F3E190DA0A000000000001614A2C14DF18FC44145D5BF5D800B784E33E3A9CFF914651EC186AFED8DD7B7BE9DF850F296C864358A76F3746114A0E8C77DC4275625349967A30017CB236F00B000000000001F9DB099C3387CCED2252727351924A10457131B3BFFB25244647716F38397BB534828F09AE38D601A810D11DDD56B5EE1DA23E2FE2DD430E40465C7D6B2E0F9D0C00000000000105E33C911412FBDBB9E20A3ADC0B7252641A464D05EA7033F487C212AE41F3183BE15D981076DAB6BE2E3FD38B92902A67949DD0DA273D580B0F486C5A66B3E80D000000000001E66DB2720E5C55537B360D0F774F1CC73246C4145690C3EAB8367194A83269B7AB01804478CADEC9A748FA6B2BBF7F33D13C61CCC88F19A0BF16908E0B0BD12C0E0000000000015F9CF8DB14A3F181CEC637BA72FBE950458F42346F664729CFBBEEE0A492EB07BDD134095EB0CAB4FA91B361999C9BE0959B55087B34DB128EE3FD6C02D7E4FA0F000000000001045B70F509F59A21D1A0FD0A9F8005C66F7556733966737A4C549A1C0AD12610A16CCE4745E8352426D85C4E0AF11B546CA400B2996B322C29C2A698955FD3F910000000000001D2D4342E8FBEE48D2E8AA9E243D9DCB48B35AA0EE43D40CE90B89731870E68C17200FA64C7A187130A45439DCFE40F0458C394F8C491F2041C1BDEABD782BD2B110000000000010212C4441F454AFA1C1AC6665B123A752D82426D32EDF0E05020D303C645B0A0BB63DD21C34037AAB34EE80578496AEFEC17A3FAFC11CE84578D979D73201B0712000000000001CB1D49A4FBAC9CE0FBC7E45ED2DE9B6B0A55CC9753404E56FF1FF2AD8EB2BF64224ADDC0CFED6A8C93CE346D9A653F16C3560C18A078D30146DBFA378874F62D130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 9732 +sm = 000000006686539E267711CC53D8B185DE1BEA3A8484A81CDD6B6B0E46CD6568189E74C033347FA34BA7448CD4D56964F49F730BDE52ED29F39B1CAE52DBEDC90A09415613AFB9FFA4CA8FF0A1C2FE2CCDC30559D5B553C328CB7D274CF36CE9104C96584BAA8EB576112AC8ED1BC3C20B09B7985E5CA1956DD1C3DCDC22628B1F901162153A5F0C71B1159C1481EACB9BDB9EB4DED57C56BF48661F4775A35225DE9D2EE101EF5B13D4DC507EFBA53E65FB539793ED8C45E5FE4763F0CAC9A29C5E66851528A4BFD1D6DBA65C7F404041CC51F47969695388CBBC506DDA3E940F9137B1E47347870006F3FF7DD32743538EECE9616E083B98BF9BC4A12CABD07B8755D2FF35D87FA3535E4A71CC53671EBECE3F0873B101013D42484FBB91435D6F763FD9817383F1FC1DDB9D7C26D23BC278FF71B1B195699353E0645FE1366E41F5786254F1A42BCF162BEADC23571504F690F39AD1EAE858CE58DA432C62AB78CB8641B1C66EF57F7EF37F89B44838292B438697FE9BA3AC1E689C59771D7AEFBDC6E5902C14AE10F94B511BF3F258EE81D8086942B14FDFC7CFF87C4570E508E7CA7B80723F5A301E7D5B757FF97878807C0432A1B22A76696C5DE9AA94F4A1AA8F5E69FD57EEAC4828EE99DBE12234E48A253102FA3FE6298ED6FB7572BA4FCE73F55E90CBD9F6F0D111DAE055BE32913F0275722C5EF30C2A1E10D6D6A783C2AACE4B819F5F9B5940B6C56D2F81C7B3BDF64EF04C81DF8C57242836691287201D11D4986E783547912E7F6A1DF5013A440DF63C1DF428F8810E0D530E691AC07820BDC33A1971F5708A3E7A5035049DD4944B8295F801582C73A9CB00CC39D1E6081038A0F2B3ECB5C6AE9C4B13997320557FDE870FAF844F8A0D4BC43DC21A71E38F14ADCBA7F3E9288F3E2612D22B8D5249E91C3F01A1F977032B7463DFF8EF72327AAED145F179E94886D5FB90ACB9004C1411158CE2F663C14C9C6DC9EC143F048F00B7F0F0979098489058E3D6AF2BE145603B827EB8B76F310D28461B13C6958BDD6EA91274779E59A5CBB750BDD51C002E808093FEBBF4CFE94EC5A51685303054C88CE780A72CD3A41FF87C89FC0C0D19B5F14555B99B813EA0046FA9D421287C14472602EB5836875B43EAF674E37D971DC563A89399440960BC748B916D898728772B9F5878191B66D626705194D259D9E1F68BEEC1B9B8895C4245571D88C52268928B51529E0099A2D8E7D49A9F766E903238F35011D0FD47A1E81039EB665108E4C6C7B4C62058F09E406FA3474A1741AF851FAF7B23AC344D791E0C14C685CA29478975828AB1516842998ED710FE128F48FB5FB3A63C08155E232D0100CF0D50ECB21D9049F34764D8724DC4E45B70E456820666848D0303384E8461D36EA162296ED6EEDE9BD81379F7329347521E4E40DF1D7BC30E0A8E41C26531333ABA5FFF195127D0DB72CD0AF27CBABF5D058CBA7DACA16C469BE9040312B01372C0EFF86F9731D10414F293702EA83D0AFB09741471A25543A8D091793D9AB64F89827A659E3B3D515E1A7DFF6D9A1CB220D1D2351B6C724383C4B20F9131D1886FC3CAAE8A853FD29ECBB19780181ABD830CBBACFD53C98661883CC31887868910F3406E821BD391C401B02112D41C31535D4D767D7AE42DD72CE68D8857D66B1CDB42D3E89EB6BB9BEB9834B5391850743E2FB46C8AC0BE0F98E5FC081409A6714C353C36A5540E163F57AA0A57FE68E2AFA78F331AB752173F3921B49E17CA30FE44412A904930D1BF967E9BD4BEE04538B02EA3058D0BE461FFC2AEA9B91AADF42AA65DA4C547EAEA680F4E5E5E6D1956AE8081CAFF8BBDEC475447D7BD9A9E8078BE92CDAD1AE866B55B593FCDCBA9AD2CF989F833D15550971A2B1731FBEA4D5D953E9E699721BAA76F564C39EFA91B1DC10F78BD396643AC730C45519FA0247B58ED7A0A4FA11342EC4789348C4FB12CCA3608E22B7EE961E6C7461E30DB4CBC9BBA8A29D722B9AA021D162ECBCDC90AAE91438D78CA253CA4A1394CAAB5F60D363BF00BF738FE348117CD26DA9452E1E4DE630074D61C1489E5DB6070417D44FE30D08926DED0EDA454D7514A29BFD8754A4399E440DBEE6B78C0F4F6D0D6A8D1F51C7E0F7D506EE906FBEF6E6ED4D2E1DD0AE58D55698A6E6B717326F2E997BE7A0CB55BD4E3DD913EC26911B595BD6331590DA242751DBA012FEC296B5DDB01F9779F939512211DBDEFA51795892B669773CDCBBCBAB4969FCA853F3030D30935A08BB3FA4CBBD318889E9F2AEBD3E8DD9428522FF3734E77B3EF92D382809BB455BED3E95E520AA3E54B7B6F5776453E7F9F6D821DCAD970FD27D1583CE527F20E0237654130E185E50CF4D62A3034FF82F32FC67E60BA74E2E6AEE1C547F81A0C38FC23EC9B8F60FB49D998448BCF6A43A995B44BD169B93D688E52DD7B964A5022A1F3117C0D0A61EE2C1A3793262BF105EA52544456FCA11B4F0177AD2BB56F4A7A5EDF483D6C04DC69E9EF95E313B526BD2CA11FCD81149033684A733DCD232E2A280492770F6B264923F975B7DC8C8A5774EB2CE5EEECF7835FC6860E7AEB14EDC3E1CB2700B6160DEDE5DCA58855A70B308E98C5B2542A5CA6A7AF4E94C0A58E0C3CF905AAEC65CF04897BE10A426A359BAD9BC70B5B9401AB423C9159EBD60965674BE8A2B3A8B0DD37547B80E62840F75E4DE979B936E321E02F42EF615C780498C801DD99F0B361E0080313C3576FB79C88749DD8533886B110FCCFF387D0883035C0241C7F568D9666082D66FDE31DD16B8A1938CAE11FE763128D2C973574FA48C24E1C90A37CF221D830A9D1712DCD3ECA38D6EDA822EC3EA2FCD4ADE875CCB990076EBF4F224A82AD779C97E3B593DAD7CFD440D1008F122F0E4BB6A201E7E86258E90E5B2F212A2B348B9E1AF78622BE875D2293505CE6693D26BFBF0445B63D0BC1C25B24593B2B978E711C3EFF6B5688618CDC5EB5BB11A18D6488FC0C70F7B1DBDF325A4539216FDEB8E392B8C1034BA9B603EF6ED6473C8A53665C9D1A1E80B96EC50C9D5A20BA05EF423806458F7F9B9FFB0C407A2861DDD3AB3DCD110A34BBA2977C9630543A13A226CD2F66AFE92228D79D91AC8A8E64AE8481E63A3C0C2A97757C8ABDE5D993691ADB3C308698A6B2869C1012D60F6D82CC77243095B8EE6C3F38155C5CDB3C314B8A1F16553BA0F3AA85FD8611851C57E1AF1E0684F05883F772654825F16F8D27ABA3AD42EE7BA3369033B20A0BAC878286671A43373D0532B4FE562902FF31BAF65A90413A0234250A9C24358F1E8A18845E2B8BCEA3FCB2935D39C7B81551EA055339EB2BA7CFA2064CBE3911FA3216ED6842BC4656448871D9B70F73C74D347A6A78CDA23A0CEC7164B5CD5A176617435A1EBAF7A98E36CCA820B50F6A0FE07F09F4BE1C8E86C5C583B001A3BE7CEAA41994109A967D84FEE131B5ABBB38D730D79BB77A49376EA5A105C711CFBC0F7FE145BC3D2067C050A13AA92D7F0F1B312C8FCE42E4DE45706FA2481375188D3F10659514E97D5A5E1A54024CCC8F19654DA2B7E5CF571C13F525E39C117CB0E7C4DC5CD27B44263DDEADC59DDAE0EFC10BFFD525B0750E992D7EE6B47FF94D0C6B5ADE35DC9CC23A1B8D464DC765173947A8347AB27C679B5CE60B743AECCD58BBA4BDF44657EC8832E02188FDBF2B6D9D3B18ED3C27E503AA3BF2517DCAF9D6F937F34FA3C6BEB756C7DFD1BA21FD55F87C399349651BADE09B047F53932D36CAB6D9BCB2D991A3224602B857FAF27CDFC3B46400F0481AEBE3B8A744B973169CE5A06C78071821E8E644CD5B66573991C6C0390B2B553534DB4D0748FB63DA09112D58D75525D6F73C94BD93CE121BE6789102B7A65B60A4EACD5C6680A6195A3038EF74263D961B1A24FAD476D6697E4881E0F7B70AA830E2AD8B52954C3574A46D50AC6EBC5E14BA1FB2C986007CEF0068C809BCE684671411C783A766B7307675CA4D04B0DD86442B1744ED1B8EE018F83D9D68B4FCAECC66FDEE75EAC379E19D0DBED5C3473089EF153433ED2B558785E0413821C2D80E4EE91C2DBE5CE074B6FC405433A00EADDFBE023E8A4C4C221B36DABF183FAE588D0333871DF98F13D6C6ABFC73783BB250875C432335D094AFCD4375BC6337DEAD712E837050FB0C9ADFE917B176BED05D90333CC981DDB972D03A1235787233D8342DEFC761A8942302E07303C19CF338856596F0E7B57869F823161FA631F2424B8C32E2A05F45763DAADB4D6502FC794B617D6A6591FD7778BCBBE2AAE927812F0361953A835E716192A3C77C4FE7062D2210042D190514CAA2C62958ED7CF63321963DD1F310F0237C988B2CF0201223930C55CC0E4BC917410D50F6751E80684FE22F1B64C46F54197427616762D8E11E0B644A20A18CFD68FC2BC4F12E00D0945696909464CA8256486CC7FEA84603F8C612A7B0EB6FBCB1FFD250D3E0B78DC6B3CB5AB69D60C2E8EE5ED147A571322C4FF0B72EA8E0AF97B46A366AFAF27FAD33998C8B7C12083969AB0743EEBC91AFC80DC24534B3620EE07E0F2B062ABC74CD98DAE3CA6875E2F72D74D4B3DBA97A2B93D3D855598C89F13BE30E960F8D7EFD077C1CB5E7D89A19EFBECCA33657C639CF92F8EFB0312DC8A2E69620F4030885B002E6F48686DC28455A44B2453A89779EC8CC42641A1E8FB65D371C2C71AB4B54631F2F6F7B7C99E37B623D1BC55BD54576817B80D864BE46D2A2E802DAF1B0148D77F9CE21A3881C23DF956737D29FAE6E052D9AC14C5F6957B801552F2749A6FDEE111A2C5484610EFE230126A005D2BD1D759BB213F974B243797EE9A20713513FE4A32883C0D1D319FBDDE35C498700B0E8096271224D1EB627E3FDE3F54E2D566535C5D33F2485E686D4B56B0C674BC5D6EB60C81488344A32BFB02FF5A309FC45088769B98930C32B2A9F269EB83E3AA316C1A5DA65BFC5C28E26DD1CF6617F5D543319DE20054BE65EBF5E4A3C1A8E39498C519DBBEBE2974AE52CB322CA7647F07F615743B1FB9F8CB2354FF4A19406D59AC8615CE015A50ABB6F308B229FFE6D5FAFB71CC6F745131BA7A449B3476C7FE7B49EAE4CBD3230C2BA977BC68E6C13BB0035F79F364E480FB36B2BC032A2E3CB6B202674261F4D1911468E9C95B6BAA96FDE0EBE07EEB47C5BF9ADCFE3A276F79C84CFE48D3A5A9A2BFB656C8A9A87B76A602508018DFEC14EA398A05022011B056386BB8FB9F62AE55D7110889D53098A6E17DCB74EB2AB09AEB036A236473A939D5C3E3C42E7C54DAD4EBF48627C2A12BA56F6A9653B7BBB68A591C6B28F8E64681C3F925B21EC850B49EFAE3CC6FFF5CC5BB741FC4F76614D9746FFF59973214609723BE5D81F250291EC4340AB735D957B6315A88A54A1E34901740EE82FCD7B181F03708C1136DD681D1E75012CA308F1827001625E7E2DA5E183EF8D5EC42C6C158D567E8CD1C700CF8C77836D9C1FBBC57A1C24CE4DCDE060E084F27A6B6EA7CC0456807FDC54031FCB8B8829D749366D1603A5DEBE435B76AB7A47DC8F9DFBC4C594F668B17E2B91AA264B024165BABD302B3D5084A723DDD30192BCDE345F2C5016C2F9DA6407B5559728C4B00AD4A45803A84F74E8DDF421FA6D838B9097AEDB9E3AAA05841A22CB4FA5FA9CF5A69B9D592AA7FF2D9ED3B86B2F9F517480DE548575F0AF25B1A567E38891A9444E997942D12FBA7B901D1A8A66967EC85D539327194092B2EDC62631C56634C1FEAEEA62CD2F32310D41DED0D89B0CE73C6E973DAF6ED7306E2C06FF48D5F4AF9255F0A4E4378539EBFE6B40A987E4F2BB93BB3E2D4A5967C918D63FF56BD89FE3C91ED40F4969D351DAC55C03F5B5F6D77BB8ED9CD99CDA42B176351633FA4C06BDEADF1867B2DA7D68D5BD5F915EE4988A16C8472450A47EB217310E79327FDB829A5B2DC0878026BEE3989D15481FDD1527A6D9100A3711FE95DE06C769E78557653CC4F713FFC3F5E7FE129C80C30860EF8D5D7453E6AE14576AC95F1A18D6D116E4AA170E023653B391D7D13CB1463C6E6D861D3D35FCBB8218EE5B5ED0455E20FC7F87BF1A268DD767AE2B17E2AD3552D6A61722F7FB75D69168C09E62172A500C0B93377634E642D4F640330DE54AB18893DDE617236D9182534900361C2DCDA629BCF6FF71F8BA270DC68AA4A984A72F2A36CD3C63BD36662115B9AEB160DCE73AAA32A112761BB3378DA1DD28F6C4A5C39836BD0E4ED8A0091537190D10F84165906321759025675F7C19164B148F4C86ED0563E116F62ECDC327160DFB11BDBC39364268F96DB0221980B5510A38DBA62A587F6D80F4080ECF7819B5EC949B2856FD2AF0DE295274718D859D64FFB280C63546D27C98873505F49D23DA88DF5E3052769C28FDCD7AAB51122FF764AF782FF548DBB5E2FA136BC20167D03193146DD5711C0063C868376E114F8528159267E167FD17286319B743D488CD77F374B8A2FA29FE4C5E71E5D03D24016424B2BF10CBDD9495E7352F040A48F46FB33690DE20A30C0ACCCED872430F7A277B4278BC83939E90B07B4B548E4D541491EB8B997C17825EAFD7DA17D01DF34EA9AEF82FFB981BB743985F0FCD454D651421DCC7ADE9649559401CF7D7E8812642C1ABB88EE592A23D253F8CFB7B3F1001AB8A68DE52FAA65A44D75418DB889DE8D701580E2C7A9E96E5D00D7DFB65577EDE71019B3D2FBD83D275BD4E3AED01D19D40338F720CCEF2676243E67B125DDA3460A96FA4E19ADACD506BFBE751CD3F3E039473367EFBE4C6F88BA0A749DD9A6EB07C40CCF69D3560F08C7EA7AE2ADE605332EDE497369E08D04ECF303A30025C2973BADE39E4A5C391DE0619C2785A646956A908271FB7F9201515F8952B287E61509B3939CC97971D4DB0F146A2B6CEC952FE8E215BB4A4C4505ECECBFAB113AA354C3445CC9BB61CE42DF11EFD55AE81A115D073F7414119EEBFA05E73D43A2D8FCF1CEC1D7FD9F0D3A1AAC4E5945A1D8400340D7E8B3F1701DD57CBD4261AF00736BC254993A9A7516C849967BF35BCEBAD46ACD20EB2C4DBA97718DD21A269EB831E429CF863474CB5276EFEE181EB1AF88E6C1AB7B26C6205A8178F006AA0029F7E2D835D4959A0BA59348BE988805AC9585172CB1AC5749644900832A67D493F54E0D898E7606276073226B5FA8036437067D193C744C0115F5C71E345A48F96A4A7B10E58D79B9A0EA10C545DA202CDA1B4AF08A968B218E5C43AB295740FA5D36D9B611932B9E0682A1EE6D5DBE228FE90E9C7E169748261E1C566EC82308884DB143C3B5C73674360B0302F946C4B9D42654B52C36DC38235179AF6149A395787727F630E454C76CAB55DC551D0A84A679223D10C8EF900328582CDC82416A30F344F42A77E3DE415BB98C6E39622DB30F3EE02C62E405A5DA0DE9B07FE58A72B61B60011C752C01FCC1245DC3049691A145558AF755BDED22872431B0FFFBB7C2A0994B3D48AC1EAFF5EAB329675498C77ED7B9520EE3588A35A48319B7AE6566F002BEBF7B39BA6A194FFB695D092A26E35CC52A2106A391178F000C931B080577CF88BF1498BDFD153C8CD13C4431966F9F4AB5A2046D5D6BC3E1758C9CFAF8DA5AC283A1AEEEA5D9B3DA041653047A088F4D1AF809549AEA457D02FD4DEC195454F12E6386D28E54A26A4F0D180DC2C86D7E892E82E29DD66E252EE56EF1F0F9E5957642BABE1DFBCAE474EED94D756CB59DA77C4848F75A96C16C5F5FA4F162DF12295985B731655D9728699598D2DFAB4E66D9A4B2A8F8B6A20FA28A8B50F256FC68626BC83637BC9604E518DD6386CD4E2593D63AAA722269475FC42F22787FB75FF59280A452633564FD89CB9BAF7C03A59EB278D7E02B382FBE98F1326CA6CE1DF7A91C6A4791BEC4EE328A9DE2C83B771A939F7069C5E2A39AFB6F39AFF4AE266C4AAE3D59D99BA1E9242A33EC319CA09C58F278CFB8B394DD6336E16F2452E155263728BEC16B81117A4CF98935F50767374587E4B7C82606AFD0CC4D2589A6A725D4DEB5EAB7F385E02099801D4C35FC384D5DB22E9C1E42361C7D10E82FB6919E74D58671F5F80EF98A29C800051DC8733A31E7D0F7B5199B93BA4E8B86543C9BF6472DCF27DEF21D432FA95263F5415E91766A1A01350C69519E728F1EA767941BEE87370EE8CBB8FAD0361E45CDE8412F04754DF98B94BDF12E42B6870169358AF2B12A0C99DDACDB7BA6F6E5EE0D8D81425E363B1947ADA640ED116E397E51955ADC8943E5435DD39E109EFECD67D7857B9A90D5344ED690E74CB0E074D499381374345BE36FC21208808AD9AA817023BB0515305083295E88501AA64A55EED1CE2D9BF856B6E3F8B7246F796F81628E623FA38F935EB2ED6194A40AB1FB08C82F794CFE63D7B448D9A6AE1183DF1DAAAAE8F4C4B14AFD727E5267714E7C731446F9912A567AFF9CBCDADD513B09D6C10D8F509EC9E42CFCCD6723B66AE50E8343085BD970267BB98C3553BB0C94F12169E87485123493623FC4845CE4D048E0709CCB3186107127DF0B2344DBA35635DEF2C2667808BC835D534C17FA77403DBD6549A9BB1C209C98CCD745E552786A268CC3E9D1BD62A980E1627F030BEF0FFE7947419AA8F702EEE5FF8CCAE5DACFCDC8ECC89670BF8E6A0563AB65FE27E27A47D18D82CF8003332F59DF37976DDB719AB48035169C6AF53DD2EDFAFD2512CE3B73D53859455B456D756CBDBC3EA9E1E869EE96002CAA7EB6A7CA6B786652E3D4F796BD25A912E159DB9EB8DBA66FFD815C61406CE01E494D29B96CDC5E4D44D98F13BC42BB696FFC90BEAE60F325B178500898B2561AF414B06C1603DF1D485686A419C4BA076AF518BA6A9F1FA808C75800BBB85CB28124A46364495B8617AA0D089B1BF88C681E73E9A692178DCBFECECBBB429323ABF29CC39AE714620F2A44C766360D51A25271F419FFDE94B390CC7018DE603418EEBFC3A0F88277FB9001CB9217DB8E44175CCC3AB8F118BC90B870BC4D07E656F74984AAD630DC431888301214C77E5468B0377D87B80D9959FE15BCB075BA4B99C7E6B265CDC537223BBE9C17A5A67B4B02ED243AD935FA8C76CC9E287052AB1473FE17BC4BFF23788C3FDFA8FF286D1EDD9EA3DD9518AF14E4D44DF1521732D0025E70A8AF60C121E236047EBDC5A26B287CB844DB787FA5C7ABE6A06038C1B17F40B75335772ED71766511C2A23CB2A1D82313BCF0D5B852207248219D195CE87C6F4E0A9D7E1B35D7475BC5B0FB5F4ACE00838CEC43F4AE4A5B6C4C3AD49D6E83244265626747EE6ADAB13649E7FCFD9D572D0939B348FA5ADB0B2F9F2B90F0080F6A60473ED136BC0FB14DB1DAE2AD08EF52E2919EA92D6AAABD880EB0FB3700D6F53B7F0F01117AC44533815B47041EBCF2DB565C908AB57DE7F980B5A1C53B627D423395C168A4201FEE645CC4AF4455AFDBD4B234160B7040E51834BCE48272CDF08070EB738D7AEF2B8B5519BD005BA5140E230C2AE07A24C4FC0B22579FF144DAD576466D6CF76C2CF3C663F5E8E1F423C2F516954B18880963338260BF4DA12E7928CD6FB411F972C86929192624854B7BFE2115FDEFAFB79ED3C084E7969DBE364FF5E57D699B5B112B4DD357A120665841C35C3B9A53773A341BA942FF09979C2E9C9C01F6131784168814A10871B63F3BF9677DEFA6F559CD700DFC65B95F6592C0AE664FB9520FF7CEF970453BE1B2A86FA6DE1A445BEA10BEA53F01345D227D25F2C8C5271FB0446B8CD5B9505FC5528A96F05FE8601AA06BBA137F9CC5251550A1BA82FD6F8409102F9510878DB871D537C67788E5D4DEF101154318C52142BCE9C779696A70D710FC247E7C8BFF58B36ABDAE37EBFB1AE8D5A5E2BF466632ABD26A05EA4BCB0A5D93B3AA47AB700AD3942938B4BB272F55B6C36B46CE3C4C39AE24B775C8D4CF174B5B30057FEB10318B0FD88B576B3408B22B49224D6E438AC84FA0A6F34D0AFC0B75A9102CD5FFA0ADFA1ADFA11422C450ED66C55C3FD4D062F978EF277E5204F434FDCFD5B6AB953DEA57C7461A62F631BC72928B16CB3E906E166C0C1ADBE398D0186C6376090092C1F12ABA0452FAB0FDAB00962023CA033195870C5AC2800B0CAD8BEF1CCFB55137D3C5D3EEEA247FE6391BA4FAB13D7A55BD3EE5F92B8C79A6E9AB6C24F5BF992964D69C1DC6578D8E09EF9FB298FAD5BFCDB62BC2665F2ABFE6DDAA0A1BC5D8351AC1E7B83F7BE92AAFBA85D519B9F6196A4D3778E25A9AFBB2D0780F416F3B90E68BF08727B9956CAB6CAEBAAA12C2CD0D6A481EE770AD66ED443DFDFF76137A5EE278857AEB240E44068898CC4083FB758D173017EF9A6A58A21DF0E11ADEC122926F68B292DDC91A9F8DA849946B52E50D682ED08666B90EAB23BAF484DDCA47F051EDE5E1FC1C67A4421B40598075B764BB78BEA5824AE7C71364AFA6A73D9EAB7792671614749FB76FBD9585F333003BD5C18BE3B6BD291237C7E315E463E225D5DBE624D2665A5A81AED53432BA48EF2327F375212019F174AA2412DAE46F7E1BB4C2E002CC480522332ADA06504F1A8331EEB21718BD62A41DC79AACED15EB077F664851BB4823454F3FD0E1747556539FF3AE95EFC2CEFD22CEB477A7B475B5EE1C200F0425E774D702126A7DF653128B09A0677D4E2732E2F8D4AC9CB50C26CFAC734B17D210E994DF9E54F70946F0133B56B520A1E184CF9FA3CFD6E930729A8653A899DAE11EE1820ADA86DB0785079EB8B1726A0339E8D3153F989249A00E2BBDBA4C1A887D41ECF34FD5A7C217BF70B47A733B5DCECC55865DBCE89C4DBD665365674327F4197D6EA82E2BBAEC16EECEC6C193921499A3E5223332E9AEC043EE5180ADD4083EBA0C605A3A47E717E1DDAE6FDA44A762E7E676BF231AFE77C234D1C73B6F9B690C08FB67B34920E5115D8524D900923025F033880359B0FFB842647E589216BEDDD1BDAF5E76E73E1C2D80EA2FE7846490793EBF8108BBE66E70D534E5C49D8F1D06DEA168F39062E92CB996EF6BFF72D6AEF92FA97FE18C8ECB177277CF35B5D021DE16DAC6B4844DAEF9B2AD79ECDA0E95A6FCFCE4370F4C3706EA64C7DF8070D1513C499ABF8CC4881FEF756053DED9329AC96A534AE5E50F9B0F3844A96C5F6CEE9DEF4BA1B29608051FA384B3912F8602CA72BE17BBC5CAE71B6189F9E6F54506CF27EC4398E0312503071DFD5D5186571B24A980DC95A24ECC889E478712BBDDFE6059F0146B2E0C3D38BFDABB019D304395C9A38913E6443D4A1BC47F8B9FAF7438A1E6C21A1E6CDED75C75D3A285AF1468AD83870F16C6C95AB3585EF0B888469887358270EC3E39D75F6540E77BA2EC7C63F9435F4D91A718E706C41AC8BB41BFC2888AF84E7E3A6088087D669098AF90EA6D92E9BBBB37EC26C1C9A705B11C71A442D32ED65BE2D79FA73C2F99690A21A627891F2BE73403F0F7919CB63F96A2BAD0CF275511DE2A3AEE1C28E83386C2814911CD0BBD61608EF9D562B1F251DF188D2E40803E3A6863D6C00D67D8869165EEB55D977A6C31A70691496A56A0AC6338ADACA88AB590597E016D913CD21A91D07AFCCBFBC32C6BE8B19121EE42FF926B8F55106D15B7B6301E6B0E456EAB19366F057C9FAA8BBABE4250F4C418DDA374DE6988F843B7F71517B385A9A1CF02931A0D9DADFB417722E17910530EF488309474E6D9DDFF56A5DDFFA3859354FE34B93FFBFB2986795C3F5D858E00B8CD6D5C30330BD1A0283CD34F28ED1B4F4832AF142579299FA4CB3DF35540F247D9FF92B7E9A53BB8F72211627E71646A7545424C4A9D7A37A1D8F98574C14907FD23DA45F811CB5AABE618B3E1FED837A80106779773040FCC9D37EE5715DD26CFD151BBCC7BF045B8672EAB87EFC08A36ECBC52FC5BAA7662A4DC4B05165A87B8D0064114CD7836FBF0E8816843C48A8FCADBB6A7FB88801F98928A5E5B90C63DEC0EA0FA3395D402190BCAD7718FF534030A15444CF7658E15BFE22A447F3E23F7CD3B21642364F858C75968120262406989789AA6381C6C7535C2EF461B882A555A1BB43239564EBA5E7450722069495EAF1D3A396C45CA714A94B1C38E13E94E14249A8CBAEEDD0EB6A1F867221D94D164CF5D47DB5C759708AE19D193AC01ED5DD678BBEC27E908CE04E5F45B13648FEBCF66AD7181BE682028A9F3C137E962B292AE5A1D8A661085461D378100FFBD3737C4FB6B436A85B851F5F823A0BFA2F981E2C0379C626F2F813B3CA1708CD9D844A8044A917DB24EAD379D5A34E90E3546AC2D9121365D162CAF65B3DEEF566ECCDB449B1CB773057B21BE4F54E6036E1923FC486AAA69AF01CE1E29A3C89F78DF91A71F1145A92FB5C12BBB2D4E43210A60286263F56951307B13956F7BC1EFDEF3C8194B815692D4B71BB74DEC510CB396F1D903FB30BF8FA8D845915B74A537CEC2F5BD6CACC6E0896A10B7FDAA6D1412CF1B29A2669A3BFBED70CC9A6D3F8E782C5AF72DC54E3D1EA0F88BF2BE93E0EB4479DA07ECDC18885ED58D555F8BE63A483C6E20A875928081C31DC62E49E550D608A6EE22480FEBEC0A3DB64056A63C772DD0C14B1D2A8EDFC0D3A799B008B5D7C63D42D1848C06F43A974DBDB5334F237E6C21481E12170947B7CF9EA5E81D7400F79936FB292C1E1910F016AE190BC1514559E027FBD2C85DDB78A3230443DF8D1F35FCDC73FB189353361C7A4C819D3FFFA3CE11E6237664C8FBD8D0AF7AEC9C2C47D0DF15B588773520C10E0285F00299584CC25D5BD18DDE6DACD091C1CCB8318F830C6051D181AA29F3863B0859EBE1763192D55AC1F413982692F909485720BD4F9B15A9EA968A63EE3F4A698AC73B58112D644CC2E1EFE05CAB29911A95C103284C83290F67B83587BBE7556294C5225374477D7ECAF9AB5EC9460765E6A40DC75A84EC417263C50D22FE5583FF9626977B8826C06E160772D6B0506861A86633446A807183935350D91EEB5D37414CF3BA477AE353761B74E05BB6DC167E86FD20D1EBDCF5C7F6AE3C16116BF9CBB6B67BB564009B597CC2CA1B16B7B3B484C6B172A817AC71985522092AEC980B2FF393DEAB2A375CA8C894A68CFE3DDCF7CC0D468B43C6531A58723A8BB14E201B277155AE268D6A3D15933778611288CF4B0BF3A33C30C1A77AB39A8E6770125995651FA889FAB2B28C87DD556DD7260ACB83D691E2B9DA5880BCFBC2EB079B0D42F673A8064710EE9CAE5913E37500A2BF7FD4B6BB409F511117323CEF7EB39EF1BCD8096E4EE0F5605D58361BB74E6656935E7B075F389DC49BE4973B7C6EDB05DD051E120406EBE62FE8A1DB88A91CDF152BFD790E3AD2308C12B75581541C17666CCCA89933F0BAFD5A0D93CB983D087BF3D1D8F388D22F6B09BC3418FB7AAB26A5754CED0B1F20E1DC38A0426E818B22F34C296DD19DBEE2F1E048C65EA766F8B9EAF074792D83B2C35D363CCCBC4516C9F0FDAD4B07A3DC3C44A9D27368A57F7C52E75500763BAF2CE58C0B9520E1CF94B584D0D9223312ED434D305314718BBBF41BD80668F2D6ECD82327BBEE9FD960898BC7227727341B863F9664701B3F77A1E01155063FF685D613EA39DBD04F12F9E72C840A286A1DB44E63C1CB55527BF3238DBDEB31328477B9089683B1F07A3A0034660ED39487C43D1DB76757D3F0A1D0B52C26E6713D66CE20A818A113D19E5A312C5127507A3C41 +remain = 1048574 +max = 1048575 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_256.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_256.rsp new file mode 100644 index 0000000000..c684aa186f --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_256.rsp @@ -0,0 +1,14 @@ +# XMSS-SHAKE_10_256 + +pk = 000000077B563C8B187847A60569B3A0CD3049A5DF6CA3EA3B446D75F99F8D37B940AA9604562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 0000000700000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A7B563C8B187847A60569B3A0CD3049A5DF6CA3EA3B446D75F99F8D37B940AA9604562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D93309000000000001000000000000000000000000000000000000000000000000000000000000000000000000 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 2500 +sm = 000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E651324F8D245291EFF735334671EFFD85F3A823D972D2D49DF408A2AE09590B24CB219D4BA4FD030544953AE56AB3CC426D1E89F8567A33D4ED495164A01434E617E01CF73FA1022A8E19ECD580802F2A359A6BE287236C711249E8CFD26E81E0D962E4E6007A684AF87B096B9034966949F56D02660E2B7279214CEB93E62073BCA7A334E8928210CE101C948DE9105A5FE3B87AB9741B4B4185D7EE42AFA3055430682E22AC918051D97466B12D2FC559413DEFAAFC677C8351565ACC58D481259F0F41EE4C3DA4365AE4ED4094E4B7406AB6963FA3883037750A6ACBD864F56826811C4DD77FD89B17FB35E2EA7C907A056063335AE03884B54E791EFC5B68DCFFA47AB17563DEFAC3A51C0C7E96367FD2A5BDB6420DB2F8E1FA8A1E04E02B5033836AC23BCDF359C659C13E9237867828AF0F173B3F932629847BAA0FF1658833035CF78699FC249FF331272A068D55590E7451D2F1C118B8DFE554FEC7D2B2E0B494B145F9033007E7EFF53151299DA3E5C48DD1F35C37DE0D832D55AED0433B04149A965F5EF8A804F0E6EA4239ABF28A694648719C1A4A315A4EE054B04CAE408D5436A081A948E75B7EF5914E0DD9A9D01018918CBF37A224824D0B936F9E659D7C7663EB4B63FABA90515F2700301544682570E6B3EF16C59082F949173C93ADEC1E111F387845B826C3523FC184B5F1D1D830191C88D1F9F3C3A81337495F73F2B992EDD1E9D930F098492BDF4DE0C16A604D71CA275176A5C2148B151E1961C11F7D8CCCE4F08E9BADDA88E17BF2DB02A6D1E1D2827021DB46592168223ED5CE3170858485437C132229DB3823CF7D727E8DDC6B6BF00983947D02DA1D6A0C82EF62F0B0A9F1FBC427D200F636E66DE934401583B67DB03BB8492A21BE921E1C2CC0ECBA29139E304A0BDF7123670D3FF614F1F0E22C7C8E161E91E90EBDABC3BDA8347463B052E4E97DBA22481C772462763AA738E424431E22FC0B8441A43735869308C228166FE2041FE782E25EC9ED80EC9994EA098FDB0782856925994C9E8FDF09EC353677934D465C348E01FEC000C30ADC8B85F0C19844A4E6B4D0E8F6B2040D9CCF85DA7C9522BD571EFF09D5B1561225886FFCD6B788E6A6267ACECD693E42C90E4730F2EBCF73204F7DBE114540F4AD0C2CAAC6D0565C6DCE9F7F1C5542DD0F7016BD1C976AC68FC2C45E702D9D428999F9041C8CD89B70FA2A90286D7A5F6EB267C45893AB7A9C0E9F75889E64F9A24ACF8963268ACA48B903DA92B5D86FA1C5E8DA5C12CD2C030F11A8F670E028AC1E3925B5D70E7EF6E258B5B1C7F64D767098FA20C976F74949B4BD4792A13DE3CDBAB345B43C1900F6F63F45D02F6A576D8E6234AF7631821A82C758CB0FE7A920EB689186D83BC6D34D4FA579D07F899DE605C6B6C53BB3EB5DBDDA07747CD49164C54A9BF8A9F6A9548A58E119830C4A1C28BDAFB0F94E7539D5F73E2043018B8FCEB218AD24D0B5AF139DE4BF0968A70B206EDA0FF3324096BDCB13A3DA1C550639C0606527E494572744D779FACB63A81CBFD2C18FDDF4883B35F19FAF86B48D5CD2DD9177065D7380AFB479A59205262C98995C8EC3B26E648E01252E75EE3278581B71C84A6F9F49B0EDFFDCE1DBC2AE84F1FD849E3E1D049EDA6A5EEFC0E5EFB68199B40274DBE381ABC0C1BB6336975F1CB08EA7A875241CB911B9853025F7CF48F75D4FA0ECC39C94887E71903538BE9408E8DD1AF757ABC63097ED308C7F0EDF784DBDCE94CF1B52C96E524E7179C8ACBBCFCAB586CE6CDAC4FD71787904D4D19A3C95963CC8A0B0F4073965CD5FEBC875F971ECD647F269A6365491CFB0E6F0908347A384EFBE009EE5ACD512C88DC34BB54340BC9B1C0CCA389E8BDE6AF14B3DC4672459266931B482AAAC2ACBB4542B22D3D25E2E279700167CD7AF03866E60B41CDBCDFFF1216F45CE0741C53B57059C2F55F8D2529C6B0E760FA3BB04A38153913A2A372B5CEC76D57348A81842EC2A2BA6D8D23C976F3CB9F3D349A8448C04962D6B064AB2B8D48AD48F1B221B7BBD9612FBD83C101B7047D793FBD30262FDB21DA3610060FCCE410A86D46779A61C7122F5BA45A814E46224EB6D5969EB9FEE6EDCEEED25B698E4E83CA574A8AC2896FBE20E91DE3BC759FB39137FE7C26A9201D40914CB387223C9F8937FE6F5503D7C207C9330CEF1A170F355484FB1A3BEEE3253FB58D7B532C7885549593BF2984B3D6FCC2E70105FC34A1CD9A85B5D7EEB3A3EB4F07F2E7E0E649042A947B4F9D9A5149F0D57913A7EFE5265E853091C4EB95FCB9EEC69656DBF47ACD54F0045644E95BC75168F17C797F9E54C42DA5ED4E72F3CBDC54D20135C64F39492E2F2F577EB888047FF44CC2528BDCF0F387DC53F045523D40423CD4BA0626CF907312F5314FD59BF41A47F18186B517A59C7B9BD07FFF6433631AC5C062DDFE499E0C22DC5E3A10AB8D8D0C5D9A098331052A74A72C2599419F61A78459B45C7976E43E96BDC2EBA3AE45FFFC8766D70CAB36512C02951240FD5ACE420AB2C8CA931E1113F541C8439AADB13BBD01D08553C645E1E8AD6AC0BDFC48F9179909E135B6055FA9CBA44BA072D2A538BE604D931A5E3273F4F5BEC1CAB03D56A297B5EB5AF99C83F60C70873CB17A1ABB1665B6D7DAB0DB36359457BE473FBD9078313419BD89B3B947A46C2FED48F0CBF057F179016B6DA9B9ABFCC164E97B4E56278799D669385C5F0EE1BC47C9DF611F3C69CD4BA07AECE7C31D5EFA0A3D8FFC137CAE208E806DCABE99584F7EE28086E4A338CE9B8073DAE5D30A9571B807D43788E72A7A499DA5589B7C5BF91173A9A93A386048112071548CF0A71C9991DBB3A11D93483E3716D9A8BAAF62BC5BB58B991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EA6E323ED6E8A520C761F371CF760445A3E865E4B2524DEC48F47386A1E6CE5561FCD200F736E4CCC848CF9D69404EE753B6CA35671A40AA2B667270FF670DCE5AF0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD +remain = 1022 +max = 1023 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_512.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_512.rsp new file mode 100644 index 0000000000..8cb2fae6cf --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_512.rsp @@ -0,0 +1,14 @@ +# XMSS-SHAKE_10_512 + +pk = 0000000A28C42CBBFDE2F32EC67C1630DF460F62D15643A6B5FD3A53D78B5A0011F6621D645A874D43300F9F334AB1D6DB08EEE382C34931E9EBEDF37ADAA8A57A37AA404D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE +sk = 0000000A00000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A4E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FDE028B6F5724BB039F3652AD98DF8CE6C97013210B84BBE81388C3D141D61957C28C42CBBFDE2F32EC67C1630DF460F62D15643A6B5FD3A53D78B5A0011F6621D645A874D43300F9F334AB1D6DB08EEE382C34931E9EBEDF37ADAA8A57A37AA404D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002AFCF3BD5578FC5A469B5EE30687A6686B9CF04E9AA88815B89EE6F2D170BF84B0BF845A75B2C303B3968643511D4AB568552F4FF6C0243725F291341AAF654E72DD805C798FCD5214B14616E7AC9F3A4EA6C211B319FC9009536A1772156E62E666788121874F472FA5CAB32BA174FD0B2218F50A3BE7BDF448263F84CE6184306BDB40D6AC6EEEB7A009144D47CFE5121C5F44044D10B0776B575F883AA5CD63B5A577409851707816E4CBFBB13B047D3902D0C7916E4C9598BDADB732E82166F10149695106C8A9F3C0D2CF4349B59CC5A66177FC51A7B1098F6D30FFD8A5D016AD38097C062E0DA6BA3EB4C8FF851503B97E7A276E026DC8D92C68F979D53F9157695FC63A97A9F58D8F92140217D196A9778CD52A9074348743BCCD068B5DF2D5B76943651822D37F217E71EA6763CED121444AA3570A5880DCF44CE21FF035E8EA8107430E6116C10485E4DC7792D04A9B9717932D621B572F42221F1BAC60D3B65D93007913BB100E8658968B0CA77C533F20B9396BE2A7DB9B233028465E54648E3329BA2820ACF6CF00D46BA0CFD045C20C6BA992AEE34F57E9C84ACA1E95C45E9EC6D0BF500A7F7E6626D5777DC6AEDB370A4B1EB82BF4CD0F63DED9A4CCA567FCACDA440EC29CC67A926059152AD7BDB3F3EB06813BFDD8314C365E490C41C6FD4A6173A13F4C4A4E517037315D0EF14428275919CC61AD393BE23333F7D8A93C59DF7FBD4DFA8235AFE88803BDD881CB8E591A721E917CE44103EE38CD499655B666AC3536A1DE850F3FCA9C393454D9BD6F0C75B11822FF23EB22DBA69B08D3F4E92B8ECFE9BE9432A8B445A5BEE8757C7C53DD96FB2058A5370EFC4368FD6B5FC124FA0B9366074719377A0C533415161E29C71D5AA85356B90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016A30B3920D43D47945F47566B618719C38844032986568606F2DCFBD7104EEAC5436CCD86E9677E05985FA63C1B6D3E642D0F145B3FF637B96F2AFBEADED75F30100000000000197C186BD25DEEE5DC2CE5B760508549B1EFB2F3E0A34047232BDCCA39B144EAE820DB1F2D3C3159D012D7CAD7AAB1C44E15F53F4B1166E23DB8AA23ADA9E23AE02000000000001C5A2B2230C54CCBDFB5F42AD8805628B6B3D4723AB84E514035694195F2FB7E716F21EE8845170F30D1BEF79ED4468F2A45A72853F2D8F601973595098010E1D03000000000001C9E730A265A6F2DDC4B0F420CEC9C7AC976ADE4FDD5CEA3B6D5445AA2562772F76635C514BC81DA00E36681EDFEAFEBF29B1C3078AFEBAE3956D74AAF351E35904000000000001B661B82380E38D5CC77679867BB8FC1C94E77006AD05DE9576A7BD210641D25D011A056637775E72395B7643018E0BA023747219D875DBA848A58E0F9D7FD2DA050000000000019F3A31924919E8711F88BC45477356D330ACF65BDA612F6AC681F64C24FD70A6AF08B3FBB6136E4AF05B38A9205ACA4A2773D100FF79057CE6EF6C3F82AA9DEA06000000000001EDF9A31569FF07104E7B2FDF78D2CFC2FB28903D720F4D2ED95AB35DEB5EE579384ABCDC10CCE008B5BF753154B78207E452D4AF2B5646C42B89EBDDFA02570107000000000001BA911C4438781B45414444B18E3EEB1F0E57D33FB8F1BFB5DF1DC85D88A29371496D214B1042FADF9F17DFAC6215231DECB7D4ED1ADE6272BA7933403D3BADA608000000000001D85DF2FBED8348BA8E34D08202B5F944A00F91F1CC1F50C50D2460DFF1CFF490D84B84A1FDCA7A5E1760FF2E3A392D3F4ABB78116DDA6CAD29E694F9A4691E3B090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 9092 +sm = 00000000BAA7550F0E617123968A7F276A4E50664475EB64F4E5DC6805ACFE998B45C1E0EF24208EC4F8C326F4E4D4B36902314578DB3668398F8D67F573F98468AC125AF0437077A8CDD3F05F6FB65D3C9AA15540627956048C55BEF5EEDD31FF57A3B38C0C8B079A22FA8C4F910E43F1C71E52AA4F621B8D4E9EDAD6BED5AA7B55D96F5377E4D1C90EDCF0E9101E4EADEB45DF369CCE46AE87D9FB350FD6F71FD8A4A9CC7169BC7BE08AF160D9C4FF4E17133E98C694EF995B78898ED467ACB68D301AFBC96E96EA6B4C8B756FD955337C4C558D78FDF7853E9519930416E4CCC396C092F2480C530BFCBA340E102AA1FA9501B6C985C9C00FD8711A216850F91A5267A97E57A963C3BB42C86E365E37A258BAD6901D1F1AEC279CE2F14E9E3CA316DE8DA0B086DB8102A746FC5C3EA9C99BAA79F74F7463F047DD6878FEA751585B40EEED6A775CCF99DA0882EA094FE37B03BF42D843B2E58EDD709D0B7157952189D6E05DCF84D7A98E006FEB4A4746BBFD556FA25DC5CE32026F4D42CAEE72DCEFCD6E085205B104F30EBBCE03D9379CE23E884EDCB5844D875098A851A999B3C01EBD13F4EE2C95ABE76E4658ADE75DE9E73F3F531DBFDF366773B69A422916B9E3B033E015454FA5A31DC03124ED69C91FA12B18C028EB56FF8025D46272390E2CC84274FFFBC61E60055D6BEBB1D24D0482C00A7240A1FA86C3B28CA8B25848B109CA18B5ED836ADE7C00DAA6B65C5109ACA7CED72AFF32B9DC99D1542F41C2726028EBC437EE5C8E3EE2326E46546C36C8F1E3B85A946A7790C59D4547DC156441C09982CB02EA2B28D887A0345D2B62A5C2CECCC3C4083C35E47DBC096D2327AE64DC84C822D511650FFA8155619193E70B2B285E98516A5815550C699FFB11384225CA719CB1AFA38992E7315CEB3BD02ECCB6BE6A1FF8D0FC74B2BAEFC196D6D1D839F16BE25EF9C595BFF82613857E6C9DD1707ECA4BFA3790367CAD1D28A49ABF2281522FE1D9319DC6A73EA986345B69D82027777002B40EC9BB896570BE4B1E74DE3016325C72C876A9D93C834C936DF976F78F33D9407D4A5CE48D5A318F39B968154700FBD33EE81C800C09B7521098E565766EC58FD6F4DDC0E0D11BBC4AE0F8C7CA5B75C3D9A3A11429120BB71A44DCA86DCAE5D9C67C1A1189587D6753B7A60679E76A6BF91AEC1A1EB2FF181DC1BB11DD597E55F3CD9D90811B3F6FDCB01B351BA04F56B749C356AFB5656B4329036B44C961EA89F3E47F5A33EBBE7E3EA6140147518E42867D2B820117E6F7BC5D685623B4557D03BF5FEE5914FA7B01D34E14B398AB4152CE9A622851DD8C4009EBB1002B88C5AD6B75B35EDB4043AFC721310C9B3B69E30EC11597B14862B8A3AB7240FFCD4444592207371036AD8A221773700BCB0A643D295C56BAC055CA672FB8F9BB7C93A62A46646A59D1A8ED7268DE772A86C557C5CCE6C59C5449069A2DABFBBBBDF7F84C221BE0973847615C4A5C770264B54F110D2FB213FD8D93C19418666CEF1FA23097234B4DFB4F8CBC84610E6D1E65C654046AD37AF98F29EBBCC67B2A3D68BFA0F1541DC569F3B755BAD59BE5A6BA5AA01E674EE71E759A8CFBA7A139D5809B3EC21C25AF2F153E8FBF4D0051B455429C81B226A21F3F4DBF46E08143B20DE9CBF9D6DB13D5C0F51C9707565ABDF0666923B99E8D488D8F35FA68D02AADBF7515566B4A2E1F80A509BCB19556DCC4DC4849A33A16D12DF9C3C686FAEE401EDFD7625AB1EA6E122CAC4755FBCB1BEDD4627A60AF9396C950F9A72FDC7337066C140AF7F26A36F27D1840E4A93FA77DE018E1B1DE1F08319F6AC6FBC4146A9663E83B2427AD4920BC3AE2AA7077EB1D2A110201928A68FBF341E11BADB18CDF00B6C24FBDCCA114E870EE6272A5F186263C7E5AEA1EFE28ED7ABFFF79B369BEBC70A98F62C8F8734BB6D068FB2051CDF4DED516260F1EF5CE952529DDA4DB8EA91AEBBBD8BDE4AA50A2CF7CD1A6DD8C0314794CD5C5FCE66734368FE141CA7D4781445B16C2D11CE41AF9AAFAB28E5A8E067FA8224D487C792EA08E406A6AD7DEDA72DCDE3AACB4ED3F7E987C750A437E4315F7CEC44A5C6556FE705C289F2BAFB0B99F61E05E7D4D88448E69C9CD8D6EAC8A2E4FBFE862F98C78AA5B242E936F2711D3E733903E6AEB012E0E27F6A7C82627D8B8E82F371418B5810ABEE5ABC94F8D082C7F3301AA3C2C4E794BBFB5AF1144292876D83BE465B4BD50E677D7A0E2E58C02525AF4213BEA0FEB8749FC24D827E7EC6071C77BDA458414AA7A7C8DBDC876734BA2FD13137B55097D940F04B04A39AD0AB325A77A358A7E574C2D64E0AC794E13ABD793C43A7F561EDA57110C63D5914AF56EB4009FC4ED230171BBB7E8732A79E3E417C235DEFC0E67E2A233B8438EA0127F6B69605E557E7DAA8F63FB3D4BDEB9DB92A0AA5014C6D7DE78C198D4AAC70C407D913C414EE858795A40D73321EC677E002A0ED64E28831C61D124CC7BDDF561D3486155286432CBCBA1024CA40204016C95DCC76639423EC073F74D448D0319EC5EDFC78EA4BB3E54322124816F87C95C17497536F10E88BA7805B566A4CFD1650525D00278AC57DAA1840D81128754DFF3E18F558F0A1A64511A02E9B48996E0EA33A994D4B6BE0D16FEB008FCA38129221A016BA24D49EC85117D771C55B145A17607676C2879740ED02395C8494C515BD27A92CCDB65479EB8A2F2D8FE303AAE2050BE07CE0FDF0DBF8C14D193676960FF278BB421D184DEA70E3ABCB6655A05347FE032DDD578F14DA40F036A8A5CADDDE1DC293925F7851643CDC02BB7A12DDFFD20A50B50904E566893F127A01089FFDADA35B6ACA4EB4D175D4645F9478C6A8DBF03AAE51AD153CC4EA6A6AD03D60915D838545A168F8191E2AD373EC5003A969FD87908B2ACDA7D1E65944A9D6A125AF9BDF078209BDDAF31634204F077F372AAB28C37E81E125484288DF6799EB714B8CA9E137BF722E2B4C5399991AC63336E7EE9E787E0F14438834BB9E5159700AA990A68730B289513DDE3FA5C824356674C3D1C08207376582695CAA359E3E888891A7B84294A2E6E99D311FBEC1F596B69080C0FEE7831E72C15FD534954B8590D68CD8A28FD20AE0CA8AE24CF2C955A09FBEDD94C5EC08CA801FAE3AF107B13352A0AE0E2E3E11BE3BF96C0D07F7FAEF067F7507F892456B3D3EC4B58873F6C83554175954E8A4FD2989F769F0E0D0ABE1926474CDEAA1E573D10FDBDAA4E588E5FE59822834B0B629825213DD022085ADCAD4A28F447CCB257E1D969B66E6F403F8509C6B94725ADCADE52ED635DC9B9E1A42B11052D69F4B131B660CD0917974902870FDE186BDF628B61856C9CBE1D04D2E80A91500E9CD68095E711F125EFE9E32D2AE1C91B1A0136C0F5422C83421D97470CA298B6C9FE37A5148F5B224496653A2B36423AAB5837AF52A131B2CB89E875FBB99D2E032D1389074FB37311A15EC81464BED81B4AC47047E462734B5FD2D192D539A4BBD39DC8524EABA99BB69925AF7E2E2B3FD9B520FD1806F90533FFDE3784390214ACBA48E89657BD5246A6B5F626C45574837A8E1691A539F978FCAE23E29D31ACBCAD633961BC741153B77BD76B3A3D1D5D302C18F9DC589039EF815C57B27C925ADD9C52E5F3A6FC226766B3E165522B344F4ED2E9071854AAF991F02D2B1AA83F111A02B017E9033A48144C34E89D9EF73B1E598969870E1A41DA9F6A610616544CD5B981255A9542295A082CDD3A66CC07FB9F2D1BB4B7B8F64E129F69EEC185C218D299B827F1814C9D5D54280FB9110198029B95C565AAE7D6295616275FA799F71C790283D7B8AF5CE60416B584FED823A46EE48289F37B55EF27DC4E507AB04A907467A17C6959045595F260C9FC1D7A02B3F364E033CB1ECD9650441EBD6B50F0E44BBA7321D33BC39D9FCA19D3A0C0A4671EA68C09057FD6705A61EF6F924958881AFAFC13DAA5B3AE9876352F6DB0ED78AA7E1EB8A5C56B9D3FE6A808741B28200C381C08BA0890530633FDF515AB52544ECCB70B1530EB2B2E39AF49264BB4864436375AE62B8F9F8E675A70AF44252999A011BAECF423E511A8B6FA5E7FB0C467476520694B36AE5C0D475D3F526CB3668CF76973985D2536EFC73711740BD5C05FD3E3521002E2EDC65EDA06B81A5AACBB7EA5C3569BFFE89DCB32A3B3CF3F53061308AB5BD1AE1C9F4C999BA765ECFDC379A2E4FABE8E6D7514684A99E198A53B778E0BCD70AAE29AA52BD4F8EDAFF89D60E846EA0305DDC8D368314248917C2F0C5AD6B107374A674100776DFDF6D44BC179C305EE7C79E16AF07AAC4BF858FD677916EA65213B1987680E3507E6C976683CB9FBBE0A223F7B2AE55E9CBB1B1AE83D8971500AE7AEE000660C989F6A3979F74D75CD1621B0D5A8751189C380579671CEA39D0BDBA4F1A975E0956077D8599C60AAE9192963B563FD8C509B2B3423FCD52F974B89C109403AE80DB6D82E5FDB28D3D6B62850D6E4EA7B71B982632C4B9067A21D3F24DC18087A335325EC49F747003438F8F088EB80861F6C1D9446EA350450C52438EF91E4A61B41BD6E74D8516DE54F6C0F2572FAAFA731ED95A6BC399ACEF17419A263F692AAF04136E62B36BB271F3D949667BB84823B00A8E5B8700FC1795378146EDBBF022F938AB6663BC1367FB1F937BF6085115218C5A3CBE7D732D8D62D2BCF54B116B7763B4ADDB6144CCF34A8768C1AACF13E1894D84082CD242E3D0ED236EB8A7ED4E35C8E72D9CEE34F89963577D0D0CA9BE8985C339B429417D816EAA396CFCE3C1A40898FC6A3DE5736891F81FE5BFF5A7EC9DA88F5123CE5126BE7F0D705CD2BBBA5B97B0EED10272D0A7496D81EC612D585F21BC5C3237794CB9E83506BA93D96FBCB62AD010ECC406D3AFFE514AB8607A1F8D9454061D760D417E210B89015C1DBD1C090BFFC39BA761EEA223D93774E7AB86F2B03B4B2A25BBF56B413E734A0870100C4F0F05B429FFC0F93BC98C45EEEB806A6444ACD5C61E8E241E93C47F73F244D38A0EAB2EE9C1F296981261F179F9AEDAB136B73950F2BD1F6A033C7F33B7E5BD902C5E9183588065D20F6C8DC3648B35641F3A33A81A430161483838FB206EAA89841888B93AA8FF8F5A3BDB35737997120E2EE9FF2409B006020641B51D8D8DF939B04103D63C099B73F2D2878246D1802AF9CE44723AB19C87FC23CBF7BF89650441837B72A1C216F7D12F687F955DEEAC751232B3745DEC50BD3E4C2575C1D13FCAABE57539AAB71694D548A9CB6C8EE765C95FA453F1630A014456FE25639FCC61CDFFCA8C41032617561AD3425C82F360320C1A63E0EC239915E2881B58C183BA66DE53330BF665C885ED53E52F316A445F35C143B80D22A999E5BEB6482EA903A3F1F76AA262A20793A9A1B2727BE1131B53AB699D0AC5B2982B9A24C590F92DA2A257B1AC570ADBF5E396D41ACCDCEC44048E7CF77A8A480360099DAEA1185A2A21C80DAA70B0139F3C3A18577D31D5A52C2B1121C25DD7C41E3735DBA3BCD4C0C94D296EAA93B096EC9918D5FFD60F23132D5B11687FEC66CA0442D6846FDA79C9A7D7D3EEC831E6B8EFF7BE7CE522821071971F4AEA58E062F8B69E00F8FCE860F995CABF7AA719EA893FD2BA50CE72ADEC147FF6D7A10633D197C52688945D36A69F80A1D1D5E1066517672B946B67D427887B77BE803C685B3CC17EFC2AB1EA4AA80052BC78F84D928F4098220CF7CF5A8B69C66AEE3744236091974DD9FCFC1EA3EE0F14BAD1868F165EC932E710CDA329D67A630C39D9EF46881E12A79E1115C35B78E47961F52AD6BD39BDC807FB7D57350207C32F439906E32702BCEEB64864B3B658D246C6933ABBA99AE14405177558C1396DDFAF20BF4B96BE166C47201204A10106E7A62E06261A5414268B4F75FFD5075675FE9CCA38593136EF843C39DBB514EC0BA5002A91EE6F375BF4910D8F818EDC39D119E650CBAF6DA563D563CA33B457C8E40B4F04349CF401B772FFF6D4EEB5621ABC1A857779B78623A2AC2AE038291C187F88352734DAEACC2D0D16F3AA45B06972CBFAC4730EDC26F8E9E093F58A35D2E97427360E5EDFF75C14D404524782DC542CB28EAF9F7E1CA0808627D7EE7C7CE279B81DB543EA575876E8A194F4B9177ED6F1B9FD89A3039A361F413AC1CF454DCF91BF014F7F401BB303F534AC8D9D54B9A6D38202B03E9A5C5412A17E210F19D433D935C2392308FFACD85FD5DFC13C5FA608FCFCD7635094833DED7AA22C0CAC4C525127B0057FDC2685EB9336930CDCFC69F1376B2DAD0A98D52CDE7E83F54016FDE66BD371C13026FC975454361626EF5A6E668028E1ED42E2F8C9C8A29864B42C665B6A44040EB470562E8B1A40731B0859CD19BDD6E82E90C73A6EE21ACB55B3A08714743FCEB566A44743E3CC39272568EC083A7CE4D7868EB12195300B224918B50C198399622704421CDBCAD2861E8E3D6C87AED11B2005990E7FE9E34C8251C777CAF4F613D91443D75C50B8C8164803BACBB4397247B943FB01F6C94C547DC9000ABDBBF9E182280E2334E9D630DAA178DF4F78D4FB0531F9C27F9CC28E269204F0AFC394516B58EB97838820FF609951952C5896C8BFFF81C4002893DE238EAB3708663A3B0284EA1ED9A04F5980F1750BBBB9010AA1E4A3DB0C96F1A71E8249B87A2E28B381341C57074491B8475204F2F67529DB15F0E54C6696139D55672BABD4D3B2FCF38EB0023E8543DDEEBF7FD8C2A609751F612DF37566BB0EA5F1DAE8A94DE5D94D39F2901AE84CB772FB59C958088F9B3BC446DB14262F9C71B963D82BC687ACFF2EBD69352F158D09FD12D232B70D61A4C61FEC224B3A47A2D18DEACB31C142BC81CB18A2ECE744A28843DF157BEDC7798FE1B4194D0EC0AA71829CA1034D0EBBD1FC49D41B19326AE664724DF88218ECD0CD6BE7410D0CF47F755B31D5E36B57E2E9294CDBF701888521B9E8169596DDF8D4A0671CBFD4BE464D6DE62BEF45BBAC3B6B1C21D873B851338771B667D727A936743B93943CD47092B0132C4CD09E7AF8F276B84F42855CCB3D56361072F23DCBCF57A490AD90C3AC8A2FB0253A65AD4835B97F3EE70C71EE481B26D947879507285F47A200294D1D58C5360E01ED774EB93613D94231C7BDA56983A055BFF871EC5C29CA34AA651FDCEF8D66F72AFF4B5BDBD0BAD54AE41C37997CFD725A9989B4992DB9F8EC6B94392D30B67220F20647A8939C61863BB34BB8177C106E32DA64EC6C3834E6C446C75258FA1CF17E0B727896A64F1A65083DC2CCD471C65977D5382F3B8F8862878CC120F6BD9CB29EFFC42BA91B9BF085ADA4B437840DDBDC8442A6FD660F9C92AB617D43FBDDFE0621A217F508AB4406D6A03B64895A5C654198FA0AAD218AAB250DE80A85295CA6944D32910ECBF9B47E5F2BF35CED98707E4F433F1958B6AB9C902C1F4BB2B67F972F29C18CD215BD3875C501039C1B677142D31F0A8C07CA1000E963FA4693EC5E7EAA929861E0D431997A536182D624D8426B74DDF841B513CBD2AC8A17397E9F591A5ED5DBAE478D6082075892CA9331219DC353F2C3563CA6745741C7A2F0C334E219AE1C0D1164DC4A81AACFFADB400846688F2982A568414F20220A01FF0780E5AD1C7E8D2E3C7B1FEEC8F7C67C9A85C3628136AC05A576F6091972AEBA9DC184CBCCD35BC61671C6B729E3F2965E7C119131864953DA34A8BB9DABF2B82EECE7455BEC8BD509BB82074DBC766F7CE25E1813444A3CD05C1A4FE28D32651B43DEF2D2511E7E64C5C7AA51BEA1133ABA11005D0DE317322A3E2095E5194B748467133FFA8CCE0CAFCFA8080A3280A231C090C7F5EA61A97E001C59E65E1483215FD96468F1E99350D24373B32136C201CDB18A81EAC0942CF8619FB636B755B4650A55489FB705E7432809E2393180D3BDFDA4E22F4286C0B5CEFBBCB9D9992DDAB4BF662E3037B6D4EB741BF66F0E82E90A6A65C71239A6C939EFA9E0B1B5F1E7FE6A4BBED7FCB163980C866740949CB298A2A0FDA5007F8659FBC18CD236F14DC5B71EDDA3C88F7C68A0833EB7325422A512573F775B87698FE54BDF14607979A04D2579CA552C22EB53AE43D21DB17E3F4618E9070F43F3E58FB206D1CBDCC8DFF1963C1F403CF207E4E9A315F0185B5CDDA7BD84D3E377439538427A5FDAD1E9FCDD5EFAE6A438299FC47AE0C5D622451447242E287BFB0D0584537C45649FBBDC8C24724EEAFE2E03A475F6DFAE4873BB35C11F85707EA90D16D5A90FFA59085F2C3EBBEABD468C69C5D4BE845D45ADE69C9A8D725CAEB9DA4FA48884B5B3570E5DA3BC102865EE9ED58E8EC07672817A72F009C9BD007BC4158C9B137E117BCE2F0255ADAA6A394E0E1DDC57DC3BD38761EE5DE81165F964F6AD48873ABB279F1A236B7A022D565089304ED57C2424213530704A052FE4BAE2E2B501DAC5E7CA411AE2124D3D9F1ECD8F2EF653554CE8B2CA9504518C21EEF67CE9A0142CCBDFDC782FD34C529A65C552311A89781307BECFF507788B97837E6715CDC96820AC849112CCC2DBE7C99C89F5A0D111E23C19BC9115EC8096B469E69324F8FFA428B81D7FCD0D38489820F83EF8DA083B401E75DE57FB7E7A88F4BA52E7B45140AA8F1A97A51C112B5DF3A562F0AFFFD87BF2BA9079EF8A5CE2D5AF0A510EF21FCAEFFF192DB398947D9CF71A2E80E3CB7C5F8E83FC0BCAA59939C5F29DE2411E5D9245FAA641556A5B15DB99A0F9A86715A28F5BCA9F58AFAA1DD0974CB899565DE9A33BFFB8F0E2C118121B8726B87EE872165241B74B2DD0F961CD47D24D81D2A8B0CE4BED4C9D1F22D88FB8311B4704034D73EC20BD63EAE3E6657B8787AC1E1CC4403A1CBDF168E151ED3D30FFAF78A1C6D1B0948F535B472FA7FBD5C7C4DD78F815CC0EACC685431AACC3DEA9A7A75D95CDBE650F6428A81BF0D21AFFF6989F64633E50FF3DA779C7A3E2157C13DB06A3B09C4F7B4947C3ACD8F816312080E7749371A621B39FDBA5F227E86C98F95FC4F0397AB5EA3D2FF66B3958D195CF9EF2F8B4D34096037CFD856EDBE0D65CFEC3F3DCC014A7E91E39AB99F4D5CF00DB910562E3F17827064826E641B0BCB2A147A0D12EA4B93A8EB85AC079400486B2F4EF1BCF288ED73EFFF3F10493AEE8AA69CC37F55CC18E0C3E1F9E9914D268B7E8101428DBDCD1F9992E4C52AC91F7C8C946CD795A7DDB6B794726950E72581306D5FF772A10F4D63276B65A26DA6198CE3C3511AE3407B7B077F978524D778C9FA6D39D27032539C10BAA82B4D9EF44248ABDB4DA1817C20C1A7AAB51F0EE40E2B1DBCE8537CC9820E3272141E23B5160C7741B39783A557F5EE9B28DD0395262473C8C5FA6BADDE0F079C39609B611C7CC402BFA755096396DB229EFEDD326681DDA81EA4DB6C7BFC873F0673900E9DF2CBC053C7CD90C86F39D3C3CC60DE7A0DF08E2CAF9436DCF06107270CCFD32618AAAA84AD18721E69F9A40D4A02114664697ADD364AF0372739CE483EF0424EF250A9D8B1868F7AF515151C7A82F57FBFFA415618720D9F6B74D26620D7DBEF6FB5BD65D21D3E23692EE7692B1AAB7144DD5BF9DC0D29F735447D11516A068B7E5E88D0CDA94894B3DF62E90B20741BA266A0CF5AF40A6B651376B3BEA1982B9A1D1FAD34E81268E178557B9D0099EA569BEE5CC37EE87DA8FB8E194AD9262017636DD3280447C7D47B4CEA5C29308EBDAB0DE6F71BE71ECB562CB68153E8657D18D826C846F51F7FF9AF0A0EE144FFDEAE4B8B4B86744ED8568131FEC11580FCD130FEF66B0F3B80FED72570CF8D05B5D0A0F04FBDADF278423E80A645F3A5950BA42CE8F5CA1AF452F8E17310609F673E8B194C45A6028856BA19525A1AF21DDF66DBB42867169293631C8ECE4248F6859608B792169A785D5B0AFA42BF20B127D0CBF3E6DBF9CA7F4339D46C0FA311E0B6D7AE4FAD7C7B7E95142670525AE1FDD8312AC7E4FA311DEB7DA2C86898E138A6A85DCA01D3907B257D870977DCCA7566BFFA75368E0EF1A5ABB4A37C1C7F479D4CDF7DA4E4F15306C250B844794A700467D10478C70ED7576CC7A47A5214E87EF2064DE4E8CCC1C79A77999B9430E01F0A96CB4596BC71157F5691AAE0CAB95A34F556364B81252BA1ED74D9623823BC1DFF2C15B803253B4BB945567148AEFD159ED587A7543A38498FAC6B9F4FA387F208FD346363E8F024B875765E509EB158959EE37CCACAB20699D2E3B93DF596C0E7858DD2769AA752D7A04DDFBE8B663368BB16BB5E5FDCA2A07BF19D6BB64D98117E7D2D3DFB0F52C5FDC84FD477FCD77CCDA54E394B4C33F3AD535474B32F4695C94B79C5412DBA1C5266DBC0F3BF3CD6053BE1F45BD6248FB43F64D2E85B2F7182BBADDCAF27C3113E3A028473065AA28421B7DD2A48D5443A13B8828909E77DE44090C2F8E173524AE3B80553479C5B6229EF0617C9D7A7E977F6308FCB273726B911CE4C32BB7862CB97B4AE20BF738E02A1CAFD80A16A60D7A34D1BF415B90C6DEAFCB3484C5E667908797D4F4AA2610ADEB56C653C8F185A7CAF56EBEF48A2848BD6171D22001FC68AC2FA840ABA5C431246FDC23BAAF6D0DF066E79526FE433EE580C1FE39DBE388E052E07284CEAAD3677383BD09D051B1805D54E5303637B33579ED70AC197F40096622FF037F212425585DADDB7463B98BA1778DF41BB35AC25CF70C28FBC38D8375F51558047B13C4ED023310CDF766B8CB1DAA02B1B636713D63BD1DC219C3BC6D503C849BE11768D1223BFCDC8334441B8F9B12B320C3FEFD135FF8570AD9A7CD41A94A840BB2BA24D5DB235EBCADC26AB29897D6FE8FD2610CFECDDE4B192191A68E65BC9220F2FEFE3A81ABB0B339B4E67616325900F15D2A08F5372598A78879243EFC57FB452D6546312B64B140014BE557F111C383E6A230577E71C0D393A5FF4A64FF24DACA82EBCAEE30D15A09B23B5A8D2D7969C7A722D759C2BCE5B4840EDCF138CB7DF66ABEAB6CB261C1C4BD58215ACD30F123BBA9B9341AB4D3EB73FD5D03AC61BA9AC088A2E54CFF758756BE0EEE2567F68BD7C1F82D320FFA0F6A70574060C855BC5AF805E6393DD72F96108C960F40FCA7FB3DFC2D6D0BFE282E47F5C5337E6E45D4D2E16B84FF3E5CEF4C234FCD100613EBC8E64B88972F76C910D3F670620DF511138B38CB2DFDF52E9C149BF2C735E55BA7E78D059B90686E457B060B430D210920EE1381B7A5D391439E8647983867DC109AB65EC8A1FC72F106B90E4AB58C4E94B1A3D1879C14D276612764132E3A83F5FEC46445A2FA4FAAD22DB92AC778226EBD0768EEF419B9B0E640CD728401106B5034EF589527DD3C723DD9BB9BF84D8B807BF5E44D9861CBD0FBE01CB67614FC637E59AEBDDDFFB2C942AF3B12025D0DB6A87C8FD2B11E097154B8926AA3C474269949F0D7527ECF258510170DD37B36E9859CB0817921D58308AEB63F82BBEFB3539949CAF754B9C49FC538016E6187F33B9E6FF1377B1B442E7C90381A15714866F555145414DF827213D9BA1379D345ABF1E5B42A9865270956B1193B1623D4086A9C9362D7AB9268829ED2E08431B6B86A49D4AE71483E00A4B881E6BEF7F3E2A88F012B3C06A7332E900E0791DB4730D1F9C8B2210824ED920BCA37246A51653BE1221C9FF9DB1FBF9C602FDD52D0092B1BAE8FBE7716635678161F1AD15FC55B651150FF4743FBC00C55EB5DDDDE5576F21B4AFEFB9DE8069DFE7B917653E4D180F6CE483BC229D37FC72424C4BE81F59B0193D2598C75AD9B818E84985DEDB445C4DABFAE5C9912748B32290F33C5169F54089F39630FF701B4EBD727B630EDA9752AD3601DF69693AEDE984E84B80D72FD9BD347545A27CEACF2B2C81DF266D320EDE2AFCF3BD5578FC5A469B5EE30687A6686B9CF04E9AA88815B89EE6F2D170BF84B0BF845A75B2C303B3968643511D4AB568552F4FF6C0243725F291341AAF654E72DD805C798FCD5214B14616E7AC9F3A4EA6C211B319FC9009536A1772156E62E666788121874F472FA5CAB32BA174FD0B2218F50A3BE7BDF448263F84CE6184306BDB40D6AC6EEEB7A009144D47CFE5121C5F44044D10B0776B575F883AA5CD63B5A577409851707816E4CBFBB13B047D3902D0C7916E4C9598BDADB732E82166F10149695106C8A9F3C0D2CF4349B59CC5A66177FC51A7B1098F6D30FFD8A5D016AD38097C062E0DA6BA3EB4C8FF851503B97E7A276E026DC8D92C68F979D53F9157695FC63A97A9F58D8F92140217D196A9778CD52A9074348743BCCD068B5DF2D5B76943651822D37F217E71EA6763CED121444AA3570A5880DCF44CE21FF035E8EA8107430E6116C10485E4DC7792D04A9B9717932D621B572F42221F1BAC60D3B65D93007913BB100E8658968B0CA77C533F20B9396BE2A7DB9B233028465E54648E3329BA2820ACF6CF00D46BA0CFD045C20C6BA992AEE34F57E9C84ACA1E95C45E9EC6D0BF500A7F7E6626D5777DC6AEDB370A4B1EB82BF4CD0F63DED9A4CCA567FCACDA440EC29CC67A926059152AD7BDB3F3EB06813BFDD8314C365E490C41C6FD4A6173A13F4C4A4E517037315D0EF14428275919CC61AD393BE23333F7D8A93C59DF7FBD4DFA8235AFE88803BDD881CB8E591A721E917CE44103EE38CD499655B666AC3536A1DE850F3FCA9C393454D9BD6F0C75B11822FF23EB22DBA69B08D3F4E92B8ECFE9BE9432A8B445A5BEE8757C7C53DD96FB2058A5370EFC4368FD6B5FC124FA0B9366074719377A0C533415161E29C71D5AA85356B9 +remain = 1022 +max = 1023 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_256.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_256.rsp new file mode 100644 index 0000000000..0726254105 --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_256.rsp @@ -0,0 +1,14 @@ +# XMSS-SHAKE_16_256 + +pk = 000000088B4832442313757CA73F5832B981BBB6B72FFD8A75EADB03605950D69CDC5FBA04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 0000000800000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A8B4832442313757CA73F5832B981BBB6B72FFD8A75EADB03605950D69CDC5FBA04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D9330900000000000121C29A3D4E6C5DAA979424FCA26B0EBE6D3FEA8F078FA9A98B0F55503C2541CE0A0000000000015EB6FB8267689B81BC8E2C8950E5F59F4B43194AB167C4A60EC9BCDA7572E5980B000000000001F02838F27F104405AA4D9E111D3A0B1849F6725926BA5B3A6412DEF900E7259A0C000000000001BA1EE79A04487C5639BA096A60E3E17F7A0E9C0238FA049EA7AFF52FAF5890980D000000000001B63504B794C356EB44A98DE32960830E6B275526432F232A7729ADA72571E8D90E0000000000014DA82230B909123D34E30FE0722BDD93EB6D56243518275547CBA7C473744E6F0F000000000001000000000000000000000000000000000000000000000000000000000000000000000000 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 2692 +sm = 000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6FE5428C1B38A2155B8EF1FB9DE8440D993A1F197229DF83843A1615CACF924D481D1478868BB902124AF51010672C7478B1AA93977097EE47375B6A5BD3ADCDB13077F648B8C7435CE755907418C55379857F06E2F7A61A232B67C86AC1352B9854E31EDDBFAFFD3992A2FF8D8B758452896E7B2D56A89B09055C2684A6FBCD2868149F65E73EF30210B36E03DCD6257185F671F78904B3F11EC67EAF994D1B9810B03806BA5E0F9C9F764CF3EFC1772C1624A7C8D63A6295339488C2FDD9CBC4D52F94BD09075E359134DCC1745B0B9A12095AC493DBCA32FAB2980588C131B31246F16CC261A56C9F1903B0B4498B849B4598E5F8C73A6A1521F7D75628427F95374C29BB0585B22A7421D7A01B07092AF4E6C0D03F0445A64110B93F814194F4EE29447A8424917FD3EBBE24F5128280697659EBE4569087D96AD8F0AC7B67D272DEFC429B7BE6E9F76ED4A60B42FF5F0CF9EC09791851E1E7D263EF374CFBBA724670050F31569813630709AB6A4E35D66684AB154CF647FD64DA3B2E5530B4ECA5ABD9666549F8079173D267642D94F9660C76FF6D5378E015B792B13BB773CEEF4C7B3AD10BC12FDEA7DCC1891BCBDC9CD83ABD7DE6012ED3F07F1CE676F9E659D7C7663EB4B63FABA90515F2700301544682570E6B3EF16C59082F949F388D9FDC43455CABDCD4AD51E010674F23D753CB00A62685205FAD8CB4BE5D5174BC2039A9D72F3887749FF061BAB898B75511280A6E9134C3379B1609BADF260A2F78C4C9863965A97BF5DA405B992E011375D9834FD1AA73799E97F4F701E1453388E6A2E01080743D9A836F20FC93663C7E4591849A616ACE98011E52BFD3C156F233100992998ABCDFE26F36A0A4191998EBFE07E2B4D7D9787DFB44F858B43CCAA440867C0C6B6C74E32368C7884B8860E5AD1B518F322EE72CEC31F5253891BCA1195D4B5CD305ACB28479FB1BE4550E16F85D9285EF98B1F325D755F2D43E285EFDDA4F0842A1727C2EAA123789C359DF0C696349055E452E7F27CC668814754D5F91CBC9BB551E5663948A692D12D054D90840580C1D66423931FC5A4E6B4D0E8F6B2040D9CCF85DA7C9522BD571EFF09D5B1561225886FFCD6B788B60A2740339A04956DC654E108016C69006BDE4C2BEBB3A3DE40FA45F5DD19D0E3F2D9487FC2287870964D9F328563E36677622B3E074A980DAB585FF96FD09B95A6065CB8246841079ABE344B55A1F2D367FB3CF72F1391462C45BCAA89EF4D623FDA3904F18B7739B10C9EAC71DCDBA418DF1E5DA13E1BA5A122000BD71E0C2060ECF72407AFDEF3BA54EC75F425B4AB32F564854AD5C39A2A1D9D06FBD74DA44B83F449072FE1E7F6A82B308A253FA60B722B0B949204E5931BCED17F2B1C5EF51D9A6F477F108EFC9DCC7F139617993D5362ED390A73955749EF1FF0825D95C689192BB35FCFF90B87519113376A44AE4BA207EE9AF82719AA72ABF543ED04221A9176561983CE0FEAE6C491381F6E112192272AD8C82CE4037BD968C1F4E7B693C41F717FEC260DC06486D04822DCD3BA1CEB89F12DFFE3534B51B107E73383B4DF8B367F2E123BC873626A8EF6142C485C932E27BFE6024722F5825CA4C84A6F9F49B0EDFFDCE1DBC2AE84F1FD849E3E1D049EDA6A5EEFC0E5EFB68199A9913158FD2FD0A1EB0C039623FA42CFCF6A0AE68C6B65B60D79C9987EBDDB191E271CD9632AA1EEDD35A437D3405B89CEED11D4871C6C1F9A9C33B15AC647845C27F1B5233F2C78E908DC396F097744D841C8BF1BD732255BC62E601A9E50DABEE504FAFD020889BD3E0335DF683D946334C147F31FEC61975DC21582CCD00E77AE099812A621537438D6AF2F1A64E98F801173C97B9EF4923BE9B179A94D20D64CDB799F04FA406789F34D5A04CE3FEA635DE803FA73EBE3439BA0238086F39970601DEBD0E7DEFA07933EAD357C796B76DB6E6F557222BBC9AE2F4840F608E59075A190F8A156CA92CC81F4F69369EF086D61EE895B7F12C300DA076E09BD43CBCAD6F5857BAAE18071F291C3D742C9FF3FC54A51D1CB8061D5A0ED4358E8AB70079EFEAEB3947276F612A4376555002FA7AC9B7EC9778FC3B4A6EE1025D4C73A8CABF27E1CC7B33448B947CD339BDFFC9F377952D6249911F099F535E6FFD1BECF740CC96822076C1C173E32EB8A2A1D282D8BFEB277B9BAD5906F6C8ECDFF4C980A4F708C8D83847A125F12D726A803911B7669FB587EDDAA13FAA92D1745DAE5494E4DBE639AA2B03412ED97FE1C1EFC391CBE070881822B2626AA473C605E9D16D8A4A44644D551C332240FC9CE25D8A9484A9F0A65B6DF11CE50A984285D2B583BC4ABD4A26907E5613CDD84BBC4B8A6FE153F5D50CDC700FA96C40B8F33F4F73F6260DAAB08BF5A02A2F664E62BC3BFAA6A4800EEE8423D93ADB908B28E1F1DAD9CCF410A1A717F2FAFAAD47C60AA96B100947EB6EDEBAA92FBE4C0AD2407EB3D645DB8FA4EEC242E907FFA8E6D5771F18739E44FF6E70221FA212F5755BD9574163E60412DC2DCC34F449167D76C769FC5D9D4AEA104824F0872C46D1E4C35F337D007F2EB9B832EFD426982739F74A14BEE901570011D4FB7F43B5069C64556087A248D8C09CFA5E34600B3BD6194649DCB093B3DF86DEEB4FB42EF65CB5CC3C3FDC89852BD57F34D20B9EB617AF516E372BBC4154AA94744BF2835AD2E71334279B019756795B96FBE4D57FFFBBD3D6E4E5786234FDC6E5768AF9329225E1BCB7F680B66729BEAAB9C5AC5A2120C8D427E349F364F595BC1D72874466844FCD43252D480576898E9037633A8424577B3DCFFA3AECFE14317B60F84E450247EEFBD497F4F79FBFD48BD99EA0CAB725A1A4F1CB10B461FA0AE6F5FB991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EA6B7E3BC14749E7C7FA2F28480EFC0784B9C5FEEE217946EF2D55F5FD2902B6E080431350D4BB60DFB6DC98FF57CE274ECF76AB7C2E9A87D99EF54D9B8A5B4481F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C +remain = 65534 +max = 65535 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_512.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_512.rsp new file mode 100644 index 0000000000..b3718c5f09 --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_512.rsp @@ -0,0 +1,14 @@ +# XMSS-SHAKE_16_512 + +pk = 0000000BE63E1958AFF9CEC5CC26706D9B33FE461CF17B8FCF54E1B7394AA3E0B51BDCC89B4D854731B25D63C27019AF9AD43E63969A575E7C181079BC1207320A6658BC4D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE +sk = 0000000B00000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A4E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FDE028B6F5724BB039F3652AD98DF8CE6C97013210B84BBE81388C3D141D61957CE63E1958AFF9CEC5CC26706D9B33FE461CF17B8FCF54E1B7394AA3E0B51BDCC89B4D854731B25D63C27019AF9AD43E63969A575E7C181079BC1207320A6658BC4D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002AFCF3BD5578FC5A469B5EE30687A6686B9CF04E9AA88815B89EE6F2D170BF84B0BF845A75B2C303B3968643511D4AB568552F4FF6C0243725F291341AAF654E72DD805C798FCD5214B14616E7AC9F3A4EA6C211B319FC9009536A1772156E62E666788121874F472FA5CAB32BA174FD0B2218F50A3BE7BDF448263F84CE6184306BDB40D6AC6EEEB7A009144D47CFE5121C5F44044D10B0776B575F883AA5CD63B5A577409851707816E4CBFBB13B047D3902D0C7916E4C9598BDADB732E82166F10149695106C8A9F3C0D2CF4349B59CC5A66177FC51A7B1098F6D30FFD8A5D016AD38097C062E0DA6BA3EB4C8FF851503B97E7A276E026DC8D92C68F979D53F9157695FC63A97A9F58D8F92140217D196A9778CD52A9074348743BCCD068B5DF2D5B76943651822D37F217E71EA6763CED121444AA3570A5880DCF44CE21FF035E8EA8107430E6116C10485E4DC7792D04A9B9717932D621B572F42221F1BAC60D3B65D93007913BB100E8658968B0CA77C533F20B9396BE2A7DB9B233028465E54648E3329BA2820ACF6CF00D46BA0CFD045C20C6BA992AEE34F57E9C84ACA1E95C45E9EC6D0BF500A7F7E6626D5777DC6AEDB370A4B1EB82BF4CD0F63DED9A4CCA567FCACDA440EC29CC67A926059152AD7BDB3F3EB06813BFDD8314C365E490C41C6FD4A6173A13F4C4A4E517037315D0EF14428275919CC61AD393BE23333F7D8A93C59DF7FBD4DFA8235AFE88803BDD881CB8E591A721E917CE44103EE38CD499655B666AC3536A1DE850F3FCA9C393454D9BD6F0C75B11822FF23EB22DBA69B08D3F4E92B8ECFE9BE9432A8B445A5BEE8757C7C53DD96FB2058A5370EFC4368FD6B5FC124FA0B9366074719377A0C533415161E29C71D5AA85356B98A138DD28D76BF35B6B9BD3AA30CEE5641266AA5B6E3476CBE1CCB18839B063A655FF7831A6B655D5DCF74C93369FC562827A2E93B53A295E86E9BF8879371A9E0A176587912D1CF344CDEA03DE86B587548FD05D775686D36B8A3B5AC77165B6226682EA37B935C9FE0E02A8FF9951E2467626865C6369A8DA0916AFBFC03DCFD599163BEE9F73F99E34A3F8356E5F193E76C4648053269A659E080A7014A3EA4D7D9766FDB36CC8919294E88D722D9996FA0EFAE5FC3DDA45C14636AE77342A5654D12731B64E40255DBB777CD68D73B7CBB3D8D1013CADE109F474DEE5565B1852F646002BDFCE39C736116E56EB8EC6F75A46F2A19ECE8F0CAD24152DFA63F89AE0C375E32AE637BFD43A1D3B027930461A8CAE0809D65E9B81DE9BA9D0D498262EF57887D6B892F149030F734B44BD9DE9A4C8E97772A50E7404020A9D64D6785059250DC03745A68353456A7229B21F0DF6AFF33894919136D210915581A525208E3FC16F1AC5BAD3908D4D7D7155929F32C5B790F625CF89B8AD926220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016A30B3920D43D47945F47566B618719C38844032986568606F2DCFBD7104EEAC5436CCD86E9677E05985FA63C1B6D3E642D0F145B3FF637B96F2AFBEADED75F30100000000000197C186BD25DEEE5DC2CE5B760508549B1EFB2F3E0A34047232BDCCA39B144EAE820DB1F2D3C3159D012D7CAD7AAB1C44E15F53F4B1166E23DB8AA23ADA9E23AE02000000000001C5A2B2230C54CCBDFB5F42AD8805628B6B3D4723AB84E514035694195F2FB7E716F21EE8845170F30D1BEF79ED4468F2A45A72853F2D8F601973595098010E1D03000000000001C9E730A265A6F2DDC4B0F420CEC9C7AC976ADE4FDD5CEA3B6D5445AA2562772F76635C514BC81DA00E36681EDFEAFEBF29B1C3078AFEBAE3956D74AAF351E35904000000000001B661B82380E38D5CC77679867BB8FC1C94E77006AD05DE9576A7BD210641D25D011A056637775E72395B7643018E0BA023747219D875DBA848A58E0F9D7FD2DA050000000000019F3A31924919E8711F88BC45477356D330ACF65BDA612F6AC681F64C24FD70A6AF08B3FBB6136E4AF05B38A9205ACA4A2773D100FF79057CE6EF6C3F82AA9DEA06000000000001EDF9A31569FF07104E7B2FDF78D2CFC2FB28903D720F4D2ED95AB35DEB5EE579384ABCDC10CCE008B5BF753154B78207E452D4AF2B5646C42B89EBDDFA02570107000000000001BA911C4438781B45414444B18E3EEB1F0E57D33FB8F1BFB5DF1DC85D88A29371496D214B1042FADF9F17DFAC6215231DECB7D4ED1ADE6272BA7933403D3BADA608000000000001D85DF2FBED8348BA8E34D08202B5F944A00F91F1CC1F50C50D2460DFF1CFF490D84B84A1FDCA7A5E1760FF2E3A392D3F4ABB78116DDA6CAD29E694F9A4691E3B090000000000017C1668200DA615F45702477762DDACC68BCBDB862EDB8F34569EE898D80B4DFB1AA4251E3C3D1692C8C50DA2BD543C84A807DA4027BBEB6EA8A4093D5E560E110A0000000000011171AA4B7778E156AC8674A7522E4E47C54E7ABB917E693DD788D8782675BFF5E0108D4853BA609E9E9C0FD4FB0B8908D8D36F3CAB806CEEF40B173B740540330B000000000001AB4927F65EF9D6DDC2CF1B044B306445ABDD4629C4D63AE6278E049C96933D81862327AEC4B7D2C31B6C7509C6E45D2945E0121A0DB90076FD84AA9C5AA53DD50C000000000001F73CC84242314EBAD62F95C79805461C1902C40FD822F19F69C029997DFBEB840EE33A9905894B1290A75ABD10F4EE3BD6E75DC6CDCF69A7FA48735C08EF85E00D00000000000125A7E166681FE462663B71CEDAAF483C1D8097F57EE39EDCE104F6B10BD85AB43EA3C766F25F76C0AAD896BBBE825A8FA45AEF3C0483571EFA6FC24E973AFE4E0E0000000000013DB4DA57E43C4A075E6A8B417B395066BFB8C7291C42A04F1095A5F410002B3AE64DDC3633B2E27A4C28475C56FCBA6F0A6D5B730FF6320C89B39E55ECB22A730F0000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 9476 +sm = 00000000BAA7550F0E617123968A7F276A4E50664475EB64F4E5DC6805ACFE998B45C1E0EF24208EC4F8C326F4E4D4B36902314578DB3668398F8D67F573F98468AC125AE12C99BC1AC30AC1C70E9F5512DCBB72A03F07AEDD114A5E2C73E994252AC7D8344377E0BD8DD7E5D8AA7C37A8350D10E78049E98C5354C298A2A97A05F1375AEF91919DF3C700D64569F90D0E42EA543393D5ECFC90F5E1ED1173810AF83E1E12445F5FB5590B3A00414C47D7419D2AA0DBE2E4003083B6294CABB043E099B1433B6322DC7AA17FF2A5B756F87FCED9FF415A70E5FFFC2794C974DB85E4737016041B8B817D20B986C1842F55C85CB40C06E274D6F22ADE5C49DCB27457A297A97E57A963C3BB42C86E365E37A258BAD6901D1F1AEC279CE2F14E9E3CA316DE8DA0B086DB8102A746FC5C3EA9C99BAA79F74F7463F047DD6878FEA751585B40004D9E5223780147183D48AE736A5EDB2D61D8301ABD2FAC1B1E60B5BD2133C25AE6158E1109CF1C3F9038E6ABAEF95BC0B8EB39BA412B4EBADED88EF612BCB5CD6E085205B104F30EBBCE03D9379CE23E884EDCB5844D875098A851A999B3C01EBD13F4EE2C95ABE76E4658ADE75DE9E73F3F531DBFDF366773B69A422916B946DCB72853EC436A574838038C65B859D520972AB0EF69714DA03A840EB9FA46B8AD366C3A3034C316001AB869808374ABF5C57D943809C2C11640C14DC9F550DCC7F5FE407E623B98262DE9618F71F36CB240F66418705405E0BA2D452296B522F1366C4DCBD16CCFC896B8DE3BE331CCCD48B291CDE4F1894B9B0AE51DF7D4FE0BCD0F86D8126430A4DEB5EEFE5AB35EB0679EE5F029BD0CA4F6E364F6F6B97D3BEF756880D8FD1F7E1978FEDE67E9068F4F52795C4258F0C001CE40F4C1B54BA7A2526D11D62E30D1D938D7B9475439E5A5A2E4FEF606A1E7FC210B415CD123A82B08539A2F9B9DC79ED7F7D75412DD6317D699A57214951587078E9F8FABB27BB02FD87E871FE65C3F2ADEFFA5C5BB430ECAC0694B88A5883710B97FCF72A39252148B1D304DDDBD9ABFC29054FF1AB375722D8C6705FD87A83E4BBE2EE1EFF9734EA129DD30BF7F62DFBFF2E7A511258E268F69A1D1656A2475AFE819AD0A624691C920445BF7C2658D34FC8AAB137C3C13ACC855A6CD66FD2BA32DBD7F5E16FAF47C8976C8569E330985CC808D67C4161399D64EA943B248C6849C3A91C0E38612AB2ADE4683B62E2F8A2418E54F8B1599331924FDDC3668DB783B4B422696A03800C9045010122E24B346B99C4A92514E0DEEE6CBB755E78EAAAE02B9F0B54AB3AC33799225B661D3F5729080FF9508EF12F2FBFE791D5819F0C283D9D4666B93C966147218BF5DBDA389086110544606F5BF6F120EA288696AB7564EBD704846D2D9DEAABB77EEC66ABE1502762C6DF1353DC29B95ADE5D05853F1C53E1F32519CCE7655A5531EFE89DC0747356D39CE8D2A52A35D7F82AF5AFC88DA85478AD66495150DBA318B7FAEC3D2EB99DA48EC9F9B5ABE09CE782A9C8FC854B53E2E5B514CA9C6623519C42514127D8D57C080EC7BA0A159BE9CD5C4D099CDA476E93A8D785AF6A303A3AA3B77FF313964E1B9E095E5634EDDA4D5BC8CA2C4333ECB93E60EA6AB7D3BE7CAAB2678F65B44991FB909802DFB0026520B1025A3435DA746BF4AC8D2CD5CC07DA809E5C388FF156FC159892D645CBC9B37B5E25BCA92AE0084379A77A4D2BEF0BCEF989E0317B0D82BAF54486B0792C312F8923C0B85E5FD4D5B8F86D9E99A12AE166F7E518713707BED5E140EF7C35277D8F0CF563CE49C71ED38C5C15D5514340457527590B9005E3C02DC8360E12DC702CE9622A16594AD89F0BB57F81BD71B0292F235EE0F52F8D5BC8317173675DFA09ABF4A19D71C21BFFBEF9B058C36B18F359ECC1A378E118EA577EAE122E71DE995CAD6048380E5A2A24F943F2468128A94AEF1CDEDEE86630F9D46155896408BF90C0FBE204D7EAA49B6F0E117BBC58E3CA42AAE72BAA21EFEF8B3C248F9C085A1B39D2733D451865BD9D23CE32519057EB3E345BEE6B5766591157B9EA7F57626EE4F9A94352646EEC8C35E41DA59ADA25FC38F5B35E520858A8E490B20FCBCAA8A487B90395CAC25B1562D77FB982C9DBEFCE6FE507841EC30E547B0C6D6E717E125450016F77CDEAEB8E6CE1E2AD4E6C5FE29C788FC473BB6A1A9EAA4CE83791D0B7A3426A2B86E5C328820E839F87FD2428F7C4A5F43477C48877F8FA0322107D10B532044720D001F62BBD5581247F6399DDCBC01CFFBD12C9D312720BC16A8BFFF3D7CB1E83D96547050B25B2881681427B16752B1F58F3EB5B8B4CF8AF877AD3E6B4EFA12DAA71D2FB9534CE5F4A6684B24956647386385D57A9944F3CA15E326CCF70F8403C62E07149558EE2FE2F5D7F015C88A93E712E3151E316B9BC4A8A031502F073DAA1F1AFCB970AB6874ECF40A3383E2BB3196BA7320A08AA644538AB234E8D299940E65093F353F0A78C01D93F58D5E70FD464E07A1B6C7E9DAD2985C8C5F9FFB489D692E482CB83F95A226F2C351763D0B1AC1EA2BAF9907F117FF3C5CA5303BDA839A3293A171B77E9F68414C5D4FDFE24129B59D15F154B984B79709EEEA084A07809697EC9CC748C2363508461D7A1F1D6DD1887FF96A2BA275E110740210E9507324C0E4DB1A0CBF541C9EBC2580D9FFB18AA03A1A1DB485552218B5F1D05A1C862AC7D0439C8F12EDAA7E7ABF2903E653691AB5A0C26C6B30BF0053E0629BA2FBEB8BC6A5A6C2315ECD6BF9F755D40DF5929F6CA05B4DB3F595E191FDECE614AA0408DB903B338EE8F2458A32CEDABDB8CC31C55220EB7EDECE225A0E0BA8DA3A4CC35408FBC8277E5F6B4BC0713B96A52EC914D4AB4100449B159127DA510E6C94C4BA751A4CCEE6AAAF7688D1AF7B8EE10B187FCF5E172FD997DF85F02771CA9C5432BEDA41F922D3DD9FC498425CBC698F32CF3C5DAB50279B204CA067735B54D33BD0F96280A1486F8AE9E692E9BD39C687796024CDB0EDACE00A83A5708EB72BCECC6A51A4D266B6C0902067DEABA6C0E4927A0BA4561A82635A058571FC30921F054D27574005C4D91C17ED8FD68F88DD71D763818AFBAAF0D6BCA51E2825730CD6516E6A9EF5C99D133A82F2D9F240AEA8AC5293C89C4228FBD398BFF0996E3AE3DCFB7A1D4BA0A3200827EA6573D349F8CC2771032A128D7A61E772C20955A3299E56D9E5B0F746555BB8C0DE252C19188DC3731747F2BEEDDF5E92BFBE630CE1A618E4E7BEAA674BEE4380456301B5D0578ADACAD2B685BDCCD8BB20A0EA0D330F284E5AA318FECFE8893138D179FCF67DA80DB5A5B0A1D83C205106555F9ABB6DC02309A8310654B736B879C5806D86994DB3F3B2076CAA13A7BD6291B0A5F18DB24A542E6CA65EA69141F5EC8726336236EA04305C638B19C6D97759361B2E9F1EF455A997BD4E48C7ACF00E1945A919C77B6DCBAFBB3C3A1ECF0178EC042C940B1D449D803A955092A32B0AD6DF0D6B22D9B6884BA21451F8430738F1D32139E4B450CED6BF244F0D6442C6D1245FB2024904325D1744CFB92DE691B5632C00AB1A333CE0CA6AAC2D056CE3AB2FF552E5AB8E4EB626E988ABF6F27010F010822710F38B85DA10A0115FB8D76D3DB3E79F27F8A5E472ABE15B46773E77511A9AB78CE4076087F5E46AA21F953E06E11AFA9D912D93EB716F9FEC1C913CD0B2B69643FA4D0BE4D354C34234F65A1358D9FF6EB3B686FC1CAFAE14EF43AF20A498356FED501E1267F3B9C1D061109288F43CE00F4E188CFA2B68CBE8395768515C48BA515A46F4E48F669786AB3D250F3AAB360214309179BBD7E6E4F36EDB424524E2E28A7C2BC00683997FEC38DA95CAECBF5020C5CBD4ED3C041D403DE200C93C0AC004E471BE71BB3EC729B853CD8FED9F22241FBA4517EA291BA9841EAF8453597BC7625E4CC78C9F9DA52147C1DA50F8E7DC3421F3F3393412D535A505BCB84BF9928F9A8F6BCB87DCF80FAC84D9A80D57879EB74D6FADBDF060F6B61A7F08CE7F274D7C365D36ADEA9DA7642CE3E9B55E7FC0F72237C02556F514DB779EAC2C89993A623F55F668A0E01079E50CF885AE8CCE63F335A33763687E2EC2A61E6DC571268B4A405D32BF54DE503BD86431B262C14E2D0B482D1D8C0516EFB1E4BC7C59A3233597BF10FCE6176F0E5F93853CA71A15EE903F51F01275C307059EBCDDB41662896327EF0CC02108DE4E66C4D3B5B1BC1C4FACB24CE6613D9DAEFB55A6B5D6C6DD925C5DEE1E43079435E6C3EC704743E7640E4C8F5FF2CB29AB5C223A1FCE9F2D4CDFCA8C9535338004AF28386A3EEC6581CE06F0B5ACF3B7CC4D11693D840746377A1781473F4DB2AFC1E71939664DCFC76715EE777832C29BE4CC0B10864EEC338196F4F38FFB2E70AD32A3C15D9082C9DC5795CD2B3C38957E03AD9261BF7B836F8BF1E50ADA19F026983B0902A37FA2DB926B1AF6C9B737356322ED3069010190286939CE20B380D450D6E4EA7B71B982632C4B9067A21D3F24DC18087A335325EC49F747003438F8F088EB80861F6C1D9446EA350450C52438EF91E4A61B41BD6E74D8516DE54F6CC50665BC5C9D9183F3195A7117BBA583A2EEFF10B57B778B7E95DA6BF8D18E2A1391112235EC64E7701AF5C73231EE6664305C79FC59BBD67D774C80D33B9CFB2EC5DD98842BC41BC3888DEAB4D33E74D3AE046E4F2B2E17F6037C4595AF6E463BC5E9F7C95CD26997F7AE62A388049D0CE33A8E9760EA94D8BC65A8002731547678F88CCE64974147E67E81052008549E3D90BC5E61C5B95AAACBCE61A75FCB4056FCCC93D91203AF60A730587960AFA8AA6F95E50E961EEF2F0A7506A685D8E975CC89BC67B777C530CB62430FF11C6508F338174719DEDA9A648D13AA86CED5936AB7026DBAB13D49DBAA5E575569BB67C0F5DE83A0452B567E8B7CE3C65F59FD12B442BBE6FB5D458F2A1A821DE40AD517559A24A8E323696F6F6DB7D8B16C5EC58E3A77530E4C29293A9DDC08F4A6D0E200D248E2C132E18C72B689F3C4D183866333B2A6CD983B4B47205E436B696D885088A5D5643ABD08F121FFB92A69470BDE73F9DDEDADCEB572A5BC2C2987493D5A832DB8417A3BE817601E11EAD608415358DB7DF5ADF61EA9864171437E0A9318BC9805C322797EE85FC7943577C831BC24072FD1F8E29241C240CC80215017D3FAB209F004983542258302E2618F67B99189CBF90FE1D3CA7A6B991E138D798ECA742954D56A43598C0D4B9D53B143A2FFAC61C96F5BA13BC6B2D81687D212DBA423675391A849225AB53DB48721F083FE5AA727A727CD1F0FABB2DE7C2744106CFFCA3E687F596DB59FC5886291AE4EBADE51171B0BBA5FAD9391938524A148BE1C9F5592B29C7C486B841975641B0F63C4FD5B60E4EE27FFF53700C77F52AE131E606BD22B79E1CB48969F4E94E48509AEDD1835044C391DA0D16C71C79317CB425A158F86AFF9C0C4F310554EE1775D1063E6AC1DF9EEC2F9855D6F9CA5D5717ABC6A03E3827911B025EE757DC6CBC8F0A521628274356F814FBE77BB65DD2BA6F24B8F68682089B0B4CCF4AB93787DDCB748F5D04F734C1F541B317C408DB77F9B6F3B41DAFA3C40C3C423A3A05B4D123ADB4A08B394FA626F5D80DB0F3E63906E32C51F6E79CAC4360DCB620AE869956C87CF448B0B012188077D179A6F21899B15F77ADA6D24062D14F8B2DC33E809F9916E4EDB68B3DC09E0FECDA436E314F6C1B9E75912DE2D553C04A63C904721FCE036C8D30E27ED04EE5AFF1DE11E9F7DC225F1852D1D66722A766CE5C26ACCC6FC379BBC0CFB966C521F50BAD8375FF6C48EE75502AD81039E7031386B91FEDABD23613AECFA6298D961EDB5D7EF31EF45398B454036593520790E422C9320569CA969D2B8228F13931AB7087849CB7743269965E1CA46CF655DA1917C3AE60BA1531580528D602EA592C9AB888ED4F5C9C0501AB6D229E3D7449650F6195B2094C91D771B7B2D237AAF3D3F1EB0A9B213CE39A9DE996B39C23A59BBCAA636FE5162D840F90C6AA6E28A0EB3629ABF902FDB60D8A6E20B1A9E5F41F858B2E35BE9BEEEF93F74CFEC0D60E6988F3CD8302F95618B11D3E55F66DA8A6A7544E92CF1F507B628D36D57360E31274AEBF3F77205FEA5CC9BF057BE026B7CFE95893F9D0583FFB15896D4FD9C485AB70D06D67C6D0CBC604BFAB9331F8F36375725D97D74ECBC95047221D0E09649C1C89D14DA15BB86CE74CDB0DFEFA89CF07C8C09AC7B78F5F8DAA070D6D3C6AA30272EC6EB5CDD6025166FAE7CDA5351A457FEAC61E5DCF917F264F61C944D6AB7791FF89B0039481572CD7C5D49098966F87801D4313C16D644DB8612DB934A7DD68BB172F5413ECA078E09E956AE5FF1AA1E70FCF82874644FE072AACDBF5001347E5DFE68B7623D21D93B10D2F658D98535E4F015C53A1292BE6357D295F65D285B0CCF9245A47E7331FD7B308AE3B0FE33F4909CFDB64F4F6A26D882B6772EED60FFC985C2F61FD3078FD2F59366D78B33C3973E40B63322D75C816F6643B34E75D00EC4D68954BC2F28A0033A541661509EB337AD0E47BC30BCC6491FAD1F664385ECB53AA091C209AE870A910083DFE4EA5EF73059803D256B4399E63E4B71D608B3FE571868760964D7C2809851E0378FDC63BF620F1363C25C30CD1B7EA77F281D50340602F9224AD5FCB34AED819909BD05868B218E233A24770D332950AF29E8B0DE35163882C0343E2AA8FF50324FC773EDE5C94319531EA89732DF779E23262FB9064A8A359E814642D1B99A36CB122AE6E0BEAAB3500F4F0D65BBF745CA24C7685DD84496DE72CE33027E8018104D3E3B8A3A35C2AFC4A602E8FA9C42BB0FBA7A426EFA9890C2AE4384C39BCDD612214254E8FE43C02754CBE3A2E2687165F0886FCB36E669EEBC3FF86F52EDF7ED16F6246816968ECB720055842C58627C7BD81D6DB051C00B993D0743B99776CE4A793654E36AD40DE4FBDBCC74F023121CADBD2C1D0C5B8EAB4A3BC583BC97B6F4E5D3F4B825A5B88025BADE3B2C04FECADBAA18DF3138E24BC55E48104F9908C9BAA96371C622F7702D6010F59894730D819697CC3EA8C3158D5AECBE6CA7AAB7FC1CB51E410831D81AF12F49E36965011EDD9110AB4936E70335BCA7142FD96BF7C7684D2C6F9371FB39B560E3DB53E2CF4AF28288E4693A45C457CFEE2DE2BBD1AE5DB1C65EE01DC660CB27746E98646478B27F1F5A6AB571E4568FDB14EE3BA815E895944798CD1EA08331F3FE931B48898FDAB48174659493B0D39956CB4828F888DF0C1E6E10BAF50D4301FC5FB92B5D1FE0D7B5491F6C750A8FB384827807273AB2E3EC3125F4C07994A12AF71C3F1D8B0BDCECB2598E602586B54B5775B292B06A407E4DBD04BE47DB9BD008421F0F70B177E71E3980B4CF2EBF6154B6306D99136E2C8B4AF2FF3604837B455A07D2732597846CA0C2AA9366D3598BD34204046428004686B881FB5F52A0BC6C244DC453B6AF4128E1972539ED0E98FDB952E756C09FEEFAD1AA03BBA471D8A0FC2F08D572AB0C5C8EE5FCCB6C40E35CAB030DD5361A86B0E30E20756D65DC4F9D5FDEC968C9ED481DB2D3EBADEE1E6741B2184CF68ADA3B04E2A92C190F01E8F43CB7FC5D6C2A7339FD09C8B8FF9135E3DDE85BA80E54F5EB2FF32851F35CB057793E912E93147ED00FFA486BE23653AA83DA8A5BC14CDC7319DAA10995F2063BD4457618802D7B8644E6F61E655B39871CC328CC62F1AA0701A36EC9FEE032B1595B0D8F3517FF85DC09678CDD9ABB313841B10CE8AA11A6DD6AEFA6CC3D876F90783173C141D0234318D679E03B07BECCD9C90D23A93A05B2281B63AB124B1DC13EB95AED53C4367973203DB6833A84B228ADD3EBA92D952795B5E6E095056C687B031CFEF4C8A9AF779E1B2ED16163C5D575E2070D7345609DF9C1DEFD133543C76A72FF590E70362F5A73C45597BA94F70A6742AFB3216201D08505147446DEB4A140958DD88504A979B25B2A23366C81CBD06DFF74E7A93B60896876B7B6276044A6C8FAA20D657C852F594EC1CAB2B148A6AB9C84F2267641FBB28BA4F867BE2B26BDCB93F558E2626065B39431EAADDCAE761FD53CAEC6FB5DF898A2C95A7D44CD5EF84E3EB1D83CAF2E5A63A02DB8098BEF89B61E971ECA06E07821BDBDEC22A8086B82F120D149F41074FC2620270462C6D23A09EC22F4BDFCB0C5C04BCC82FF67816A4C203D80B7AC18BB30710235F1B0A02DF94FCBBACC7A1CFB719D048DA86556ABD468C69C5D4BE845D45ADE69C9A8D725CAEB9DA4FA48884B5B3570E5DA3BC102865EE9ED58E8EC07672817A72F009C9BD007BC4158C9B137E117BCE2F0255A1CFEBC2BFD8C36EB534A1B2D9CD8C8F87905375BD8B802322779248174E5F15041EA7F546F1B0D042A53A93A253DB083D7F81FEFC70DD5BF1DA47596F77BBC6459D4A79DBAA24C05B2EC968DAB2D3D21A430B98989DB43169B3EE9640178D66B3A80694647202246DF5D090CF3F3222EB4A3817760F193E38417E9DF5065D379FF6481580DAEC9956337BA21B066210588A6F80653171297D3B3F516784A02A6DCD7DD23C9340F0C13A86C7B25F84E1893D166D47F134A082C2B2EE4DF7E1D6E6EC747CCA360DA11122815F448356BD4B9B6DE4F5AD60AA47C9C7DE640B428494673ACACD8FFAAA3D6E36D657425D8F1A60C31EE940BAF7BCDED624CDC0E4DAC6A9A1F8951B1A87CB4849CB5D37AFFE410B3D00E014D8425B4D74C3A76497B6A5F1C08A9FBBB3FA4D67B1D8DBC76306EDD94D6226ADC0A202849C65D7E1AE11C1E4D21E02F3C939F17FD1E066EC50C0C81265CE0C7733836AA43EEF5A888EF0A557C964BC1CB08701FD91CE0A166D1E2D8415CDF34647D3B67434EE76B89B6BDE6368D909747004212CD632D44A4280E0C92645C44C3EAF0C01B4FF14A52CC1710058A99FA7C8CB46E06588BA723CC3FE2BFDA8DF36A7582E3F54E128D1BA5E8BBEED00464387B3280A80E9AA5724E44ECCBE883CF15B07E593660AA01E853F18BF5A511D6640386AD0867475E85766E0220AF8158FA8E494347AA140009EEBC3D423A059747C621A148B107DEC26289F9F92CBC66BA9CF0CF883E53BD62F899163FE38C74FD9AF0874493DCCE34428608C4A14CE76BB1A7600CB5D60CE0AA5454AC1A62F02F393DA1E5EA3186D510D15AE626406717C81BCC494DDA9430E2C24DA506184136CD2CD06E4626822F04E56EFB5B93FD89195B4D6D7E0835E339957E2F2F6E66F65BBB512ED0DDB2B36C5C7FB039EBAD72FE891E6AA459442EAF99929BEF947199C08EAA89A719F8052BCD3EB273EB11F1EA1914133E6545A4D6B9A1D259ED760F90C5CF56FF6E3946E008A752163AD517A3C443DF600A8E5D83D32ABE887022437B08EA6CA008A2FE72B0E7E6A22903873879656CA49391B2968E7B6029EC15B1C737DEFF674BB3340BD24D435808B781BDECB2CAF2EACA15D01856F389E7E0BA887471F85607FFB4444A16CF5FC9740CFFB0F91D3CCDC6C27E9CE96F01271341A7236502141B41DDA4EA016970395026A77B5F068F62D4432FC0CA6B377E6C634ECFD43AFB4A01DD7AD33FE82DB3FBA3924B1A48ABF1E4FCFE9CDC0F8BD4595EEB4CCF0EADEC874E2822536177FA3AE9B4570DC928A7175068AB4EB8B44F5D85A98C6D62C7DC519788142BC08915A5C25B8AF7D57AE1535320EAF9DA27806E77CBCD36102D24A29486FFDB5B3F21F88E9914BC2C9524F9010B72217CD3E524290AE85841407C5529E4AEB4C9A9121CB89E28E2FED2EEBB3EB10AA0F04FBDADF278423E80A645F3A5950BA42CE8F5CA1AF452F8E17310609F673E8B194C45A6028856BA19525A1AF21DDF66DBB42867169293631C8ECE4248F685DDDD67C5F8132F2BE3400D02571629FFF8DCD4EB8E3455370EA9672DD8C9DCFA6D125B4DA10DE0C166920E025E423DD0509E46D86876A69B2F09D11CDCAD6F4328A2B59AFF5C51CEEE28AE7023E726120A24346BC27FFA4188AF834FFBCDBAE46CA3A56911854FF595CBE35BB2D25F9A49EFAD39AE131B60DB8825496709967B4844914AE127276F74E593B36D00D934EB3B59D791D9F509B9D00BC245DF26E76DA86218E33FD2DF4019EED80A7B35D239F09C07F99000A6D0AFDE4FF6E88E596578BBA2E9CF89D070D1FD3B220E7A040EAA2D365AA75616C844C1ACD07FB19F3B7DCEA8859289B01609A3C0D7A6B790776FC7E9A606EAA2E424C2BB7C5A1E9636BC5485AF0FF25D6324E13DD067C3F88AC0F509A3D90CFDB259CE19B3FE27C6951BA56150D2293B7A5C64E8F564C0BDA74FDB4B60D9A66585F053F0BED5AC7BBD50557FA874640AF8F2EEDE4199813DC53BEE2CF3D4EEA1FF20F99E459568F899BA40448EA614964FC2844B13A83234502A4962830E2FC0AB04AD714B6FE95FFBEBE2550373E8AAFC2E192B9EC1B1BF441C56B6A1ABCC562C51258D46D63F585874E319EC6C777B6EFA137E564B38600DDA185A20727B6431825575F1731DB56560041763020F5950375ACD5DF0630E6308DDEEB474C65E36EEA086E76FE316ABAC8DC6C9C9298E22307DDA9A4170DDB6027DA5FCC4C5BC3D924D4403BE7472EB5FD9DCFEB0B74B2C59F37263E622FEAA18EE65F29A6B04F19D19397B83E24EAAAC4DC4B89E1F8E8FE22DBAD71DBBA2B1E3E3B9883C023516F4070A2EF4D60C79986459920B5402C455B856092DD9834AE32E3F6B3B4419B93EFCF288D50A0272E7E657AA76D91BA47032F7276B98E7DB9C1C676C40C3D2ECB76A243141606300D18AAD44AFCD29E626BD50EF268E83EBFEE1254039E00DCFC1C9EF04D5D1C4B68FB6DC3AB906082296F3C5ED29907A28F3CD5AB4EDFE18FD93E145F8A22FA69243EFC57FB452D6546312B64B140014BE557F111C383E6A230577E71C0D393A5FF4A64FF24DACA82EBCAEE30D15A09B23B5A8D2D7969C7A722D759C2BCE5B48B8906C6F67AABC72FA964752A7D92474A8A5EF85B50AF508F6FE268F3AB7EADEC9210CCBB4005D44ABAFE1653F5B529503F5CFAFA171DC71A6B5E714D6DE20E1ACE60FCCA0CBE39808144826CF71D57F66EB4CD9C84362FD3024AE7C94C905EB0575070E29D59B8EFABF17B2B69FE4C376232D718644512C19B10B57C137168545A00EE2B08C511ECC71007AC5587A1107BC3A186C0BA320D0CD19121906C8BD489B683B846998F33199457B4BD9B35FB9F5539746E37C00D02AEC01EE7F689CF130231ADE5CF12620C5F3CDA95C65532FB0421DE60E0974045B9FF51F6B33FFB9E57FA4F33C1E9285C5B231D3F896902592A0FE2F750C782A72A11FC421FE34E30C2A3D25E11D8942F94A2880FA2F79ADD49E81156DCAA92701B6C69C85546B09603AA65EF5FBF3CED9DC6352F3FE826DC7CB4A4A27B69FFEB1435645D5AF065727A4D6D1196D4F220DA715702F8BAD68D2F53CF02DBBB753DF045F5612B4EA3E5E64402F384C274407B43804B0AC429BB9F41B422734B95E4663D62B22A694F51D409BB9B70881732B7ABACC1333B74384F706AE7F8EA87DED4F94678BD8D61AFCF0F7DBC46E1CF96571182EBAB284DDC5649215CE1AEC155756794BAA2B3AC06A7332E900E0791DB4730D1F9C8B2210824ED920BCA37246A51653BE1221C9FF9DB1FBF9C602FDD52D0092B1BAE8FBE7716635678161F1AD15FC55B651150FF4743FBC00C55EB5DDDDE5576F21B4AFEFB9DE8069DFE7B917653E4D180F6CE483BC229D37FC72424C4BE81F59B0193D2598C75AD9B818E84985DEDB445C4DABE5956646227A2354289FBABE2CF6EA9877DC08630651D69B78AFFA04446720B55738BF80B08BDBCE28A935B020DE50DCE55E56566C607D9B8901BA171CE5D8752AFCF3BD5578FC5A469B5EE30687A6686B9CF04E9AA88815B89EE6F2D170BF84B0BF845A75B2C303B3968643511D4AB568552F4FF6C0243725F291341AAF654E72DD805C798FCD5214B14616E7AC9F3A4EA6C211B319FC9009536A1772156E62E666788121874F472FA5CAB32BA174FD0B2218F50A3BE7BDF448263F84CE6184306BDB40D6AC6EEEB7A009144D47CFE5121C5F44044D10B0776B575F883AA5CD63B5A577409851707816E4CBFBB13B047D3902D0C7916E4C9598BDADB732E82166F10149695106C8A9F3C0D2CF4349B59CC5A66177FC51A7B1098F6D30FFD8A5D016AD38097C062E0DA6BA3EB4C8FF851503B97E7A276E026DC8D92C68F979D53F9157695FC63A97A9F58D8F92140217D196A9778CD52A9074348743BCCD068B5DF2D5B76943651822D37F217E71EA6763CED121444AA3570A5880DCF44CE21FF035E8EA8107430E6116C10485E4DC7792D04A9B9717932D621B572F42221F1BAC60D3B65D93007913BB100E8658968B0CA77C533F20B9396BE2A7DB9B233028465E54648E3329BA2820ACF6CF00D46BA0CFD045C20C6BA992AEE34F57E9C84ACA1E95C45E9EC6D0BF500A7F7E6626D5777DC6AEDB370A4B1EB82BF4CD0F63DED9A4CCA567FCACDA440EC29CC67A926059152AD7BDB3F3EB06813BFDD8314C365E490C41C6FD4A6173A13F4C4A4E517037315D0EF14428275919CC61AD393BE23333F7D8A93C59DF7FBD4DFA8235AFE88803BDD881CB8E591A721E917CE44103EE38CD499655B666AC3536A1DE850F3FCA9C393454D9BD6F0C75B11822FF23EB22DBA69B08D3F4E92B8ECFE9BE9432A8B445A5BEE8757C7C53DD96FB2058A5370EFC4368FD6B5FC124FA0B9366074719377A0C533415161E29C71D5AA85356B98A138DD28D76BF35B6B9BD3AA30CEE5641266AA5B6E3476CBE1CCB18839B063A655FF7831A6B655D5DCF74C93369FC562827A2E93B53A295E86E9BF8879371A9E0A176587912D1CF344CDEA03DE86B587548FD05D775686D36B8A3B5AC77165B6226682EA37B935C9FE0E02A8FF9951E2467626865C6369A8DA0916AFBFC03DCFD599163BEE9F73F99E34A3F8356E5F193E76C4648053269A659E080A7014A3EA4D7D9766FDB36CC8919294E88D722D9996FA0EFAE5FC3DDA45C14636AE77342A5654D12731B64E40255DBB777CD68D73B7CBB3D8D1013CADE109F474DEE5565B1852F646002BDFCE39C736116E56EB8EC6F75A46F2A19ECE8F0CAD24152DFA63F89AE0C375E32AE637BFD43A1D3B027930461A8CAE0809D65E9B81DE9BA9D0D498262EF57887D6B892F149030F734B44BD9DE9A4C8E97772A50E7404020A9D64D6785059250DC03745A68353456A7229B21F0DF6AFF33894919136D210915581A525208E3FC16F1AC5BAD3908D4D7D7155929F32C5B790F625CF89B8AD92622 +remain = 65534 +max = 65535 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_256.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_256.rsp new file mode 100644 index 0000000000..a6484c2776 --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_256.rsp @@ -0,0 +1,14 @@ +# XMSS-SHAKE_20_256 + +pk = 000000091EA51EAA13ABDB2B1A37732B47125C74B4F2D624F9145E295C560DF4FFD6AEB404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 0000000900000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A1EA51EAA13ABDB2B1A37732B47125C74B4F2D624F9145E295C560DF4FFD6AEB404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C7D176B37A7DC26214FBBF555DDEF8D970B6AA840AFCEE7B674EE05845118A6FB277ABEB1A792B61CA4D24646DBBFD623564F93B74C1277C1AE4CB326411850F0371D6A848ED0BBFB8B0BC3254398F513E630D075CDD277E0AE10D8D13EBDD0CC60AB0FFC61631C5D17989AD9DDF25BADAF0BB87FD0E32975EB673434812D58CC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D9330900000000000121C29A3D4E6C5DAA979424FCA26B0EBE6D3FEA8F078FA9A98B0F55503C2541CE0A0000000000015EB6FB8267689B81BC8E2C8950E5F59F4B43194AB167C4A60EC9BCDA7572E5980B000000000001F02838F27F104405AA4D9E111D3A0B1849F6725926BA5B3A6412DEF900E7259A0C000000000001BA1EE79A04487C5639BA096A60E3E17F7A0E9C0238FA049EA7AFF52FAF5890980D000000000001B63504B794C356EB44A98DE32960830E6B275526432F232A7729ADA72571E8D90E0000000000014DA82230B909123D34E30FE0722BDD93EB6D56243518275547CBA7C473744E6F0F0000000000017AD15652FFFF1B8B9E752AD4A07EA737B8D79DE25D7F194E19ACF003E62C48F610000000000001D6819E585CEA52B14299092F01E66E9A6E7AFC9613A69B89ADE061890A230145110000000000017FB1A159FFBC19461AD72D4E385722A08E9A942BDBC3CF8352CAECD938737D89120000000000017B2C7FC20B3305327D2F0FC3C4854B0053D00E56EE4E005E43CBE807A619BEA813000000000001000000000000000000000000000000000000000000000000000000000000000000000000 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 2820 +sm = 000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6429AAFF05B285E06B6EDBBA11503F92E15E17C582FDE9CCF8FB0E5BDB90FCABDB107005759C1AD991FBACA5F12BE25CCF5A487CDCB35D2FA0415A48AED18AECFE49E32AF457F664D605D54CF42246B21C1B822727BF0869E79C2479B3CF7EF92B2D92D18C1A9520CC21A0A17908D121E1EA426738CFE364AB99172E83544AD0FEC48EF86066353B471BDF03374C02568B2ACA5D9787A3547B32EAD02723B86085852D62225D7554249CC1FE71B8CA3B01240808B769DC4154DB886DB5C1EF5B5CD1E9A5781AF0B8028EC1D1E1E82D6AD6AA45A6D07B244962F9CC5A5A14674087C37F5C128471A780F7E20C5F04EE713489718EA13D2DD776EC37B91AEC089A1CB652A4CA27DF77D2B59BDD5DB0D4657882E1C3D50D022B673C7E4C1DC6AA9D0961BA4254B0FBC7E8A37B1D610C74A511E52A8A50F4943217493F7EA4C92CF25FC55C8986FBEA375F95A3E2EEA5595322FC1079823D49731A6713DD270B3AD1DFA54D60EC4408C15DA7FC4B5BEC5120F1966279A400F0AF374CF6ACD439AB0307168092C3A8F03F4024169DBE782051501D6CFD53F3344F583668D2F25276D0F93B0896752FCAE3699AF03C2E8C8725BE6073251317D1EEFB497336A32C511CA3D91BA9C3CF4528D139148FFFBE43536D085EF62CA9EDD4A56A4127C96366A690A32F4705C98818ACAC9A62F3421985687FC5107199B035FFCFFF5103D7B169AAFA3F7873198C245BEA6FB442A5EA0710814787B60EF727174C29BA2DE46E283BDECDC6DB095544CECE9268232729556E6339B9B8A2F22FEEA16F32E6FBA5577B4CA665BE58EE459BDEA5C1765D63045C230ACB40DEE76D8FFD25275D33730D608B41AD8FCF6149DC8C5602305056A1E00EFD26E79C204239C69DEC416E8AAA98B43CCAA440867C0C6B6C74E32368C7884B8860E5AD1B518F322EE72CEC31F52CB0B5D16C7813F05F9578CECC287D621864B54E54836F3315642DAF8E0F3A61C68EFB4FCE7D560363BC9F3A5A0086D87169AAB81B9736674E598CB301F84E7F03D94EC6741B481B978440F93D3B0A5426121B516C7A4D5DDF078995BD22D0970A4E6B4D0E8F6B2040D9CCF85DA7C9522BD571EFF09D5B1561225886FFCD6B7884FFEACF7644B9DF10F6FF9F1408EB28E5F212BFB503C2F8FC7981663C50B7739E3F2D9487FC2287870964D9F328563E36677622B3E074A980DAB585FF96FD09B7A843E4B2BA51E42D964AF28BDFA113E2853EE1051EF044C34EE020DBC7172C1A1C5F71AF0F2B8A6A8F9C2E4C8BBEA834A94F34114CEE3ED19E514449946DAEF69516854BC502BB54F46086F5FA4EDAD92893384F67C4D1C11E826B5F1E910DDA7ADFB66C00FA7BEC717F2419E026C3492CE4DE1B568A4DBC25C6C592641852AD2D562A9CEF92CDA1EE295DAD0074EA1C01DC90A6831D3499FA6DC8D6B5D737C95C689192BB35FCFF90B87519113376A44AE4BA207EE9AF82719AA72ABF543ED8EC30C89BEF5ADF1723437F91863B0B6CBD2373F9638D74D6EF309D1B787311CA839339BB9AB60CB5B1F922D6C430FDF84A3A8A81B7FC0282C404FAD61A9AEC0E974476860D49A2BA734DC223B46D2C25797CC55E16A37D56B5021A9413F7F65DE41A840258A1A492267B8EA54C51DCCC1A4572023546321CE81E7F51B4DB3836B1E2CC30E6E7DC45BFDA37C100EB88E44069492CECC82E9E4EC8C7C2C9F85B0BB6B57713F156B0F0B1F2D50589DEF2CDB05E5790D34CECE7C22212AE889BAD4A39F127D0F88709DF1FA2D58AB09D249014EAD040C0934787438A1A5C7C9520F36D18AFC8DAB6866EA201DB358B45AA0CDCA0959B4F0BF7ADDCDB0CF61ECC7FBCEDD43D7F85EB9C9B771CB8EEA797E79F369BCE45087374A20BDC6FEB45871AF744BD1C6D91F72509602FDCA13C0F43D8C9C0EC8141AC267D940537B86335E609D558CB2D1DA9EE891F338DFF31CD3748B61CDE572EC77997A2BCD420E58ECBDAAFD9BDBA4BD815108B240DEA39524C501079A2815C04018C444AAC8AEC51B9207412600285537487F1C65E5E53B472D0836698B80E10F1F06EA466C78F7065088E07801C44DC68A93ECA841BFA02881FA3003878D8EC6E3CA1CC6590607558CE59C93E72BCDE6D87961B3185CA3ECD7D6A913D9F86EDB5017F5A1F28FBFF054D1BECF740CC96822076C1C173E32EB8A2A1D282D8BFEB277B9BAD5906F6C8ECDA3BEEE3253FB58D7B532C7885549593BF2984B3D6FCC2E70105FC34A1CD9A85B9B2A48FA806BB1FE35675ECD1BA10FD998068C0797A6874B02F3759F9DCD3B771041F74F76D99E4FF70A47B904C80118090DA4220AC717C36C588FD89EFC473084AB49FC4849D497AAEC8FA2A8C8DB244001F4348AE47425932E61A64C79846C4214ED25F04D7E07E38C51FF1B1B3BCF0D8D38B31CD3B8A69210C1C3E5A92FB8CD5BB3A57E03D5D9672A86589501558211537988D9B6FD2B248B4C6B39CAD3A41052A74A72C2599419F61A78459B45C7976E43E96BDC2EBA3AE45FFFC8766D70EF340F6C1BE587DFAED8EA010542245C17684A9944E53BB33C776507D940D6990B152898366FC0906F835ED4B9FE9A776EC249F3B7A73C8ADD42D2B17B5893634E68CEE35D6BFFC32B9C588DE07ADEC32475AE5AF1F29EDC5E4EBB848C5DF4EEFB01A405403F4ADDD2097729FDE708EB369DB19FAFC35528A11EFF706445E69FC3F47DDF27092C44B520438B711428B717CF2D19F31D996047E852CC36403C86BD4C2485B886668646E164CD67132C6D187490F3B18BD3A339FD5FB07DFA9F1F74466844FCD43252D480576898E9037633A8424577B3DCFFA3AECFE14317B60F573A7CB1C938876CA58C9DEE64B7EDCB6BACA85C9E20AFAD6B68054B862DDFCEB991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EA6E323ED6E8A520C761F371CF760445A3E865E4B2524DEC48F47386A1E6CE55611B40AFF393D6177502756D15DB5232BCD58ABDB633EFEA7390FF8BEA443BFB32F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C7D176B37A7DC26214FBBF555DDEF8D970B6AA840AFCEE7B674EE05845118A6FB277ABEB1A792B61CA4D24646DBBFD623564F93B74C1277C1AE4CB326411850F0371D6A848ED0BBFB8B0BC3254398F513E630D075CDD277E0AE10D8D13EBDD0CC60AB0FFC61631C5D17989AD9DDF25BADAF0BB87FD0E32975EB673434812D58CC +remain = 1048574 +max = 1048575 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_512.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_512.rsp new file mode 100644 index 0000000000..d573423186 --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_512.rsp @@ -0,0 +1,14 @@ +# XMSS-SHAKE_20_512 + +pk = 0000000C2A857867C4C12EC4296D971A38A242B9DAB9C173678C2BC776A662A1619B1B0149358B252995E4B17AD6593C1ABE2AEFE1D2A0E4FA52E24E73AFB0A4B61A3D544D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE +sk = 0000000C00000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A4E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FDE028B6F5724BB039F3652AD98DF8CE6C97013210B84BBE81388C3D141D61957C2A857867C4C12EC4296D971A38A242B9DAB9C173678C2BC776A662A1619B1B0149358B252995E4B17AD6593C1ABE2AEFE1D2A0E4FA52E24E73AFB0A4B61A3D544D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002AFCF3BD5578FC5A469B5EE30687A6686B9CF04E9AA88815B89EE6F2D170BF84B0BF845A75B2C303B3968643511D4AB568552F4FF6C0243725F291341AAF654E72DD805C798FCD5214B14616E7AC9F3A4EA6C211B319FC9009536A1772156E62E666788121874F472FA5CAB32BA174FD0B2218F50A3BE7BDF448263F84CE6184306BDB40D6AC6EEEB7A009144D47CFE5121C5F44044D10B0776B575F883AA5CD63B5A577409851707816E4CBFBB13B047D3902D0C7916E4C9598BDADB732E82166F10149695106C8A9F3C0D2CF4349B59CC5A66177FC51A7B1098F6D30FFD8A5D016AD38097C062E0DA6BA3EB4C8FF851503B97E7A276E026DC8D92C68F979D53F9157695FC63A97A9F58D8F92140217D196A9778CD52A9074348743BCCD068B5DF2D5B76943651822D37F217E71EA6763CED121444AA3570A5880DCF44CE21FF035E8EA8107430E6116C10485E4DC7792D04A9B9717932D621B572F42221F1BAC60D3B65D93007913BB100E8658968B0CA77C533F20B9396BE2A7DB9B233028465E54648E3329BA2820ACF6CF00D46BA0CFD045C20C6BA992AEE34F57E9C84ACA1E95C45E9EC6D0BF500A7F7E6626D5777DC6AEDB370A4B1EB82BF4CD0F63DED9A4CCA567FCACDA440EC29CC67A926059152AD7BDB3F3EB06813BFDD8314C365E490C41C6FD4A6173A13F4C4A4E517037315D0EF14428275919CC61AD393BE23333F7D8A93C59DF7FBD4DFA8235AFE88803BDD881CB8E591A721E917CE44103EE38CD499655B666AC3536A1DE850F3FCA9C393454D9BD6F0C75B11822FF23EB22DBA69B08D3F4E92B8ECFE9BE9432A8B445A5BEE8757C7C53DD96FB2058A5370EFC4368FD6B5FC124FA0B9366074719377A0C533415161E29C71D5AA85356B98A138DD28D76BF35B6B9BD3AA30CEE5641266AA5B6E3476CBE1CCB18839B063A655FF7831A6B655D5DCF74C93369FC562827A2E93B53A295E86E9BF8879371A9E0A176587912D1CF344CDEA03DE86B587548FD05D775686D36B8A3B5AC77165B6226682EA37B935C9FE0E02A8FF9951E2467626865C6369A8DA0916AFBFC03DCFD599163BEE9F73F99E34A3F8356E5F193E76C4648053269A659E080A7014A3EA4D7D9766FDB36CC8919294E88D722D9996FA0EFAE5FC3DDA45C14636AE77342A5654D12731B64E40255DBB777CD68D73B7CBB3D8D1013CADE109F474DEE5565B1852F646002BDFCE39C736116E56EB8EC6F75A46F2A19ECE8F0CAD24152DFA63F89AE0C375E32AE637BFD43A1D3B027930461A8CAE0809D65E9B81DE9BA9D0D498262EF57887D6B892F149030F734B44BD9DE9A4C8E97772A50E7404020A9D64D6785059250DC03745A68353456A7229B21F0DF6AFF33894919136D210915581A525208E3FC16F1AC5BAD3908D4D7D7155929F32C5B790F625CF89B8AD92622A0B155ACC09CA4CDC24518B84CCF0C924388B77DDD51F3FEE646A774CE41367F983402ED44E85B679908928FF5F7522BF9199CA1A41A6B42C6CCE575A6343E512475A3CC90B7D0A456141E1C3ED6ACAA15C6241328BA1936A6F78E0D6BEE97827CE1E329F2CC6B58E311847B4195B396C8AEFCC5D9A8F08EE282B26B4CEE8B79043589828F854650D73A433E0B879E11C577ECCFC08AB67DD9FAC9C3E5128060C2F2695DCAE7520EF6C12DB22F74F2F261ABE6F9FC6244489B96ED9222803F635DAD7FBB43AF6C2913FF809E208C97D9379BF5BC7E4276CEE51C6509A6D13D4EEC779A04A07B3D80569AF1A325ACF378A219999B8F91DD48AFF90105FFF878F400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016A30B3920D43D47945F47566B618719C38844032986568606F2DCFBD7104EEAC5436CCD86E9677E05985FA63C1B6D3E642D0F145B3FF637B96F2AFBEADED75F30100000000000197C186BD25DEEE5DC2CE5B760508549B1EFB2F3E0A34047232BDCCA39B144EAE820DB1F2D3C3159D012D7CAD7AAB1C44E15F53F4B1166E23DB8AA23ADA9E23AE02000000000001C5A2B2230C54CCBDFB5F42AD8805628B6B3D4723AB84E514035694195F2FB7E716F21EE8845170F30D1BEF79ED4468F2A45A72853F2D8F601973595098010E1D03000000000001C9E730A265A6F2DDC4B0F420CEC9C7AC976ADE4FDD5CEA3B6D5445AA2562772F76635C514BC81DA00E36681EDFEAFEBF29B1C3078AFEBAE3956D74AAF351E35904000000000001B661B82380E38D5CC77679867BB8FC1C94E77006AD05DE9576A7BD210641D25D011A056637775E72395B7643018E0BA023747219D875DBA848A58E0F9D7FD2DA050000000000019F3A31924919E8711F88BC45477356D330ACF65BDA612F6AC681F64C24FD70A6AF08B3FBB6136E4AF05B38A9205ACA4A2773D100FF79057CE6EF6C3F82AA9DEA06000000000001EDF9A31569FF07104E7B2FDF78D2CFC2FB28903D720F4D2ED95AB35DEB5EE579384ABCDC10CCE008B5BF753154B78207E452D4AF2B5646C42B89EBDDFA02570107000000000001BA911C4438781B45414444B18E3EEB1F0E57D33FB8F1BFB5DF1DC85D88A29371496D214B1042FADF9F17DFAC6215231DECB7D4ED1ADE6272BA7933403D3BADA608000000000001D85DF2FBED8348BA8E34D08202B5F944A00F91F1CC1F50C50D2460DFF1CFF490D84B84A1FDCA7A5E1760FF2E3A392D3F4ABB78116DDA6CAD29E694F9A4691E3B090000000000017C1668200DA615F45702477762DDACC68BCBDB862EDB8F34569EE898D80B4DFB1AA4251E3C3D1692C8C50DA2BD543C84A807DA4027BBEB6EA8A4093D5E560E110A0000000000011171AA4B7778E156AC8674A7522E4E47C54E7ABB917E693DD788D8782675BFF5E0108D4853BA609E9E9C0FD4FB0B8908D8D36F3CAB806CEEF40B173B740540330B000000000001AB4927F65EF9D6DDC2CF1B044B306445ABDD4629C4D63AE6278E049C96933D81862327AEC4B7D2C31B6C7509C6E45D2945E0121A0DB90076FD84AA9C5AA53DD50C000000000001F73CC84242314EBAD62F95C79805461C1902C40FD822F19F69C029997DFBEB840EE33A9905894B1290A75ABD10F4EE3BD6E75DC6CDCF69A7FA48735C08EF85E00D00000000000125A7E166681FE462663B71CEDAAF483C1D8097F57EE39EDCE104F6B10BD85AB43EA3C766F25F76C0AAD896BBBE825A8FA45AEF3C0483571EFA6FC24E973AFE4E0E0000000000013DB4DA57E43C4A075E6A8B417B395066BFB8C7291C42A04F1095A5F410002B3AE64DDC3633B2E27A4C28475C56FCBA6F0A6D5B730FF6320C89B39E55ECB22A730F0000000000017B5CF3181D29B993558C7A0E3AFD4320F7B7D1EEFDCD2FB0A3468643C74BEA9FAA355404C1E87E21758F95A9550DFC35D65FE4CF5B7023C963E54A680F9B06E210000000000001C9E3EF53D631E6DFDC8C3AFA9A9587423B4B2EB4A98CD686B3C50BFB5C9C99D7D24DB39B7D9A2E75B23666B0B7B5FAAECB29A98E1A814408EBF10A7B75C110C9110000000000012A5B873804EAFF769CEBCCB642FB8FA833D7F189AD87DFE06243AA869FC10A204159BF0E0A8C197D275F7F5402AC39337575938407F162E20FDDEBFB39D018AD12000000000001982FC2AE47D7278B0DCDD6CAFDDFC61B07E892F823F5569457913E9E6B46D137BE1E39EE028AB4DADBF1343208EB64F9ED562CD46BC8AC4F3C3F71B4C6738404130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 9732 +sm = 00000000BAA7550F0E617123968A7F276A4E50664475EB64F4E5DC6805ACFE998B45C1E0EF24208EC4F8C326F4E4D4B36902314578DB3668398F8D67F573F98468AC125A48D7968F80492509E1DADA7B6A244DB720657882BB29EE8EB5B2909CA2E050ABBF43CE3BDDFEA41964793A0E69CA85B0886938A7261F46A7DDD3AE5B2480894D524551F101A16B171E57FAED681E13356AE6949546E9B60D753BBC664F564BCF0FCCE0ED541FC5E2C3DCCF3CC35453A3AFB3250D9D21A5BBF905BA7A717F8383456EFEE4743ED451D4452861D9F91A7AF09714028A201BC2724A2F72037FB25AFC45938D425A5E3736A9DB00958A4B4207BAB54956B772C52A52AFEA8F831D9686CC4FAE8749A070DC047DB8BDB3008FBA6051528245CD1B3DB51AD261601361060C7C25138B342A815AF4EA2B32C3CF6F0765B9ACE46BCF7C20067A6F4BDC15FE2CC72B09A6F66E468EB6A056FEA2C17638BB4A642D95B9FDE18620C35DACC1D5A2CBA71FBA4C29D539F57F54A59056C422CAEF6C6F889073ABABFD9CD5F8907E6C3F60F38A328B2F2D51A03C900F4E38E81BC8E787C64F3185F2DFE129E70F8443AA8747B57914EBD06B80147A2CBC463C564D048FA7A3B2241F1850FA405BC98B7A42EDBCC38EB1B46F14C3E07DBAB10B4BB0DC090214FD105BF5A488D9131D2DE5C7FDB78CA17B03F899C3DD77E3C132D4512A6BC6658CC2ABDC229A207D3F993ADA9A1E6899BE1F550F6477A2CD9652E8298EA0ABFD3BE2D6FB92C913A4BD09BCCFA92A14293ECD9C7A7DE6BBFF45EEB4B204C66FEDE1D75C64FDE7647D580E99DF34AB555CDC3A3D5E325830FA5FD722D09F2F0DB129EB5BD82C9427587FBDF6B28E52D11307C468E9D1AC46793889EE6349B75A90D1834C05B5E914E225A5E7AD158AB48F11CF733F612485319E88FC57F9EE728E5264EADFEF56FCA94E7166C148548ECD1485A9A126B8339A457881CFAE65F87533765219D657592D28A49ABF2281522FE1D9319DC6A73EA986345B69D82027777002B40EC9BB896570BE4B1E74DE3016325C72C876A9D93C834C936DF976F78F33D9407D4A5CE48DB5879D08AF016B67FB0DCD68E12FB0770CE148944F4F4218C5BBACB24A8327E029AEBB399607EA3981BC7ECCE1978FB7C226F94ABFDA6D836F6B9A9C34B8648C29F71D9A442F0027B461AAD8E6C12E70782D89DC3371B3DC225E9AA57AD4E785AEE6D5C21DDD122CCD3B13438476E450DE59729B2A1A71A6A463AF30B4E62E7F33EBBE7E3EA6140147518E42867D2B820117E6F7BC5D685623B4557D03BF5FEE5914FA7B01D34E14B398AB4152CE9A622851DD8C4009EBB1002B88C5AD6B75B332B06E65FFBFFEC017F20C84C6670237479738DD67B0D49BC66A859051B65C42BBDC0CC4C91A15FFF9A8CB89266E4B177FA4F9A735B4B64A939C0F4FAF31B5C38A174F671F86DD21D6461D4E0B71F85F58E0F1D6C366C27254FAB70A4E7381790F81DC2BA72A96DD9738B5B8571AD2983874BEC370BBA303413922FE613DFDFCAF3E6201A69D246B10067AA141C6AFB35F79E7B8C8089145F07735986C77AF22E6C832C26AFD931648477E434B3FA47BE828F89B2FB1ACB5E1EBE621BEA0EBF225AF2F153E8FBF4D0051B455429C81B226A21F3F4DBF46E08143B20DE9CBF9D6DB13D5C0F51C9707565ABDF0666923B99E8D488D8F35FA68D02AADBF7515566B354D17A95F5787424EDC05E4739B1145265A2F7137C3D44CFEE8528520B8A98A547DAF2D8FC30E325CBA9DAE98682FC48AC544A2C7C8E4425744D7917C4B9A275238F06715D8BE40F2AE5ABE5C5594A080CC8302F91AB8B44CA0A445EE129B9A1F0D4CAFD3CD742DAA99327B2D2927E399FE9FF50D12BD3713C3A0D1843D953DAE68A90CE2435930A5A8CA8A852D12082C138BA64D31225E3901A2203EF75A1A33B64380D3C6A8A0D8C8D150097C707B4D2C6971CC79EEB8D57DF801401165627905F18017C394EB5953CC4976A022484803434DECEB76EF259C17BA424570C3DE4871A60564EEFD8BA801550ED0C8CDE89D7EEC693F01A8CD3E9E8089DB3116515E53D6747DB93DAEDC2ED26B37A1D32277EE3642C48DA63E8922672469DE0C2302DB2FBB9C5A84D55BCFE4541505370EB4984AF724A52FDCBE9ED53A634E4B9201DE89D486A5CD10CBA000F0032A954FBD69AE65C2EA4851C1C0EBD1A5AAE6C88546A21CCA42CFB70CA4CD8BAD566721249AC8D536AE892CA4E856D3042CAE77C9A15FCADA3FEC9E4A8AE7C6D63AAE1F06982258A0170F9008ED55498373EBDFD242BF018DD5810663FCFEEA83A9625135E9971F2E4943283A53D0A24B5994527BE2B7BD4EF8CF2CD51BAD59B01A2752BA68ACB92173059A0ED6E7435657963D9D048877B430DBE6DA6D99A4B2339955E4A62B7879B1AE0AB62B4718C40D0CF11000E959F9A99B95F650C75216DF446D8781EE8409FBF3D9CCCC795791621962BF96E063BFB23D9E781F4F21663871110172C46A04606DF46F57CF382D3465F1146A054C7E221B439DA76A2203491782FEE368E90BA6045CC4E0EF9CE63C69284BCBDFBDFB41FF1450FEF4BB22EDD14A0DF06A69F042C193C7823BCCB97797B50576960E352E73FF2E8F722F7A687CF296C8856863BD5F69D009D8198812F383CCC1AF142DD76D44578A50AEDFF30CB85A61333A7D58BDAEBF575A486A754F7AC60D88660EB148F3FB8BC31B6B057023013CE84EFD806FDCE46D0C2B359FEA6E4C77E358BA93FB2B71B47B0FD6EE17A4267797FBB9F11B1192941FC13992B67099757A124009EEA46A89579F361F19ED02D6F3A17F58DDF52AC0881F3D0B41B89603234CFED7DF3F4E20C1ACBD505B9EAF7A742BDA1DAC0732C1F37CF98C98A216DB63D6A6B79AA2FD02BF1F1688FA20558BF4C3F2E7CE7B054CD73495C2945105FE7A80DA396F953D456CFED09DAF45F511B1C2908A12B55EA575B23B9B104D58150D334FD0E79D4C911A845E38A7B30A586D2C0A1B72122FF85A09177630655235DCE989256B7064DC8018DCCE8DDBC1B824A71C9B3F920682CD8D522529AA613124A9DC598DACAA16A538159213D12B341AD1BF372A4E95C571826A6E7E81E87E691449B73E10D2924719190C26D394C42F015F4B581E4C32319F02D3428E611C44A86FB7DEED726826421BF21A9638C10A5E2F921B616BC9448229A71C30627C398C4257406F9ECE7BEC2E9F7B2AE1F7047E80746B156E0DA9F4D22D50731747F2BEEDDF5E92BFBE630CE1A618E4E7BEAA674BEE4380456301B5D0578ADACAD2B685BDCCD8BB20A0EA0D330F284E5AA318FECFE8893138D179FCF67DA8CED69059EE410D7B12BBA676297F731A568D53BE999E31F5F76B924C710B8C72545012CE23973E52D4FB9A7F9B934EDC2B6E27A7AD412F52D3840E70BC8A4F0DE5ED7A890D5705BC40B0732AEF50CAA5563E15310B5EB6E70167B693185124F828E88FDC6E147591CF31F0524F981832ADD6CC9D75DC323077D810A9AFB623C41245249AB508B6E84B9FDE68B70BBA0EBD51AD50B2798B2B0A3FF30BF17FD109D5B66C9D1741C3D1FAE1E33FA503AD68526AED523A0F59AD785FB6764E3E4F26AB8E4EB626E988ABF6F27010F010822710F38B85DA10A0115FB8D76D3DB3E79F27F8A5E472ABE15B46773E77511A9AB78CE4076087F5E46AA21F953E06E11AFA08EB04C98C285F1D54B29F4BA70F95758BF633C778F8A674B94AEBB68A470C68BB07CCE6E83BCC2AC6FCA5789D0AD80FEE6983E5AD6C0D877E1B378DE56C225B5E04B7CA6D668DE404B150A615F3AA81CF775C8A7087BB390BD6468E13D3C01F480ACC4E92CBE0AFFC10CA5A83BD8F800AF3C908CD95DCE85E42C6976B645F27F94BF40BC9F175B15F85E4BF965528BC226D1C56937DA29EAA5C6E37D2A73686D4287A2006FAD01878C9F18A519084C0B0E7F92907713A01060F545798F2D6DE67B1750C52289BC5A9EFC8D71617C6FC30AC2FEA0A3FCA3C689A6D7E0FF05BCC0777B60E1227D97CFE10042E03A16D18AA235D78E3991407DD87CF8E9E265A5E39AF49264BB4864436375AE62B8F9F8E675A70AF44252999A011BAECF423E511A8B6FA5E7FB0C467476520694B36AE5C0D475D3F526CB3668CF76973985D25367D037C379A06D142F39D41B86BE8897CD327A765BF6490DD33E809315C4DD225D109D978B972FC62AC0BE6EB86B2B5F49198E8E1D60BE1852F2CFF34CFCDCDDC207622E9A69BE9F363D5AEB8161D28B32116DF586770E65ACD5D0FC2A8C8969F666705D3FAFF3D16848ADF972E99AD4D8BEF1CDA5040FCB87897BCFA8CFC0160E16AF07AAC4BF858FD677916EA65213B1987680E3507E6C976683CB9FBBE0A223F7B2AE55E9CBB1B1AE83D8971500AE7AEE000660C989F6A3979F74D75CD1621ED0AC65FFB20CCB56830970F137D0014E7F334E957714A35AF3CF85935C7636D90604AA3F5D1AE5651F59456DDADD77340B873479C47A41C8480DC2D57EF6948521A23E73F677C3E78830BA27218421C098795D3DA41103F744C8A0A5A6FE6960F26C0F90C31E51A893FAA00C6B6EFD76BFA5E224E9CE76AD683B41C18711E1BC50665BC5C9D9183F3195A7117BBA583A2EEFF10B57B778B7E95DA6BF8D18E2A1391112235EC64E7701AF5C73231EE6664305C79FC59BBD67D774C80D33B9CFBDA295C483A7E063493FB8C96F915FD887E5ECCF96652AD374BBA9689BC8DF98B70B672943C21F5FD0D52D44811D76ECB7A16FA0A9DFA37D4759DAF65D69B2D84C0429F3A922A23734B95BB35D0C52E3C123214315BB9BD108C9350DE588FA5002E6A3536A4909B3924A3E7F8674D4F74C09380FA35982123E584F970820802F0E4B7561A54715D3D0A37850E879605AA0BC7546544827A8EACCB0772DFC330FF0356D34AEC0C3BF1BCEEB5B4BE7FCD9E21919F1EADC23C414ACF0599B0C9963DD2455A237B4C7AE8950D17829F5030BEE7B01D5DFB552678F0A36E9E1DBE1F0E4767B2C1820DC77C436BCC6DBA2A0707D7D8D8C9F3E754E717AF878A48FC83A89C1F296981261F179F9AEDAB136B73950F2BD1F6A033C7F33B7E5BD902C5E9183588065D20F6C8DC3648B35641F3A33A81A430161483838FB206EAA89841888B8DD0A9468616B40464A5ADF80E28A5E33E1D2CFEFAEE6A7A4C59E975913F1BDFF49B40479D4903CD92108EAE54CD4B7247FCAA5FCAFBA7E32A4C4DA1805362DFB72A1C216F7D12F687F955DEEAC751232B3745DEC50BD3E4C2575C1D13FCAABE57539AAB71694D548A9CB6C8EE765C95FA453F1630A014456FE25639FCC61CDFFBAE0A154EB7DAE4928F40B0AB881CF4D0E8A1D0725733500815124F1705DA0FDA52F7E3B270EB81FDB86B1C5AAB117032906CA96FF73661E2C707D64D27E45D9979B4DE41D64FC42DD7F8FFD0227E9421BE8D47131204A416E3B6A78BA749E5F0EA8E9902360DAF05ECD83A5D494E1E4D8D42A41621E263ECF9F6D6E01FB83A0F5CBD435C9D9B367AFB579BC0393118DF8FC3DB793A2C0D504CF5A484D346BEA86571177C4E9ECF80B77498D64305EC9B287CECDA7FDD9CBD1A3CDC3EB3EAAEF6F7236BAE6FEABC4E17F8E8173066E2AA77CB6B435A5E81F04E866262495E2682BF7E1CAC4986E7E63D6C350DF4BD4338288716B8E50E3A2DEE49BDE27FFCB8627A97941FBC5BF74E7B2811E81E3D51AAFD54C4512EDEE3069A58C5CCC95F059DEB17257D6B16F30C34D6998ECD12CCC24EDE44E2A6113DDA9D3D9B298D58E61F663070364EC4A1CED4B70676E87706D4F4281761B900D8E10B8EA9B42A1364EFD4EDB44231097FCFFF21AD515B93BCE77F9D26C3432593976AA386F0A48B70BC659FDAD0399914A577A401D24C88B971C60DEF61D30F36EA9040F301734941742B66E4D4E9C883DF71D6EE901A135E0E110FCEB8A24A609EA226DF949704925DA1917C3AE60BA1531580528D602EA592C9AB888ED4F5C9C0501AB6D229E3D7449650F6195B2094C91D771B7B2D237AAF3D3F1EB0A9B213CE39A9DE996B39C2BCB4B909383CEB2A32F361B71D6CEC12FB0ADF2EF59277E4DA927AA08D2B2354D2451E74B2425019A6FE8D29672B103F92AB1377DE4DABF8B9A03A33FC6D641604644A9E153AB0BA4DF62F4F3AC71B34BFD2ABA44C1EBDF9B1176A2139D5E8DB791C9AC2638B80F2B312731C8E9F0E01CF4FD6B1BFA84DB2A02ED6E4AB4653A167D3F65AA04A0FCF7C87FADFAD06D7A146063735C4E7BF2E981B71302E1575CF6D15AAD2C9F327C5A65712D112511376988387A3D62F90D878E3E7C8874FB439CB059979E86C18AA096BC495F516B01627B50A77009A9101E925716334B9BBA939456E42F829EE45B902EDC68E4768E5A2EB06670F2F69B2118619168D82B3418C8AE26444E3E43034A88DDEED8464B6DF093A48545712B8D86D3DB7EBCC586E589174EBBF66743E972D342EE1FB62BAE073961B6CC3264D2C6D09932AF46841964D924AC5C317BD2F4643AF98DEEB154AD6E1D6505F98AD460F35597A262EEC900BF6B0A1EE36F31D54FA32BAB6FC6C3CA6501792168FD1A936FB732231B1DE5E443EE0B5CF8CD64E7B2EE04FEFEF8A517C40FF0F78F87247C8CBE209B000C36D44DD313B226B09522D087B73C04AE187774DC21A1FA0EBD77B4DA23D067461296CD4D0FBC79B36396A3B7640212C4DC10CDFAA8643FFDFBE5B1A1D23A3D8A56AD621FEE0BEA5AA24EF6BF0612367CEB4DFCF152018C7DECB6689A94708AA9C151498DE7009EFA79D220DF6781107BF7B50FA7DEE57BDEC2100B92A493B57FE6233D87129D1602645BA18F2207A3406F7704D24C6CCB0BFFC9CB6122E73512E3CBBE36936032559E18272F127ED2313B77FE6321FE6063F8581BE30DCFE3E689E4098EEF571C08F7A38F99F2CB3FCC4BA0FBF52A07E47CE5928AAC17F69C83C0754D22DA22CD4077D9A8E8D7782E897B2F1F192845B9A334C6714AE2FEFF4B308ECF6922BD982D862CE33B170F17A1E8FA9328C63A70537BED3B893048CD8D7BD5F8447B037D153051CECD070240EB03033D416C4B765E3B47D4B2AC61FF18703D8317D400D0DE8A2B94A9D5A851E1834BD29EDDC78470C325AB8ACA665B2333712B846CFB7F65720AE12D74731181BA5A63396C1B1F5C3E00544F6B7559ADEC52DC827DEFD24C8F44CE7627CEF0759E2CC4271F7F2FB1B06FE3DFF6E78C1711CAC99350E7D5E71B811DE6DC8D845960E9E35631803E3683B85C82E861442A9F582D1565C104FB333B3EA2D86F87373BB9D0E22DD3D36CB5A6CDE4EA6105AA1B84FE4B49DBA80F67CAD6DA4535B56529EB354ADD5C31DEE3BA77D4382938734ECFC58C016085320DB34F7287F38BD74C73762603B2BE31ACF4FC6A87112E4BB69834287E01AF41CA41D26AA4F74DE75F9840439BEDDE6804AC022BE7D9104956F66E458EBC1C98B6DE4CB004DECC068398286F5F26CBF0414852AA46F9ED6B73D157274F9D62A909D4D4975923208738DBA0D55B64FD54B5EC4A1691A4C335BA8E87A5517FB4547035C995B76B7B8BAB6B990063B5C5D8A4B482E0C8625E0E1967CDF3467380F69B9628B864CAD2FA430D40180708493E9BCEA465A49B0A705DE89CBC3AA934D8336F33C86A308F229FEBDEF3DAE69416FD9A977DD92753D6801DB3D3D72CB55D60F047D1DACE7A7CD19B2B2F5BFE6E8CFE888855EB60E61D4D6346F5CB03EA0BC74119803FFA0AB111BE22B4A98318C7F503EC9F585C7891B598FA07F260D25D5F4B5E3BF38330CDAF77658BB4669E6FD54F4AA798E6B7CFFE772D6D53D2D8DA94BADE6112FCA7B093174E3AE87E0A66B20AB61E208D9A6DED593453148E4A9DA7E88B3744CEE26D19344347313172EAB5D962DF2BB9F01E6D620BB9672C468B6A4D422FCCCC1C30886C4AE37027E5D50F219CB67CE662394745B28598FB6C8E08428D00D7190D09625F02EF93EEF410FEF7546B621CF9E332E6F428D83EB15C665DB735F860727983396E43C448909A92419DC369577859DB56501B6371A250892E8BE86FB19F251307BB7F5EAA9354E73B0F2A45E316933747BB153D0700887F3FF4B76735C8309BF4868A3087C02A91F53D8EE4FCDD389C18028ABF0A74D19594A2C5B7637FC8009E7D5EC2E4C2DC1E133866C5D896E3BAA033265E8E243F95F952DC451A307A0114B4165868E04A59837708ED0248D04D7DDD886115FE37498DD905AE9FA6613689297A2D892672F0EA422F4C376107B5F07B1B033EE4E43B578D06A5429422768C6A27CCEDB58435A9D04C59ACEE99AABD468C69C5D4BE845D45ADE69C9A8D725CAEB9DA4FA48884B5B3570E5DA3BC102865EE9ED58E8EC07672817A72F009C9BD007BC4158C9B137E117BCE2F0255ACEA158E95FF35B2366BEEE9DD02F9E3909ABAD9BD170F8564E6F182655A46A54B927465A61222E88762C981C512E1D70EC65F5F7A7ECE82F760250BE2E6E65515AF363D99A7A2AF47A553CAD49732BBC49E97D2D5AB3248F79586DE72CB48FBA20A0F737D387A10094788A7F916B2355ECEF0BEF38AAD9C67DE08CF31A2F6288CC2DBE7C99C89F5A0D111E23C19BC9115EC8096B469E69324F8FFA428B81D7FCD0D38489820F83EF8DA083B401E75DE57FB7E7A88F4BA52E7B45140AA8F1A97ABE03F4E9C9852B58B450CD01FA92F0666B3F7FD89BECFDED69D3D70A789858143B8F521B2056EC817CEC2A0E61DC5E9D769ACC5A8D62893D32D3A7AD89C406BE462C460ABC57996D5759EAD97AFD5D382240679C3F2DB42A7CBBFD12AA735961BA74F1DC0235248F64E2E8F424276D0D66A54A5AE6286F489FFC3C52D4BEF770482358B4F679BD838E184C509497E99D91496193C5838A6F9A0C69853C2E645ABA8E0F0E59640642EB0069F2EB959A4C57DFE1D3FD7A64BB660906520A4ED133F1B0CF864780EC1E211B2B2451CD4F9D04D6060EEFED3B0E09DD4BD8D7639C35AAA4F2290EEB5464935509FE16C377C0161DD0AB95B3CF96A874C709802272763F0E283FEA8E53554E6354DB7E5F1C4D5EE09E1F6194C8CA78406278F5F41C47306DA5A81BDBC8F8466F32822EF7F585A5626A1FFF904F0C5F86930F9F5728232E3F17827064826E641B0BCB2A147A0D12EA4B93A8EB85AC079400486B2F4EF1BCF288ED73EFFF3F10493AEE8AA69CC37F55CC18E0C3E1F9E9914D268B7E810120DD18FF54527BE73929E57D787F167E48AC4D7887CCD78E4C4C8295939276EAD69FFD48143702864706D7217B1C5A83D233C0611077873C3392B6D209ACAAAB0713F38B758C2250950CDB8F1CDD9219C9EDFB0BF70A997EC0E7145BCA47800FFD7B09B94BFB24BD16B1F0AC0C7E6E4B6607E7BA1D11146EAD9B81378F4E0511CDAF8183CA4532A421AA2893B59A385B2C6C849078C3CE7F21C81B4215305C71DF7A9AF97D79FFE8EA57B1A147EC4BDE9F0B7A18797BFB7F48E641D043F9FD65A2F1A8B3CFD1CB637649CBE52E413F960CE2716CE25344EB7C67881263862BAE76344B5C11679FEF3CC8D06AAD204ECF9D82C785CCA36E8CE64D592B6FE14BCD941B204BD944D775AF18235F12478D3A6D195DA8034543DDF772388F1F39E994A99D78E83B45A3F72BE242BBF0B047B65AD5B957CC19C245CCC04607BEB897BF7E5C9E6A5BDDAE4684E52D065904DC71C2420EB4E8C28AC5DFA77EA3DBC314D547A2BCA9D8EA7A95E3452FFFBCEDE40BD7C73AD778525626A832B097B5F46ADAAEEF9C02B55D82B592817799FF2D350122654E686683C2BF15AF65893CC327B740F4036E0E7CCCCE6A60287777AA16E6858B1EA90D7F1BC3061C733F25DADFD612B72EBD990CDBD767665D4EAD421C4AE17815AC7AE5E959736FA4DD505E90CFCB188774C18880D264E71E1D043112C00C65E127582538CE792AF5B909015547F7BF244D66EF008BDC434CEE3AAEE28F5A7D6865B3ED85D08ADEBC9BB7A0150C8BA780ED98503FFFC4FA99CFC7CF0F3905355077761BC69BEAE276BDC22133256D2373E64DB496C9FA01809000EEB661D4098278B4A7BB06D3CD53F9CFE0D8A44E4560B0E3DD1EB1F36A57C00B8A0C49F5384BDE2F10A945E41AA4CB95C1D28E7EF2064DE4E8CCC1C79A77999B9430E01F0A96CB4596BC71157F5691AAE0CAB95A34F556364B81252BA1ED74D9623823BC1DFF2C15B803253B4BB945567148AE7662C135511008E1D291A603B4886202E9E9843ADAC01ED8BE39EF346B8AAE1A5B7FCDB5A9412235012273797811C7324255CF7B7EC4E1158B16DCB13D499A817743AF3B1F397EE3E060DF378FF06C6D9A8A0D5F4CD38F81A015E0754B3D8EBDE9E53E52A889E3E87012EE48669939D49E54D9E1B2159841E2C7D1572F52D4A4AD7D950B009967F7FEB07ECB4C861FCF6B037BC999E353F1B7C65AA3B0FD06D5CE6627C14DE5B489DE4485A1D73DD057235F1A68021A2A6A69DD0EB196131F05593178EA151B216B920F671F358E64A4DAB6977125DE0A7459B7E783C849B8FD4DF8158B3EBD370AD97030AC84824672B5EF5088E3EEDC909261D3AC83D617F29CF825EE12519A07CFF5F95F626A6484446B343EA6E02AD2ED9382293373B347177765B5316AD91F916C5D12DBFF4483337C7D819E02681A0B2672D14F1285E507284CEAAD3677383BD09D051B1805D54E5303637B33579ED70AC197F40096622FF037F212425585DADDB7463B98BA1778DF41BB35AC25CF70C28FBC38D8375F5E096E90D04A5C7A6CAB3AC340B286A730CDBD291DE9F88C472C09D494DFAC4463ACF0378F3C12D982CDBE556DFA2B61DCC65F49C453CEAA5131B2AAD1544DA7DB46C5553160EEC3A96D509E2BB0C80FC6D141EA7B730F019F0BD7ACE57470A9061047F19BAB4E8E88DAEE4A4F703BCF24CD75CC0930B02BC0CF69B640ED66FA9B99719330DE9DB8838CEC4CE696DF786A636BC0FE9714482A72491DC1DB0E7F3048FF370309AF7C2F3859DB9CC42C0A742419BB35384C0BD03F80FE006370A853983B376E904E29632FC9C56396E1E434FAC69358F814FBD1B85AC8640A6F64C90B79E1D08A03602880535556290E3A74AB0481C87A219173E3C4B47D3C3ED5328DCF97C1FC490788157F0A2CFA9BC1A920A972A21AF6A0DBEAB0577D7C39E96D66A1E1EB566A10F3DDACA296EC1B893002AC989F48CB64E2CA0239FC08302917406AE4E1F9CEF6A7DC96B5CCE0725F7EF4EB60814B4694F872D8FC56096FFC033340E794E9093FC9CC32C8A7E666A4775E2DED466473F2AA0C88331ED3D97630048ADBB3E1A652445E3AB583737CBDC1513939ECD3BD151419584B373428142C6E392BDD288C8E4D9B176AE5ED5222715C3A991933B8A497C57C5942232D34624AFB8777D190C621E71A3E55B650FD8860ECD34EC57659A17A3AD94A035EFD9161EB42DD9785531B2203F67D87AADC0A886602AD1A26BBDEDCEECAD38B844326F5C60764AF5085EF0E02E26E223907347A6773A1C9273C289168736D79C8F8515F15E62428307174C1AFBF16FB2B016861B05FEB38213833CE77990C78FAFEF51D409BB9B70881732B7ABACC1333B74384F706AE7F8EA87DED4F94678BD8D61AFCF0F7DBC46E1CF96571182EBAB284DDC5649215CE1AEC155756794BAA2B3AC06A7332E900E0791DB4730D1F9C8B2210824ED920BCA37246A51653BE1221C9FF9DB1FBF9C602FDD52D0092B1BAE8FBE7716635678161F1AD15FC55B651150FAB011DD61BCE11599B5AEA7C13DF99C13894897E44034E068549AA6DB284686CB1D3AA3BD00FD06ECACF21B3541991DE3F7362C01F95FFA9D826D41ACC2038BBBF859BB7A27A6F7525FBD906D0C6016A2A6FD9BB914832D6BB46D0CBAF2EC2900729E050028D722F67D59A1D811A5DE513BF9AB4174304172DCC0521FDB0091E2AFCF3BD5578FC5A469B5EE30687A6686B9CF04E9AA88815B89EE6F2D170BF84B0BF845A75B2C303B3968643511D4AB568552F4FF6C0243725F291341AAF654E72DD805C798FCD5214B14616E7AC9F3A4EA6C211B319FC9009536A1772156E62E666788121874F472FA5CAB32BA174FD0B2218F50A3BE7BDF448263F84CE6184306BDB40D6AC6EEEB7A009144D47CFE5121C5F44044D10B0776B575F883AA5CD63B5A577409851707816E4CBFBB13B047D3902D0C7916E4C9598BDADB732E82166F10149695106C8A9F3C0D2CF4349B59CC5A66177FC51A7B1098F6D30FFD8A5D016AD38097C062E0DA6BA3EB4C8FF851503B97E7A276E026DC8D92C68F979D53F9157695FC63A97A9F58D8F92140217D196A9778CD52A9074348743BCCD068B5DF2D5B76943651822D37F217E71EA6763CED121444AA3570A5880DCF44CE21FF035E8EA8107430E6116C10485E4DC7792D04A9B9717932D621B572F42221F1BAC60D3B65D93007913BB100E8658968B0CA77C533F20B9396BE2A7DB9B233028465E54648E3329BA2820ACF6CF00D46BA0CFD045C20C6BA992AEE34F57E9C84ACA1E95C45E9EC6D0BF500A7F7E6626D5777DC6AEDB370A4B1EB82BF4CD0F63DED9A4CCA567FCACDA440EC29CC67A926059152AD7BDB3F3EB06813BFDD8314C365E490C41C6FD4A6173A13F4C4A4E517037315D0EF14428275919CC61AD393BE23333F7D8A93C59DF7FBD4DFA8235AFE88803BDD881CB8E591A721E917CE44103EE38CD499655B666AC3536A1DE850F3FCA9C393454D9BD6F0C75B11822FF23EB22DBA69B08D3F4E92B8ECFE9BE9432A8B445A5BEE8757C7C53DD96FB2058A5370EFC4368FD6B5FC124FA0B9366074719377A0C533415161E29C71D5AA85356B98A138DD28D76BF35B6B9BD3AA30CEE5641266AA5B6E3476CBE1CCB18839B063A655FF7831A6B655D5DCF74C93369FC562827A2E93B53A295E86E9BF8879371A9E0A176587912D1CF344CDEA03DE86B587548FD05D775686D36B8A3B5AC77165B6226682EA37B935C9FE0E02A8FF9951E2467626865C6369A8DA0916AFBFC03DCFD599163BEE9F73F99E34A3F8356E5F193E76C4648053269A659E080A7014A3EA4D7D9766FDB36CC8919294E88D722D9996FA0EFAE5FC3DDA45C14636AE77342A5654D12731B64E40255DBB777CD68D73B7CBB3D8D1013CADE109F474DEE5565B1852F646002BDFCE39C736116E56EB8EC6F75A46F2A19ECE8F0CAD24152DFA63F89AE0C375E32AE637BFD43A1D3B027930461A8CAE0809D65E9B81DE9BA9D0D498262EF57887D6B892F149030F734B44BD9DE9A4C8E97772A50E7404020A9D64D6785059250DC03745A68353456A7229B21F0DF6AFF33894919136D210915581A525208E3FC16F1AC5BAD3908D4D7D7155929F32C5B790F625CF89B8AD92622A0B155ACC09CA4CDC24518B84CCF0C924388B77DDD51F3FEE646A774CE41367F983402ED44E85B679908928FF5F7522BF9199CA1A41A6B42C6CCE575A6343E512475A3CC90B7D0A456141E1C3ED6ACAA15C6241328BA1936A6F78E0D6BEE97827CE1E329F2CC6B58E311847B4195B396C8AEFCC5D9A8F08EE282B26B4CEE8B79043589828F854650D73A433E0B879E11C577ECCFC08AB67DD9FAC9C3E5128060C2F2695DCAE7520EF6C12DB22F74F2F261ABE6F9FC6244489B96ED9222803F635DAD7FBB43AF6C2913FF809E208C97D9379BF5BC7E4276CEE51C6509A6D13D4EEC779A04A07B3D80569AF1A325ACF378A219999B8F91DD48AFF90105FFF878F4 +remain = 1048574 +max = 1048575 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-2_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-2_256.rsp new file mode 100644 index 0000000000..4a3ba78be4 --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-2_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHA2_20/2_256 + +pk = 00000001049D5FE86EA348F4C6D28583AA3F9F86C36156FD23AAE68BD09B104163E2E2EB04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 00000001000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A049D5FE86EA348F4C6D28583AA3F9F86C36156FD23AAE68BD09B104163E2E2EB04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD0900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E7040000000000017D93C20AE191054626B3138F02E186A4607EDEF6E32DD3B2D788325E88FB01E90500000000000159008B71F97B67D9710ACBCAD0DCEB434823D0DDE4E8526701AF9ADE23FBCDC406000000000001410E6F39D12638391198E1827F643E6547AD7438BE85774B713D8FF3D8CB682507000000000001030C34B96241353C81CD7DDEA97ED6CBED8C9F9FB86DB60A6B78E39A253C001B08000000000001B07CBF5330F3B30963D6B0A4AC7AC4DD77585E4EB8A08B62B9AF1FBF42B76FE509000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014BCBE4FA64052B0853EDE00CD41BF95B66DA2A519216FA1A0A8BA5F10B4EAFD8BE62C40DA2A76DFD8A5EE8EF42A8B808C55A533FC488A2B33A935A635E24F3E0C717E2320FF575ADDB18C567B1333DECB0855E069D5759C48FE6D8C6A9D217BFCB7A9D40735A3151382E3456CC4BEDF6C7EC94F186FCB6BF9398FEC934714E8E231402FC7BD5153981C7C789B26208DDD77E4796F70D6A72B7B9C5EC75E4E3CD122F72621E92B1AC515A33B12B1801B2C3E461AF788661815E6BAD2E6472116B89B941A0E68A232089C6F831229BE2EB0CD244BE4FED78C8371D2DC614445C76907F4A3EDF18722BF0998FD03209C31C348CC79A2AD06ABB1B3CC549E73B206A05345EC801A1C5C42D794BA1A35747493D76CA8567B62F0C2151923D8D9CD2F37D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB385C19D6AC3BDECA5BE59F322A17FBAFF466E945FBB943BFE35854802837FEFEA3937069240712886742E890428C0C21BC057E82D5BB961095A5A18DE149CD19F79E9DC3CF0FEB5149F856C5A7BB82B6AFD4B5310993D9E4E1D33B4CC601265906186B98CAB4AF1570CFDC928C0A221A3BBFFE8E566D580A689AB51BB69826FA60135F60C1A1EA97CCCC9AE96CC93B66942370BCF910D916CBB7F87A0BF5EF46DFEBB050637754B0E40509441E19465B238EA45270D7BF5E0610A89B4A47AA821D9A3BA58127DDCEE4E7204C38E0EEDDFF72B07FA5AD8EB1FA89554D940C2C88EF588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE5966743689380FD336A081B8C7F753B889BD73F10345B8C4988A7A4C865250E3707A8424B606059E3ACEA75F2F732058477097D5BF8F5A2DF82E4AF0EE9C4BB251A5657C15808B7EF26806E2F3D61137B44C9DF4196A9208065ED1C70F9DCE3C75AFD719F14D79818812360E4709E521E78B983F99B31863039069D3F86FFAAF318853EB4A1AFFC5E598ACB6B15198E016C779BB7D77C54971E4566C2071EDFC0D19B41827913C5F7EE5D8A9411AB2706F3C9DD8E2CF4AF497765A647C1AA42E3645485AD6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291B3530D6094FDEDB782E1C927C11235EE632F6C3FA150DE1BC1125FEB330079EDB0733B58F1CDD3D20904F85DE31C06FE375E7D1E20F4C79484C5431A026EF8F5C8AC47E7FEA2A80E17256ED956484E9004BD99AD8ECD0D1EE5790A83CF9A14827C3B5D5C25AA18255F5D512917BC1FA868AF35ED3540BF0C10CABB267F612C26AE27DEDB5665A4DE3913AA2631C034C1BD22E5A721194BE6D1E4337D1CF488E9F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA498B7DA996B2692EB8C3D1D8BC9BECCFECC8EC67EE3A87DF5B0B9C7C887DCB0CBA7F5E1372399F3A4F4CC7DF247752994CE0D024D2C6E620EDD0B8CD30891FAF58D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB074AA6092A1F23DCD01D8B8C70674D55670C07A6D0655CF37D0516E6E1102865F0C53C5AF80A45B09B078337D61AFBD12DA2820AE45CC4B213C00576FF3D5FC21D0DB8D877757226F81078653EB4C90C0D2C7D304A6E0C4265DC3C1DB343202664008385964C6C56FA11532D7CF41E93F92EF28F3DE2CA1D5817AF2114A97BDA7F6504EBB2A6EE6BF4753274BE064D3CE467673717AD7350DE4E83A1BA27306F11DF36A2E30572E3FEF2EF6B2518419395DA9B7D4B191C88F3A863A477A2D226E5BCC04E39AAF1AA042A7B115CA26BE8DA52A162FDCEC6E511B1497FFB8B8AD23D3C429F71236DCAF9DE275D7B1D2DBE83822FF7D8C9BC7BA3AB5CB517228AFE2E30C53E64C44D02CF9CB51CE371827CDBDF798B1723B418EC7CDF66CF09F444A06DDB94355F529337D6A3178D754D68BE658934FEABD4F4874B11E739F0EE4E95D2D23B41F037B9668C9F74D2B3D31027861779FF8516A29246D766D2A61A02CD5B8E338B9630E8E0ED5BDACB017A6D3B89C8A1108E525BAD96E203E7A0C0B7F2148274FD20F9B53601F2B38DF303D7F8785D06260485D7507782E11855EA62F44C755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E695CCF3818C69AE16DC71782D99440EC9AF4A9C33FFBC728C9C62C47E0D37CEA661064246A8B2BBA14ABF5767F33E490AEAD721929515F091663B4437BDC34F5B15C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFFBD90B13035960ABEF4E3CFF91B9871E49B16A6F0FF86445C441921D2E698117109D810C864F024F62F8D25C263CADA33916763373D76EC8955ED113F71C40834E79A1BD5E21CC2373598C66168492FFCD083D2A8E7E480F76274C048719AFF98C5E2774BB1039646BD25A240875655A77023B7F884F5852DCD9C5DA173DACEF7F01F6527CB7F5375FEC1FD2D5C90A46D3D0501715B2D4CF51166226D8F35DB7A9ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272AC230107F230E29845C2E2283763A5832809AF2428C304C07CB21A96D7B7CDADF857F54C91A22B8AE6E4EDC0DEE01FA60697269BB1299F9FD7D3699D4D865A25BF0F31F93DAE1D51C42FE755219BC2A4B2505487483A1B81BFA86BF6A99642C51AC3DC78D5E42FEA4ADCC51C0501A8FD543217134694262E0FF5957CE719766EB0CB34CA2E541992CC2619C65822A763FE6572E3B33C4C8C216B4A62A13BE7FE6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156D49ED44C7713B7A50EEEBC575166A1B6CC3AEC2CA98398971F648242C35E8EAA21257BFAC587485D48AC54BC306344EDEBBF2A42B7E37B6086B1D9F54255742F + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 4963 +sm = 000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA701095690ED3CAA8519B752CDFBACE3666EDC260EE5325F9EA849CF9DFE6CDAD655BFAEEE83253874CD01D7C5D07C53050812648A4891B86ED9B949459337CE4E48A389B5FA7E67C06E689894EBA9EF2B30A6E85FAE21DB5E8D5F6499CF1C5A59A6D7A8D490A5464AF68854E65606D09C887C8A95A511E76865A1B432139E0C164EEAEDB66976EB9610DA9403923B229A8A81AD64A8292003BCC9A8FBD97284FB83F255CA9569583D0B40DC8A5942B9284515CCD9497D7AC749BEFAB0032A08D412C0291B9F93EA852A8937854ABE02DA2E505DE98BE606DF1ECF315300F6145C26529510438E87AB06D786CF52C18D7F9C95D7B82F4F0E1AEB59E4221D40C67EB13EF80BB3601C44E35C901ABEE1EE25BFAAB80639021377FDA25672D97ED4126B888B571BCF4A34CE363BF227A5830ACB4844CB17A942625686FEB09DBDA47AF7568C4ED2AD3DC8191BE8F775AB35E37528F5B94BE4DDFF4E56600E488856881A622BB8619A78752AB810E1EF1E95A04A10597D7B674C38102590FA8BB21B909B3E05A4453E58D0D1EFC4EE285C0B3EB81F2DB7E57C22946C3ED1D4155D0A6041072FB2968834D281510FE4DCCE2D85ED825C3F2C646CB718C5C742C8E7694C288548F3B542B812369DE5C5B650683CCAA23D4B8BBEB833B694BE7EAB094F39BD8D4E6FC2CFF5A94DF26DA0C0170FD8713CFC44391EB96DA0957FD5066FD83C6A49E07417E807C087062711DCC7BBFA4B0D54077AD8DB142A191E6BA6BB2518374F77E9F7FB8C2790CBA9844A7FC11D1E6C38E1E9EA573E0A80CE46DB790375D915D3C1F311F819D63F288CAAC1F49DCEFCF8F9B30E025FB946B8A8520860ED5D425878CEED7D6CA693518B5A2F5418135EA9316EFFDECDB1DFFC9EE3A62EFF0E6647A2D39C98B01A8BA4A8B9FDFF89292303C02C3AEEC2EEDB69DB6CAB0F45463BA7A25D6C3E4B7D39A28A65A5628A93556FA9F54E273B583F9A197BFF4731E04237D992BAB4119585A36F7584D2B25A2263A428A218CF009BF9EB533839059E362FDFAC5E8EE98639254EB106410A8BEE8214C66A7BB81C99C989737A7EC3EDB303EDD88D20A7D32FE8E2735A21A0055B3473BA260666DC3A9CD83E3AE3B6FF7D7D8D5964AF6A4DDD928553D5D44D3A6ED501CED954E06F89F82D334C458125844219EE3DB69A83DDED1030CBEA57D3D2EFE8AE168D83856DA3FBADB0102D52C5EB3E72F1046CBFF94254043D879CA0B64F7BD7AEC79F5F87C11DE3DE80756E92F7BDF93266EA7D5A17B974C518C7024DE642D12B495063AC5363EF6C532E0D9C96AA96BFC9E1D6A851663336861DA97A10FFC00A4D5A8E4F1CA04A8C91FAB90CEA2895370C57B8BD4DAEBA7B426B8E8B3968A6ECA166D917889AEBDB335E3B8115DAFADB4F258D8BBED23B21C65486E46D8BCA833B6967A09FC7DA038DE146403C9AF2D41510FE1D89C15CE442C7FCE52DD7AEF5B65923DD8CE7C031E671882B33206242916D836656273E7BCF440A020F6BD2212AFED89DB1DF7C77FEDA1143CC52238532A9293D465022828337D62D54CD964879D20BD79F2F5C8042F16A9C2FB2E1A7013828FF9CFA9903E4C46D7F0A4409133EA2AF9207A68E5DF1EBB203398C519742B581D604C13E10DFEDBCAD3EB1F66133D21F83B2C15BA70E2084E20169B68E73B20457198BA678C4496B02F7124E0474EE3BB9B7107646385F85E396D5B6413A9FF0BC969B011DC3639F1798CE4EDACACC625459A25639F6F2C5C15DB24488CAC196FD09E1A5AA1ADF13D6A4316B27BABDF3ADD912C5D1A25114B322FAC7F9853AD29B44EAFA7AA9A4ED2471B0BC91B4E1FDB7E6A80056C0F264C07EA4901DD4FF16E8E94B742AB1BA0D9B7C12674D959DF58DA15C7E22363C8AE8B2D2003632CBB912A4F788E97B9BB1C7EED5532B3026F7B8574061C607F615F7BE429B3D9A386E40B99329DE24163911705BC3137F0C728AB5848532999315D2BFD2336DA5A304D0F3455927360BF5040E95D1454106F2A8A7CD27D5510E7B54E165DB2CBF8027EE9B5CF5EBCC9DD06A5C319E2B9611BE946B6020CE4D9DD7329B336BF3E1A68CE17D1FB3485EC4AE8A823AD73C293A8AD9C8A45B2313792CEC3A649FB0DB6EE6F511B9B48E3DA2B198695DF9ACDD096ED9BE58CB5A6DFE702D4F9CEF844F63D60F6E671DF4C58FA9737EF38E41D273D28CB5091AFD0A9857C87AD54963C2B8344F1B0B7D04CF60AF2F462FC9E118D52827FEA10BB9FFE8A0669C43C7F0FD2B44AFC59F5F1E04E13D3FAEC42EF2E5CE5C39BB7E9A671F6FC6AE6BF9D49BB099E99E115FB80548BDCA3276CA7DD2F3200DA1FC5724E17D63321E7518484F9CBC19EAA901C9B4359152FCD7C0E51C82C962FF3F9A68B4F8B30440B23AD28725612F5FB98FF740AFB457915740084644120ADD17B445078AAF541DDAAE3B630834D387AA4B42958AAFD178D333B9E1D92DDDDC028609DD1C65C57A704637AD2E628163EE49D33FFA1530ED03F0A3E771B74CCF546BEF58EF21DD186BD74BB36D42E7D9D5F94DD718412DD7417024BA0156A865CBF27A461847E450F0DD03D0B6940BF0A7A3D0DCF04FFA9F744E8EDE879679E9B2B30DF30EC5C8C9AB598E42C39CE458F83C500EFAE48C4B8B2B688A9AE8C84C68CCA9D73C640BF005BBEC6C139005A872F0D032278DDCFEE8E636303308F418F73E3FCB7B63464D0B798AF6C9717BBC5DEE4C9150E8B271E12B53D2DC24D62BB1B522696BA13C5F73022D8B7CF740D798573335CAA3B04CEE0BDCADCC2DFD20E920A0B83391E2CFA2E0441B6473EBD291791F09B4ADA70A5286EB05167BD59BFD8C46427413D6079846BE00FC21D586D7F2C2AF4FEF5A3F2E0AD8F4D487B9B6BF50ACE604177339912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70D676B893C9B7BEF24DF70145E4CE1DD2B660884C82FB0EE47D1473FDD0B8C4414011CBE8E48BFCBC428382A66B103B905C0CAB36A7511B1BD6E23F4C69073CBE6C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A14BCBE4FA64052B0853EDE00CD41BF95B66DA2A519216FA1A0A8BA5F10B4EAFD8BE62C40DA2A76DFD8A5EE8EF42A8B808C55A533FC488A2B33A935A635E24F3E0C717E2320FF575ADDB18C567B1333DECB0855E069D5759C48FE6D8C6A9D217BFCB7A9D40735A3151382E3456CC4BEDF6C7EC94F186FCB6BF9398FEC934714E8E231402FC7BD5153981C7C789B26208DDD77E4796F70D6A72B7B9C5EC75E4E3CD122F72621E92B1AC515A33B12B1801B2C3E461AF788661815E6BAD2E6472116B89B941A0E68A232089C6F831229BE2EB0CD244BE4FED78C8371D2DC614445C76907F4A3EDF18722BF0998FD03209C31C348CC79A2AD06ABB1B3CC549E73B206A05345EC801A1C5C42D794BA1A35747493D76CA8567B62F0C2151923D8D9CD2F37D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB385C19D6AC3BDECA5BE59F322A17FBAFF466E945FBB943BFE35854802837FEFEA3937069240712886742E890428C0C21BC057E82D5BB961095A5A18DE149CD19F79E9DC3CF0FEB5149F856C5A7BB82B6AFD4B5310993D9E4E1D33B4CC601265906186B98CAB4AF1570CFDC928C0A221A3BBFFE8E566D580A689AB51BB69826FA60135F60C1A1EA97CCCC9AE96CC93B66942370BCF910D916CBB7F87A0BF5EF46DFEBB050637754B0E40509441E19465B238EA45270D7BF5E0610A89B4A47AA821D9A3BA58127DDCEE4E7204C38E0EEDDFF72B07FA5AD8EB1FA89554D940C2C88EF588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE5966743689380FD336A081B8C7F753B889BD73F10345B8C4988A7A4C865250E3707A8424B606059E3ACEA75F2F732058477097D5BF8F5A2DF82E4AF0EE9C4BB251A5657C15808B7EF26806E2F3D61137B44C9DF4196A9208065ED1C70F9DCE3C75AFD719F14D79818812360E4709E521E78B983F99B31863039069D3F86FFAAF318853EB4A1AFFC5E598ACB6B15198E016C779BB7D77C54971E4566C2071EDFC0D19B41827913C5F7EE5D8A9411AB2706F3C9DD8E2CF4AF497765A647C1AA42E3645485AD6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291B3530D6094FDEDB782E1C927C11235EE632F6C3FA150DE1BC1125FEB330079EDB0733B58F1CDD3D20904F85DE31C06FE375E7D1E20F4C79484C5431A026EF8F5C8AC47E7FEA2A80E17256ED956484E9004BD99AD8ECD0D1EE5790A83CF9A14827C3B5D5C25AA18255F5D512917BC1FA868AF35ED3540BF0C10CABB267F612C26AE27DEDB5665A4DE3913AA2631C034C1BD22E5A721194BE6D1E4337D1CF488E9F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA498B7DA996B2692EB8C3D1D8BC9BECCFECC8EC67EE3A87DF5B0B9C7C887DCB0CBA7F5E1372399F3A4F4CC7DF247752994CE0D024D2C6E620EDD0B8CD30891FAF58D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB074AA6092A1F23DCD01D8B8C70674D55670C07A6D0655CF37D0516E6E1102865F0C53C5AF80A45B09B078337D61AFBD12DA2820AE45CC4B213C00576FF3D5FC21D0DB8D877757226F81078653EB4C90C0D2C7D304A6E0C4265DC3C1DB343202664008385964C6C56FA11532D7CF41E93F92EF28F3DE2CA1D5817AF2114A97BDA7F6504EBB2A6EE6BF4753274BE064D3CE467673717AD7350DE4E83A1BA27306F11DF36A2E30572E3FEF2EF6B2518419395DA9B7D4B191C88F3A863A477A2D226E5BCC04E39AAF1AA042A7B115CA26BE8DA52A162FDCEC6E511B1497FFB8B8AD23D3C429F71236DCAF9DE275D7B1D2DBE83822FF7D8C9BC7BA3AB5CB517228AFE2E30C53E64C44D02CF9CB51CE371827CDBDF798B1723B418EC7CDF66CF09F444A06DDB94355F529337D6A3178D754D68BE658934FEABD4F4874B11E739F0EE4E95D2D23B41F037B9668C9F74D2B3D31027861779FF8516A29246D766D2A61A02CD5B8E338B9630E8E0ED5BDACB017A6D3B89C8A1108E525BAD96E203E7A0C0B7F2148274FD20F9B53601F2B38DF303D7F8785D06260485D7507782E11855EA62F44C755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E695CCF3818C69AE16DC71782D99440EC9AF4A9C33FFBC728C9C62C47E0D37CEA661064246A8B2BBA14ABF5767F33E490AEAD721929515F091663B4437BDC34F5B15C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFFBD90B13035960ABEF4E3CFF91B9871E49B16A6F0FF86445C441921D2E698117109D810C864F024F62F8D25C263CADA33916763373D76EC8955ED113F71C40834E79A1BD5E21CC2373598C66168492FFCD083D2A8E7E480F76274C048719AFF98C5E2774BB1039646BD25A240875655A77023B7F884F5852DCD9C5DA173DACEF7F01F6527CB7F5375FEC1FD2D5C90A46D3D0501715B2D4CF51166226D8F35DB7A9ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272AC230107F230E29845C2E2283763A5832809AF2428C304C07CB21A96D7B7CDADF857F54C91A22B8AE6E4EDC0DEE01FA60697269BB1299F9FD7D3699D4D865A25BF0F31F93DAE1D51C42FE755219BC2A4B2505487483A1B81BFA86BF6A99642C51AC3DC78D5E42FEA4ADCC51C0501A8FD543217134694262E0FF5957CE719766EB0CB34CA2E541992CC2619C65822A763FE6572E3B33C4C8C216B4A62A13BE7FE6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156D49ED44C7713B7A50EEEBC575166A1B6CC3AEC2CA98398971F648242C35E8EAA21257BFAC587485D48AC54BC306344EDEBBF2A42B7E37B6086B1D9F54255742F000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F7 +remain = 1048574 +max = 1048575 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-4_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-4_256.rsp new file mode 100644 index 0000000000..a5a2cd2a31 --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-4_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHA2_20/4_256 + +pk = 00000002CFA7F813F78C9797C0F6AD44C84059350BE2D1EE249919C6E1F305D3C0E7024404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 00000002000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94ACFA7F813F78C9797C0F6AD44C84059350BE2D1EE249919C6E1F305D3C0E7024404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E704000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF54961000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113CD47F2466A56323209409FD7FCF7485A71CD8CE96D61298A20473D9ACBF99C010000000000019AB3950B30D3E7877159B364A25B214B41B8AA32E293E2DDD44AEB7DFC560A82020000000000019C359D104347B69607EB28A02E6924C24BD2A26DE4CFFF3FF98E48688E291E58030000000000011EC9B78F3B1189A5482238BCF700922D642E45D07E7EA10833E31A4CBC3CA08F0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019C1A7BFD8300283215BA57DB5CDD95EDCBD04E1C41419317BC2069C2AAAE22130100000000000143ED646E32FC21554D8DAD350C5732270CC220F7E264ECB5B7A8E8A4586D0CD002000000000001762D040EECA13E137753604D099809D946063368BFE1C7CF0E6549FCA746F7C6030000000000015FB7406F1B25A2B4A6A1666269772EB08D6FE78D8A8395C56AD80FE6924DF082040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009D550F851D023315BE35A69C83D099341F6BA69B6A40E224DC554A3489D33729C9EC8196BD665514030C26AAEF80CD6E1BB9EC739BAA2B8E4A63EE691AD2BFBABDDEE2B13CFFEEAB7C25273CAD45409B5270678CB1535AB800679906CE77189DCFE05BBF92FB5E31F184CECF3C427437958F695917E343ACF46DA2B9D988CFE316313FA9FAAD49EDB72B007A7F3D6FC55A88E6BA784FEBE9737803AF05B4801CE0C723C0D15CD8E7CA8E237D4A1C0BB1413D369FC3F21F69205D428069EABE626B971A2B5698ED05BAE54218300BE8C4BC9A52EE5FB296BAF2A9AA42F3C865DCC1DDA69969F085C91D3CC5934567476EB70461B942059AC0F83BA10DFE783F5FB405F159563419B3F5699179D6F33AD05E840EC9227C592E361A49E31D99445437D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB3844833CA9CC7907865878A01BCAE7DB72BA4F7701F20523E0E98B27AF08AA747B57DB1DAAA1B616DE469C7FC83CAA1DA1D6BA6F0C2B0F7F2CB7A4F58FBF7FFEC292AAA7FC3B87E797DCA067ED7672BA9B4CBC27FE9AAEEA63C8569A567129990E1E12A8D23039A877F7FA3EA9B9359A842A19E33CDBF284AF95FAE2A2DDEB80030A8245A7E51131D27EAE94B6C38A8C4818CA7EAE0A1C0841E7AACDDF68A4C4491EF97D5F3F6AD8CC47D2489DF1FF96B7DD444D31DD2FFFDC69C9ED7F750526B3CD81EDEEE2CBBFC0BCEBE875DBB644B3828795D2B81DFE37E0E4E68F9A798E09588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE596674368D1D405B742EE812FB88947D9F5DE52083777E54C2F0A1F605027BCA5A12BDBF9CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318ECCE515F732608A96D4E557ACCA60F144A212276CD52FAC0F12C39F7F45565346B6EE409558FF37D5C50280099C9D75B688C7D873EA7D07EC6C9305AB367ABC2FEAFF9200CAD14D71DE9E1F1DFFC4F15FD0908C6687F585D9721AA773BDECA4C7DBDA2D8275C59A2E90EE07ED6734A09566174D695356166041C646F18180DFC5ACCBA61F1672213C3CA6933A5ED65898AEB4BAF534751900D2CF25A7A94C273533B8694EEFB366F4B3E6D4DBE7FF5FC70EF5341217906FCEC863502598936A4A0D7DD4267B1C0C6E8175CFB3B9B6BA86CF3094D4677BD57712235CA8395A6914063B4E2849AFA406B7EC6E3AE39B343EE39348D2D29A0C2319BB34655A53E1A816CD5FBAD3A3796FEF2C7B67BE4507438E5AEB603B1A0796293A274A3F3D63C7C1F14297987085EC271F06E8DC986CE41DDA37ADBB39613E6790644A669594AF10B5D7C2DCDA7190B03F77E69D79A143E9B7D8B42E18E56D1D191DE05D58DC29F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA4C86ADE353F4AA57DE2220D13EAC9BC8FE02D625EBE3BF2761493F180F968DE438B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE8D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB07425116F11D430A927D45FBAC134C59EA8E5907C35A59E0CF2FA548F9AA27A3530AEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBE6FFF1A2A91E8DD23131A7840BF7CDEA3E18E706A324AB688A5866B82EC18082D89DB83F78DB30D5CE6EF134BBCE7628AC017E6D6974B1D82E4227235AEC9862899B7A4E0E8B10A8AD0B19A54DE7ECA861D6AFA1D91C9CAC7B8D6AE536C458E176AE68697912D7EC853D514AD4EDE982FA89400CE895D3241E5610D0AFB17AEFE51FBB41E2DE044A00D84BE759242476BC0099DFE159F0CAF2187BB311DF2342A59C003778A56907F086C8DC9309D8E41703779C8E1141070708E02B9F987ACF3214A8E442B76121374DD243643D64283D01279A49154760E3567E46ACE89898BCD67842223D5B8CAB03DC13930BE7210FAB7FB2318BDCD92B642F6BF178BC30B4F959F5D8BE15F67C5AC4A4C81F1E3E707AADF0B4CD02982ED4E4E52A81EA2FCB60ACB5817849D53C2FFFBF7906E290BF76E505071913AE0361FDFCA4B279897C9DECF546FB0366D65C9F81A9B51402F3694F0B5DC600B7E4F084383B643AABC755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E6C007F614D3C0A2E45486C2E457C2E6636BC1AFB76B2A7FA351FD88399098C64E379F99B64A3340473DD46C11564937DB9A28C4DE3745308433153B2BC6D5E0D515C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFF0116375D404211C3D3302D17DDD0390712E06CA05FB4BB2AF749D3439A5B30D3E9FF4731822AE6607BD96108BD229A4BDA5ACF50F7185BD1C0F56CC56D69C008077082C0869F237A6F19D73ADCF9844686E3C5583E7D8FFDA636E70E989B1742ACA4DCE98101BBAEDA8E852555033A46F8DF4E3DCA1B9A09E9F938E0C1E468C52F7DC695389C21D0F425B4DB554FD5BE1FDC2765B997FAB1F94D864DE1B4C8FB1323A8D90DC0CD7FA7363AB70728FDBF33C2325FF97C59ADC84C104E730C85CFBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272D144DEFA2E32DCBE8CF7843CBDB9A67EAD7892ABCE9B25A6B91AF0B893846ADDDB6C26354D4D8B77B14FC2FA2D8D589237C4BAF80344C306439619E5A4DDD4630B558BC9B3581AB842BC8B630F232BD18D4BB10FFA1DD3805B18635F6A9A22CE0D470FAA2AB813662EF63C784628138499A1A3648CC877300401E61DA9A379FDB3FC6DD985CA26EE8093A24879BEF107C4D6A38017BE3AA5CCE124259C42519C6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156771072191C21BC3190193111CD3BD0604EC5427C6D70B1BF21DB6E59ED636342BC417CD9F69B804EDB6359C9F8E347AD253370E065D500CAC64BFABE3E420E39C27D20CB93DA243BB3270F1EF2DE68AFB80842E8BE7C1FD48BF0F5622530CE84C1D30BC69EE1164CC602F2522FA39158D4D0D30ABE4FDE43213ABD6E4D65E62FBEC9AA1D485599FB7ADF5C2C97B90C82A1DCCD2C44ED66CCE79EFCEDCAD0CA1366FA51DD03DAC9BFC60B79719033B32247DDA9195233329F5AA36627FCEC5E42F078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DF657C03A3914FD3BF1E82EF96AD7EA46373B0A4DD0F5655F22F754DCD35ADA89358DDAF6AFF78EEEF21010DBC6556C2C3A018E4DA1D612CC3EF237BC2B1E9E600D923E2CE04FA27CE8EE63B969F6079FF8551B8C06018E99D84669C059AE08081E3A1C7ABC19272D7FA3F2704CCF6E491AF93C7CBD4660410389D86BBA47BD5A0E996F788FB9CE600AD76485D265628019B57FC69631D5266E8E46913ED9142FEFAD87E26DE53ECDF43B352EAC14BF6DA899058228C9414E7323430F9357D6244E7165F5CA2FF2DC9899AA6D8C2B8DDE8E2C5FB7C6E02BF74F578823CFA2355F2FCA1F776C6A87943344A5E53BFA39559EF98C397423C75EB318EA9B5F375C17E7B46A8D592651E7D50E70233224592389C1EBD1EB66678AC42C2862A2C660BACD03BA4064EA38D34A7D44B32DB9E75ABC6B5025B504DEC60512A80F78876C54D36324C7143FEA85ECB9E66800E8F4004061EA7607EAB964DE3F9A273D2C7A4CECC1B4270ECFF87A254A139DEA1E0F0B0F6366C02A0A790D46EAC94866A82DD8349F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DEA67846512E96901F78E601EE427F8B1A7986FB8832D091D575C277CB202E87602D670CE131CC6023A9E83AF41486A04D62616C1E912D4EAECD5DC815BAC1C0DBDB347F6B5DF06B0F58441FAB98B9511AC0423ACFA43E0422A62AE32A48E935C6288BD0D2314C6A739A7779BFE24DD7E2D66E9C4A4111E22481688EA39F256224531ED241A9D35D395F340421F2D8F5C05B873052D2128CEDF4ABE49E609176674363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D02AB14858954A117C6B6F2CDF4823BEEF1904FFB4D841B30537D57C577968CDF18EC8631C536AF09B54D5887FC0EB11A70E86B72EF315FD722FB680EF03A3487434215A0EEA412C0D78DB2EFE20061576237453927710860F0A49DE0ED0C42FDE2A5903D635B19D4F2001EE353D7B5210E1C01F50251ED6E753635A972EC8C1914E36522B1B41BA51E9F3F1CE83BB5F526FBEC31C21983736E42EB7880B9B27EF6CAE0618E57F881193714D3E8B38C9E9056378DD79E78422BD7C4CD57D230EF44B38F6A107ABC77B8D5A953D3A3969FBB7DAB145C4F4615FAF8F2172AA2BDEB35C4A0494100CB9CE188DA4318EA5B617EBACE910A32F0A280C82AF82121720569232D71AD065E45268B36F92DDA13673529F24E6B83A865F3E266635D9655C8000C06478530294DE092640DFB324E09DB3B87497C94502BD46092D72DAEDFA93A0353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB51691B3F0ACA92B02FE916D2AEB98BD9E23313F49A0F44394883A432523EB5B34B690EF9C16B4D60572EF2D791F2BF403255A28D9BC3352B02687AD9200D34C05259FE0C93B75455218E031D59A65D4F571CD7F8B130A0CA1363BAF2D9895A8E8925ED20ADBE8FE96C34A6A13B9318AC8A23A7EA320B83B7175FB54868DAFA9E233B0F4B18CF6FC7D85F7A2B28CEEC561222C5051572B092F2FB269ABF1CC7826675F09949FC443EF723AB476E9E5D670C5F05E46DAE93837AA0F65A4E83AE2C71DD02CAB1038086531F93E163AD65BD962ACB9497C0F268876B5AD3CBBFC4C24EB2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADB0A78B6C1C4ACB8B4C97EA8C4CC3F3778CBF761AA653D9531216588A46701366E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC4050CBFA6FEF6B9FE785A59511CCCE21EC5AE3F429A07B4626A4F0C555A15B42C26A5F353E7A479A700595689D5734C39D61177AAB2943775ADAC879B4ED7B8ED826CB43881D2C1B5734F64A5490A4F77ED4DCB9775B258C18182B42C560E6CEE89A329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB041A19053D3003420EC262BF0F45F1C7CF6E55BA9001E4BE097329CA460D335BA899503CAE0D617BB7FFF0AD37076C91B1659BD448C05C49D9360462B4BC601536844FF2C635BB654EC5749FBCEF3288E41B8A7835B645E0BB501FF805EA4B39785C203BE03F0B105D17E513D50B7738E78EC18AFAB3FE134FD551E754CAA189DC4FA2308B6EED1B8CE87EBCE212E15E72C9516B778C1F62819131E2EFA7AF63BCF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0A2979199F43F2F59FB2C62E8AF2EABAFE9B89B71E75AF029BEC77A6A56F86EF6A4A7212A7458986D2DAC9E00CF68EDB81CA05A297B522D3CB2E0AC3146E4638995B683EC201C67C911C83E6BA3567D31565DF914783F41077E2C31B06640446A6D403F9D46BB9D00B3C436FE1FFDA80AD0AC466AF0417D18D5E7DFEDD7D68987BA55F545F3B89A38908BCCA1DACE0B89FFB49FBA3A67EE7384DEE68FD05721483030ED53913A6CFA059DDB451C780877E919BB86DDCA9E18814123CCC822A8F30D0AB4602815D2279398ADEDE00B23AF4EE605A771AC616CAFFCD3AB12991023A6BE6BCEAFB1672ADA631C6CC29827088627EF9380FFF46FC479E2B586432B58F95A824C0D5F08704C2B596A7BD0A36A52BFD8C14D999F92E676C83EA62DE54C3ED7ABF290BF17C48DD69F949668E11D957299DB6920D740252A9AFB65179FDD62B69D2A1A339CEF805FD258D83FD2F406841565AEF5E42ED7687D9D466E6A4E513E072A9EF6181016DAD988F7C2305A77740F196465CE30A35BF3D098781DBA7285753A9438517AA7159A9C806A19CE8B8BA5F9C99250358404671F36214E8A7B5A04767FF8C094A3CD74751835BD896FAEFD1747DDFBBE79F48148D56BF585CB0CBBF34300CBFAB9DB32469814F107EF7822151D158CAD68F01418F88B181B092970DACAE4D5DEA7AE39965D1929CBAB7685E758206D309CADC07687274657F6EEF56A657D3FED4D34C7FF6C9CC5F344F0EF4F0E752F83E06B8A23DA0D65A2C10C2D675CB3A214F5D363C35E6E10A1323579803E4268F7D868F4716BF849B3C3D8EDA94476BE7322891C36D6DF146075F11AD02434D2216351CC26600662BE0D38E1DFEF9A832B9F066718FCB2134115F33717B57936CCD2DFA3A95C1D4C4C98BD09D64EC04912C06C7C6A2FFDCA2801628D873EE6D0D43EB67FF0AC93A7666C9ACBB9400593C00316E05F0F5706ABD923D85DE72A0D1CA9F0774F5180B65AA578B95BD20C1FCC322A5B23995ACC9DC97CE3043B1A723AA2815314637B7667DE02ED0FA0924C0791CA09FA028633CCC594429D6E7429930C7F01EB6A134952E89B8CCEC743A23C63CDD9E161B5A2D1F1E0D005F16727A3B0E8B90C20656B850A4F8B5D400B65E91E45AA25A880B76BE09F226DDD4F0E0AEA00259E19634EBAD387CCAB556997A153D1C1B87AA62E5B613A5E02C65E7EE7DDE2E19D965D27B42AF8542066549A6FEFF3E10A93B349EACB843759F5E4EECA76CF82277BD55C57FAD09BE938ABB47720E49CED626AC860446B290C7FE9BC83DB0C7FDCBD5CA2B8FF6C52B2CF2556040B3792BA99DD43EDF1FD4CBE38970D235E8BEE40DDCD2708E432008992D3F9DCD73AD594171092909019E9BBE7A5D4A21EADF82C5C22D877F422EBC64734717C93A027E9EA7EDADFFBB8A04B465E2F1BDDA54BA30963A41978562C27EE91E8ADD7A95B97A1F9F5C0494C3E44AC5422759F971200B1927F5C37B003499B213C1CEF1823847ED4A308D7D98FD5E42115D49B1FD42C7405B55437E1C8C0226884DD801CD89163AEE8D74105F621EF2CE222B13ABBD14078943CE054E3D68F7E8D763948CA83876F0AB7CA5123ABA8C5F68679FCD116D03391F2A53F637D26EC486FF6363F0C297E1A672EB717107ED9540C2AAD46038F8D4C2B5D1D918AF6BFBA7DE46E6628B2C217672257EB98F585A4E4CDD87729BA5ED16719F869FA1495302E8BD043F92ECF8799DAB7B9C501DC956EE3E55FF30E6D565E228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023E10A68B5275694C30FA7BE9BE2392EE6B18651980A01348A97C4BF091DE3501B30B528092599313ADC93C8407FB07E740F784E80461A23A1DCCD78BE8A72EE2AD69CC6E63F385963275DF49AF300E5D468285CA4457F090504D42056F571A8D453903B85D7E63F893431A5A1C8A66A8E4C999F0592D75717940E296C8275952C4A8DC6E97B3D5602408DF3644E8A1338C856296C37B1BA8445883CAFB408EFB9A545AB53CD632C40659DC607F4937A4F364F7E3B47A907BD30D8558C76A8EA9EB357177B8B2639477433604EB74F9C2E3528215459533C1A989FEF107944FC8A402E29495F72F2C210135FD836028B9E21E76C6F13096DBD2BE9721DD2C35504D648C474907FFB896B014CB022942F308C3263CFF227D4444763A483658E728EE6B7954C48E3FCAB1246CED1B1E2EA9CC4D5475BD4FA43FFEF56AB2A2D779E9D206E3E657A2244108BCF55C7F4F97666457CF5F796105ABC773C541173B9E338B4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F9338191406A4C257E6B7C058565272FB78A54A46007F5550234FE9B7952A82581C08AA6A1EA68E497D663F82C5D20E9D1134816EEA319EEAC8E431A0D82B6D62F7B93D121D8382F0EB3DDBB9FCD43901C8AF1AA019A7160B76B72D4E8CA1228E5E9DFD49E24F3154F4A914987FD0264ADA4C8D6FF9EBB91C59C03CBD484E9EE72F1A98C3F97B9F2479FFB79DFAFBC33C8ED249286369F003C471C8B64A9B1546B1F31BFDD0ACA06AAB3EFB61E49CDF5506AF8A4693A7591498D9D7F8B28A72A10EC60F806A9955D7EB41D2654EE5B37C284F41CFF3F591C227E3FD0CD524379DCB384ACF486CE7B1E658CC743293DCF546BE85382FC40CFDFDFA407A9EA33AC46468E060524BF06C9CC109A726CEAF0811D0F857C08A3D4AEA67CCC0B17B2C38C53DA9F860C99E3AA769EE27CB7C9229207ACAEFE6C62D3ECFCA201DDFAAEEE1EC7BFD40086AA922961198B53C94BCFA97EEC1DC0FB8FF1D9448B6770DE4F5703CAE179FB51CEAF935F666F398B74BDE9FC87B01AFB6EE8B47490453198F9B38AA2259D2194E9EBC42E1C57994921413D6327018B91538CCB0B90E965564171D133CCD9E7F65E851971FB71F2C47B4592C2A52A4101D2EE7A69DCAB3852A56C4DBC9295D2EEC5BAD1B8A13B7EDE84768C0AF5FF0B0253B44038C236412ADCEC91508A76BD8D16E6D6BD5CBB3179B34DB8902863056CC65A4DD40B6A1929F28DFAE1CEC64A74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7E8104E8D9DB129F0AEFF48177BE4EB60236851F6D0DF3EAF508CA7F97E4D5814F71ACBCF00471EF263D3B5CD58ADEEF11E3465C704D90101A5FCC1C8CAC25387B7D6B83C7CBEF04E05BBA1766C5C5D804642609AF84AF3FA7E4572393761664021A632DA048F2A10C2A349E2E1C260C1C3CA6184BEF6045F43D9C767E2328B9AF5E48EFE8298DF69599C49CFE153BF59010741DEE011FFFBFB4EFC5AA4B5DE409B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F83369497B16CBA6B3104624902242C468F89E89322D299123ECDD8ECC98FD5C53D99FDFBBADB056D1034CA39CBBFF29300769BFF634A38678FE7BF929676A43CD0FC3161391877F0623D9B59DF30E28F5B47C0445F83B36F0AA67F6A2DB8C0C3D3F45738A4DE393D8675E286F4530AC810D244C621963923BEB20810EE32909D + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 9251 +sm = 000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA7010591AF601BF50208B6C5968D4F692F07279A9C6AA2E66590F7D2E54DCFB47261CD2CB50DDA1EDFD708F002ABF07D0001C3357A70F6511884C4185790EECECCC57389B5FA7E67C06E689894EBA9EF2B30A6E85FAE21DB5E8D5F6499CF1C5A59A6DE8D17E2B400CB70FB0A864A239D1985E799F31F1ABDA096C57123F06B2260714AEDB66976EB9610DA9403923B229A8A81AD64A8292003BCC9A8FBD97284FB83F96A944CC1878D4FBA0A59E308F18BB3A90F9704B0342262BB5FC542743D246CDC9AB35B9AE477B083CA1810094CA5FB540A37E570282E48E4CEB5FC19A7FA82B29E510FD11DA67C0C0D3B6448B88B96E0834210FDDA112F57C7B4FA60EC32332EF80BB3601C44E35C901ABEE1EE25BFAAB80639021377FDA25672D97ED4126B8D5943C4AFC991D3AD0413BE1E84DA3156547C13C9BA17DFF08C34E5B226D7389E9E8D58659CAA4ED33A02C4FD0D3315C22ED07A04A4D89DD74EB188F9E0FF02F0B87F56AFDE4094CB079CD0DF2CB4106DEA80FDEA7967AC53FC349C83C144DCA2D75F2338FEDB00B906C9EC104C5E837EDA2180E53BCF4279D3487DA42B1605BC7329B6C264A9B24F73BD95BC8890AF4C36695EC8E2C29B32F4CEF4E02DBA54908D2003A825CBFF22E3F6A582C3944C6CE0F79099F574A57715E751395D7428173F09C28EFF19BBC4B99C5ED3075C013067DDA903F8D8067153887B056A1BEADCDC912C2D8FF1E15C4F4B6AA4FC3A25CD8150DCB968F8910F6D22AFA80331596967C92BD4979E062D2D38663ABC59D3CBFED0FC6D94A1F157100389EB4322BF05345F497F595F49DEC594407A3E14B55229FC1F72F4926A530EB5F018889C61F4E34D56CFBFE507E95A9E3D86591149D0E5DB6DD9A9A83A811D103580A40F3EAFAA8FD4A12AD43A403062FC7003ECC756E3E26F8B1BA47801DAA46173063E3788684AC3B47FBEA813CEFA4754D02086281392EADE94F003AD0EF78DA65C89BAA29BA00E66D42A900F85130532F5303C7BE837860BC82BC2CF7CDF0ECEA9429324A966984DC99442F4ABA490765F650C46FB2FF9CEA7A8549C511820CB2C81C1119E23CF21A5FADFDB79C0C60627E58576F274261515F1D9F4ADBBC5F6E4DB507F51EAD30CDFD170155A675ABB01E2C06C2E04365A619CC6294601207BA2CCCC2C1B049484D6D933B4EA4A53B85BA8826BB108E2C952F3242AF6AFADA16D637C5A2328C40E977558DBDECCB8D643E07A573A9CB5DB4518877320FBB4998BFDC592B0C80FEDEE27F500EE81F76D642DA862FB4DC7DDE2B33A88A1C5AC5EBD3E3E887B7E0BCDD9121C2855C87CCC9078FFD868D7F0BCAB9C6072DC52A6153A0DC12803AD91DBE0FE7081209F6371361D5124161843DA7EC990EB54FD15CB869367DD46439B14A2742EE6EBFF2C55CCA5FBB9C29C633E4C347BBE6E4C95A0F0F9BCE5B2498F110E32A3127A635B6DFE2413D522BD462E99E87FB994697278830F86200B9471B5BB0CBC8D62AA1AD1A74AC26884557924123193F3F7540906676F61AC572A5E6BBC3E395E57FAA869661A2E4E12409A5E93DC41D80304AA2C5460A3C233D422BE3274839110264F30E81818E6E3C7E9BE404E7FC7F65B63D626E1E2E34E94DA2CACCA212FB48BE3F9EAA310547E73C388D881F36AE21EFEDD23744F620169B68E73B20457198BA678C4496B02F7124E0474EE3BB9B7107646385F85E396D5B6413A9FF0BC969B011DC3639F1798CE4EDACACC625459A25639F6F2C5CC0C8F560E82F0063AA2E8E30BE04FA85AEF5C9611EF09217024036C5BAADA004AD711158BFAEEB39C98014D0C1A172699F3C6D33C5D9DC9BE93C7F3A5780F02A0D255B78E7882973749CE5859469B762FAA1148C77AADD965812EBEE90117C4CA841B2EF96801D464F6EA1053BF96F6E69F495D45535AC3FD4411C27FF7DEE1AEE1E3CC0C81F4B82E43B89CACC69C9B8ADCA1670F7D4E50DB7BCD94C2115E75F382819029917785C50C6293EF5A4461875F80FECE5C7F7BFD56D8B45D8D59D19FA3E07904DA1B884619C6E3FF0826E79AE517976FC153C3398CB2DC279B1E90BBFE9E700412A7D23BDCA95940640182B3D6373522124BEA741629250B1BEC7BB67CF87021CB7E256C70F86B56C1B9C8E222683513965F6CB1CAEB8A6E90054B7B720A94A981790243729EDAD9D6BE0866AFCAF7BA6E3B7ABF0CA31CFC74DD2C1E852D3991702738A85EC058C598740343B21D7817D3CB805E07860B3EFEBB2B2B70F2AF126A3DABA5C918B224DE444B8733E6FA601B3D349307E94583D0EC976AEDA2B90972324B3ACE8C7B79A67723AEA037E12DA9EFA9CA9668A4F5FDADFB92C273480A18885B0DC4B717D93BCDD352B3DE4A2A90F04B239520B8C1149BF0D4EC078D85E41744750FDA0D2767044797A4C3BDB3307C68D3782370C2FC6F67129BE58F68365C622E70B4DFF55E2C1B9F1759BBABCA9629C31DE06948FC51E605F1B5C01196329311414797CD5F67FFC54AAD04C803FF7E83C2E8BA224CE8369A9FBD8420530F63CD1638B988724A1E11888CB9A2B11411C221BA02F0ADCF54F6F0BFEB7D77B5227DB43AC1360C86DFEDA86872B28FA47CE1C78A4DA2508F21483C440334815B9506D25B8D970FD578FC5AAF4B225892F9EC8E55F185005E630CF90BFF0245E82E1D31C75E2D8542DB6E613BA52A0831D06796D3F4D752CA7F4D280B6021BE71887616028A0B0ECB4193524480B917CD352870C0C33591E887DF0B23E656D7E2729177C18213323818435F2951FAF7288F66F9B7B6ABBFC9617B0191CC9DA4EDE34F511E0849E7C27115FA6EB6C43172DC2FD4CB1AF4C27A4A6CFA68635EAFBE197FA2785E5C4BC21108FBB7FF7D8B47C356EE380B7A1DD9F2F9912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70DCA617FE06B50B30FDC6C79E168F5C8BD57CBA8E2CC34CCD54E6665ED65E0F64F8970AA0F4B350BBE7F49626406F6F1828F6C57A1CF9FFD94051500D66388DC4FC22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC9D550F851D023315BE35A69C83D099341F6BA69B6A40E224DC554A3489D33729C9EC8196BD665514030C26AAEF80CD6E1BB9EC739BAA2B8E4A63EE691AD2BFBABDDEE2B13CFFEEAB7C25273CAD45409B5270678CB1535AB800679906CE77189DCFE05BBF92FB5E31F184CECF3C427437958F695917E343ACF46DA2B9D988CFE316313FA9FAAD49EDB72B007A7F3D6FC55A88E6BA784FEBE9737803AF05B4801CE0C723C0D15CD8E7CA8E237D4A1C0BB1413D369FC3F21F69205D428069EABE626B971A2B5698ED05BAE54218300BE8C4BC9A52EE5FB296BAF2A9AA42F3C865DCC1DDA69969F085C91D3CC5934567476EB70461B942059AC0F83BA10DFE783F5FB405F159563419B3F5699179D6F33AD05E840EC9227C592E361A49E31D99445437D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB3844833CA9CC7907865878A01BCAE7DB72BA4F7701F20523E0E98B27AF08AA747B57DB1DAAA1B616DE469C7FC83CAA1DA1D6BA6F0C2B0F7F2CB7A4F58FBF7FFEC292AAA7FC3B87E797DCA067ED7672BA9B4CBC27FE9AAEEA63C8569A567129990E1E12A8D23039A877F7FA3EA9B9359A842A19E33CDBF284AF95FAE2A2DDEB80030A8245A7E51131D27EAE94B6C38A8C4818CA7EAE0A1C0841E7AACDDF68A4C4491EF97D5F3F6AD8CC47D2489DF1FF96B7DD444D31DD2FFFDC69C9ED7F750526B3CD81EDEEE2CBBFC0BCEBE875DBB644B3828795D2B81DFE37E0E4E68F9A798E09588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE596674368D1D405B742EE812FB88947D9F5DE52083777E54C2F0A1F605027BCA5A12BDBF9CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318ECCE515F732608A96D4E557ACCA60F144A212276CD52FAC0F12C39F7F45565346B6EE409558FF37D5C50280099C9D75B688C7D873EA7D07EC6C9305AB367ABC2FEAFF9200CAD14D71DE9E1F1DFFC4F15FD0908C6687F585D9721AA773BDECA4C7DBDA2D8275C59A2E90EE07ED6734A09566174D695356166041C646F18180DFC5ACCBA61F1672213C3CA6933A5ED65898AEB4BAF534751900D2CF25A7A94C273533B8694EEFB366F4B3E6D4DBE7FF5FC70EF5341217906FCEC863502598936A4A0D7DD4267B1C0C6E8175CFB3B9B6BA86CF3094D4677BD57712235CA8395A6914063B4E2849AFA406B7EC6E3AE39B343EE39348D2D29A0C2319BB34655A53E1A816CD5FBAD3A3796FEF2C7B67BE4507438E5AEB603B1A0796293A274A3F3D63C7C1F14297987085EC271F06E8DC986CE41DDA37ADBB39613E6790644A669594AF10B5D7C2DCDA7190B03F77E69D79A143E9B7D8B42E18E56D1D191DE05D58DC29F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA4C86ADE353F4AA57DE2220D13EAC9BC8FE02D625EBE3BF2761493F180F968DE438B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE8D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB07425116F11D430A927D45FBAC134C59EA8E5907C35A59E0CF2FA548F9AA27A3530AEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBE6FFF1A2A91E8DD23131A7840BF7CDEA3E18E706A324AB688A5866B82EC18082D89DB83F78DB30D5CE6EF134BBCE7628AC017E6D6974B1D82E4227235AEC9862899B7A4E0E8B10A8AD0B19A54DE7ECA861D6AFA1D91C9CAC7B8D6AE536C458E176AE68697912D7EC853D514AD4EDE982FA89400CE895D3241E5610D0AFB17AEFE51FBB41E2DE044A00D84BE759242476BC0099DFE159F0CAF2187BB311DF2342A59C003778A56907F086C8DC9309D8E41703779C8E1141070708E02B9F987ACF3214A8E442B76121374DD243643D64283D01279A49154760E3567E46ACE89898BCD67842223D5B8CAB03DC13930BE7210FAB7FB2318BDCD92B642F6BF178BC30B4F959F5D8BE15F67C5AC4A4C81F1E3E707AADF0B4CD02982ED4E4E52A81EA2FCB60ACB5817849D53C2FFFBF7906E290BF76E505071913AE0361FDFCA4B279897C9DECF546FB0366D65C9F81A9B51402F3694F0B5DC600B7E4F084383B643AABC755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E6C007F614D3C0A2E45486C2E457C2E6636BC1AFB76B2A7FA351FD88399098C64E379F99B64A3340473DD46C11564937DB9A28C4DE3745308433153B2BC6D5E0D515C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFF0116375D404211C3D3302D17DDD0390712E06CA05FB4BB2AF749D3439A5B30D3E9FF4731822AE6607BD96108BD229A4BDA5ACF50F7185BD1C0F56CC56D69C008077082C0869F237A6F19D73ADCF9844686E3C5583E7D8FFDA636E70E989B1742ACA4DCE98101BBAEDA8E852555033A46F8DF4E3DCA1B9A09E9F938E0C1E468C52F7DC695389C21D0F425B4DB554FD5BE1FDC2765B997FAB1F94D864DE1B4C8FB1323A8D90DC0CD7FA7363AB70728FDBF33C2325FF97C59ADC84C104E730C85CFBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272D144DEFA2E32DCBE8CF7843CBDB9A67EAD7892ABCE9B25A6B91AF0B893846ADDDB6C26354D4D8B77B14FC2FA2D8D589237C4BAF80344C306439619E5A4DDD4630B558BC9B3581AB842BC8B630F232BD18D4BB10FFA1DD3805B18635F6A9A22CE0D470FAA2AB813662EF63C784628138499A1A3648CC877300401E61DA9A379FDB3FC6DD985CA26EE8093A24879BEF107C4D6A38017BE3AA5CCE124259C42519C6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156771072191C21BC3190193111CD3BD0604EC5427C6D70B1BF21DB6E59ED636342BC417CD9F69B804EDB6359C9F8E347AD253370E065D500CAC64BFABE3E420E39000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D00C27D20CB93DA243BB3270F1EF2DE68AFB80842E8BE7C1FD48BF0F5622530CE84C1D30BC69EE1164CC602F2522FA39158D4D0D30ABE4FDE43213ABD6E4D65E62FBEC9AA1D485599FB7ADF5C2C97B90C82A1DCCD2C44ED66CCE79EFCEDCAD0CA1366FA51DD03DAC9BFC60B79719033B32247DDA9195233329F5AA36627FCEC5E42F078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DF657C03A3914FD3BF1E82EF96AD7EA46373B0A4DD0F5655F22F754DCD35ADA89358DDAF6AFF78EEEF21010DBC6556C2C3A018E4DA1D612CC3EF237BC2B1E9E600D923E2CE04FA27CE8EE63B969F6079FF8551B8C06018E99D84669C059AE08081E3A1C7ABC19272D7FA3F2704CCF6E491AF93C7CBD4660410389D86BBA47BD5A0E996F788FB9CE600AD76485D265628019B57FC69631D5266E8E46913ED9142FEFAD87E26DE53ECDF43B352EAC14BF6DA899058228C9414E7323430F9357D6244E7165F5CA2FF2DC9899AA6D8C2B8DDE8E2C5FB7C6E02BF74F578823CFA2355F2FCA1F776C6A87943344A5E53BFA39559EF98C397423C75EB318EA9B5F375C17E7B46A8D592651E7D50E70233224592389C1EBD1EB66678AC42C2862A2C660BACD03BA4064EA38D34A7D44B32DB9E75ABC6B5025B504DEC60512A80F78876C54D36324C7143FEA85ECB9E66800E8F4004061EA7607EAB964DE3F9A273D2C7A4CECC1B4270ECFF87A254A139DEA1E0F0B0F6366C02A0A790D46EAC94866A82DD8349F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DEA67846512E96901F78E601EE427F8B1A7986FB8832D091D575C277CB202E87602D670CE131CC6023A9E83AF41486A04D62616C1E912D4EAECD5DC815BAC1C0DBDB347F6B5DF06B0F58441FAB98B9511AC0423ACFA43E0422A62AE32A48E935C6288BD0D2314C6A739A7779BFE24DD7E2D66E9C4A4111E22481688EA39F256224531ED241A9D35D395F340421F2D8F5C05B873052D2128CEDF4ABE49E609176674363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D02AB14858954A117C6B6F2CDF4823BEEF1904FFB4D841B30537D57C577968CDF18EC8631C536AF09B54D5887FC0EB11A70E86B72EF315FD722FB680EF03A3487434215A0EEA412C0D78DB2EFE20061576237453927710860F0A49DE0ED0C42FDE2A5903D635B19D4F2001EE353D7B5210E1C01F50251ED6E753635A972EC8C1914E36522B1B41BA51E9F3F1CE83BB5F526FBEC31C21983736E42EB7880B9B27EF6CAE0618E57F881193714D3E8B38C9E9056378DD79E78422BD7C4CD57D230EF44B38F6A107ABC77B8D5A953D3A3969FBB7DAB145C4F4615FAF8F2172AA2BDEB35C4A0494100CB9CE188DA4318EA5B617EBACE910A32F0A280C82AF82121720569232D71AD065E45268B36F92DDA13673529F24E6B83A865F3E266635D9655C8000C06478530294DE092640DFB324E09DB3B87497C94502BD46092D72DAEDFA93A0353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB51691B3F0ACA92B02FE916D2AEB98BD9E23313F49A0F44394883A432523EB5B34B690EF9C16B4D60572EF2D791F2BF403255A28D9BC3352B02687AD9200D34C05259FE0C93B75455218E031D59A65D4F571CD7F8B130A0CA1363BAF2D9895A8E8925ED20ADBE8FE96C34A6A13B9318AC8A23A7EA320B83B7175FB54868DAFA9E233B0F4B18CF6FC7D85F7A2B28CEEC561222C5051572B092F2FB269ABF1CC7826675F09949FC443EF723AB476E9E5D670C5F05E46DAE93837AA0F65A4E83AE2C71DD02CAB1038086531F93E163AD65BD962ACB9497C0F268876B5AD3CBBFC4C24EB2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADB0A78B6C1C4ACB8B4C97EA8C4CC3F3778CBF761AA653D9531216588A46701366E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC4050CBFA6FEF6B9FE785A59511CCCE21EC5AE3F429A07B4626A4F0C555A15B42C26A5F353E7A479A700595689D5734C39D61177AAB2943775ADAC879B4ED7B8ED826CB43881D2C1B5734F64A5490A4F77ED4DCB9775B258C18182B42C560E6CEE89A329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB041A19053D3003420EC262BF0F45F1C7CF6E55BA9001E4BE097329CA460D335BA899503CAE0D617BB7FFF0AD37076C91B1659BD448C05C49D9360462B4BC601536844FF2C635BB654EC5749FBCEF3288E41B8A7835B645E0BB501FF805EA4B39785C203BE03F0B105D17E513D50B7738E78EC18AFAB3FE134FD551E754CAA189DC4FA2308B6EED1B8CE87EBCE212E15E72C9516B778C1F62819131E2EFA7AF63BCF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0A2979199F43F2F59FB2C62E8AF2EABAFE9B89B71E75AF029BEC77A6A56F86EF6A4A7212A7458986D2DAC9E00CF68EDB81CA05A297B522D3CB2E0AC3146E4638995B683EC201C67C911C83E6BA3567D31565DF914783F41077E2C31B06640446A6D403F9D46BB9D00B3C436FE1FFDA80AD0AC466AF0417D18D5E7DFEDD7D68987BA55F545F3B89A38908BCCA1DACE0B89FFB49FBA3A67EE7384DEE68FD05721483030ED53913A6CFA059DDB451C780877E919BB86DDCA9E18814123CCC822A8F30D0AB4602815D2279398ADEDE00B23AF4EE605A771AC616CAFFCD3AB12991023A6BE6BCEAFB1672ADA631C6CC29827088627EF9380FFF46FC479E2B586432B58F95A824C0D5F08704C2B596A7BD0A36A52BFD8C14D999F92E676C83EA62DE54C3ED7ABF290BF17C48DD69F949668E11D957299DB6920D740252A9AFB65179FDD62B69D2A1A339CEF805FD258D83FD2F406841565AEF5E42ED7687D9D466E6A4E513E072A9EF6181016DAD988F7C2305A77740F196465CE30A35BF3D098781DBA2F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549617285753A9438517AA7159A9C806A19CE8B8BA5F9C99250358404671F36214E8A7B5A04767FF8C094A3CD74751835BD896FAEFD1747DDFBBE79F48148D56BF585CB0CBBF34300CBFAB9DB32469814F107EF7822151D158CAD68F01418F88B181B092970DACAE4D5DEA7AE39965D1929CBAB7685E758206D309CADC07687274657F6EEF56A657D3FED4D34C7FF6C9CC5F344F0EF4F0E752F83E06B8A23DA0D65A2C10C2D675CB3A214F5D363C35E6E10A1323579803E4268F7D868F4716BF849B3C3D8EDA94476BE7322891C36D6DF146075F11AD02434D2216351CC26600662BE0D38E1DFEF9A832B9F066718FCB2134115F33717B57936CCD2DFA3A95C1D4C4C98BD09D64EC04912C06C7C6A2FFDCA2801628D873EE6D0D43EB67FF0AC93A7666C9ACBB9400593C00316E05F0F5706ABD923D85DE72A0D1CA9F0774F5180B65AA578B95BD20C1FCC322A5B23995ACC9DC97CE3043B1A723AA2815314637B7667DE02ED0FA0924C0791CA09FA028633CCC594429D6E7429930C7F01EB6A134952E89B8CCEC743A23C63CDD9E161B5A2D1F1E0D005F16727A3B0E8B90C20656B850A4F8B5D400B65E91E45AA25A880B76BE09F226DDD4F0E0AEA00259E19634EBAD387CCAB556997A153D1C1B87AA62E5B613A5E02C65E7EE7DDE2E19D965D27B42AF8542066549A6FEFF3E10A93B349EACB843759F5E4EECA76CF82277BD55C57FAD09BE938ABB47720E49CED626AC860446B290C7FE9BC83DB0C7FDCBD5CA2B8FF6C52B2CF2556040B3792BA99DD43EDF1FD4CBE38970D235E8BEE40DDCD2708E432008992D3F9DCD73AD594171092909019E9BBE7A5D4A21EADF82C5C22D877F422EBC64734717C93A027E9EA7EDADFFBB8A04B465E2F1BDDA54BA30963A41978562C27EE91E8ADD7A95B97A1F9F5C0494C3E44AC5422759F971200B1927F5C37B003499B213C1CEF1823847ED4A308D7D98FD5E42115D49B1FD42C7405B55437E1C8C0226884DD801CD89163AEE8D74105F621EF2CE222B13ABBD14078943CE054E3D68F7E8D763948CA83876F0AB7CA5123ABA8C5F68679FCD116D03391F2A53F637D26EC486FF6363F0C297E1A672EB717107ED9540C2AAD46038F8D4C2B5D1D918AF6BFBA7DE46E6628B2C217672257EB98F585A4E4CDD87729BA5ED16719F869FA1495302E8BD043F92ECF8799DAB7B9C501DC956EE3E55FF30E6D565E228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023E10A68B5275694C30FA7BE9BE2392EE6B18651980A01348A97C4BF091DE3501B30B528092599313ADC93C8407FB07E740F784E80461A23A1DCCD78BE8A72EE2AD69CC6E63F385963275DF49AF300E5D468285CA4457F090504D42056F571A8D453903B85D7E63F893431A5A1C8A66A8E4C999F0592D75717940E296C8275952C4A8DC6E97B3D5602408DF3644E8A1338C856296C37B1BA8445883CAFB408EFB9A545AB53CD632C40659DC607F4937A4F364F7E3B47A907BD30D8558C76A8EA9EB357177B8B2639477433604EB74F9C2E3528215459533C1A989FEF107944FC8A402E29495F72F2C210135FD836028B9E21E76C6F13096DBD2BE9721DD2C35504D648C474907FFB896B014CB022942F308C3263CFF227D4444763A483658E728EE6B7954C48E3FCAB1246CED1B1E2EA9CC4D5475BD4FA43FFEF56AB2A2D779E9D206E3E657A2244108BCF55C7F4F97666457CF5F796105ABC773C541173B9E338B4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F9338191406A4C257E6B7C058565272FB78A54A46007F5550234FE9B7952A82581C08AA6A1EA68E497D663F82C5D20E9D1134816EEA319EEAC8E431A0D82B6D62F7B93D121D8382F0EB3DDBB9FCD43901C8AF1AA019A7160B76B72D4E8CA1228E5E9DFD49E24F3154F4A914987FD0264ADA4C8D6FF9EBB91C59C03CBD484E9EE72F1A98C3F97B9F2479FFB79DFAFBC33C8ED249286369F003C471C8B64A9B1546B1F31BFDD0ACA06AAB3EFB61E49CDF5506AF8A4693A7591498D9D7F8B28A72A10EC60F806A9955D7EB41D2654EE5B37C284F41CFF3F591C227E3FD0CD524379DCB384ACF486CE7B1E658CC743293DCF546BE85382FC40CFDFDFA407A9EA33AC46468E060524BF06C9CC109A726CEAF0811D0F857C08A3D4AEA67CCC0B17B2C38C53DA9F860C99E3AA769EE27CB7C9229207ACAEFE6C62D3ECFCA201DDFAAEEE1EC7BFD40086AA922961198B53C94BCFA97EEC1DC0FB8FF1D9448B6770DE4F5703CAE179FB51CEAF935F666F398B74BDE9FC87B01AFB6EE8B47490453198F9B38AA2259D2194E9EBC42E1C57994921413D6327018B91538CCB0B90E965564171D133CCD9E7F65E851971FB71F2C47B4592C2A52A4101D2EE7A69DCAB3852A56C4DBC9295D2EEC5BAD1B8A13B7EDE84768C0AF5FF0B0253B44038C236412ADCEC91508A76BD8D16E6D6BD5CBB3179B34DB8902863056CC65A4DD40B6A1929F28DFAE1CEC64A74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7E8104E8D9DB129F0AEFF48177BE4EB60236851F6D0DF3EAF508CA7F97E4D5814F71ACBCF00471EF263D3B5CD58ADEEF11E3465C704D90101A5FCC1C8CAC25387B7D6B83C7CBEF04E05BBA1766C5C5D804642609AF84AF3FA7E4572393761664021A632DA048F2A10C2A349E2E1C260C1C3CA6184BEF6045F43D9C767E2328B9AF5E48EFE8298DF69599C49CFE153BF59010741DEE011FFFBFB4EFC5AA4B5DE409B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F83369497B16CBA6B3104624902242C468F89E89322D299123ECDD8ECC98FD5C53D99FDFBBADB056D1034CA39CBBFF29300769BFF634A38678FE7BF929676A43CD0FC3161391877F0623D9B59DF30E28F5B47C0445F83B36F0AA67F6A2DB8C0C3D3F45738A4DE393D8675E286F4530AC810D244C621963923BEB20810EE32909DC96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A3 +remain = 1048574 +max = 1048575 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-2_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-2_256.rsp new file mode 100644 index 0000000000..8fba48c4f8 --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-2_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHA2_40/2_256 + +pk = 000000030D4B3BE22EE30889C2EA6A12AD6FCC92452E1B92832A599FB4CE52C86E8C429504562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 000000030000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A0D4B3BE22EE30889C2EA6A12AD6FCC92452E1B92832A599FB4CE52C86E8C429504562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5832CE029A1A95FFCBD5C8B157282F7364E680C60B252C49483FCA03529693B074E0D2B1F6DFD6463B974DE6829A616F20C839B0D2B8BE5405623B5B722EF22F7A3BB78E91315F715D9DCDB0C8639CB8A90685BEE7969671789047083CACF24FBC4B601B1B23B2E79E42176B2438CB405BDF46369F4DE5F411B2ACD32BEE3065DF9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD09000000000001D5DA3370DA40FE4B2AA8D93A4C52E009ED16134083746A63365266ED868E33160A0000000000010EB7A75A56A1497F0FC1FE5B3F6B396014CC9357B7FE8A6D2BA1B553EE3518610B0000000000011B23B9B57C09E7B440346ACFAAB7028D8821AF52CA85D5CEEE66FA4E95B45CA40C0000000000016AC8FE7754C3CBB4F71F8514603EAE30A764437F404409A1283CFF4B7159C0F80D000000000001CC6FF52DE53BEBD4E1D3DD11D0BE5FFEB977CA63FF2ED1099705AD3D5BEB1AE90E0000000000019B6C3951BCA1748DC7B89630F962DEB3937A4F8D15BF5634741113C38D2699F10F000000000001F21F01A1F02A9D105C71E89A189791BDA7CFB7BC89003D2EEB2AC6E7DBC26814100000000000019CD3ED9E3D49C10FE36B3813045F452DD0B3CEB702EA9FD3DE2289FEA46C9E41110000000000010CD4EC639F5FA5159D505EFD1215E62E35B38AC9A8B36077EB263B10F5BB4B741200000000000111A178357024706621EF264E4A66422A6F5B9F4C24A35579CB17DC686277D0591300000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F7F8F9EAAA74A5C910DD60B2FA5179B3FC341BEDAB53B1E957F40AFFE59FD454EE839D34EE92ED029C1B5853A46CC8B48B58DC4F74EBE2164B7F867B17ACD180761BBD5017870DCC53B0ADDCBB8DD1A6F5D014B1A789493C53C3D7B304F6237F836AA9372B0CD7007588A7EE166C1F8BC1C7826CA9D6E2D73B1B217E238FFB65DA1671204B7137B3C91D19ED0DAA12A98AB71C239C6F0E6B29D3F61DE3F71688560646DCBB9846A8F28BD1E7606E2C93CC0CBAC8A85BB578671BB01347E7B2BA757AA92131B2693D7F9501E87FC7C1BBEE1B8BF15E28DAF9B74487ED12BE8A4075FDE22DA018C0531776136F0FAB5ABF372E160CF51685CD0B8FEC7D63D39F4A7EE635051E54EEBEC7E8C4A408EBE848B7255685201592E3730C4DCCC6E7DE956B4FF296E76D0052EC6C037ACACA6E6474CB17AB271FFCA98A688D224C3A25425F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E7040000000000017D93C20AE191054626B3138F02E186A4607EDEF6E32DD3B2D788325E88FB01E90500000000000159008B71F97B67D9710ACBCAD0DCEB434823D0DDE4E8526701AF9ADE23FBCDC406000000000001410E6F39D12638391198E1827F643E6547AD7438BE85774B713D8FF3D8CB682507000000000001030C34B96241353C81CD7DDEA97ED6CBED8C9F9FB86DB60A6B78E39A253C001B08000000000001B07CBF5330F3B30963D6B0A4AC7AC4DD77585E4EB8A08B62B9AF1FBF42B76FE509000000000001D62A2ECDA2D153580BB57CB3FC1EDFFE89B6C06DE234962509FDD49A5A2438EC0A0000000000013792F4A440FAC20AF31472E40F1E79BD1E1C5DADC93FCA0319589FC55A542CBF0B000000000001FC454756AAA4BF5A8163937BA2E80D39CEF46D765C11FD66664120A83A61838E0C0000000000015DD4A3768F248125F414048EBD3F6AA793AAE4CA471DEDF5A9890841DF6DD56B0D000000000001CF0D1BF19096E3DE0950E9EB4C435D0C6B3DB4604FEBB60342D5B7C30528D4730E0000000000016ADD9B858AD6562C3B812B026D9BCE050D5A40ED6D936B1034C036AA490CFF910F000000000001925FBBBD85D4CB4AA7F5D18D703449AEABB18A5D32CEF076C16B7131DCFC08D8100000000000018DBF8B67F11FF96E3229EF8CBDD85719101DC3D8E6F636CEC6D19E63ADF5679011000000000001AE3D1E12FA31B287D509FBE36C261650C199242799057289B96E8D67301B473312000000000001AB1B5ABFFCFA0D28692F1FE23A1C1C3C31133714D112C66E05A09912A1CE32C213000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087DFB8B692D4548E69E8F52A40B52D87261DAAEA3F734803A146D4622D4C8B17E1D98A7B04CF346B99E512072176F7A8811405EF38E007181DA3563CABBC577F41D6B8EEE36B0D67FF4AA525185A5821F2ACE2DD7F0607828ACF8AB08FE940D7FD268225449F5D20ABF61D2C7DB585A8513AEF60841E1BFD4AD3C47D3A00F68F71DCD9236D7E0FBC428C7095CA12D8D10B2E69C9FB6C976F4831246C9C0E2686091FB040E21C594960A1F6734A0B84BAAACE4EEC7FD1FABCA7F71373620EF656309B93B9D768970B0A03B9E07FA9C888A01D85B0B92F6550534E528BFF6289CC398003AC6A91CF86329B6BEB13854C20A8A75DCBE7A470B216C334CFE6AC120B8AA42EF5A9BC9FD224967218F17A334DB9364F966DA366BE08CA2D1C6DBAD769ED1537C3F5528CA849841BA495B78D07901481631E624DC0656F7F5D0B4820B6FC2269E404ABD245B49EB4FE7FB119E88663C8B8E75EC63C9C5A8EE478313B3B058DF1ACA81F65DB0F2E3E411A30158178585699BE52B6C11A2DC966753D7485AFBC75AB6EB6D0443DAD871D0BF43128A057593EBD325466AFCA3EA492311A31788F75372B5321217937AB4FF23D37D3A01E3578E758A2087941120E801C12F26FCC55D089C712C0A05E67122E28351745998168D1760B16D105D854BF2EFF369971D100CF448D3D00C2C34D5F6037A07522DE2EBE014E1E60D7A535B4CAC42EB69F7856E7A259627F4492A0CDA142D743D7BB90F78EDCC15B1EDF8DE7D0D4366367E581254AF959768265DAC9175E18F133DFFEF628CF769EE7E9BD0E07259AFD067AD441ABF81FA7726FEB1140C3146BB510185AF098DB53040DB97F1EF894CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318E413A87250637B5C4A4BF18A2D661BB2458CA7C7F9E320228FFFEE614E88838DE28767053DAF289E9BB8073D60114D20309CD17A6EBA5FF2FC47B49402DA3600DBC4323559761781818334D1C0CAF34FAB5A940C83D6A363433E390C3B589E1B6D09A2F4276547FB279D1F0E2D1ED91A3AFC953F9E7942BEFCF2AA66B19AE877A6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291D560067063A6EBCB1EABAF7FC12F66BD94F1BAD021254D0CE1F1F850B081262A446E84188C3A9A3CB89A80BC9E8F597EA247A39A6F59BE2D76CCDD6C96DDEB9EB0A272D02C5327DF20934FF8C0E26C71F6736FBD5B85A56F15E41F03DF2713DA70DEC489B962A1F7E119465FC8D72AD1DA559EE0F25FF661AD2F62C6BF172C4B7B0891FF05D0C985FBDCC4DEF2DFC3A73AEA39EAE9010A080DD47BC1268BBC1B5282DA83C62A9FE25CBC62E611951A411B03FA8832E227D761A35F4FB902E54083FD05142177B5D2987BE26FC4F9C5D13FFA21E7488F19245FD19D9FE2DA32608B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE5BCC31B508B8177B41775B459DB06F4AACB419F24EA979AA24C996554DEC91EBCB16E9E1B754DCD221E02231F10FBAABF79E362A514D54670DE7493B7CD7B66BAEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBB0A1E0563E934CB60493FD19327C71D824F361B1133A15E47857567979B5F8288D5FABC9D1D47402577CFAB60BF840EEF0D9173D47757BAF197EE10941704811690592F587BC7F532446BA10B875CB7994CA2613A25F65D16A6735E9CC0C4238036F68FFC1A893DDE19859CCE3F5ABA348F769D122DE567889C14924B243B1379AE65238446E7294F293F0DF1751C166CCF58B4F76A4A7A6178A136E3F72D120FCCFDD47311A340A0734C7DC77664B6D7BD87EA93215C69CA59F0DAD8E258637B49DF9864B84B76089E4F50B6C2BC496835D701C6F106B2B96CDA03A7F118AB5AC2F7073E7596BAE489C83FE68A8DB1E9A5427A31E8A6DC4E2962E5571FF061908EBBED929D64B2505C1C491CA277C2917E0A964218059309167716F47FF2699FEE7248ABFC6723085934D706ADBA0BE046CE3156EE682A5E0ED51534CFEBFE9B7118577F6D3157F31E8D849071E31A734BCC1DABDEF02B7D817FBFFF2CF120ACAF9BE403C35D92B960CDABB7242115FFBC4208977E19BFFBF250DE7C71814EC7206CB8F2E1D523E293E557D49801FA6D9E5AE279D396F91021690DF5EA153B3020CA3E08D8C53DC9DCD731315CB24C9394C6DEA84543806DF231011B086BE37A57CA2B888A74FBE7379EA346ADB56D932BA4B7B857A7918116B70987865FEAB8A42792F788F8CE13F75670B36029660F68A7E27FA23EBD2CC06C7CE9A51FC7B92220D44C4E9C7900E1FFD77D08D35B34B201EC5DCE6348FF7AA08F0DE5A4AE7C664F8E70D3531E181B4B5F7D74E8B6FCA7AE776AC73C4620B77C1C2397B987C241CC139C6407FEBF5B912A407695EE8AB6612C8C3D610D6E11E107E43AA6C638FF86104557546FD5CA0098C44C4EFEF0825DD5E8B33E5311238A32672242BD19ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDC05256E7B9EC23FA6F460956174696C9283AF19A615B7FD209C25EEA0587D15765808D7814EA792B7C31F469AA7004FB9A78EA5E59459C6E3F75E9E4DE961B5FABE5149967C9F97B1BC5DBF8E297DB4B25FC55241FDC189E9488FE06F71E9D1D4E19D50E7A3B81FCFA4799B127AA0D8C12FAF48811D52E4EA08D965813E20A7CB532F3EBEA5CB60601DDBFB1CD19FCE3F0A9CD1E452D1BCDDD215B91160F6EF5892280D847E32600F50E5DBB0DA83A650FD17E4A58EC02BC05DE23CD3B2C04172708C15A96A3D43A212FFD4401EEC87861C35351A0BE9D7D4D6AC5D60DA8AB5E1BBC7D943F4439AEBD7A6B022C8EFEB712BE5EAB7A1802CDD2FB9D93FA6E4383586E517A4D79D9FD2F6BBFEF8C65F1F3111067670E6A059A1308948697F5650C + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 5605 +sm = 0000000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA7010591AF601BF50208B6C5968D4F692F07279A9C6AA2E66590F7D2E54DCFB47261C040A14FD137EE498C24B0DC750905F56FED22A393C31815CAF6ECFA1D3BC458E3DCC2B150E1DD088C95AED7DBA928946BCC8351DAF6136F7335FA45EE8F4651C6B0A4897AB5ED84C95BF9D9D78816FE9E92F843558029A08EF7015764C3D1AF1852C50D360F65F887479E9631A2CA30FE3AD92E7BF648643835F4F8CC081A6C9255CA9569583D0B40DC8A5942B9284515CCD9497D7AC749BEFAB0032A08D412C7E9C14ABF9DB094E3BC134A7340CCC65AF466D98443007DC0D228B92614C4AEA2949A5EB26C517909E0E663E36753491182975206009107509DFFC898D308B903E84A8B29718BF7125397AFF5467D53CF8F36EB945B6B98D48E81C0174A0E035CD71994D48CEDA477BF92043B7E7C743DFD9E32948D29632C6C47355A5701C0EA6EEF78B8184B2E355CC338055DD2A26DD02B1A0740CD15F6CBA4EF429254DBC42B4E4CAF8C6A654DC35E975B5D6F725102362943C6BE446FE298B8F60D4F7945F48FA30DE2E92AD9D0EAC1F4B2F6B8DBA9D1F8CCB77367706BBBF6A04658E8B5B20D28D1B9384DF1D710AC39FAF699989418B7856C2034C695A693ECC336EB44A408370993A75DB92E04D2AE87E9B68A9B3ED860AE3B2FE35CF590BBD5C8FDB578DDD5CC10FD6A277CB7F7E3FE7D4A0BE921B1618FEA9ACD67A0A6403A4CF19503DD53FB1B3AF7ACFE24C28A700632DD3934A56129B66BA60E6BE40B7EC27DAE98F99E31983B4C2DF95885EAFD770642683F7BE36EBD50B76020DA763EC0CDFED7CF9BAE790E7EC9573A0DE43636BBED92A210DFE814B95600B775240CF7337D124B757C9441C0D52C3585DD7B4EF2379A73DDA87B41CE87DDCD392A4B6FD9942A9A24E79B7D98A56EF751FD1AAB89A95F99301932337C4E7820B84B1DE9CA28684AC3B47FBEA813CEFA4754D02086281392EADE94F003AD0EF78DA65C89BAA18FB1BD12E0428923AEF51F55928C8DA0D632382E3325E4CC5C6A3EBC4776C9F6520EF2C6960F0129A707F90315AC1AB035A7BA0D293A6400C30D363DF000F536BC9BE5B558AF33A21292D74831447DC10BDCE1DDE460F168D09CE0EBC1866581CDAABB3A1CF1B2F23B1B131831F0AA6A9B9812A422573EC10548371DA356F10510E48DFB7E23CB49D6FCA39A1E0F471F16A8BB65AF02150D059036D00386DD2921D5E8459ACCA633C5B50F7C6A36062BE168AF6246317A8B052CD7F15A96EDC0BCA137C5F65137C2F61DC5E02708B286B4A416EB49929D86E713FB912E44B87F85D73CB40792FF03F8F20427D951444990CA3976A71368A7DC1455E880722F0300029FD0D41FB427D0515FF9AA3344F5F3E4811431191A1AC406B7A16DA1063115DAFADB4F258D8BBED23B21C65486E46D8BCA833B6967A09FC7DA038DE1464689E09376BF39F4C562ECB1A68E02D5D91318EC0C91D38E8E480B8A0E65F45252585CE1A0C20AF62AA5A28C4FBF5D15AA7B0A71F964FF58031123CD5A9986D9F89CC18F2B6664B4D83235357E327821B297F813F86DCCDB13E3B5903FAD26CFB2298461DDE724EDA70528C54B09AB368C492937993E3093A695AF1F950B14A1D348B12C3C63D8F8EADB9A26B8FFD6DFE7453EC8B6FAF4B9F5D6F74F6CDB81B5420169B68E73B20457198BA678C4496B02F7124E0474EE3BB9B7107646385F85EFBFDFA55C12A388836717BB2BDD97E89121C56C3B53E8198242315C9E438512ED74BEB3BDC53DC8CBD2A281340B78F7635419636A3C38E9D5515CF8A035A439DA3D8CAABF1F06E36E322294F3AE10918203801BE05F8E4EB9A2663EF7894829F1A380C43F95D362E0680D9EA2CA47E1DC8C49703E22650B765F847AD86BE25A31377FD516E97B6AF21BDAACCDC8D36619B7D89C62EAB646A95A90E0EB467A75C97C1014D748D6338397737A54B2CD2CF860C14CBE1AAC697CC39DDE00C3037102F1EAAC7944E4E7E754B78F741D7B3858E4BF33C370C36B8A7560D6445B6D2F64E165DB2CBF8027EE9B5CF5EBCC9DD06A5C319E2B9611BE946B6020CE4D9DD736E8EEAA2FEB1CC855F0A745AAC84A610DF0238112C6519F8E7346C45331A6036D84CE48A25C1D687C6AB85A7863A51EE463CD2CC2686DF144AEC6049484E3FC1A1646DDEF29122F153C5B5197A2AA78E9DEBDF712F92C42BEDB4BF1AF46B1A2F47D9A150ABAFCBBB6BD37E68B51E1E3B76A88186784096804E0CA23134BDB161FC9578D9E5B309675B6C05FC8264D3591B80770D4DDFAD2AC53E7A93D8A8469837FAFA9FE1D707144A2290523A7D25AC1BB6206AB824556519D2B909E4D04DE82C273480A18885B0DC4B717D93BCDD352B3DE4A2A90F04B239520B8C1149BF0D4EC078D85E41744750FDA0D2767044797A4C3BDB3307C68D3782370C2FC6F6712FC7EF1891A77E1A3F29D810C205EE212E75863F3B8B1ED216DF888ADD07AFF47738AE40641E2FEFB1097D7048C618D4A0B99C75276B6F41EAFB4FA57B0925FB775013C6C36C81EB0FB69F86B4514EA931FF7E4C4179DFDC31A92EE8F618321A2F4DC28CF39967D04766E592F7D01995F16BA6C9D1FBA22CE251F5F0FA554D59D75BD46109FC202692A3FE21B7739AA9C39BD1B24AB82C59373CC06D3F92D48BEFBA495E0499587494A9B6E4974C37F5C006A34FF102A23985FA9F660326DA393AC26CB1FAC5A29BA262D95C83C292FF3D75F4DA803F4C139AF1778793988AB25608A8216E5C8E91E1E89EFEA60DC1306CFBC26529D23619E354A7F1332E790C6730FBF34A79269B4FD988E4712D927E6487995B4A33B3DB9292AF35F278442B99E10440F06BC626856A2015DD832F087A72864D390131A760B46BFE305E3B4E9912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70DD4CD344ED3ADDBE4C748D918BF1846595ED36485972F668C65B6365638B4D41B7AA1071D740ABE2895647F286260874BBE8C609165131481CD81E4C6D98293F1C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5832CE029A1A95FFCBD5C8B157282F7364E680C60B252C49483FCA03529693B074E0D2B1F6DFD6463B974DE6829A616F20C839B0D2B8BE5405623B5B722EF22F7A3BB78E91315F715D9DCDB0C8639CB8A90685BEE7969671789047083CACF24FBC4B601B1B23B2E79E42176B2438CB405BDF46369F4DE5F411B2ACD32BEE3065DF987DFB8B692D4548E69E8F52A40B52D87261DAAEA3F734803A146D4622D4C8B17E1D98A7B04CF346B99E512072176F7A8811405EF38E007181DA3563CABBC577F41D6B8EEE36B0D67FF4AA525185A5821F2ACE2DD7F0607828ACF8AB08FE940D7FD268225449F5D20ABF61D2C7DB585A8513AEF60841E1BFD4AD3C47D3A00F68F71DCD9236D7E0FBC428C7095CA12D8D10B2E69C9FB6C976F4831246C9C0E2686091FB040E21C594960A1F6734A0B84BAAACE4EEC7FD1FABCA7F71373620EF656309B93B9D768970B0A03B9E07FA9C888A01D85B0B92F6550534E528BFF6289CC398003AC6A91CF86329B6BEB13854C20A8A75DCBE7A470B216C334CFE6AC120B8AA42EF5A9BC9FD224967218F17A334DB9364F966DA366BE08CA2D1C6DBAD769ED1537C3F5528CA849841BA495B78D07901481631E624DC0656F7F5D0B4820B6FC2269E404ABD245B49EB4FE7FB119E88663C8B8E75EC63C9C5A8EE478313B3B058DF1ACA81F65DB0F2E3E411A30158178585699BE52B6C11A2DC966753D7485AFBC75AB6EB6D0443DAD871D0BF43128A057593EBD325466AFCA3EA492311A31788F75372B5321217937AB4FF23D37D3A01E3578E758A2087941120E801C12F26FCC55D089C712C0A05E67122E28351745998168D1760B16D105D854BF2EFF369971D100CF448D3D00C2C34D5F6037A07522DE2EBE014E1E60D7A535B4CAC42EB69F7856E7A259627F4492A0CDA142D743D7BB90F78EDCC15B1EDF8DE7D0D4366367E581254AF959768265DAC9175E18F133DFFEF628CF769EE7E9BD0E07259AFD067AD441ABF81FA7726FEB1140C3146BB510185AF098DB53040DB97F1EF894CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318E413A87250637B5C4A4BF18A2D661BB2458CA7C7F9E320228FFFEE614E88838DE28767053DAF289E9BB8073D60114D20309CD17A6EBA5FF2FC47B49402DA3600DBC4323559761781818334D1C0CAF34FAB5A940C83D6A363433E390C3B589E1B6D09A2F4276547FB279D1F0E2D1ED91A3AFC953F9E7942BEFCF2AA66B19AE877A6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291D560067063A6EBCB1EABAF7FC12F66BD94F1BAD021254D0CE1F1F850B081262A446E84188C3A9A3CB89A80BC9E8F597EA247A39A6F59BE2D76CCDD6C96DDEB9EB0A272D02C5327DF20934FF8C0E26C71F6736FBD5B85A56F15E41F03DF2713DA70DEC489B962A1F7E119465FC8D72AD1DA559EE0F25FF661AD2F62C6BF172C4B7B0891FF05D0C985FBDCC4DEF2DFC3A73AEA39EAE9010A080DD47BC1268BBC1B5282DA83C62A9FE25CBC62E611951A411B03FA8832E227D761A35F4FB902E54083FD05142177B5D2987BE26FC4F9C5D13FFA21E7488F19245FD19D9FE2DA32608B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE5BCC31B508B8177B41775B459DB06F4AACB419F24EA979AA24C996554DEC91EBCB16E9E1B754DCD221E02231F10FBAABF79E362A514D54670DE7493B7CD7B66BAEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBB0A1E0563E934CB60493FD19327C71D824F361B1133A15E47857567979B5F8288D5FABC9D1D47402577CFAB60BF840EEF0D9173D47757BAF197EE10941704811690592F587BC7F532446BA10B875CB7994CA2613A25F65D16A6735E9CC0C4238036F68FFC1A893DDE19859CCE3F5ABA348F769D122DE567889C14924B243B1379AE65238446E7294F293F0DF1751C166CCF58B4F76A4A7A6178A136E3F72D120FCCFDD47311A340A0734C7DC77664B6D7BD87EA93215C69CA59F0DAD8E258637B49DF9864B84B76089E4F50B6C2BC496835D701C6F106B2B96CDA03A7F118AB5AC2F7073E7596BAE489C83FE68A8DB1E9A5427A31E8A6DC4E2962E5571FF061908EBBED929D64B2505C1C491CA277C2917E0A964218059309167716F47FF2699FEE7248ABFC6723085934D706ADBA0BE046CE3156EE682A5E0ED51534CFEBFE9B7118577F6D3157F31E8D849071E31A734BCC1DABDEF02B7D817FBFFF2CF120ACAF9BE403C35D92B960CDABB7242115FFBC4208977E19BFFBF250DE7C71814EC7206CB8F2E1D523E293E557D49801FA6D9E5AE279D396F91021690DF5EA153B3020CA3E08D8C53DC9DCD731315CB24C9394C6DEA84543806DF231011B086BE37A57CA2B888A74FBE7379EA346ADB56D932BA4B7B857A7918116B70987865FEAB8A42792F788F8CE13F75670B36029660F68A7E27FA23EBD2CC06C7CE9A51FC7B92220D44C4E9C7900E1FFD77D08D35B34B201EC5DCE6348FF7AA08F0DE5A4AE7C664F8E70D3531E181B4B5F7D74E8B6FCA7AE776AC73C4620B77C1C2397B987C241CC139C6407FEBF5B912A407695EE8AB6612C8C3D610D6E11E107E43AA6C638FF86104557546FD5CA0098C44C4EFEF0825DD5E8B33E5311238A32672242BD19ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDC05256E7B9EC23FA6F460956174696C9283AF19A615B7FD209C25EEA0587D15765808D7814EA792B7C31F469AA7004FB9A78EA5E59459C6E3F75E9E4DE961B5FABE5149967C9F97B1BC5DBF8E297DB4B25FC55241FDC189E9488FE06F71E9D1D4E19D50E7A3B81FCFA4799B127AA0D8C12FAF48811D52E4EA08D965813E20A7CB532F3EBEA5CB60601DDBFB1CD19FCE3F0A9CD1E452D1BCDDD215B91160F6EF5892280D847E32600F50E5DBB0DA83A650FD17E4A58EC02BC05DE23CD3B2C04172708C15A96A3D43A212FFD4401EEC87861C35351A0BE9D7D4D6AC5D60DA8AB5E1BBC7D943F4439AEBD7A6B022C8EFEB712BE5EAB7A1802CDD2FB9D93FA6E4383586E517A4D79D9FD2F6BBFEF8C65F1F3111067670E6A059A1308948697F5650C000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F7F8F9EAAA74A5C910DD60B2FA5179B3FC341BEDAB53B1E957F40AFFE59FD454EE839D34EE92ED029C1B5853A46CC8B48B58DC4F74EBE2164B7F867B17ACD180761BBD5017870DCC53B0ADDCBB8DD1A6F5D014B1A789493C53C3D7B304F6237F836AA9372B0CD7007588A7EE166C1F8BC1C7826CA9D6E2D73B1B217E238FFB65DA1671204B7137B3C91D19ED0DAA12A98AB71C239C6F0E6B29D3F61DE3F71688560646DCBB9846A8F28BD1E7606E2C93CC0CBAC8A85BB578671BB01347E7B2BA757AA92131B2693D7F9501E87FC7C1BBEE1B8BF15E28DAF9B74487ED12BE8A4075FDE22DA018C0531776136F0FAB5ABF372E160CF51685CD0B8FEC7D63D39F4A7EE635051E54EEBEC7E8C4A408EBE848B7255685201592E3730C4DCCC6E7DE956B4FF296E76D0052EC6C037ACACA6E6474CB17AB271FFCA98A688D224C3A25425F +remain = 1099511627774 +max = 1099511627775 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-4_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-4_256.rsp new file mode 100644 index 0000000000..ced74682a5 --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-4_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHA2_40/4_256 + +pk = 0000000463FD804E9E56657035D9C1FC5A291B8586E41D1E5E5560AA76B30C26198181A604562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 000000040000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A63FD804E9E56657035D9C1FC5A291B8586E41D1E5E5560AA76B30C26198181A604562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD0900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E7040000000000017D93C20AE191054626B3138F02E186A4607EDEF6E32DD3B2D788325E88FB01E90500000000000159008B71F97B67D9710ACBCAD0DCEB434823D0DDE4E8526701AF9ADE23FBCDC406000000000001410E6F39D12638391198E1827F643E6547AD7438BE85774B713D8FF3D8CB682507000000000001030C34B96241353C81CD7DDEA97ED6CBED8C9F9FB86DB60A6B78E39A253C001B08000000000001B07CBF5330F3B30963D6B0A4AC7AC4DD77585E4EB8A08B62B9AF1FBF42B76FE509000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549619B2CE208EEF551E81A9AE87029B4302D012853622BB3BCD47FBB055E048923FF9ACD043DD40211F720396E02E71DB06FCE4E8D757DC264B4F5AC3089FE49361710B3FEBAE56D82E67A6C29504D6B061DB48FFCD3AB91E7B6B870AF8042312735EA06532FA075BA5DCCF6C9E92AF59BAD50EF0A3797C335F50FC43DF22481EC203C13BEEEB42DC753BE45EC74C10D40CFB3D55B68602D288855C63FCE824A2F4A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113CD47F2466A56323209409FD7FCF7485A71CD8CE96D61298A20473D9ACBF99C010000000000019AB3950B30D3E7877159B364A25B214B41B8AA32E293E2DDD44AEB7DFC560A82020000000000019C359D104347B69607EB28A02E6924C24BD2A26DE4CFFF3FF98E48688E291E58030000000000011EC9B78F3B1189A5482238BCF700922D642E45D07E7EA10833E31A4CBC3CA08F04000000000001F37353B4AAC3DE6FA6FA583102CC2F35D6CC95325A07AB88D9B0304EF6F8103305000000000001E087F84EB8A6A13A9581B22CDEEF8942E186FE62896C636D0503675B28692B72060000000000015FDAFB6EEAA60CDFFD2E2D1C034AF7306D60B106F145206FADB857BA565C66FA07000000000001CA463E7885C94740495E419265530662D2D8B0CF6C9E7C290FA86E8E136261DD08000000000001761CA5CF20BB11D4515629D8BEC9D72E02E0D3392C20084723610CE22260DF920900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A3928351163E04D8BA817C168A0CE68CAA6FA744E7E30A2670B2BB88F27810C887E48E90EFAD40F9735B5767F60EC515C146D56EA534C970E04BDD10302D85A2317C478BD195FC93499C051F5AF61A6C5CECB89A1D67BF5BE2CA7EFBDCC20B884597EB2BB0799DB9B86E2EB8FD93389AB91A391F2D68A057FDE361AC97A87F4406F40A7EE2E7709E46DCD756617DCB0DBBF43E6BD4851F3D834BB53CB150D2FB7B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019C1A7BFD8300283215BA57DB5CDD95EDCBD04E1C41419317BC2069C2AAAE22130100000000000143ED646E32FC21554D8DAD350C5732270CC220F7E264ECB5B7A8E8A4586D0CD002000000000001762D040EECA13E137753604D099809D946063368BFE1C7CF0E6549FCA746F7C6030000000000015FB7406F1B25A2B4A6A1666269772EB08D6FE78D8A8395C56AD80FE6924DF08204000000000001207155BDC49069839D60C0C74C9F57C739D2F36E6AAD0F698CA840A48FB11EFE050000000000012B5052F4510570C5839D41287DA3BD24DE8CBD40BA9E159E783C5812A28606A7060000000000015C07001390BCC398A47CF40395338496D66003B5E0C1DD7187A5D605984F79ED07000000000001285C8B2D9B398B8A212B3CE0FA820CE44048C2105C067AB9FE6FA70B1E712C33080000000000016F81A741E38029A214AF0CDE4C75E79A618C7B4942F7819A53CBF8EAA263EE490900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014BCBE4FA64052B0853EDE00CD41BF95B66DA2A519216FA1A0A8BA5F10B4EAFD8BE62C40DA2A76DFD8A5EE8EF42A8B808C55A533FC488A2B33A935A635E24F3E0C717E2320FF575ADDB18C567B1333DECB0855E069D5759C48FE6D8C6A9D217BFCB7A9D40735A3151382E3456CC4BEDF6C7EC94F186FCB6BF9398FEC934714E8E231402FC7BD5153981C7C789B26208DDD77E4796F70D6A72B7B9C5EC75E4E3CD122F72621E92B1AC515A33B12B1801B2C3E461AF788661815E6BAD2E6472116B89B941A0E68A232089C6F831229BE2EB0CD244BE4FED78C8371D2DC614445C76907F4A3EDF18722BF0998FD03209C31C348CC79A2AD06ABB1B3CC549E73B206A05345EC801A1C5C42D794BA1A35747493D76CA8567B62F0C2151923D8D9CD2F37D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB385C19D6AC3BDECA5BE59F322A17FBAFF466E945FBB943BFE35854802837FEFEA3937069240712886742E890428C0C21BC057E82D5BB961095A5A18DE149CD19F79E9DC3CF0FEB5149F856C5A7BB82B6AFD4B5310993D9E4E1D33B4CC601265906186B98CAB4AF1570CFDC928C0A221A3BBFFE8E566D580A689AB51BB69826FA60135F60C1A1EA97CCCC9AE96CC93B66942370BCF910D916CBB7F87A0BF5EF46DFEBB050637754B0E40509441E19465B238EA45270D7BF5E0610A89B4A47AA821D9A3BA58127DDCEE4E7204C38E0EEDDFF72B07FA5AD8EB1FA89554D940C2C88EF588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE5966743689380FD336A081B8C7F753B889BD73F10345B8C4988A7A4C865250E3707A8424B606059E3ACEA75F2F732058477097D5BF8F5A2DF82E4AF0EE9C4BB251A5657C15808B7EF26806E2F3D61137B44C9DF4196A9208065ED1C70F9DCE3C75AFD719F14D79818812360E4709E521E78B983F99B31863039069D3F86FFAAF318853EB4A1AFFC5E598ACB6B15198E016C779BB7D77C54971E4566C2071EDFC0D19B41827913C5F7EE5D8A9411AB2706F3C9DD8E2CF4AF497765A647C1AA42E3645485AD6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291B3530D6094FDEDB782E1C927C11235EE632F6C3FA150DE1BC1125FEB330079EDB0733B58F1CDD3D20904F85DE31C06FE375E7D1E20F4C79484C5431A026EF8F5C8AC47E7FEA2A80E17256ED956484E9004BD99AD8ECD0D1EE5790A83CF9A14827C3B5D5C25AA18255F5D512917BC1FA868AF35ED3540BF0C10CABB267F612C26AE27DEDB5665A4DE3913AA2631C034C1BD22E5A721194BE6D1E4337D1CF488E9F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA498B7DA996B2692EB8C3D1D8BC9BECCFECC8EC67EE3A87DF5B0B9C7C887DCB0CBA7F5E1372399F3A4F4CC7DF247752994CE0D024D2C6E620EDD0B8CD30891FAF58D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB074AA6092A1F23DCD01D8B8C70674D55670C07A6D0655CF37D0516E6E1102865F0C53C5AF80A45B09B078337D61AFBD12DA2820AE45CC4B213C00576FF3D5FC21D0DB8D877757226F81078653EB4C90C0D2C7D304A6E0C4265DC3C1DB343202664008385964C6C56FA11532D7CF41E93F92EF28F3DE2CA1D5817AF2114A97BDA7F6504EBB2A6EE6BF4753274BE064D3CE467673717AD7350DE4E83A1BA27306F11DF36A2E30572E3FEF2EF6B2518419395DA9B7D4B191C88F3A863A477A2D226E5BCC04E39AAF1AA042A7B115CA26BE8DA52A162FDCEC6E511B1497FFB8B8AD23D3C429F71236DCAF9DE275D7B1D2DBE83822FF7D8C9BC7BA3AB5CB517228AFE2E30C53E64C44D02CF9CB51CE371827CDBDF798B1723B418EC7CDF66CF09F444A06DDB94355F529337D6A3178D754D68BE658934FEABD4F4874B11E739F0EE4E95D2D23B41F037B9668C9F74D2B3D31027861779FF8516A29246D766D2A61A02CD5B8E338B9630E8E0ED5BDACB017A6D3B89C8A1108E525BAD96E203E7A0C0B7F2148274FD20F9B53601F2B38DF303D7F8785D06260485D7507782E11855EA62F44C755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E695CCF3818C69AE16DC71782D99440EC9AF4A9C33FFBC728C9C62C47E0D37CEA661064246A8B2BBA14ABF5767F33E490AEAD721929515F091663B4437BDC34F5B15C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFFBD90B13035960ABEF4E3CFF91B9871E49B16A6F0FF86445C441921D2E698117109D810C864F024F62F8D25C263CADA33916763373D76EC8955ED113F71C40834E79A1BD5E21CC2373598C66168492FFCD083D2A8E7E480F76274C048719AFF98C5E2774BB1039646BD25A240875655A77023B7F884F5852DCD9C5DA173DACEF7F01F6527CB7F5375FEC1FD2D5C90A46D3D0501715B2D4CF51166226D8F35DB7A9ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272AC230107F230E29845C2E2283763A5832809AF2428C304C07CB21A96D7B7CDADF857F54C91A22B8AE6E4EDC0DEE01FA60697269BB1299F9FD7D3699D4D865A25BF0F31F93DAE1D51C42FE755219BC2A4B2505487483A1B81BFA86BF6A99642C51AC3DC78D5E42FEA4ADCC51C0501A8FD543217134694262E0FF5957CE719766EB0CB34CA2E541992CC2619C65822A763FE6572E3B33C4C8C216B4A62A13BE7FE6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156D49ED44C7713B7A50EEEBC575166A1B6CC3AEC2CA98398971F648242C35E8EAA21257BFAC587485D48AC54BC306344EDEBBF2A42B7E37B6086B1D9F54255742F1C9BBD708D6DB1AB7F44BC2473A4897D83DAEA510BADD3ECC8C9F2E4F889D5AB62334F4B56AA20F9BB57C09EBF41BADB20D36485AD613C790428C382B437866A681635BB509C97D4AA12387C320F6CEFD1838459F0DABA3DA54684B83E3ED10C07B8CE62549A876A13D86D8F3D001504D939500462E64C94B6EEAEDDB8856D13AB345659CB16C8B977B6670208B70920BA34E31E6A10EC724CC6FB3C299ABE890047E1F6B3D5A69BF731EFE803088FC8D3B9E69DF3102AABBEBE90C3EE20DD829BC1C46E6764AA8C8E2396E4FD1A65A171D9EEDB2B04843DD2845B5E5F5BB714212BBF4237C6D69B1D61531257FAFB41BCD74462C292880AA396FDB392A42C4AAD9B5492EE4F2A076CEA42927C22BF7CA54FCA135A0FF512CAFDA620DA75DF70C37EDADD455AB3C8EB0F334679EF94E6ED2E8BFACF20DECAC68B3AFF3979869B755D1BA8476CF0553AA3B5049EB57DF8F00AC5DAC2C1DEF316793E5DDAF9F352894CB9E2B7C860E4D2BD42D0053B2BC8C7F3C11FC0DAF6DECA58CA37526095779A89119240A8E28D1D44AE57D7D3252B69192353D745AE1C066DB60F6C6E82F35854FE73C1C961A0E178F047DE9EC62C589C2D7E30929DEA6CE37C4042F04615F48FC178E8CD389A2DEA13C83E2534271AE7DB54D7C89B8714666381C388D37BEC8102F8497D8A820C70C47254582C5C27D3D97A6ECE379315D5520BA346E8F5B5F7887F9E3E44FE4C156E7472EE8D9C327587A0704A8035E519B1C4A9D2E07949F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DB9D6E9AB3A0926402DD8095AAFB46217FC41A2E0D7C5960C1FC814E461B1F1F219CBD0A97D50180BB017229AC9F884896F357900724A3A7A8E4D479CF6A093FC30778F755C63CF618073C40F6042FB2143DECEE8DC32CE9D3E0064EE378F78B8F945A05629C118D60A6AB5DE2DA55A06B7325FCCEE42C01A5C408F0291E3610C44684BE1F66D3FB8F6BE43EDAD2EA87FAD50C993CC447DCAF79AB19DD406B20974363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D024DAFD78B7F2D3B3C54AE60062DDCEEC2BF3A579A53E27A72402BED5DA1678158142C023B3C238A93F3D1CB8E48EF84C168E27E6645DC6DC6689E89CA0A74D07087B760743BB526662636725B7FB700BBC0B3A73793C291EBBBCD4970B27370C2E85E7BAC610B75AE5CFA9DD39290DA4DADF4F61BEFE0F87959174D2BC28BD76B780BF58A5656928CC6684D80B728FA0C1570B8268DFD57EC9168CF7D39997BC8458A5D4126FEB278B26769C4F55EE77EBCD778D00F836BFA6EB13307BA2D7417B0812FDA4CEEDA359BF73865982622728D7EA8BAE1620A63483DAC957E4F8E082588E12FFC57A2871119AED0B43DE4ED1EDC4AD6434A485C64D9FAFBFC7F01A8793E5649BF33A7186BDBDBA5DFEEBCC16F2CCB67E355774B8C32B932119DA7158A4D131F560491BB42B47C9EF1594FF6F09BF29E972502A7D62A2240FBBBE55C3D82050B374EB42E433CDBABC163A95A6492A7F7DA6824B5A20527C9D0933B97C753932ED9ED277E40CCB8C4A042FD5B88E9C5D569A48F512ABA1DE68C821BD20C1A995235727654ED6E59B063EBA5F4046E7D047B886A22A7D7C5BE009F3E14629FFB78F8555B7376AA2B7B4B360F0D3C295ABC2590CE1AA36943A46379C1085D66FFE0DCF3C37C89BBF1C7D76B6D62D5D2D265EAC52164E4799C52D9A7E67836B66532608870BCF43815BA0633B82CF8E92FDD0A4DF829039370202BBD93541D4D398C42900F96D70AB85AEE46D4AE2CDB5BC61B0E57DE8AF9BC4A366730CC4A8443203C374F1F58A2203BACAA6A0C93783B0BFD8E85A869ECA37AE0FA0349E9A943B50EA190BF7E28B4406FC4B14E77203739F8DF7D168EC43FE06D0645ADBFBC26542CD0335EE21852C8CAE8DBE734028D2F6BF457CB086172F176456A64E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC40509461C2CEE814F7E26684AB01D51A1385EA51162E9CE43172A1564809B328A45AA68BC14BF38692467DE23B8908FB07BA05C90DD44A372477233DEEC84BF89287B1F8E1FED4F275FAD98265AA76F0D798266081567140ADAF2A9C64F41E053D1F329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB03F8A842A1FF048CFCF92A8D77409DE43CA455C5ED59F89358559BE214EE1B531915180697A948C945A9924FD6864D9CFF00E1D47F38B54092E4CFF1F92A65CCABF206A7D71F25A66969E37EA7D52EFD74B80E93CD7A048F71EDDE1EAF82A24F20145528EC96BF1857E0F1D8F19812EAB34E07D4262D195D1BB4D20FF3E226C2468B90E951C8212023248340ED5B7E4EDF3C6AF6A6FEE63F8DE613EC6F1526E3F6A9327A17C2279BEF50B6CCF1569A86FA56DC4B8866C365DC5D16B9BA888234D6860885B2A420401C0E3F8A971BE2CCF46FB27EB58D6C8EDE207B703FB7EBFEAC77465237E1EE73B675C37F656EBABF91BA91A79FC679C5566A637F6417B8981C93D4B2B08DD6DD375D4C84791CE66913FD4E3D6B01287F258E8EB01A223CD222F81B1412BAD3DF60D89E29F4FCED352A1DC0D52A296D6D8145BB66BCC936BAC362F309AE4520552C369E4BBE918F20C4AEDF8F037EC9AE0A3BE8BA1BA0CBD40949CEB55F41C8728AA639789BD51539F1AFA46F71106F428C9FC659F34F6BAA879DADCECAAFA80505AC2E0ECBBDBA3679A483BC7B92A54BDEAADFA7F386BA0AA79EB4AB02F6134488DF1220F8FA56D2C14630DA6F79094DFEE7180D218C621A32C153D6E5AA82C318BCBEC16FD901CB860793B8B3E9E357D0F008EA80BADACA56795A369F5E6F910F706986E7F66A84B100C265BB5339972BBDF6B770B694B8D2DD8323E86A90E83EE039AE031A331E6D7B99E75FDE0E8E42AF855F52C925F1DE1A2B10D241ECAD1523291D88D5D0EFE1D5CA4DE89F22AB2605BB5AF0CC6564C0FEBBCAAE5A19E133CA77B6C4AFE98FA12CFEB1A87D38463C35DE33D5B7D2E08C3DAED2A32A25502AA2B4E2F2A330F06294E202466F0701D4B361C71DB74253ECA3148CC5E1119591830C19DE38FEF1A5F9302B766F68E4E6616611EA940522EE92E6625C8783357799CB4B9F6A56A84976EDB84939B94A676D4657DBD04F7D754A901CEE47AFF04327CF6E0193DD3EF8CD61ECAB28CE8CDE2A56ED422C47BBD5E4B1C005EFD6C982E1601461DFE8EFF46797FCA8B79156473C7A964515B4A0B4373513F5DE44B5088663F1B9D235681C2A0F31675B7BD215F95D42216FC76E5C93A2C8929163064A58FCAB39F6A8700820BBC9EB62588C0377C15BD74E5B7E4F11559E54EAA502404D245774A51F17A9CA804C570941434AE4464CA23D8CB2D042633395BB951DF71EFCE0FEB7AA66CB0EBC83321C73AAB08C45F89D8DD625753795B7BDABB1CC042A4EA7BEEBA6AD585ABE6849B63C9630142B7191742C772BEDBDA162F8B4101824D6F16D189D65446852A08B37F359617ED6B0F2DC1A5648983AFC78D3D4009BFBB088F85D85B551DFCB0C99B46C65130CF3A25EEA02FAD2159409FEA41A7F3BF71F020CE618D82E4A2D5DD005E1E8839EF6B43D864647D89502AC44A7517F0D0E9E06BF9F55BE677F11F7A4689D51E5DC4892181C32AB56A831AD8E8691C9DC7C8D59FB0098C7581BF682298C353CAE2242C7BDE5F5933B48E88624CFC605A87E401D4B01FCE73BCC86D9FDDE138A185AB4B79B2394FC0718A30D5B8FAB24C2A67DF7C57690E380B21B9BD08674E49328286D6CD82FD782FF7BABEE169FCEF38BD5DC8ED8ACB324A374F426B0D835A5A947627DD5D026DACB3669212EAE997EFA073A3800694A8470BA89780C06F034BD1ACA26229A7C13345B4514B3C48A810C8A017062BA454688349B3244A3022F86EBD132636D566A899C38D183C149E8C9EE50F7F254409A4FA45ABB9B74750B0FFE552845BD460BDB3FFBF6259FA6D048B59198B4FD2B135A9DD870881D24109F95CB1B0857B395683A40C358ADFBED50D70A8FA540F6006D2493B59AE4BEECC8BE3E70396BF298B2F49B468B64DDAF12FD0C594DC243A782FB8862B2B73BF1F59FF1B812DCE96AD72D73D928EDD5D6D384CF214C7EBBE25676FE612556461D465BD1D1C8AE96BD8F349371553AD9E9B80623B49D5C8C38489415ACE7DB17DEA495DB1CE9B68AE228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023C8C898A4A7D16063A2F7FB6F6C00EBEBADE4B5A79A9814803CDA526D542E0C4C44DAFAE06659E810969F48EAB6EB002F7938B62157E85E1BF258D2B81ABD9195EB828938D84BCD92C9793BDA17DCD6ECB92068BEA49626C4595EE621E192309156F9B0127FA44454075F7C73A94992400B22CAB60A056EED2E04045E74494017E601F044245A2B64B83EA8BFEF2A02A32029224D3C9F5DAE64E4A3298688C1E4205FD9038743CEF33B08CD9366560AB57EEE937008332B6A4224476A759B07D04DEB016DDB8EDF3665BA71053A894F98DBEBA95EFEE3F46AFB944601CC71C39315012B024E672E7CEBA843F35C6F435983AAB0F14BDB63B2D130A91AF9F72CDFD73EA39DC02AD3074F0E4B3780E81732B550B298998169B1640D80FD56474FF655A233E3ED6C48E5D94A4C6D31ECBB5257DC07F29D5A4C98177DE0A4DE1BE24D2CA3CEF4DD2A3FFBD818E75023732E1F1D3F9051AF6E8047081FE588E2492E5EB4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F933819140A786527AEFC7A872908B98E8356286485E2ADA68D8733129C32FE7E0D0B7AB63E890DE8AEC5DB2D52F88D328E1DB56FF586DC2026817A277844C18228D01C4A792C6D27D72D4E36AC852098685807B31A411B62DF550CE9C5080F1BA5CEB1634B8EE7CBBDA91DA660CECF740A502064AF7781F544A2A9F6527CB431A33A905262210B977C09374F03C360642BB200F00F13EFCAB19685DBAAAD7EFBD4D42A8B428342F44A61D9D58808B9E7620ACE2D4FA47D16FA98950485E67EA182414D9C7B78C51CAA4960A79B1BEF4B6BB5CBA79515042433C7505B5038C4DD0CC8805CB9C1AA93B2BF96402909E229C46A5C2C7CB18F0B7747642714BF204D42A8AF263AA6C8F1DED9414FD0E6586D7B680D4BF1CB6CB6DD90D63511150A76C2C40384A4F156E827A22D0D207611E84477254E492397A85643BE2EFA36371F9DF6119813B2CA7F31D099B0715927919FFABE384400D3AA0869AF2E95B525D9A1453679B1624C4F2718AF080BE493D1DF583843CB08C5FAC4587627805AF278A009530F8545958E7C04ECD445240A70C6D0450DE5A3F3CBE710E610D8EEEA17F97381119B8A53A62EF7F4B0D8F84BDC86BCA2245664DA120E7E36945038F7973099B1ED88113E6594EC0CBE05B5CF5ECEFD58D48FFE4C16E0F941FCFFFDE6D3E584584EC8A03AEDB6126EF5F479E4FE8C97BA01A4980F78D12717DF17BC4E9040B105B2D74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7566DC65863A7E07D0D8774305019C67D504E7FC4DF77A8821AECBFB762EF377DFDE75F24A9DEF9CA7997E8F4AF3B4E60071F11DBA6303A964B7F9C3FD443C766346B4B1E50EA1D79357CA76ACE991F4760184016A12C2368F7D4E6BAF0C8EFCF4A869F3973B41564F52D762BECBC7FA49B40D6FCA22052287E1B10DD8FA257423F984FF4CA38BD49F322C84CA37874056055B3A0C51060360F05BE3E1DA6E1829B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F3171151E6F5442468D000FA46F17DC7437B058242696056ACAAC06AF22742452798DA226D91074DEFCAC6C3D770DC54CF7ECE9ADFEDB3B421ABCD9DF305D412A71FC77801FAEA989C03A0D633C4B06766491F4C0DC67FF8DEB16AFC8BC7E3D41601BF7B964B91A8638DDB7CC08B68691D5D501B5D3D72915442F0D1B9EA4DE4A + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 9893 +sm = 0000000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA70104A82ECC99EF0F9172F36D2B461A6515DC13666B7F1D917746E7086F99C8F1A63D2CB50DDA1EDFD708F002ABF07D0001C3357A70F6511884C4185790EECECCC578715C21A26FC1E7A951C54A30ABCDB7EC71AAD92F2662BC900F9E9A93054CF398017E582746F531B4697925154A22E2D6A0F1B81913438000C295153D7ADCA8FB21C6552D41F5F3865791CF993DD00FE3A036175178B6407E88A3F76605B5EAA51B83B77608A08C021821DA61962CFCC8E97D75441921D39C5AD537543EFBAF05BA4B0955661EA3FC882D9D64954405502E2BEF7D3063D36F993460D2557C79729E510FD11DA67C0C0D3B6448B88B96E0834210FDDA112F57C7B4FA60EC323321A23B8EE4F3EC419BA999054325BEB9B8BFCA6A2BBDF11FF7F8A170E9C5481D78F113C56F2E3BB35FE284CE8EAEC342D0D110591B00EBA3DBCD0FB7B965F199AA6EEF78B8184B2E355CC338055DD2A26DD02B1A0740CD15F6CBA4EF429254DBCD060C040187ECA41B2E544463458CAEEF75CA6EF08474060A8A1A356F1BA92EA6CE2FDA531076DF2E6296DD460D39973BF771E938FC21B05C01C27ECAEEF1B29C7329B6C264A9B24F73BD95BC8890AF4C36695EC8E2C29B32F4CEF4E02DBA54963C09D5F56674AB6CBB75352E7D87BFE1D85372318F051B955CA3661F1797D3C46191DCEFF06EAE14F3762FA5C231D3D57770F230802C2188D108FE326778A109E07417E807C087062711DCC7BBFA4B0D54077AD8DB142A191E6BA6BB251837447D20C4427ECD55AF940037B6D3485F6D6C7B3CDF5A5C19C958655A51A34BA73B87452100271944681A77667368E04F077001DD9B1454DA4614F631A83335A8C8953DDF5F0562A9D378DF36D061DCBEAAC8613034756516EBF622F21096E20646F3D05BD9D5F8679B536BB6D39792B28DF2481A6EECB9BEE40B11A10D39A90EABA7A25D6C3E4B7D39A28A65A5628A93556FA9F54E273B583F9A197BFF4731E04E7725CD11443807BC4EECBC46D46EC3D79A9C0C755A65AB867B1BA4B07FC1C2F151BE85B8E8195CC2F070BFD482702182B8A4A43ED942F6BD3CBF9DE7E8AEB17BE6840E11EDD8EEB095E890AF71214311C2811E2E07C1EBBEA8EFB786EB321559FFEB8219555DB545D7DA6FB9A32B0A8F38A664FABAC2918C2C79A154F293CA8B7BC5ED49FD2BA5A1CA39BFFC9118DF8EBF732962924BC11BB190413E9BA0C7EA2328C40E977558DBDECCB8D643E07A573A9CB5DB4518877320FBB4998BFDC59FA3DFCF5C9CEC2D80AD509A65AEF0E3E663B7F31BCA437311BA799D4C2ACC1386FB466CD5FEBEE9FBC50D64DB78AB57238911EF50154835A6F32A63B7723BC668B79FD7241614D2FED6D1E2E5795827F146C2158BE0A39E9556BCE1B08B774530628FD7AD334BD17A52436209CB5E0CB08299AC5D618A73889380D9D4AF03D7E689E09376BF39F4C562ECB1A68E02D5D91318EC0C91D38E8E480B8A0E65F4525BB4B34F69DE75E4BBA54CE08465263BCD35B6C89003D738D145B03E200113735C572A5E6BBC3E395E57FAA869661A2E4E12409A5E93DC41D80304AA2C5460A3C55F9CA097AA6C3B65C5CD659AAE22F412427C2918AD8C309342C8369BB454C50B3A6F2E555E150F9C05581F09882E165B19FF0F393EBC3AC3C842D4DDD647F96B48E4353B554747AC62ADD7FE15D0C5CBE5A0CEA51D5E9339C72AE9F93FAD05EC782FFE265FEB6309F643277F09495ADB42B4C362E1EBD6790AEEB0C5329F797D0A9FC8BFE30C11D7093D7B9A82A4E2A7A62A65FA32300FD0750E3B6D38CE5763DDD3FD0A0CFEFE8577D87D69AA8E668F66279BE02DEC2D05BBA330A504C68A789B198A28F6AD355B74455297DDA5CBC8B88DEA9B7AB7D59E2C78363EC25A2601906247CBEFF8540483C95BA2BDD8E11CBE540D0B6958770D798891C01C696A3ADE5F5BA26D69ED191B3B47599B1CF4E28004F8C1DA229C20EE36147369CE8C9EB4272CF4BB9282993823EE7F187D67EB5B220C01EB64244F80B74F3A82B819BE69444398FBE437D944C74C4A366503580CC17367118F5FA8F818D7903BD4C0C9E8CEE39FB9496CCB77190F052B8DC58C76C5ECE6F0FB81A47088D8AA2085533BA507C80E3BEA5C0A43536117479EF4EFAF26DEBE8B536B932C8726E54D309445E44D90F65A4EC5BA93065A2A731CD107EBEFA54AADA64C3014C9A6A25066075A718AFA60C9411C80143C846F4E65173BFA7B8E0E02F10ECE9CBAD48DA9E0916B70F2AF126A3DABA5C918B224DE444B8733E6FA601B3D349307E94583D0EC976E6BF9D49BB099E99E115FB80548BDCA3276CA7DD2F3200DA1FC5724E17D6332169D5C20AA99EDA34414373F438014E66E104843EFEB4D8C735C73A32E68E00D0F22790BDF69AB447551B814FDB4BC3FEE56516113672C869715AB940097C9F18D612C657CB314841775DF71EC753FD66B70DF8C75C96468E20AE8126BF8BF62D20F53E003B1D12EB97F7B0B9A2A8B101C3C30C8FB78B8BE3267E1F3149A49AF062737735846EF0C8EF26765413ED32BA0C4D0359151681DB165A82B25B9C5D7F839CE80CEA428581B6CE720C459D6D2961C5A7FA8256FEC4951B69C04FD5383B74580BC603BF35A74329BF88F2621953FAFF5398064AE5E95A44336EC46CE73B986BB677DE38EDB99E61FCED7CFB2FFE50FC26E59109A2F3A365893F037E2C27DFFB2756E97349C738E49615B3CFC7A7AECFFAE45EE75E4B94D35E5F625EEEA50CAF3D4773504CDF16EBFED64F678FB18F012193B1DCC67B722A5D175DF541B89B2327AA33BB2F01AA3598D08D6246E5D4CBBB73C8008D6EC423B27CEC92CC88AB2ABA8C222B35CAB84737275612307A060F36E3012E9AEA3B69196711BF0BC48D2AE42D887D10EDBCABE6AAF951E0A070D881879332064C99F8527A5EFF25241013CC40576F20A6467A647F7E679E6C7D146BA3071C18496307D2DB4CE99FD37AA1071D740ABE2895647F286260874BBE8C609165131481CD81E4C6D98293F1C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A14BCBE4FA64052B0853EDE00CD41BF95B66DA2A519216FA1A0A8BA5F10B4EAFD8BE62C40DA2A76DFD8A5EE8EF42A8B808C55A533FC488A2B33A935A635E24F3E0C717E2320FF575ADDB18C567B1333DECB0855E069D5759C48FE6D8C6A9D217BFCB7A9D40735A3151382E3456CC4BEDF6C7EC94F186FCB6BF9398FEC934714E8E231402FC7BD5153981C7C789B26208DDD77E4796F70D6A72B7B9C5EC75E4E3CD122F72621E92B1AC515A33B12B1801B2C3E461AF788661815E6BAD2E6472116B89B941A0E68A232089C6F831229BE2EB0CD244BE4FED78C8371D2DC614445C76907F4A3EDF18722BF0998FD03209C31C348CC79A2AD06ABB1B3CC549E73B206A05345EC801A1C5C42D794BA1A35747493D76CA8567B62F0C2151923D8D9CD2F37D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB385C19D6AC3BDECA5BE59F322A17FBAFF466E945FBB943BFE35854802837FEFEA3937069240712886742E890428C0C21BC057E82D5BB961095A5A18DE149CD19F79E9DC3CF0FEB5149F856C5A7BB82B6AFD4B5310993D9E4E1D33B4CC601265906186B98CAB4AF1570CFDC928C0A221A3BBFFE8E566D580A689AB51BB69826FA60135F60C1A1EA97CCCC9AE96CC93B66942370BCF910D916CBB7F87A0BF5EF46DFEBB050637754B0E40509441E19465B238EA45270D7BF5E0610A89B4A47AA821D9A3BA58127DDCEE4E7204C38E0EEDDFF72B07FA5AD8EB1FA89554D940C2C88EF588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE5966743689380FD336A081B8C7F753B889BD73F10345B8C4988A7A4C865250E3707A8424B606059E3ACEA75F2F732058477097D5BF8F5A2DF82E4AF0EE9C4BB251A5657C15808B7EF26806E2F3D61137B44C9DF4196A9208065ED1C70F9DCE3C75AFD719F14D79818812360E4709E521E78B983F99B31863039069D3F86FFAAF318853EB4A1AFFC5E598ACB6B15198E016C779BB7D77C54971E4566C2071EDFC0D19B41827913C5F7EE5D8A9411AB2706F3C9DD8E2CF4AF497765A647C1AA42E3645485AD6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291B3530D6094FDEDB782E1C927C11235EE632F6C3FA150DE1BC1125FEB330079EDB0733B58F1CDD3D20904F85DE31C06FE375E7D1E20F4C79484C5431A026EF8F5C8AC47E7FEA2A80E17256ED956484E9004BD99AD8ECD0D1EE5790A83CF9A14827C3B5D5C25AA18255F5D512917BC1FA868AF35ED3540BF0C10CABB267F612C26AE27DEDB5665A4DE3913AA2631C034C1BD22E5A721194BE6D1E4337D1CF488E9F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA498B7DA996B2692EB8C3D1D8BC9BECCFECC8EC67EE3A87DF5B0B9C7C887DCB0CBA7F5E1372399F3A4F4CC7DF247752994CE0D024D2C6E620EDD0B8CD30891FAF58D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB074AA6092A1F23DCD01D8B8C70674D55670C07A6D0655CF37D0516E6E1102865F0C53C5AF80A45B09B078337D61AFBD12DA2820AE45CC4B213C00576FF3D5FC21D0DB8D877757226F81078653EB4C90C0D2C7D304A6E0C4265DC3C1DB343202664008385964C6C56FA11532D7CF41E93F92EF28F3DE2CA1D5817AF2114A97BDA7F6504EBB2A6EE6BF4753274BE064D3CE467673717AD7350DE4E83A1BA27306F11DF36A2E30572E3FEF2EF6B2518419395DA9B7D4B191C88F3A863A477A2D226E5BCC04E39AAF1AA042A7B115CA26BE8DA52A162FDCEC6E511B1497FFB8B8AD23D3C429F71236DCAF9DE275D7B1D2DBE83822FF7D8C9BC7BA3AB5CB517228AFE2E30C53E64C44D02CF9CB51CE371827CDBDF798B1723B418EC7CDF66CF09F444A06DDB94355F529337D6A3178D754D68BE658934FEABD4F4874B11E739F0EE4E95D2D23B41F037B9668C9F74D2B3D31027861779FF8516A29246D766D2A61A02CD5B8E338B9630E8E0ED5BDACB017A6D3B89C8A1108E525BAD96E203E7A0C0B7F2148274FD20F9B53601F2B38DF303D7F8785D06260485D7507782E11855EA62F44C755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E695CCF3818C69AE16DC71782D99440EC9AF4A9C33FFBC728C9C62C47E0D37CEA661064246A8B2BBA14ABF5767F33E490AEAD721929515F091663B4437BDC34F5B15C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFFBD90B13035960ABEF4E3CFF91B9871E49B16A6F0FF86445C441921D2E698117109D810C864F024F62F8D25C263CADA33916763373D76EC8955ED113F71C40834E79A1BD5E21CC2373598C66168492FFCD083D2A8E7E480F76274C048719AFF98C5E2774BB1039646BD25A240875655A77023B7F884F5852DCD9C5DA173DACEF7F01F6527CB7F5375FEC1FD2D5C90A46D3D0501715B2D4CF51166226D8F35DB7A9ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272AC230107F230E29845C2E2283763A5832809AF2428C304C07CB21A96D7B7CDADF857F54C91A22B8AE6E4EDC0DEE01FA60697269BB1299F9FD7D3699D4D865A25BF0F31F93DAE1D51C42FE755219BC2A4B2505487483A1B81BFA86BF6A99642C51AC3DC78D5E42FEA4ADCC51C0501A8FD543217134694262E0FF5957CE719766EB0CB34CA2E541992CC2619C65822A763FE6572E3B33C4C8C216B4A62A13BE7FE6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156D49ED44C7713B7A50EEEBC575166A1B6CC3AEC2CA98398971F648242C35E8EAA21257BFAC587485D48AC54BC306344EDEBBF2A42B7E37B6086B1D9F54255742F000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F71C9BBD708D6DB1AB7F44BC2473A4897D83DAEA510BADD3ECC8C9F2E4F889D5AB62334F4B56AA20F9BB57C09EBF41BADB20D36485AD613C790428C382B437866A681635BB509C97D4AA12387C320F6CEFD1838459F0DABA3DA54684B83E3ED10C07B8CE62549A876A13D86D8F3D001504D939500462E64C94B6EEAEDDB8856D13AB345659CB16C8B977B6670208B70920BA34E31E6A10EC724CC6FB3C299ABE890047E1F6B3D5A69BF731EFE803088FC8D3B9E69DF3102AABBEBE90C3EE20DD829BC1C46E6764AA8C8E2396E4FD1A65A171D9EEDB2B04843DD2845B5E5F5BB714212BBF4237C6D69B1D61531257FAFB41BCD74462C292880AA396FDB392A42C4AAD9B5492EE4F2A076CEA42927C22BF7CA54FCA135A0FF512CAFDA620DA75DF70C37EDADD455AB3C8EB0F334679EF94E6ED2E8BFACF20DECAC68B3AFF3979869B755D1BA8476CF0553AA3B5049EB57DF8F00AC5DAC2C1DEF316793E5DDAF9F352894CB9E2B7C860E4D2BD42D0053B2BC8C7F3C11FC0DAF6DECA58CA37526095779A89119240A8E28D1D44AE57D7D3252B69192353D745AE1C066DB60F6C6E82F35854FE73C1C961A0E178F047DE9EC62C589C2D7E30929DEA6CE37C4042F04615F48FC178E8CD389A2DEA13C83E2534271AE7DB54D7C89B8714666381C388D37BEC8102F8497D8A820C70C47254582C5C27D3D97A6ECE379315D5520BA346E8F5B5F7887F9E3E44FE4C156E7472EE8D9C327587A0704A8035E519B1C4A9D2E07949F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DB9D6E9AB3A0926402DD8095AAFB46217FC41A2E0D7C5960C1FC814E461B1F1F219CBD0A97D50180BB017229AC9F884896F357900724A3A7A8E4D479CF6A093FC30778F755C63CF618073C40F6042FB2143DECEE8DC32CE9D3E0064EE378F78B8F945A05629C118D60A6AB5DE2DA55A06B7325FCCEE42C01A5C408F0291E3610C44684BE1F66D3FB8F6BE43EDAD2EA87FAD50C993CC447DCAF79AB19DD406B20974363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D024DAFD78B7F2D3B3C54AE60062DDCEEC2BF3A579A53E27A72402BED5DA1678158142C023B3C238A93F3D1CB8E48EF84C168E27E6645DC6DC6689E89CA0A74D07087B760743BB526662636725B7FB700BBC0B3A73793C291EBBBCD4970B27370C2E85E7BAC610B75AE5CFA9DD39290DA4DADF4F61BEFE0F87959174D2BC28BD76B780BF58A5656928CC6684D80B728FA0C1570B8268DFD57EC9168CF7D39997BC8458A5D4126FEB278B26769C4F55EE77EBCD778D00F836BFA6EB13307BA2D7417B0812FDA4CEEDA359BF73865982622728D7EA8BAE1620A63483DAC957E4F8E082588E12FFC57A2871119AED0B43DE4ED1EDC4AD6434A485C64D9FAFBFC7F01A8793E5649BF33A7186BDBDBA5DFEEBCC16F2CCB67E355774B8C32B932119DA7158A4D131F560491BB42B47C9EF1594FF6F09BF29E972502A7D62A2240FBBBE55C3D82050B374EB42E433CDBABC163A95A6492A7F7DA6824B5A20527C9D0933B97C753932ED9ED277E40CCB8C4A042FD5B88E9C5D569A48F512ABA1DE68C821BD20C1A995235727654ED6E59B063EBA5F4046E7D047B886A22A7D7C5BE009F3E14629FFB78F8555B7376AA2B7B4B360F0D3C295ABC2590CE1AA36943A46379C1085D66FFE0DCF3C37C89BBF1C7D76B6D62D5D2D265EAC52164E4799C52D9A7E67836B66532608870BCF43815BA0633B82CF8E92FDD0A4DF829039370202BBD93541D4D398C42900F96D70AB85AEE46D4AE2CDB5BC61B0E57DE8AF9BC4A366730CC4A8443203C374F1F58A2203BACAA6A0C93783B0BFD8E85A869ECA37AE0FA0349E9A943B50EA190BF7E28B4406FC4B14E77203739F8DF7D168EC43FE06D0645ADBFBC26542CD0335EE21852C8CAE8DBE734028D2F6BF457CB086172F176456A64E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC40509461C2CEE814F7E26684AB01D51A1385EA51162E9CE43172A1564809B328A45AA68BC14BF38692467DE23B8908FB07BA05C90DD44A372477233DEEC84BF89287B1F8E1FED4F275FAD98265AA76F0D798266081567140ADAF2A9C64F41E053D1F329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB03F8A842A1FF048CFCF92A8D77409DE43CA455C5ED59F89358559BE214EE1B531915180697A948C945A9924FD6864D9CFF00E1D47F38B54092E4CFF1F92A65CCABF206A7D71F25A66969E37EA7D52EFD74B80E93CD7A048F71EDDE1EAF82A24F20145528EC96BF1857E0F1D8F19812EAB34E07D4262D195D1BB4D20FF3E226C2468B90E951C8212023248340ED5B7E4EDF3C6AF6A6FEE63F8DE613EC6F1526E3F6A9327A17C2279BEF50B6CCF1569A86FA56DC4B8866C365DC5D16B9BA888234D6860885B2A420401C0E3F8A971BE2CCF46FB27EB58D6C8EDE207B703FB7EBFEAC77465237E1EE73B675C37F656EBABF91BA91A79FC679C5566A637F6417B8981C93D4B2B08DD6DD375D4C84791CE66913FD4E3D6B01287F258E8EB01A223CD222F81B1412BAD3DF60D89E29F4FCED352A1DC0D52A296D6D8145BB66BCC936BAC362F309AE4520552C369E4BBE918F20C4AEDF8F037EC9AE0A3BE8BA1BA0CBD40949CEB55F41C8728AA639789BD51539F1AFA46F71106F428C9FC659F34F6BAA879DADCECAAFA80505AC2E0ECBBDBA3679A483BC7B92A54BDEAADFA7F386BA0AA79EB4AB02F6134488DF1220F8FA56D2C14630DA6F79094DFEE7180D218C621A32C153D6E5AA82C318BCBEC16FD901CB860793B8B3E9E357D0F008EA80BADACA56795A369F5E6F910F706986E7F66A84B100C265BB5339972BBDF6B770B694B8D2DD8323E86A90E83EE039AE031A331E6D7B99E75FDE0E8E42AF855F52C925F1DE1A2B10D241ECAD1523291D88D5D0EFE1D5CA4DE89F22AB2605BB5AF0CC6564C2F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549619B2CE208EEF551E81A9AE87029B4302D012853622BB3BCD47FBB055E048923FF9ACD043DD40211F720396E02E71DB06FCE4E8D757DC264B4F5AC3089FE49361710B3FEBAE56D82E67A6C29504D6B061DB48FFCD3AB91E7B6B870AF8042312735EA06532FA075BA5DCCF6C9E92AF59BAD50EF0A3797C335F50FC43DF22481EC203C13BEEEB42DC753BE45EC74C10D40CFB3D55B68602D288855C63FCE824A2F4A0FEBBCAAE5A19E133CA77B6C4AFE98FA12CFEB1A87D38463C35DE33D5B7D2E08C3DAED2A32A25502AA2B4E2F2A330F06294E202466F0701D4B361C71DB74253ECA3148CC5E1119591830C19DE38FEF1A5F9302B766F68E4E6616611EA940522EE92E6625C8783357799CB4B9F6A56A84976EDB84939B94A676D4657DBD04F7D754A901CEE47AFF04327CF6E0193DD3EF8CD61ECAB28CE8CDE2A56ED422C47BBD5E4B1C005EFD6C982E1601461DFE8EFF46797FCA8B79156473C7A964515B4A0B4373513F5DE44B5088663F1B9D235681C2A0F31675B7BD215F95D42216FC76E5C93A2C8929163064A58FCAB39F6A8700820BBC9EB62588C0377C15BD74E5B7E4F11559E54EAA502404D245774A51F17A9CA804C570941434AE4464CA23D8CB2D042633395BB951DF71EFCE0FEB7AA66CB0EBC83321C73AAB08C45F89D8DD625753795B7BDABB1CC042A4EA7BEEBA6AD585ABE6849B63C9630142B7191742C772BEDBDA162F8B4101824D6F16D189D65446852A08B37F359617ED6B0F2DC1A5648983AFC78D3D4009BFBB088F85D85B551DFCB0C99B46C65130CF3A25EEA02FAD2159409FEA41A7F3BF71F020CE618D82E4A2D5DD005E1E8839EF6B43D864647D89502AC44A7517F0D0E9E06BF9F55BE677F11F7A4689D51E5DC4892181C32AB56A831AD8E8691C9DC7C8D59FB0098C7581BF682298C353CAE2242C7BDE5F5933B48E88624CFC605A87E401D4B01FCE73BCC86D9FDDE138A185AB4B79B2394FC0718A30D5B8FAB24C2A67DF7C57690E380B21B9BD08674E49328286D6CD82FD782FF7BABEE169FCEF38BD5DC8ED8ACB324A374F426B0D835A5A947627DD5D026DACB3669212EAE997EFA073A3800694A8470BA89780C06F034BD1ACA26229A7C13345B4514B3C48A810C8A017062BA454688349B3244A3022F86EBD132636D566A899C38D183C149E8C9EE50F7F254409A4FA45ABB9B74750B0FFE552845BD460BDB3FFBF6259FA6D048B59198B4FD2B135A9DD870881D24109F95CB1B0857B395683A40C358ADFBED50D70A8FA540F6006D2493B59AE4BEECC8BE3E70396BF298B2F49B468B64DDAF12FD0C594DC243A782FB8862B2B73BF1F59FF1B812DCE96AD72D73D928EDD5D6D384CF214C7EBBE25676FE612556461D465BD1D1C8AE96BD8F349371553AD9E9B80623B49D5C8C38489415ACE7DB17DEA495DB1CE9B68AE228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023C8C898A4A7D16063A2F7FB6F6C00EBEBADE4B5A79A9814803CDA526D542E0C4C44DAFAE06659E810969F48EAB6EB002F7938B62157E85E1BF258D2B81ABD9195EB828938D84BCD92C9793BDA17DCD6ECB92068BEA49626C4595EE621E192309156F9B0127FA44454075F7C73A94992400B22CAB60A056EED2E04045E74494017E601F044245A2B64B83EA8BFEF2A02A32029224D3C9F5DAE64E4A3298688C1E4205FD9038743CEF33B08CD9366560AB57EEE937008332B6A4224476A759B07D04DEB016DDB8EDF3665BA71053A894F98DBEBA95EFEE3F46AFB944601CC71C39315012B024E672E7CEBA843F35C6F435983AAB0F14BDB63B2D130A91AF9F72CDFD73EA39DC02AD3074F0E4B3780E81732B550B298998169B1640D80FD56474FF655A233E3ED6C48E5D94A4C6D31ECBB5257DC07F29D5A4C98177DE0A4DE1BE24D2CA3CEF4DD2A3FFBD818E75023732E1F1D3F9051AF6E8047081FE588E2492E5EB4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F933819140A786527AEFC7A872908B98E8356286485E2ADA68D8733129C32FE7E0D0B7AB63E890DE8AEC5DB2D52F88D328E1DB56FF586DC2026817A277844C18228D01C4A792C6D27D72D4E36AC852098685807B31A411B62DF550CE9C5080F1BA5CEB1634B8EE7CBBDA91DA660CECF740A502064AF7781F544A2A9F6527CB431A33A905262210B977C09374F03C360642BB200F00F13EFCAB19685DBAAAD7EFBD4D42A8B428342F44A61D9D58808B9E7620ACE2D4FA47D16FA98950485E67EA182414D9C7B78C51CAA4960A79B1BEF4B6BB5CBA79515042433C7505B5038C4DD0CC8805CB9C1AA93B2BF96402909E229C46A5C2C7CB18F0B7747642714BF204D42A8AF263AA6C8F1DED9414FD0E6586D7B680D4BF1CB6CB6DD90D63511150A76C2C40384A4F156E827A22D0D207611E84477254E492397A85643BE2EFA36371F9DF6119813B2CA7F31D099B0715927919FFABE384400D3AA0869AF2E95B525D9A1453679B1624C4F2718AF080BE493D1DF583843CB08C5FAC4587627805AF278A009530F8545958E7C04ECD445240A70C6D0450DE5A3F3CBE710E610D8EEEA17F97381119B8A53A62EF7F4B0D8F84BDC86BCA2245664DA120E7E36945038F7973099B1ED88113E6594EC0CBE05B5CF5ECEFD58D48FFE4C16E0F941FCFFFDE6D3E584584EC8A03AEDB6126EF5F479E4FE8C97BA01A4980F78D12717DF17BC4E9040B105B2D74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7566DC65863A7E07D0D8774305019C67D504E7FC4DF77A8821AECBFB762EF377DFDE75F24A9DEF9CA7997E8F4AF3B4E60071F11DBA6303A964B7F9C3FD443C766346B4B1E50EA1D79357CA76ACE991F4760184016A12C2368F7D4E6BAF0C8EFCF4A869F3973B41564F52D762BECBC7FA49B40D6FCA22052287E1B10DD8FA257423F984FF4CA38BD49F322C84CA37874056055B3A0C51060360F05BE3E1DA6E1829B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F3171151E6F5442468D000FA46F17DC7437B058242696056ACAAC06AF22742452798DA226D91074DEFCAC6C3D770DC54CF7ECE9ADFEDB3B421ABCD9DF305D412A71FC77801FAEA989C03A0D633C4B06766491F4C0DC67FF8DEB16AFC8BC7E3D41601BF7B964B91A8638DDB7CC08B68691D5D501B5D3D72915442F0D1B9EA4DE4AC96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A3928351163E04D8BA817C168A0CE68CAA6FA744E7E30A2670B2BB88F27810C887E48E90EFAD40F9735B5767F60EC515C146D56EA534C970E04BDD10302D85A2317C478BD195FC93499C051F5AF61A6C5CECB89A1D67BF5BE2CA7EFBDCC20B884597EB2BB0799DB9B86E2EB8FD93389AB91A391F2D68A057FDE361AC97A87F4406F40A7EE2E7709E46DCD756617DCB0DBBF43E6BD4851F3D834BB53CB150D2FB7B +remain = 1099511627774 +max = 1099511627775 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-8_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-8_256.rsp new file mode 100644 index 0000000000..395864aeff --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-8_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHA2_40/8_256 + +pk = 00000005AF6E11950B411D09B02C47AA513FC66675E96AA47C3B284279F9543FA23A226804562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 000000050000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94AAF6E11950B411D09B02C47AA513FC66675E96AA47C3B284279F9543FA23A226804562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E704000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF54961000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113CD47F2466A56323209409FD7FCF7485A71CD8CE96D61298A20473D9ACBF99C010000000000019AB3950B30D3E7877159B364A25B214B41B8AA32E293E2DDD44AEB7DFC560A82020000000000019C359D104347B69607EB28A02E6924C24BD2A26DE4CFFF3FF98E48688E291E58030000000000011EC9B78F3B1189A5482238BCF700922D642E45D07E7EA10833E31A4CBC3CA08F0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019C1A7BFD8300283215BA57DB5CDD95EDCBD04E1C41419317BC2069C2AAAE22130100000000000143ED646E32FC21554D8DAD350C5732270CC220F7E264ECB5B7A8E8A4586D0CD002000000000001762D040EECA13E137753604D099809D946063368BFE1C7CF0E6549FCA746F7C6030000000000015FB7406F1B25A2B4A6A1666269772EB08D6FE78D8A8395C56AD80FE6924DF082040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044E3C9C3413B4497ABA623AFE3257572D979FD7234C04292B8EC507187752446AD11D10DE925035D368AF83D202AF6979123C7F3B7FCB8D83812728A890B5C09B482529FFC0737FB59C35B552AD7C5820E27332D2E44F2A31ED972E2E5C834FCC652204BB401557D6FEC656BD9F63B9226056E2D025988ED1312A2A767D418F1342BE489B463AA4BE823D471648D9893364758DACBAA63BED8B3D8D4DE1E4A7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017F7DF0085A4DAADCB03AB4E8241B0E6DC05E727E817C3B6FA27F05AE1FA2DE1601000000000001BCF2F650C31EFD6F2F09775A3B4F87BBB33AD0D51537DAF37E0D1C1AE8BE8DC00200000000000174F4FE7914F390776AF328164E738CA8EB0751EF9E535BB1B0E80B05762E683C03000000000001241535B940156367A4ABD922871FB10B37235B67CA38CD8B2B02AA8064C5CAC60400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D4FF586D6CC300F09F878FF5FDD7E7BFD0AC3AA2AEC0C223DE23D190C6F67AFF7C00001F7DE39C907235BF8D5EC16A34AD2D2E6DDC419F5B24EACE1A17BEF5CC52AAA05F04D5AA8BB018210354282E98DABB918100165E7D962A6F396F22753B1FB928AE3576A91CE62216E9E6214ABFF91FCA2E6E77611AD13F70CC87E67A1E6D886120CD2C2404E0312A57635D1C2524C97EC0BDD9DE011D158F8FCA7AD1A2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000186A69EB284CFC56C72C2C83351D5CCDBEC831992175BC2D2D91B3F9378E0DE9E010000000000010A318F954C197DF2DF39A85C4B322E7EB1B16B0B4EB8C8A492F4F3B904C47E7602000000000001A9204F8E84112663772797AF87ED34C559ED4D6D37E634EFACE6A18C700CD53A03000000000001D2E20083FA11E157A2E5B72C9A986D3F47348E54C1935F48A86F7A9D78B2BE600400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6442DC6DD49889C3DA3AAF0FB310C3AD990480EF12059DD23AE881D5A72603F50C7C61626AB2E0BF9C8C198CB0F637EF72954E04DF5956355147B5073EEF3848CE65EBA73E67955A1CFF187CCA758372FB67823E230B05EAA9982488E8D22F6DA1415A731BD0A2B036F858FE16FB4349149B507D9DF770B9F3D3B45ED752EE888F40FEE65C4F3EC6897906303A19863DD968C666AC1980F26D8B574D5A16C95000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100132C90901F97161C5614019A534B035942B26ADCEF40AB97BE258B03C87585010000000000012BB35E6F2C4AE0A3430CE207629C011B30E4C6F5D6BDFF2AB750EA0C69BE95C1020000000000019CAFA71D2E43D02FBB0C55294A6CD0AF3AF0816F6E6D1F4022AEFD413DBE8C1E03000000000001943191FF197E71722D961AF04F9570BBEC438A6D22058F1018F6C61F3CED67E50400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000290F4FE6675D4A1FBE8A93A91C6B09B1456828554CD0CDA039569E2C08430C3481E2970BA760DA29C31944AF18085694530E8A952B54516062CD9528A95D0772323B4B8E02C7DCBD71FFD2236E772268E25F6D4C622F07F5D437275B2FEBECE7605967771BFA2007FECA33154FB46A3B788E9E7702F38BCDF175EFE4611B61147D89195BE90840FB1E365A76840BD9B40C21949F2D41205A491C019B7F49139C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012A13FF51186CBFE9467BCAB51417E5129671EFD5D0D686D09E2C5BB683FD45450100000000000184D0629348E528473585F873A1929F01BB41F19090B770D155E497E4AFF30A990200000000000163EB4A114558605E9DDBDA75D10B78F28322197D1DF7FB4214438DA12328F8F203000000000001B86361D142F7F14ADAF4EC3E307CA82B6106FBDE3777E656781187D3558E3E1F04000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009D550F851D023315BE35A69C83D099341F6BA69B6A40E224DC554A3489D33729C9EC8196BD665514030C26AAEF80CD6E1BB9EC739BAA2B8E4A63EE691AD2BFBABDDEE2B13CFFEEAB7C25273CAD45409B5270678CB1535AB800679906CE77189DCFE05BBF92FB5E31F184CECF3C427437958F695917E343ACF46DA2B9D988CFE316313FA9FAAD49EDB72B007A7F3D6FC55A88E6BA784FEBE9737803AF05B4801CE0C723C0D15CD8E7CA8E237D4A1C0BB1413D369FC3F21F69205D428069EABE626B971A2B5698ED05BAE54218300BE8C4BC9A52EE5FB296BAF2A9AA42F3C865DCC1DDA69969F085C91D3CC5934567476EB70461B942059AC0F83BA10DFE783F5FB405F159563419B3F5699179D6F33AD05E840EC9227C592E361A49E31D99445437D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB3844833CA9CC7907865878A01BCAE7DB72BA4F7701F20523E0E98B27AF08AA747B57DB1DAAA1B616DE469C7FC83CAA1DA1D6BA6F0C2B0F7F2CB7A4F58FBF7FFEC292AAA7FC3B87E797DCA067ED7672BA9B4CBC27FE9AAEEA63C8569A567129990E1E12A8D23039A877F7FA3EA9B9359A842A19E33CDBF284AF95FAE2A2DDEB80030A8245A7E51131D27EAE94B6C38A8C4818CA7EAE0A1C0841E7AACDDF68A4C4491EF97D5F3F6AD8CC47D2489DF1FF96B7DD444D31DD2FFFDC69C9ED7F750526B3CD81EDEEE2CBBFC0BCEBE875DBB644B3828795D2B81DFE37E0E4E68F9A798E09588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE596674368D1D405B742EE812FB88947D9F5DE52083777E54C2F0A1F605027BCA5A12BDBF9CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318ECCE515F732608A96D4E557ACCA60F144A212276CD52FAC0F12C39F7F45565346B6EE409558FF37D5C50280099C9D75B688C7D873EA7D07EC6C9305AB367ABC2FEAFF9200CAD14D71DE9E1F1DFFC4F15FD0908C6687F585D9721AA773BDECA4C7DBDA2D8275C59A2E90EE07ED6734A09566174D695356166041C646F18180DFC5ACCBA61F1672213C3CA6933A5ED65898AEB4BAF534751900D2CF25A7A94C273533B8694EEFB366F4B3E6D4DBE7FF5FC70EF5341217906FCEC863502598936A4A0D7DD4267B1C0C6E8175CFB3B9B6BA86CF3094D4677BD57712235CA8395A6914063B4E2849AFA406B7EC6E3AE39B343EE39348D2D29A0C2319BB34655A53E1A816CD5FBAD3A3796FEF2C7B67BE4507438E5AEB603B1A0796293A274A3F3D63C7C1F14297987085EC271F06E8DC986CE41DDA37ADBB39613E6790644A669594AF10B5D7C2DCDA7190B03F77E69D79A143E9B7D8B42E18E56D1D191DE05D58DC29F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA4C86ADE353F4AA57DE2220D13EAC9BC8FE02D625EBE3BF2761493F180F968DE438B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE8D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB07425116F11D430A927D45FBAC134C59EA8E5907C35A59E0CF2FA548F9AA27A3530AEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBE6FFF1A2A91E8DD23131A7840BF7CDEA3E18E706A324AB688A5866B82EC18082D89DB83F78DB30D5CE6EF134BBCE7628AC017E6D6974B1D82E4227235AEC9862899B7A4E0E8B10A8AD0B19A54DE7ECA861D6AFA1D91C9CAC7B8D6AE536C458E176AE68697912D7EC853D514AD4EDE982FA89400CE895D3241E5610D0AFB17AEFE51FBB41E2DE044A00D84BE759242476BC0099DFE159F0CAF2187BB311DF2342A59C003778A56907F086C8DC9309D8E41703779C8E1141070708E02B9F987ACF3214A8E442B76121374DD243643D64283D01279A49154760E3567E46ACE89898BCD67842223D5B8CAB03DC13930BE7210FAB7FB2318BDCD92B642F6BF178BC30B4F959F5D8BE15F67C5AC4A4C81F1E3E707AADF0B4CD02982ED4E4E52A81EA2FCB60ACB5817849D53C2FFFBF7906E290BF76E505071913AE0361FDFCA4B279897C9DECF546FB0366D65C9F81A9B51402F3694F0B5DC600B7E4F084383B643AABC755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E6C007F614D3C0A2E45486C2E457C2E6636BC1AFB76B2A7FA351FD88399098C64E379F99B64A3340473DD46C11564937DB9A28C4DE3745308433153B2BC6D5E0D515C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFF0116375D404211C3D3302D17DDD0390712E06CA05FB4BB2AF749D3439A5B30D3E9FF4731822AE6607BD96108BD229A4BDA5ACF50F7185BD1C0F56CC56D69C008077082C0869F237A6F19D73ADCF9844686E3C5583E7D8FFDA636E70E989B1742ACA4DCE98101BBAEDA8E852555033A46F8DF4E3DCA1B9A09E9F938E0C1E468C52F7DC695389C21D0F425B4DB554FD5BE1FDC2765B997FAB1F94D864DE1B4C8FB1323A8D90DC0CD7FA7363AB70728FDBF33C2325FF97C59ADC84C104E730C85CFBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272D144DEFA2E32DCBE8CF7843CBDB9A67EAD7892ABCE9B25A6B91AF0B893846ADDDB6C26354D4D8B77B14FC2FA2D8D589237C4BAF80344C306439619E5A4DDD4630B558BC9B3581AB842BC8B630F232BD18D4BB10FFA1DD3805B18635F6A9A22CE0D470FAA2AB813662EF63C784628138499A1A3648CC877300401E61DA9A379FDB3FC6DD985CA26EE8093A24879BEF107C4D6A38017BE3AA5CCE124259C42519C6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156771072191C21BC3190193111CD3BD0604EC5427C6D70B1BF21DB6E59ED636342BC417CD9F69B804EDB6359C9F8E347AD253370E065D500CAC64BFABE3E420E39C27D20CB93DA243BB3270F1EF2DE68AFB80842E8BE7C1FD48BF0F5622530CE84C1D30BC69EE1164CC602F2522FA39158D4D0D30ABE4FDE43213ABD6E4D65E62FBEC9AA1D485599FB7ADF5C2C97B90C82A1DCCD2C44ED66CCE79EFCEDCAD0CA1366FA51DD03DAC9BFC60B79719033B32247DDA9195233329F5AA36627FCEC5E42F078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DF657C03A3914FD3BF1E82EF96AD7EA46373B0A4DD0F5655F22F754DCD35ADA89358DDAF6AFF78EEEF21010DBC6556C2C3A018E4DA1D612CC3EF237BC2B1E9E600D923E2CE04FA27CE8EE63B969F6079FF8551B8C06018E99D84669C059AE08081E3A1C7ABC19272D7FA3F2704CCF6E491AF93C7CBD4660410389D86BBA47BD5A0E996F788FB9CE600AD76485D265628019B57FC69631D5266E8E46913ED9142FEFAD87E26DE53ECDF43B352EAC14BF6DA899058228C9414E7323430F9357D6244E7165F5CA2FF2DC9899AA6D8C2B8DDE8E2C5FB7C6E02BF74F578823CFA2355F2FCA1F776C6A87943344A5E53BFA39559EF98C397423C75EB318EA9B5F375C17E7B46A8D592651E7D50E70233224592389C1EBD1EB66678AC42C2862A2C660BACD03BA4064EA38D34A7D44B32DB9E75ABC6B5025B504DEC60512A80F78876C54D36324C7143FEA85ECB9E66800E8F4004061EA7607EAB964DE3F9A273D2C7A4CECC1B4270ECFF87A254A139DEA1E0F0B0F6366C02A0A790D46EAC94866A82DD8349F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DEA67846512E96901F78E601EE427F8B1A7986FB8832D091D575C277CB202E87602D670CE131CC6023A9E83AF41486A04D62616C1E912D4EAECD5DC815BAC1C0DBDB347F6B5DF06B0F58441FAB98B9511AC0423ACFA43E0422A62AE32A48E935C6288BD0D2314C6A739A7779BFE24DD7E2D66E9C4A4111E22481688EA39F256224531ED241A9D35D395F340421F2D8F5C05B873052D2128CEDF4ABE49E609176674363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D02AB14858954A117C6B6F2CDF4823BEEF1904FFB4D841B30537D57C577968CDF18EC8631C536AF09B54D5887FC0EB11A70E86B72EF315FD722FB680EF03A3487434215A0EEA412C0D78DB2EFE20061576237453927710860F0A49DE0ED0C42FDE2A5903D635B19D4F2001EE353D7B5210E1C01F50251ED6E753635A972EC8C1914E36522B1B41BA51E9F3F1CE83BB5F526FBEC31C21983736E42EB7880B9B27EF6CAE0618E57F881193714D3E8B38C9E9056378DD79E78422BD7C4CD57D230EF44B38F6A107ABC77B8D5A953D3A3969FBB7DAB145C4F4615FAF8F2172AA2BDEB35C4A0494100CB9CE188DA4318EA5B617EBACE910A32F0A280C82AF82121720569232D71AD065E45268B36F92DDA13673529F24E6B83A865F3E266635D9655C8000C06478530294DE092640DFB324E09DB3B87497C94502BD46092D72DAEDFA93A0353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB51691B3F0ACA92B02FE916D2AEB98BD9E23313F49A0F44394883A432523EB5B34B690EF9C16B4D60572EF2D791F2BF403255A28D9BC3352B02687AD9200D34C05259FE0C93B75455218E031D59A65D4F571CD7F8B130A0CA1363BAF2D9895A8E8925ED20ADBE8FE96C34A6A13B9318AC8A23A7EA320B83B7175FB54868DAFA9E233B0F4B18CF6FC7D85F7A2B28CEEC561222C5051572B092F2FB269ABF1CC7826675F09949FC443EF723AB476E9E5D670C5F05E46DAE93837AA0F65A4E83AE2C71DD02CAB1038086531F93E163AD65BD962ACB9497C0F268876B5AD3CBBFC4C24EB2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADB0A78B6C1C4ACB8B4C97EA8C4CC3F3778CBF761AA653D9531216588A46701366E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC4050CBFA6FEF6B9FE785A59511CCCE21EC5AE3F429A07B4626A4F0C555A15B42C26A5F353E7A479A700595689D5734C39D61177AAB2943775ADAC879B4ED7B8ED826CB43881D2C1B5734F64A5490A4F77ED4DCB9775B258C18182B42C560E6CEE89A329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB041A19053D3003420EC262BF0F45F1C7CF6E55BA9001E4BE097329CA460D335BA899503CAE0D617BB7FFF0AD37076C91B1659BD448C05C49D9360462B4BC601536844FF2C635BB654EC5749FBCEF3288E41B8A7835B645E0BB501FF805EA4B39785C203BE03F0B105D17E513D50B7738E78EC18AFAB3FE134FD551E754CAA189DC4FA2308B6EED1B8CE87EBCE212E15E72C9516B778C1F62819131E2EFA7AF63BCF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0A2979199F43F2F59FB2C62E8AF2EABAFE9B89B71E75AF029BEC77A6A56F86EF6A4A7212A7458986D2DAC9E00CF68EDB81CA05A297B522D3CB2E0AC3146E4638995B683EC201C67C911C83E6BA3567D31565DF914783F41077E2C31B06640446A6D403F9D46BB9D00B3C436FE1FFDA80AD0AC466AF0417D18D5E7DFEDD7D68987BA55F545F3B89A38908BCCA1DACE0B89FFB49FBA3A67EE7384DEE68FD05721483030ED53913A6CFA059DDB451C780877E919BB86DDCA9E18814123CCC822A8F30D0AB4602815D2279398ADEDE00B23AF4EE605A771AC616CAFFCD3AB12991023A6BE6BCEAFB1672ADA631C6CC29827088627EF9380FFF46FC479E2B586432B58F95A824C0D5F08704C2B596A7BD0A36A52BFD8C14D999F92E676C83EA62DE54C3ED7ABF290BF17C48DD69F949668E11D957299DB6920D740252A9AFB65179FDD62B69D2A1A339CEF805FD258D83FD2F406841565AEF5E42ED7687D9D466E6A4E513E072A9EF6181016DAD988F7C2305A77740F196465CE30A35BF3D098781DBA7285753A9438517AA7159A9C806A19CE8B8BA5F9C99250358404671F36214E8A7B5A04767FF8C094A3CD74751835BD896FAEFD1747DDFBBE79F48148D56BF585CB0CBBF34300CBFAB9DB32469814F107EF7822151D158CAD68F01418F88B181B092970DACAE4D5DEA7AE39965D1929CBAB7685E758206D309CADC07687274657F6EEF56A657D3FED4D34C7FF6C9CC5F344F0EF4F0E752F83E06B8A23DA0D65A2C10C2D675CB3A214F5D363C35E6E10A1323579803E4268F7D868F4716BF849B3C3D8EDA94476BE7322891C36D6DF146075F11AD02434D2216351CC26600662BE0D38E1DFEF9A832B9F066718FCB2134115F33717B57936CCD2DFA3A95C1D4C4C98BD09D64EC04912C06C7C6A2FFDCA2801628D873EE6D0D43EB67FF0AC93A7666C9ACBB9400593C00316E05F0F5706ABD923D85DE72A0D1CA9F0774F5180B65AA578B95BD20C1FCC322A5B23995ACC9DC97CE3043B1A723AA2815314637B7667DE02ED0FA0924C0791CA09FA028633CCC594429D6E7429930C7F01EB6A134952E89B8CCEC743A23C63CDD9E161B5A2D1F1E0D005F16727A3B0E8B90C20656B850A4F8B5D400B65E91E45AA25A880B76BE09F226DDD4F0E0AEA00259E19634EBAD387CCAB556997A153D1C1B87AA62E5B613A5E02C65E7EE7DDE2E19D965D27B42AF8542066549A6FEFF3E10A93B349EACB843759F5E4EECA76CF82277BD55C57FAD09BE938ABB47720E49CED626AC860446B290C7FE9BC83DB0C7FDCBD5CA2B8FF6C52B2CF2556040B3792BA99DD43EDF1FD4CBE38970D235E8BEE40DDCD2708E432008992D3F9DCD73AD594171092909019E9BBE7A5D4A21EADF82C5C22D877F422EBC64734717C93A027E9EA7EDADFFBB8A04B465E2F1BDDA54BA30963A41978562C27EE91E8ADD7A95B97A1F9F5C0494C3E44AC5422759F971200B1927F5C37B003499B213C1CEF1823847ED4A308D7D98FD5E42115D49B1FD42C7405B55437E1C8C0226884DD801CD89163AEE8D74105F621EF2CE222B13ABBD14078943CE054E3D68F7E8D763948CA83876F0AB7CA5123ABA8C5F68679FCD116D03391F2A53F637D26EC486FF6363F0C297E1A672EB717107ED9540C2AAD46038F8D4C2B5D1D918AF6BFBA7DE46E6628B2C217672257EB98F585A4E4CDD87729BA5ED16719F869FA1495302E8BD043F92ECF8799DAB7B9C501DC956EE3E55FF30E6D565E228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023E10A68B5275694C30FA7BE9BE2392EE6B18651980A01348A97C4BF091DE3501B30B528092599313ADC93C8407FB07E740F784E80461A23A1DCCD78BE8A72EE2AD69CC6E63F385963275DF49AF300E5D468285CA4457F090504D42056F571A8D453903B85D7E63F893431A5A1C8A66A8E4C999F0592D75717940E296C8275952C4A8DC6E97B3D5602408DF3644E8A1338C856296C37B1BA8445883CAFB408EFB9A545AB53CD632C40659DC607F4937A4F364F7E3B47A907BD30D8558C76A8EA9EB357177B8B2639477433604EB74F9C2E3528215459533C1A989FEF107944FC8A402E29495F72F2C210135FD836028B9E21E76C6F13096DBD2BE9721DD2C35504D648C474907FFB896B014CB022942F308C3263CFF227D4444763A483658E728EE6B7954C48E3FCAB1246CED1B1E2EA9CC4D5475BD4FA43FFEF56AB2A2D779E9D206E3E657A2244108BCF55C7F4F97666457CF5F796105ABC773C541173B9E338B4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F9338191406A4C257E6B7C058565272FB78A54A46007F5550234FE9B7952A82581C08AA6A1EA68E497D663F82C5D20E9D1134816EEA319EEAC8E431A0D82B6D62F7B93D121D8382F0EB3DDBB9FCD43901C8AF1AA019A7160B76B72D4E8CA1228E5E9DFD49E24F3154F4A914987FD0264ADA4C8D6FF9EBB91C59C03CBD484E9EE72F1A98C3F97B9F2479FFB79DFAFBC33C8ED249286369F003C471C8B64A9B1546B1F31BFDD0ACA06AAB3EFB61E49CDF5506AF8A4693A7591498D9D7F8B28A72A10EC60F806A9955D7EB41D2654EE5B37C284F41CFF3F591C227E3FD0CD524379DCB384ACF486CE7B1E658CC743293DCF546BE85382FC40CFDFDFA407A9EA33AC46468E060524BF06C9CC109A726CEAF0811D0F857C08A3D4AEA67CCC0B17B2C38C53DA9F860C99E3AA769EE27CB7C9229207ACAEFE6C62D3ECFCA201DDFAAEEE1EC7BFD40086AA922961198B53C94BCFA97EEC1DC0FB8FF1D9448B6770DE4F5703CAE179FB51CEAF935F666F398B74BDE9FC87B01AFB6EE8B47490453198F9B38AA2259D2194E9EBC42E1C57994921413D6327018B91538CCB0B90E965564171D133CCD9E7F65E851971FB71F2C47B4592C2A52A4101D2EE7A69DCAB3852A56C4DBC9295D2EEC5BAD1B8A13B7EDE84768C0AF5FF0B0253B44038C236412ADCEC91508A76BD8D16E6D6BD5CBB3179B34DB8902863056CC65A4DD40B6A1929F28DFAE1CEC64A74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7E8104E8D9DB129F0AEFF48177BE4EB60236851F6D0DF3EAF508CA7F97E4D5814F71ACBCF00471EF263D3B5CD58ADEEF11E3465C704D90101A5FCC1C8CAC25387B7D6B83C7CBEF04E05BBA1766C5C5D804642609AF84AF3FA7E4572393761664021A632DA048F2A10C2A349E2E1C260C1C3CA6184BEF6045F43D9C767E2328B9AF5E48EFE8298DF69599C49CFE153BF59010741DEE011FFFBFB4EFC5AA4B5DE409B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F83369497B16CBA6B3104624902242C468F89E89322D299123ECDD8ECC98FD5C53D99FDFBBADB056D1034CA39CBBFF29300769BFF634A38678FE7BF929676A43CD0FC3161391877F0623D9B59DF30E28F5B47C0445F83B36F0AA67F6A2DB8C0C3D3F45738A4DE393D8675E286F4530AC810D244C621963923BEB20810EE32909D5F79B7F944D0041C0130B7F59B0ADCCAD97670C92355CCC8F0FE34612A088BFAAB33542EBE8F3283AD67A79EECC3E7B7C5D4CCC29B6083AEDF7AABBFAC8281B7D7711DED8D4CA70C383C5042272379356BB80EC0A9BB8E4F1C73F2D2DE1676BF5AF43AF87AA2B2C4A6826DCDE46E599B2F31E9EA87A816EC5D8163952A7384603C8FEC20F58E1AAC52188E42774382077A35700EA5EA2FBD04135593A7E40ABA137FE400EB63BAC7F417252EF6AF6EA8FA9CB3BABE7718FAC4A756702AD64BF1F912E6ED44DC6D424CD15D3E45BC9F86ABF7CB2924D7B4E8AAF67D69401F5609B17D251140842D7A94FE5D911BF2FD37418208B716D2DC66320743B79E64CDAC6F2257AD34D112E22F977AE6034068C0E0F089FECA11DE03396BFBD365B1A788B2C550ACBED3643C1E4F13618F904B40031CA9E73F9B13293DC92102B33FBC16C9CDA02E511D49394D5DEFB95770E5CC750801623042B7113D385E8BE8FEDA1D7F9105D545B18AE98870B1326494F9BC31B33EC24CCA7CB8E53F9AF1A7E099B0D9A40CCF40B085C0D406B5F1DD7DCA794345FF98F272F7D9A11C30CC5448D2D311502B7F0F81437B52EB11CC5FF11C1FD62B9A34E2E102C5C59D14A3326702F6B6862383B5BA1041A59B2F4E009161857FEAAE3F0C4006926444BE77169E9963DF262BBACFC643F032414200B26840295326BA1983CF450DDABD0DEAF05B3AEE35CC029B1E67729517B6555FDC996782FE0CB275645E739BA0BC75A08869998C082BF6680E2DED0D643F06EED3947CB24E4D240CDAB6B07EB71762DB159BD8E8FEBFF190763906FAEE1D307115E7D6697AF3DB2192D37468806FD49ABAFFD157647B652B339A8912CAA3730EDB23593BE64CE9A50A1622D43538926E5B05D878029C5AE57DB40072EBB7889423A948257F9E8684E5B4F10C09A22AC506B5105246ADE89409D3AA78C4A88181FD562EB714E9402F8C4AB2129E73FD77BB64F3F6752E5AEEBC4DACC209D01A274E39A84857736671BD0604C153703CEC940CB0D79CC433D157EC5004ABA2F359B80DA9FC04267584B2897B594C494883185E613283B939DEBE0F324B3CB9F45A6FBF11AB1CF2704C5F83BE3B8CE1C38663757828909CA4AC49ACC134F533F5DAF470EC30D2E8FBC66C9B6C58CBD2ACBFBFA2842E78DEA2DCB820CCCBFB17454EFDB2B1D706B93B0254B3209CFFECDA9F52CFDC1CF312EAE3035C1A3D75D8764F693350C2301864EE1A3797F6574AE38F66B40F82904FFE6CBB34655B99959759EDB652F6A3BDC1D0F24E8EBE1761B43E876A6A7AA29E8B1158F1D150E25A742B5FBC7161234A85B35803FABBC0AEA40821E9990D48BA7EF7E1A50178ABB3CDBEE228B40C8B02C98C5E8B70CFF650E570988E64E6F4FB69DD11814016F8AFC30F853DCF0B793E150C3B796CDE2B1B43B3E346E257302026A4B5934CC6A417A99706CF783722DC2663F469896FF8EB4CC741D531F3C32B41F0BC6DCD4A32786747BE120B33718A94639FB4D754E0508B0315990F31555D6C1DE281244E229377BB4FDB9CBB38AE483A3569F735AC438C492DFE94149EB3F4A4F9779A1AEFE60FA343AC04323795C9D33DE8AF95219B8711B1168A107EF83062F033203511E5663EFA0C45ACF54432C9D4EFB5678332B5E164092612E42C61560D9EEC768594F4E0E6AF10AC7B3DCD22D229AFA8C022EB00AFA626C63E8E96B72DF979586867B42B8FEDE446A0F6807F1F1C775595FB5DEAA3BE2A45570235BF1169F163501B400DB5A48D7FF08851543CA92A0E8448F98BE619F41FACBF13EE45A1F97C20748CDC3B4068D993D944D5A165FB858FDF4FBF88632FB826103B1276C7791C64195106635996700A71E299889131E533F7F060C7F96E7C54F02D2A32835106FEBE6D40CD4D56B57ED26A7431731B04A78CB5A4884F0CACDF007DA6E1C4195B2B59A53F31C48EF9FC33CC7F6BD147032A1B6313C7EEC43B1E46164BEBFEF16FADDB1A176FBFBE34DDA7C88AC9C1EEFD4F33B7960D847872B8B433AD5D1293EA480E6FA097BB9AE29A7C0270A062EF9BADDD796FD8EBB1502606E9262357EFCBCC9B7343ACBD03CFAE6907BE46BCD32C4C4C4722C8D3A9EBC76EE4CDCE71B049D688C42104B94A1F7FE6F945BDD02E3DCE0C345C047AB31E7E8051ADDD3DBCBD33699AD660C1CE3E25D203C4EA56368B19C77D498E67CFE083ECD3D36BDCDF29A148224623E0D70D060EC964B329186162C1567F7E7B5B6921CAC8894E88BD8BD6FBA1E8EC4081D35931ECA2BE1E72E32D7C986956EE9CFB07CE0B5091605780D9770A00252C92C4DEDD4D8B942E14C90DFC5BD612D85CE24C5CEFDB3EA964FFF256B20A4DC2C0EFD50DA4BAB56BC846B09DE27F341EE42E63C0C23B6C61D15F2C9FFEE5663E3CC74F7400D0645219751B70C916C03C0C67159F71BC0B3BFA0956F026B91F8C2419D671D3E00D7F633DBD2DBE88126DEEFC7733C2C926D1D8B0C8BFB1077A700BBF3892F0C4F3E30DF78BCE0A340A8F98EBA5BD384684D1E0081C1237440B3A6F117178C0DE4F19D05D4241240924D9EAF9CA45E3D4231AC903C8EE5298A3445F01961D6D3786E36D24875E6DF3EB1D6C1BE5EEA0E060D3E0EED1DB2D4E795D35A0DABE4A745764F05A858291993541AE149CECC5147FEF0F3A96B42F38963B9B29466FD66AD46CADA8F10E2D53BFC3B823CFED410147B5FD315FAA62ED06429D6D3FE6E5778A64B5C9BB06A8CF5561EB7A8B15838AA226DDFCFD4C31805D53A6EB7D2DB861451027CF84218C39078756B2911021C3EAFC2E82ABF792C5012CFCA3AAFB0A277A9C9E1E515CBC4439D95B2A54510318F5D6EBF97C8DE2AE0D4FF669493AA354C25460D3C15B1A57AC53D7E6C07CA407AB1EEC4A366A637AD4081F0343433C555DE72B71ABCD8ED3C043532A61125CC3CA06CAA634E5F75B750BF262756A57E3FD235FA9EF00CDD9553D37968DD680EBD5935FBDFE43A82E9DD39F96FD483AAB7F2D0517F23727E8F4DACBF1442D207EFD647078CA9CDF7800804012D4EC23BA14C99666610A22DA87523E4E5E41A6698E5235743A9B9E1C4795F38AE20CBE5C3A2111ABA307C3BA6E03F092E96AC6EF297548A3F144ECF7F643EF19024B2E98B51173450ED06ED68EFFA06EFD60721E73C9C6993F14C00E3E4BE441791C648110F699AB5089D7CD092AAD82AE007C0C3C8659506D5F2817E75EAE8B803734822A2526861036E35C3689EDCBA348A7A2E4BE2F1E291F63473988AFFE650C1BC49CDEA3875DF4E6B541727B5AA6F04C9C1E4D06BC5CC744D1B955958E2578C6176AFD7E3262CCBC0F6FA21596BDC36349BF9329BCBA08FFF934E31DC1FEDB7D7F6B459BB1A0165043B902D600C447792A618B77C1671E5793473DED54FB3322180F198873E306E1F8BD17BE04FCD3CF4D6A9201B9B804BBC772B742097663C42F0FEE3766B3B205F14A39D6ABA56963D03DCDF538ECFB8A7AE64DA3C116BFC09506BACF5E8B5754B220F7CF70C5AA4492AB72D20CF8F4966A114833B057662EC63B9570D9B2DCEAC86590569934F91A61A03E18835E31ADBC2EED3BE0BC148FF004675C9555C901B280BFB56FF8A1C079E1F290C67FD1B7E53A6C27A5C649ECA9EEF836621F9E708EB84B6F5C529ED2F07BF0A6160154F41F323DFF8A498177FD09D22DB15A273F787529852D898A6DF0FDBEBEFBA3F3B602B1E67352224860125216AD6D68CA891606E179FB415DE4B95484CA6907319438F69337316203F06AB1488A471924545C81A470D78E2EA29AAF89E94920AC4B0E7F2FE01092BC8CF3839480A02C0E8DAC1E864C9BFF5CBF46C0FC7B6A01FF0DBBCF96E3585496C392C6496D06C44765878B26B6DFF2C2FEC20F26A9A2706838A2048E579C65F3BDDEFC58C89D8830FB8C75FAF96788998DD200D48189C3B59B41501BD310420DB96F7CC5B61A2EAF88B498ACD890F7DF623A35479472694CDDA58C000D9BC04FD903E4AB88A2E757700FF3F460F075F9876DB3F76F17003E01DC96A92543DCDFCD7EFC86A5C0DF387A50ABB69953D6DC19A699CD225941F82438A8EB7889B212F65ECA7399F89CA0D9B9915E827D2E520B6D481C27D4CD833EE7D985B20FA5BF7A21E4DFCAD092628EC0A6E2DC876E4C5BF248F94C2ADB3D6C9F23C3E70D1F611A2041C7759317B8EC1696B2632CA10CEFA498D7571D016E102DAC10051DAD086BEC58AD5DDFD7988C5F433DE87C314E3930FFF937A6E0C81787F04B77F893287AB63125CAB8B7460F119D03BF3076A98FF029EA5022201DD54C854711B8BE718EE678544B51AB13B7ED0262C8180C2F36CBAB64D862D38AD7D8172AD8BA3380706D52048826CAC611B07468967CA4A4DB52628A2FD56DD3A323382E5DB171811EA861E2D46537D0A4E545C65F238380083A064421DC7CE13EC2F715580924D9B6EFBDBB0D45AD8952F602BDED6455C0BC2734CB135B79966464546A261D0A551DEB43E5AE111CD02D0F2F2E996454DE17B471C6103D851CCE2E1FEDBB828C7F4EE66053A57831C708C377FDC6FDF037F400A09E9A610350BE6C013239D7F1C42758CA84B428EB06C6A6A3E05F10FED769CEE2D8EDC3EEA29204605005468B0366B2E957A7A55FBCC7842598F55021E58DBEEF44C5313226E6E56A2D3837F2A098C94BEC791737F355E6CE5643C954C4719C6C1C939B7716A29191CF0530BC2E78CD028D526EC286FCF02B18A077C86BC54F078A19A529F6EAF69D5562D4B31E4CE3B953A24655429BDBAEB5378C13E5B404A138B2B5473A415EA236245B0541B6D92F384D4CE63680ED5A6C035FFFC663C893C8F51C5DEC6F90D33573A05CBAED63B69079EE77DBDD21AD7A778B37EA5E0543BBDCD47497F355B1B2D8AD93DF4BB96A5E85A2344192B782D54C4C8DF251BD5F72EC415621FCE91148DB266EE1BDA0885827E96E8A9AD9C50F43D947DFA8260661FC9326B9E76214D36B22172C026EC12E04ADE3C62D4E957AAAAE686D350793BC6E9C862D968C0E56B3160B5C70520E9AC7767AD2BD8D1D6DC951A23BE9FAF9DBFF407E7766C84CCC3F281C6383079DC3188FBE8F9675D0A26831EC44071AC6184AACBFA0A2326D7EF097650C1D4D1E58134408C11E839A0DBA17CAC9DE3B437E697663AC136380D0690DA4A52070A2DC552275BA09C01B601D55E97AD7DE83A32B962D0A9053C1533600FEFD1171C638A50922B9962C195551F81FE80BE28342A13ED0B25FF8986E0E9C39F3C2F29B9F40AADF8CF61E879A7FC863B32F02C5B5BE16F0E2CF00F30E312820E84D09BDF073E0B16B1F32C73F0E6031DCB3221DDC48670D0F2DF9A8065BD027C30DCF9F12782C812753F109615828997768C75660D469691278A111D50A72CEE9600124E3850507C0B963E9121C8B28262B6C82510AC69F4785752AE1F619E3D334170A4ADB4DAF3138AE90AAF8D82573E7AD25A16243E16650219C47F4CEBE6915B433B0ED0354EE62FABFD3E118AC777A63316637DA755A99AF97DFE9857B2F58A83ED70041EDBC49997EC93C03A7D55524CCFFF8018EE1A587AAB9FB5D3E33FE7BAF2642CF9421540C134F9BDE458A65E6B9BB209359F7FA47B95EBB79C83F329ECF88C7541446868CEF363218841F55D346A2B714DD48C711555BB25B1CCEFA6199A0E7646646B667634E486116C0AAD7E977C091A5EA356778C299EFFB7DBD3232C4B73B54C796BD1E33284CC8E4354C772DF1CCF762F615715FAA903D1551A67965FED6C7E1ED7BABB9325AC30F92305FC284724C59079B11D1A0E32F4665AD8390B34968D1885C9EB8BC5DDF63D7858E042CF7C66FF5E36365F1C7156C79CCDF596EFA551E203456E5BB22C2D9B742F490824B1D5EE482F335393E34E69C7820A639858C6EFFC2E8377876E461788FD2736A2D1BAAA432B008850BBB44FA193DC54757D8C75760638A12DFB614580A882EBD945716D7A3D3D29396D4A0D267B07B035EC001CF29C87E23D8446E21D604BCAB110869FFA98C32E35A9B6C878360FD7BF8D564B09384D5C52E0C9BE0F45E814C954FBA214F3D3089AC4D01ACBCDB25B9331558FE1D29E67628E13BFC928F7A9A88D13E0759B77674C3F2795CDFE0C6617022F9C6A87B60C4B5A69E8D1706749FB0B4E086C94B5BFC16CC3B34FF3B7EC227A5CC646E9A003E5D897871067191AD1F8A8C33A0E567F4DF2D91D00FEA00B152183D202BD72DC0694F16ADFDD6E44A248D80FC6609E601CB91EE691C4535CD80BECFF9F23F32BAB5F106234A8867CAC0B5269CA2BC588E48AF922B5917BB6813E9D1005F35CCBFDFD419404B59A84497BCAD743384461F24267C497A932411B690BF405A7ADCA63858F439B123201F41AAAAA4D0A478101EDC6AD214E025B5DB6D24021464C53FB376503B6CAF4E4D4974E072F8C88A7C61957239581B589ED8D1753844ED928642CF96E5ACCA32E69B52CFA3AF54B9FF793E7553CBE16C4F9DD6114D1357E539C238AAA4434C5E540AB31FA584B82AFBF419DC51D6B08FEBE34B7991EBF2A82FF8E94990BFD02764F7D1DC049A635A08B7BFDB46A521170B6B8BD940883CD4505224D9DF930E33C5827E303083CAC4F846D9CB9A6E3FF57E755C7CCA541DF51819C5A52BDFDF005217000967A2776F51217813B2FFC509EE35F8AED6481BBFF5D5E61732BA17C90FBBCE1FC29E8DE849C146642845F982A2F766DFC0A703B5BB612E4C2B8CC426BB56196D714FC6F1BCAA0F19F32CBC06C3DD1406B591D2B0CD0E834D003CE56313B66C224594354866598118C87C1A86F7D247593846100395EE6303E54D130F91FDF81D0DFD021C274AA9567B9F9A500F35507519BCC25535407E419B52FA4D9ECD3D53F467B6295505DE979CBF6C7BC909812265ED65B30269FA1500264347FBCF1CB34AC5A405F208E73DD503D0D0E15FA474802F273C76C3D3DF98070BF3151D5D338DB368DA0D2280BD821880265763EAB2076766540EB9A51EAE647B96CA4326C82626DBCFCA1B3FF6DBA63DD64AEEA6741FA49E358E97D8F60C7F1A56248E8CE18933CD6F850E667134F69176DFBE2A4FC259994ADE12676F63D483FE16F7658F1003C1561B8D46FEA0888D2C82A4254AEB9E4104B9FBC973CF836BCAB5E263240ED9D87E9C434DC66E8F4A7B73EAEB30BB745F4094A4B82EC96CF99219F557ADEFA605DDE957CAD9D5343558A9A0904575A7A954948DC927E71786394DF40E9328C9B4382CF4FD8423B97088BB07CB4B257E5AC7B817088C3A6912441992153D374D477EA4EFD21C9F706D3619634AF7DB364F5FE73D12FF9623B665980B98E83991215E188462A57C4B3F653E11B4B1E16522CD421105A1FE67AD0F58F3D4AD34A8BDDEC13454EFD5FAC6146012476391769D4AAD22B1A0BD1CE9599600EEDD95DD265C4640CB064F92C22B0C45C64FC411375852E596F268EB415B03DA88ABF9A089EDCC5F06ABBD96E1BA461D4DFB3772938CCBE093AF922F5CE290295EBA2289660868ED4B6AE38B28B1ABAA06B66BB97A5396218691B13D099ACB89D6754517372564CAB054763190677139C9E2F0BA2FB19D0471E49BF6A0DFF2F951A414ED5D0F17C729891F4EF658F19FEB6D31F0BD8EC15DC9F9CC1FD73BBD7A6CA326AB06F55078D4F2F90CF185849567E8C78F2773938A916FDA23279FC3A9D62CE3C3AAD309264EA076635487EDE98CE79ED297D1BA99D96C84EB712CCE028298C8BAF5B5CB3EFB2EB8996EFFF6F7682D6EAFE498B886FFDC157AE3995D8493BC6B51541BE6862B41B5A35AC420D4D120957AC00B6E488AFA394C5C3F99DEDB4BC4AD4127082E44F22194654D3FEF9CFF3AFA66A764864D8344939255F4BD77942D6B2063FA9C0F82DD3B8D9ABF5C633B6CACB152AC09B9DF3BD12770444F99843FD913E2C815368910DECDB46DC4E13EF2E89AC3FC7D13749B88197F633BB6044E1EA0FF4CE060C7F426D01D0CE94833304CDEE3C857FC7258DB654F49E7C949C4D4B2DDD689DEA7E0C526E694B5EF77F8DBCC199F73D833C54C6C389C9C63A9E203FDF4389D83A4DF4AD86D7B36D3847C8DA829E04E31BD81791E403D6098AE9DA476D75B357A74FBE2F0C42FADDA27AC72B653FD87A8D1D72E72E2BAF5D852D1FD6DE10D5A6A600C795F65A4A59A00E2C503DA0BAD2344CD62FFFAF6761831AB2CA4055C18294DB1CCAF2BC6A13DB522CA1BFBA9DFCB930E4D6C32EC24DB5A8D5C15398CF2202878D240BEE11756559F26355C059A81765FD0D993FA64887D5CB6EDE1B379B2B8B5D5430F3D7A6ECB8259220DA7C9106CACBA69CF6444192275A2C6EDC588234E8D24985A0770607FE1C4AE8CC7559B3687522EBF7D3CEF0E19B229509D2A247E8650C3676B3B272340EB71C69064FD3CE931406569E7AC1603E49A13BEA93B2892704378ACB4796CEA77687C98E8AAEC3501143271E504408CA5D7ED271C45A1A7637CFABEA8EDFCB11DFF3F8324C8C2C7D9C73A26B8B1C05B6F18013E03928FFFBBB5068FCF4B29FBC21A5819EF85B91B19A5098883EF40D91B7E287749A578E7743680786FCA565BC4D19AAC06BF70C283E7649992BD6BC0305A0A093B75DCFAECD7E049E16F274AA9B017CAF3F5068FECB55C6FA6ED97F64E17CF1CDDDAEDB45036C6B2227A0AD5181AD7389B72C8967B8176E18CAA3506BECFCDFFF15B598C47D10E11E65D9AE8AF9AFC8B189562D98BBB02EE55D0A5C41EEFFD3D6E8EE69878B3A003DE7A52A98978892E51219387C24BAA7A773944F530816FB27BCDCA933370CB340781A70DB5724C597F72F7A34DC05B732FEB79A18171281AB7A94DFCDFC2C96DD00784F2E67D7E56D0F146F1585EAA1448BE1CCAFC6F334CAB07A27E524BEB95E19D426689B900176A70B21E32278F27EA3BAEE623F92B14696CFB1EABA0D90EDC414FAAB03AC0572B4B8836F071A375849BCF46E83A05979A4111167CE5C43F6FF48F386E3E8F92FCA1655E3ADF4C2123DA2C5551E252E9BFD93276B5B2BDADBC8F23C0406875614ABDE72C520002AFE6F55BF1D19ADB7F26D4F71842FC66335FF670C60583CE65DF747AA6DB218471551478BF36140DCC5C6B9AECD22944CD2B781A240C914D2BC4B37877709794CA33ABA878615050637B0A0B3F04DE2FCF37A2442A242E6C97398CF483260BE8A092F998EEA5FB5519EB25BB10B9350AC7F6948CE13DC282ADFD3A251C07E32A25A8A93276A563755B3164C0A9510260425ACDC093CBDBC6C8C5D0FEC94A6DDB415C80D45BF9A6D8DCDA606E3204EEF6AA291AAC9AF7122810A77E0E1160A461AED63687B3C137EC40897B972493F33636B2CFF07747A394747C0887C0402CC4F50E78F70785E5DA4C6084BFD7AE379F0AADBA0CBADF8C70C34FA7A6B0C14F32D52FE8AC726F750DDDA95C741131C7F692CAF7A3A80173479690A3CC0A93D1823BA1AFD5634A9D14E17E7858221497CE6934D7630E73D615127209FA239A190EB60B4D49770A1122DE7ED76708CB660EC4E52900D130C9A4638448CBFB16B1943D7C007D521F945D00D42CD0AE51FA89D5BBB9DC68360C2551D3A0E08CB0025B061057FEA0855305C0F6496903EC94DDF067E722AE07D06AD5AC67A1B5A9D1D036F4D157220087AB098F2C6A911F710332AC3AF782A6747B8E079F12A768B9372BAA222EF43084F65A46EFBDC5D8BE794084FEDD23BB2BE82A7FD1C5FCCCA0E10FFF7CD47FE805A43F82E73773670C4F43571767DB9F9A59A16B1C6DFF3AEB739FDFDCEE27D8699BC080B9D5973F30BD546DAC6DE594F91E5C2F0DF432099D949C5FD0E9ED66BA4FD37F77CBBA8D511A0D712DD62859D6E3C0177A264EDC37393FA86D8BB241B13A2023CECC4A8A57242DA1C7BB796DB4B50197F8E7DE6FD645C6B9099D6F76701B0A36CF2DBC1C9E2F56AC8CB222D37682E19D33A1728916687BE117E14BC7D137CE28948A0997FD9B25545316DC91AF2780D34EB5D9A262B327FE0E57AF30D9299C1CDD7FF92E3CF8C70A9CBA640A71425B164DE8D2D0D78A19853125F684FB1E94D7D02473BF12C6537595311354BAB832C69593F4195132C6552176CD781A04D4293BB9E329B78AE8929A249AAC01C5C81DC46DF707C914E08A642BF4B0277302BBFE3950EAB036CEABBDDED57D2AB2DAC00B61474150F0F641A571573A79C7CEFE5B1E08C2A0D7C144D69764BBAAA9DA45E8C1CE02AD4BDA14E86E6F4509823913D553117C25BA7727244D0A5F4106962D2441C4D3813A780757E169AB7DA6FAE572D7CB919DF7BA028ADD524236473F8CEC4509FA954310D970F13B8F57505F248413F93CCEB0D2A8B81A3B6B812422E630863D5F37142EC8B03444B7509B92C2C46E8B7DB79679EE93FFC1DF1B807E29773C0B9A280334CD97CFFA2AEAACDA2A662F8767A323DA9D48CBCD419ACB2EF27A01A26F7F2968B572B679155717F7AE7CF17987EEBF9B088B153D06F88F683CD8A53B1D69CA429BC5D17DFF465377F6895611C319A8C8BC23438BED492817703D83BDBB93CD491EA8C39122ACD809BA158D5951E0B78FA5409E63E7CC69B5B6BC9BC56349CAFB05B71BD8C8ACC90F929F58037617118351CC1E0E0B3CC4040BCAB505CA4AA36C06277B4D550922DC424A005854FEA6EBE6C833980D3F7D49F38F595E3B156B89809B65E62B57E0C79947B2EC463027DE21FECA9FBEE0CD5B8EC64BB776FC95D93232C53A5A5D8F5954AD65E6BA6A3677C62497C3F4DD408AB08F2B05E00F865CAC6983159D2E4EB54EC0B89384F890E6033F71C5C888A9EF25C2E5563F4B79CF7F80E221C59FCC0CBA7A56ACA182D6A22A77AFBDD2209D5BBE8400605B918912E1F8268EEA13534E86FE8B6588ACF64A1322DFBA8990E280AD5A2E185DC29AE3AB7AEDEBDFF8932A21ECB57071D2C6207740AB48DA0286EBABE44AB1566D845A6B231073076634B6493FF5F4669CE06BB0BEB477C3BF2F9173ED7A36C22EB347036E7358BB62192E4E7BF5B9515C6A433D21E47F56C886AF92422741D1CA07EEB3A67A027283E78A27B64C89AC0EDF6D3CA5AAB03AB2437B7813BC5E349434386F00F0C0D592256BB28E68D0ADD1F23F001F2F0DC867BE42CFB316FCC3AB7F2ADE8F262E2F2A817435D72D2B9F181E285F7D58C2E9D0ADCA7E67933CEE6F908BBF182523A0367EC978CAC6373140022E3B851EBAE9D7086C4191C0BB856FBA1C5785F57A555985D0060A4BD79FC0FBD7798CE46C543B3D26C62BF07B7FFC0C5CB00729D2F9DC75A8A308AD312EFDB71DCF069034FB4F970969B749BD6F487F5E77627FFA00F64DBCF819A4F8EC0681AC3816282EC1717DA96444B3EC00B32B8C07E806988EEE0B8CEAF0CEED4F400F27F1D79267AA4BA333E61B84E6F10222FDEAF05D3561F5796CD819C879A07E780BAE63E780C05F024F2880EBCAEA6C1C8258D94B753BEED298829CF221BEEFF249643A4915D5C0E8AEAD2C85ED170790074EEC22327260470E99DD940227A671D56A9204224861E56624244241513ED4AC7117ABD09523C29C4F23E0C41900011215540597EC1BF8516CD28C228D03F8C7A65E4FFE575C6F5FB1F833B04F3DD1FE2DA3F983FC8A6BEE8CD7FDCFBB4436D8E8F09D466CA0129B4080F5C4D2A078B1CA2BAB5B306B26B4F75F49335E128D5E27B6FE1D96B9B863268E813A092C5176087562125530D23E8F6D61D99ABF133B032021530A5FBD7CAA65063B17304B76498D90B0F3E6541534667952F6B31A74394000AA731CD42D2CAB1EF3AD7AADBAEC7541D04E60B843FD337D7D08B9991452889376EB57FFC5D2D454B35DE0BE42E0B04E5C21D950E809C5D499AC04DE0E4FF912237DD83AF0FFC5CB8E520493400C91235F9D49BB30724098295713F70ACB57194F53B656D4B3E5879E2E28734370A052FE51C8139021ADD0DFC6D3D8491AE9C7C8E3AEF6A5C1E119D65923212BFDC35792BB5E3109BC36003C17100DF5302C7FE73ADA012B36AFA5452CFE356C38E63C59E80C1F3FAA1735150F1F3CE87E7008281D125FE7627B3D6C8DB3A2101DD6D650656EE5B8E0E8F0CA1DBEE12303499B6CECE8AC80111C504804F9ABF9C616D22DF34FBDAF27 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 18469 +sm = 0000000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA701095690ED3CAA8519B752CDFBACE3666EDC260EE5325F9EA849CF9DFE6CDAD655B850B4D00B825B12E384E4CE8F666B543D8C8BECD261A578DDE551E6CF90A36003E412EE569DA19D006D0826FB3293AC847724330EA49515D4E5B4DC3E46EF7486B0A4897AB5ED84C95BF9D9D78816FE9E92F843558029A08EF7015764C3D1AF1852C50D360F65F887479E9631A2CA30FE3AD92E7BF648643835F4F8CC081A6C9C439720087F16209AD7D3DAD7FBDFDFED8B6E91E5FD0D118B85F3616E510B8229CA2443C7CB3E2CB8A4496225E251B20EF7BF07A1A37D00A59DBFCC0BCFF40DF1E71AE21A2F47E739C7AED529E7EED5825FDA6446E40F6C889E249C813F2656995B25FB9169A3460E4AC08509F6C41627AFB5261A8E5ED535C7D0FB4869E1FBB9F9B5545373C3A86DDFDB1D863609DA537E44270132411E8A373729B4D37C277197E5E72AEDA323C10FB7CB3E7F169199EB86F5018CBAAC09E9B322FF53B461C6197F55B8A2C849396C4B19633627442973CA4FE54442355306C2207D6A632117E6AA6D434BAB8FD8B67091BE465C3BFB21CA9D16D794635422DEF832911110F5B20D28D1B9384DF1D710AC39FAF699989418B7856C2034C695A693ECC336EB44751F234CE3EB9DA99AFEA939C270AB221C09C99C1538BBA65D88E13DEE3D82EDDB9994161F2F83D2829B47A2886BFC4FAC9CCBF78EBBA2A40C9F2F0946579887C7CD9EC770C111D9681D6F1B97D908CBBD436444853FEB47F234D31F5E92B9EF436C0E8C75BF71D78A7F90EF443748CAB197234EA10CF3209320CCF8ABA1BA0E3A789C1A3A7E2EF2DD79D3C48A562D4599D4C204E3A393724FC11749CD28AF44E34D56CFBFE507E95A9E3D86591149D0E5DB6DD9A9A83A811D103580A40F3EAAC60C3D0D40B8744BD2A8C97E20821F46750D130024AAE8D968515F6314D8F25B7E267BC7716B6F64367028A87D330880BF8CB7FC94AD8DF4CCCD6D6C5C24AB9E7725CD11443807BC4EECBC46D46EC3D79A9C0C755A65AB867B1BA4B07FC1C2F62FDFAC5E8EE98639254EB106410A8BEE8214C66A7BB81C99C989737A7EC3EDB49D00B96789B4DC9018224DD7B1CCF3FC893A10C06EEAA776CF0013263513CF0F51EAD30CDFD170155A675ABB01E2C06C2E04365A619CC6294601207BA2CCCC24D08B9D0A5A3F6009F660E9B15456060AC696B025F2A874623DBF0B61F73C56A921D5E8459ACCA633C5B50F7C6A36062BE168AF6246317A8B052CD7F15A96EDCFA580D8FB229B0797A6B4C45DCA773108A4A0893546B4F42192E0B146B33581687B7E0BCDD9121C2855C87CCC9078FFD868D7F0BCAB9C6072DC52A6153A0DC127C0D7AE9E6AC7062BF0E32260C11266C4AEB1815B9D80CC2C7F5898A39D5C1CD10002B3D710DC236EC8D68027C56FA74F71482643230330B6FDF0306DA1A39805F56FAA5EB1B2038CF5FDC70F204F0F1D4982B7DBE1BFAEBFA628CA56052B581C1DDCC1B058B92BEAD301E8F3B8F5EF71EEE7966302B44D2E26D2A02393713E50E97A5E1309649D4E93719A883E1C7EAB902CDDA5AFE46434431417A67D20C0555F9CA097AA6C3B65C5CD659AAE22F412427C2918AD8C309342C8369BB454C503398C519742B581D604C13E10DFEDBCAD3EB1F66133D21F83B2C15BA70E2084E0E96D865CC4D6A606FBF4DE92C66BBFB686C56D23150B560DF6C4A899A3CAAD123DCEE5A1D81F1E20ABD1DEA550546C1D13ACB5AAEA1E6F2304541F641343DDEE6E0A066BC266687463E93C5A235862776216A7294A9B18BEAFDFF95A17AB7CB4E7FAB3B1D2265743AA9CEDE4423AA9D5E65EE25DA90FBAE188B81FEB612D3597B7615487DE8858DB8A45448140CF4A9D2152E12279DC7A6AE1DE1239BF9B1AC54D212926B7F2F17985DB1943D5ED8EC711A88DC5AF85CE6CC47237014255691B2B5807FEB4B1F2FA5FD7108614F0111A2006FC13859790AC63FB3A98442D30D2F1EAAC7944E4E7E754B78F741D7B3858E4BF33C370C36B8A7560D6445B6D2F6186530FE32C466597E512DC0924A135CAE452048EED75B482355223F2A9DAF3FCF987E323EB63EB61FB83F76123FD8CBE6155DD251E20F090991CD6489A6F433B8C51B0C6412F36BA064FEA5ED935CD8FC498C92D651E2C9BB0A294D35E87BE85E44D90F65A4EC5BA93065A2A731CD107EBEFA54AADA64C3014C9A6A2506607547D9A150ABAFCBBB6BD37E68B51E1E3B76A88186784096804E0CA23134BDB1616C6C6171F79A60A5759406D13E1DE37665471E194598FBC67D2713E4C767B295AEDA2B90972324B3ACE8C7B79A67723AEA037E12DA9EFA9CA9668A4F5FDADFB9E4278B48367B4C50FD7C42161E491BC40C35FE359EEE17A1333375545BAD7576FEB7542B22B51702D73D0253907F7AC6D32AFD378410070FBAB10D31A4B2BC818AE5DE2ED5D631B575F59F445A94E79190E6640E42F2A3DCAAC94A1C6E3D522BA874184C8A8D15DDA84BB247C2A2E48B5FC81BB64A1CE95161CE2661F6CF8ED45BB7916AC42B1861F5CB527FDBCD82DBFA31C5ACF981D8414203837504263C96BA3C6B4565D4163160F135D27A95E1105E4327276D2BC3688C76EAEA804631DF081B3C44B0F10FB7300874B5011FF0F97C52F975A31355884C2F12B6FFEE20E8371D38183C9D04977BFA037C9BD4DD7F7CE203FD7FAD3852B3C2AE9D078ADEC7886E0D5DCB57ADD979B87904537D98A9179696CAEFD7FE3EF62AD44C8FCBE817976035CED8547228BBDEF5341D9C876901B08FAD036AC277A918FD8D8CFF38F7E9447636C3FD64C2AAB9F44C2FC2E4B27A6D4D7CDCB4295F43E2B4B04C931AB8987079555572152AB8ABF9DE2FC4ECC91A00B7E36D11F49EC02620148D3147EB8D2AE42D887D10EDBCABE6AAF951E0A070D881879332064C99F8527A5EFF25241E773D96CAB3EC602D83261F07793CCE2DBF7A28EF9B5792412414567DBA9372712689DF5DE30ED5313C773311EC605B8E44C297ED4AAC95D3B1DAA8631F7786C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC9D550F851D023315BE35A69C83D099341F6BA69B6A40E224DC554A3489D33729C9EC8196BD665514030C26AAEF80CD6E1BB9EC739BAA2B8E4A63EE691AD2BFBABDDEE2B13CFFEEAB7C25273CAD45409B5270678CB1535AB800679906CE77189DCFE05BBF92FB5E31F184CECF3C427437958F695917E343ACF46DA2B9D988CFE316313FA9FAAD49EDB72B007A7F3D6FC55A88E6BA784FEBE9737803AF05B4801CE0C723C0D15CD8E7CA8E237D4A1C0BB1413D369FC3F21F69205D428069EABE626B971A2B5698ED05BAE54218300BE8C4BC9A52EE5FB296BAF2A9AA42F3C865DCC1DDA69969F085C91D3CC5934567476EB70461B942059AC0F83BA10DFE783F5FB405F159563419B3F5699179D6F33AD05E840EC9227C592E361A49E31D99445437D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB3844833CA9CC7907865878A01BCAE7DB72BA4F7701F20523E0E98B27AF08AA747B57DB1DAAA1B616DE469C7FC83CAA1DA1D6BA6F0C2B0F7F2CB7A4F58FBF7FFEC292AAA7FC3B87E797DCA067ED7672BA9B4CBC27FE9AAEEA63C8569A567129990E1E12A8D23039A877F7FA3EA9B9359A842A19E33CDBF284AF95FAE2A2DDEB80030A8245A7E51131D27EAE94B6C38A8C4818CA7EAE0A1C0841E7AACDDF68A4C4491EF97D5F3F6AD8CC47D2489DF1FF96B7DD444D31DD2FFFDC69C9ED7F750526B3CD81EDEEE2CBBFC0BCEBE875DBB644B3828795D2B81DFE37E0E4E68F9A798E09588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE596674368D1D405B742EE812FB88947D9F5DE52083777E54C2F0A1F605027BCA5A12BDBF9CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318ECCE515F732608A96D4E557ACCA60F144A212276CD52FAC0F12C39F7F45565346B6EE409558FF37D5C50280099C9D75B688C7D873EA7D07EC6C9305AB367ABC2FEAFF9200CAD14D71DE9E1F1DFFC4F15FD0908C6687F585D9721AA773BDECA4C7DBDA2D8275C59A2E90EE07ED6734A09566174D695356166041C646F18180DFC5ACCBA61F1672213C3CA6933A5ED65898AEB4BAF534751900D2CF25A7A94C273533B8694EEFB366F4B3E6D4DBE7FF5FC70EF5341217906FCEC863502598936A4A0D7DD4267B1C0C6E8175CFB3B9B6BA86CF3094D4677BD57712235CA8395A6914063B4E2849AFA406B7EC6E3AE39B343EE39348D2D29A0C2319BB34655A53E1A816CD5FBAD3A3796FEF2C7B67BE4507438E5AEB603B1A0796293A274A3F3D63C7C1F14297987085EC271F06E8DC986CE41DDA37ADBB39613E6790644A669594AF10B5D7C2DCDA7190B03F77E69D79A143E9B7D8B42E18E56D1D191DE05D58DC29F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA4C86ADE353F4AA57DE2220D13EAC9BC8FE02D625EBE3BF2761493F180F968DE438B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE8D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB07425116F11D430A927D45FBAC134C59EA8E5907C35A59E0CF2FA548F9AA27A3530AEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBE6FFF1A2A91E8DD23131A7840BF7CDEA3E18E706A324AB688A5866B82EC18082D89DB83F78DB30D5CE6EF134BBCE7628AC017E6D6974B1D82E4227235AEC9862899B7A4E0E8B10A8AD0B19A54DE7ECA861D6AFA1D91C9CAC7B8D6AE536C458E176AE68697912D7EC853D514AD4EDE982FA89400CE895D3241E5610D0AFB17AEFE51FBB41E2DE044A00D84BE759242476BC0099DFE159F0CAF2187BB311DF2342A59C003778A56907F086C8DC9309D8E41703779C8E1141070708E02B9F987ACF3214A8E442B76121374DD243643D64283D01279A49154760E3567E46ACE89898BCD67842223D5B8CAB03DC13930BE7210FAB7FB2318BDCD92B642F6BF178BC30B4F959F5D8BE15F67C5AC4A4C81F1E3E707AADF0B4CD02982ED4E4E52A81EA2FCB60ACB5817849D53C2FFFBF7906E290BF76E505071913AE0361FDFCA4B279897C9DECF546FB0366D65C9F81A9B51402F3694F0B5DC600B7E4F084383B643AABC755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E6C007F614D3C0A2E45486C2E457C2E6636BC1AFB76B2A7FA351FD88399098C64E379F99B64A3340473DD46C11564937DB9A28C4DE3745308433153B2BC6D5E0D515C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFF0116375D404211C3D3302D17DDD0390712E06CA05FB4BB2AF749D3439A5B30D3E9FF4731822AE6607BD96108BD229A4BDA5ACF50F7185BD1C0F56CC56D69C008077082C0869F237A6F19D73ADCF9844686E3C5583E7D8FFDA636E70E989B1742ACA4DCE98101BBAEDA8E852555033A46F8DF4E3DCA1B9A09E9F938E0C1E468C52F7DC695389C21D0F425B4DB554FD5BE1FDC2765B997FAB1F94D864DE1B4C8FB1323A8D90DC0CD7FA7363AB70728FDBF33C2325FF97C59ADC84C104E730C85CFBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272D144DEFA2E32DCBE8CF7843CBDB9A67EAD7892ABCE9B25A6B91AF0B893846ADDDB6C26354D4D8B77B14FC2FA2D8D589237C4BAF80344C306439619E5A4DDD4630B558BC9B3581AB842BC8B630F232BD18D4BB10FFA1DD3805B18635F6A9A22CE0D470FAA2AB813662EF63C784628138499A1A3648CC877300401E61DA9A379FDB3FC6DD985CA26EE8093A24879BEF107C4D6A38017BE3AA5CCE124259C42519C6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156771072191C21BC3190193111CD3BD0604EC5427C6D70B1BF21DB6E59ED636342BC417CD9F69B804EDB6359C9F8E347AD253370E065D500CAC64BFABE3E420E39000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D00C27D20CB93DA243BB3270F1EF2DE68AFB80842E8BE7C1FD48BF0F5622530CE84C1D30BC69EE1164CC602F2522FA39158D4D0D30ABE4FDE43213ABD6E4D65E62FBEC9AA1D485599FB7ADF5C2C97B90C82A1DCCD2C44ED66CCE79EFCEDCAD0CA1366FA51DD03DAC9BFC60B79719033B32247DDA9195233329F5AA36627FCEC5E42F078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DF657C03A3914FD3BF1E82EF96AD7EA46373B0A4DD0F5655F22F754DCD35ADA89358DDAF6AFF78EEEF21010DBC6556C2C3A018E4DA1D612CC3EF237BC2B1E9E600D923E2CE04FA27CE8EE63B969F6079FF8551B8C06018E99D84669C059AE08081E3A1C7ABC19272D7FA3F2704CCF6E491AF93C7CBD4660410389D86BBA47BD5A0E996F788FB9CE600AD76485D265628019B57FC69631D5266E8E46913ED9142FEFAD87E26DE53ECDF43B352EAC14BF6DA899058228C9414E7323430F9357D6244E7165F5CA2FF2DC9899AA6D8C2B8DDE8E2C5FB7C6E02BF74F578823CFA2355F2FCA1F776C6A87943344A5E53BFA39559EF98C397423C75EB318EA9B5F375C17E7B46A8D592651E7D50E70233224592389C1EBD1EB66678AC42C2862A2C660BACD03BA4064EA38D34A7D44B32DB9E75ABC6B5025B504DEC60512A80F78876C54D36324C7143FEA85ECB9E66800E8F4004061EA7607EAB964DE3F9A273D2C7A4CECC1B4270ECFF87A254A139DEA1E0F0B0F6366C02A0A790D46EAC94866A82DD8349F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DEA67846512E96901F78E601EE427F8B1A7986FB8832D091D575C277CB202E87602D670CE131CC6023A9E83AF41486A04D62616C1E912D4EAECD5DC815BAC1C0DBDB347F6B5DF06B0F58441FAB98B9511AC0423ACFA43E0422A62AE32A48E935C6288BD0D2314C6A739A7779BFE24DD7E2D66E9C4A4111E22481688EA39F256224531ED241A9D35D395F340421F2D8F5C05B873052D2128CEDF4ABE49E609176674363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D02AB14858954A117C6B6F2CDF4823BEEF1904FFB4D841B30537D57C577968CDF18EC8631C536AF09B54D5887FC0EB11A70E86B72EF315FD722FB680EF03A3487434215A0EEA412C0D78DB2EFE20061576237453927710860F0A49DE0ED0C42FDE2A5903D635B19D4F2001EE353D7B5210E1C01F50251ED6E753635A972EC8C1914E36522B1B41BA51E9F3F1CE83BB5F526FBEC31C21983736E42EB7880B9B27EF6CAE0618E57F881193714D3E8B38C9E9056378DD79E78422BD7C4CD57D230EF44B38F6A107ABC77B8D5A953D3A3969FBB7DAB145C4F4615FAF8F2172AA2BDEB35C4A0494100CB9CE188DA4318EA5B617EBACE910A32F0A280C82AF82121720569232D71AD065E45268B36F92DDA13673529F24E6B83A865F3E266635D9655C8000C06478530294DE092640DFB324E09DB3B87497C94502BD46092D72DAEDFA93A0353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB51691B3F0ACA92B02FE916D2AEB98BD9E23313F49A0F44394883A432523EB5B34B690EF9C16B4D60572EF2D791F2BF403255A28D9BC3352B02687AD9200D34C05259FE0C93B75455218E031D59A65D4F571CD7F8B130A0CA1363BAF2D9895A8E8925ED20ADBE8FE96C34A6A13B9318AC8A23A7EA320B83B7175FB54868DAFA9E233B0F4B18CF6FC7D85F7A2B28CEEC561222C5051572B092F2FB269ABF1CC7826675F09949FC443EF723AB476E9E5D670C5F05E46DAE93837AA0F65A4E83AE2C71DD02CAB1038086531F93E163AD65BD962ACB9497C0F268876B5AD3CBBFC4C24EB2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADB0A78B6C1C4ACB8B4C97EA8C4CC3F3778CBF761AA653D9531216588A46701366E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC4050CBFA6FEF6B9FE785A59511CCCE21EC5AE3F429A07B4626A4F0C555A15B42C26A5F353E7A479A700595689D5734C39D61177AAB2943775ADAC879B4ED7B8ED826CB43881D2C1B5734F64A5490A4F77ED4DCB9775B258C18182B42C560E6CEE89A329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB041A19053D3003420EC262BF0F45F1C7CF6E55BA9001E4BE097329CA460D335BA899503CAE0D617BB7FFF0AD37076C91B1659BD448C05C49D9360462B4BC601536844FF2C635BB654EC5749FBCEF3288E41B8A7835B645E0BB501FF805EA4B39785C203BE03F0B105D17E513D50B7738E78EC18AFAB3FE134FD551E754CAA189DC4FA2308B6EED1B8CE87EBCE212E15E72C9516B778C1F62819131E2EFA7AF63BCF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0A2979199F43F2F59FB2C62E8AF2EABAFE9B89B71E75AF029BEC77A6A56F86EF6A4A7212A7458986D2DAC9E00CF68EDB81CA05A297B522D3CB2E0AC3146E4638995B683EC201C67C911C83E6BA3567D31565DF914783F41077E2C31B06640446A6D403F9D46BB9D00B3C436FE1FFDA80AD0AC466AF0417D18D5E7DFEDD7D68987BA55F545F3B89A38908BCCA1DACE0B89FFB49FBA3A67EE7384DEE68FD05721483030ED53913A6CFA059DDB451C780877E919BB86DDCA9E18814123CCC822A8F30D0AB4602815D2279398ADEDE00B23AF4EE605A771AC616CAFFCD3AB12991023A6BE6BCEAFB1672ADA631C6CC29827088627EF9380FFF46FC479E2B586432B58F95A824C0D5F08704C2B596A7BD0A36A52BFD8C14D999F92E676C83EA62DE54C3ED7ABF290BF17C48DD69F949668E11D957299DB6920D740252A9AFB65179FDD62B69D2A1A339CEF805FD258D83FD2F406841565AEF5E42ED7687D9D466E6A4E513E072A9EF6181016DAD988F7C2305A77740F196465CE30A35BF3D098781DBA2F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549617285753A9438517AA7159A9C806A19CE8B8BA5F9C99250358404671F36214E8A7B5A04767FF8C094A3CD74751835BD896FAEFD1747DDFBBE79F48148D56BF585CB0CBBF34300CBFAB9DB32469814F107EF7822151D158CAD68F01418F88B181B092970DACAE4D5DEA7AE39965D1929CBAB7685E758206D309CADC07687274657F6EEF56A657D3FED4D34C7FF6C9CC5F344F0EF4F0E752F83E06B8A23DA0D65A2C10C2D675CB3A214F5D363C35E6E10A1323579803E4268F7D868F4716BF849B3C3D8EDA94476BE7322891C36D6DF146075F11AD02434D2216351CC26600662BE0D38E1DFEF9A832B9F066718FCB2134115F33717B57936CCD2DFA3A95C1D4C4C98BD09D64EC04912C06C7C6A2FFDCA2801628D873EE6D0D43EB67FF0AC93A7666C9ACBB9400593C00316E05F0F5706ABD923D85DE72A0D1CA9F0774F5180B65AA578B95BD20C1FCC322A5B23995ACC9DC97CE3043B1A723AA2815314637B7667DE02ED0FA0924C0791CA09FA028633CCC594429D6E7429930C7F01EB6A134952E89B8CCEC743A23C63CDD9E161B5A2D1F1E0D005F16727A3B0E8B90C20656B850A4F8B5D400B65E91E45AA25A880B76BE09F226DDD4F0E0AEA00259E19634EBAD387CCAB556997A153D1C1B87AA62E5B613A5E02C65E7EE7DDE2E19D965D27B42AF8542066549A6FEFF3E10A93B349EACB843759F5E4EECA76CF82277BD55C57FAD09BE938ABB47720E49CED626AC860446B290C7FE9BC83DB0C7FDCBD5CA2B8FF6C52B2CF2556040B3792BA99DD43EDF1FD4CBE38970D235E8BEE40DDCD2708E432008992D3F9DCD73AD594171092909019E9BBE7A5D4A21EADF82C5C22D877F422EBC64734717C93A027E9EA7EDADFFBB8A04B465E2F1BDDA54BA30963A41978562C27EE91E8ADD7A95B97A1F9F5C0494C3E44AC5422759F971200B1927F5C37B003499B213C1CEF1823847ED4A308D7D98FD5E42115D49B1FD42C7405B55437E1C8C0226884DD801CD89163AEE8D74105F621EF2CE222B13ABBD14078943CE054E3D68F7E8D763948CA83876F0AB7CA5123ABA8C5F68679FCD116D03391F2A53F637D26EC486FF6363F0C297E1A672EB717107ED9540C2AAD46038F8D4C2B5D1D918AF6BFBA7DE46E6628B2C217672257EB98F585A4E4CDD87729BA5ED16719F869FA1495302E8BD043F92ECF8799DAB7B9C501DC956EE3E55FF30E6D565E228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023E10A68B5275694C30FA7BE9BE2392EE6B18651980A01348A97C4BF091DE3501B30B528092599313ADC93C8407FB07E740F784E80461A23A1DCCD78BE8A72EE2AD69CC6E63F385963275DF49AF300E5D468285CA4457F090504D42056F571A8D453903B85D7E63F893431A5A1C8A66A8E4C999F0592D75717940E296C8275952C4A8DC6E97B3D5602408DF3644E8A1338C856296C37B1BA8445883CAFB408EFB9A545AB53CD632C40659DC607F4937A4F364F7E3B47A907BD30D8558C76A8EA9EB357177B8B2639477433604EB74F9C2E3528215459533C1A989FEF107944FC8A402E29495F72F2C210135FD836028B9E21E76C6F13096DBD2BE9721DD2C35504D648C474907FFB896B014CB022942F308C3263CFF227D4444763A483658E728EE6B7954C48E3FCAB1246CED1B1E2EA9CC4D5475BD4FA43FFEF56AB2A2D779E9D206E3E657A2244108BCF55C7F4F97666457CF5F796105ABC773C541173B9E338B4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F9338191406A4C257E6B7C058565272FB78A54A46007F5550234FE9B7952A82581C08AA6A1EA68E497D663F82C5D20E9D1134816EEA319EEAC8E431A0D82B6D62F7B93D121D8382F0EB3DDBB9FCD43901C8AF1AA019A7160B76B72D4E8CA1228E5E9DFD49E24F3154F4A914987FD0264ADA4C8D6FF9EBB91C59C03CBD484E9EE72F1A98C3F97B9F2479FFB79DFAFBC33C8ED249286369F003C471C8B64A9B1546B1F31BFDD0ACA06AAB3EFB61E49CDF5506AF8A4693A7591498D9D7F8B28A72A10EC60F806A9955D7EB41D2654EE5B37C284F41CFF3F591C227E3FD0CD524379DCB384ACF486CE7B1E658CC743293DCF546BE85382FC40CFDFDFA407A9EA33AC46468E060524BF06C9CC109A726CEAF0811D0F857C08A3D4AEA67CCC0B17B2C38C53DA9F860C99E3AA769EE27CB7C9229207ACAEFE6C62D3ECFCA201DDFAAEEE1EC7BFD40086AA922961198B53C94BCFA97EEC1DC0FB8FF1D9448B6770DE4F5703CAE179FB51CEAF935F666F398B74BDE9FC87B01AFB6EE8B47490453198F9B38AA2259D2194E9EBC42E1C57994921413D6327018B91538CCB0B90E965564171D133CCD9E7F65E851971FB71F2C47B4592C2A52A4101D2EE7A69DCAB3852A56C4DBC9295D2EEC5BAD1B8A13B7EDE84768C0AF5FF0B0253B44038C236412ADCEC91508A76BD8D16E6D6BD5CBB3179B34DB8902863056CC65A4DD40B6A1929F28DFAE1CEC64A74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7E8104E8D9DB129F0AEFF48177BE4EB60236851F6D0DF3EAF508CA7F97E4D5814F71ACBCF00471EF263D3B5CD58ADEEF11E3465C704D90101A5FCC1C8CAC25387B7D6B83C7CBEF04E05BBA1766C5C5D804642609AF84AF3FA7E4572393761664021A632DA048F2A10C2A349E2E1C260C1C3CA6184BEF6045F43D9C767E2328B9AF5E48EFE8298DF69599C49CFE153BF59010741DEE011FFFBFB4EFC5AA4B5DE409B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F83369497B16CBA6B3104624902242C468F89E89322D299123ECDD8ECC98FD5C53D99FDFBBADB056D1034CA39CBBFF29300769BFF634A38678FE7BF929676A43CD0FC3161391877F0623D9B59DF30E28F5B47C0445F83B36F0AA67F6A2DB8C0C3D3F45738A4DE393D8675E286F4530AC810D244C621963923BEB20810EE32909DC96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A35F79B7F944D0041C0130B7F59B0ADCCAD97670C92355CCC8F0FE34612A088BFAAB33542EBE8F3283AD67A79EECC3E7B7C5D4CCC29B6083AEDF7AABBFAC8281B7D7711DED8D4CA70C383C5042272379356BB80EC0A9BB8E4F1C73F2D2DE1676BF5AF43AF87AA2B2C4A6826DCDE46E599B2F31E9EA87A816EC5D8163952A7384603C8FEC20F58E1AAC52188E42774382077A35700EA5EA2FBD04135593A7E40ABA137FE400EB63BAC7F417252EF6AF6EA8FA9CB3BABE7718FAC4A756702AD64BF1F912E6ED44DC6D424CD15D3E45BC9F86ABF7CB2924D7B4E8AAF67D69401F5609B17D251140842D7A94FE5D911BF2FD37418208B716D2DC66320743B79E64CDAC6F2257AD34D112E22F977AE6034068C0E0F089FECA11DE03396BFBD365B1A788B2C550ACBED3643C1E4F13618F904B40031CA9E73F9B13293DC92102B33FBC16C9CDA02E511D49394D5DEFB95770E5CC750801623042B7113D385E8BE8FEDA1D7F9105D545B18AE98870B1326494F9BC31B33EC24CCA7CB8E53F9AF1A7E099B0D9A40CCF40B085C0D406B5F1DD7DCA794345FF98F272F7D9A11C30CC5448D2D311502B7F0F81437B52EB11CC5FF11C1FD62B9A34E2E102C5C59D14A3326702F6B6862383B5BA1041A59B2F4E009161857FEAAE3F0C4006926444BE77169E9963DF262BBACFC643F032414200B26840295326BA1983CF450DDABD0DEAF05B3AEE35CC029B1E67729517B6555FDC996782FE0CB275645E739BA0BC75A08869998C082BF6680E2DED0D643F06EED3947CB24E4D240CDAB6B07EB71762DB159BD8E8FEBFF190763906FAEE1D307115E7D6697AF3DB2192D37468806FD49ABAFFD157647B652B339A8912CAA3730EDB23593BE64CE9A50A1622D43538926E5B05D878029C5AE57DB40072EBB7889423A948257F9E8684E5B4F10C09A22AC506B5105246ADE89409D3AA78C4A88181FD562EB714E9402F8C4AB2129E73FD77BB64F3F6752E5AEEBC4DACC209D01A274E39A84857736671BD0604C153703CEC940CB0D79CC433D157EC5004ABA2F359B80DA9FC04267584B2897B594C494883185E613283B939DEBE0F324B3CB9F45A6FBF11AB1CF2704C5F83BE3B8CE1C38663757828909CA4AC49ACC134F533F5DAF470EC30D2E8FBC66C9B6C58CBD2ACBFBFA2842E78DEA2DCB820CCCBFB17454EFDB2B1D706B93B0254B3209CFFECDA9F52CFDC1CF312EAE3035C1A3D75D8764F693350C2301864EE1A3797F6574AE38F66B40F82904FFE6CBB34655B99959759EDB652F6A3BDC1D0F24E8EBE1761B43E876A6A7AA29E8B1158F1D150E25A742B5FBC7161234A85B35803FABBC0AEA40821E9990D48BA7EF7E1A50178ABB3CDBEE228B40C8B02C98C5E8B70CFF650E570988E64E6F4FB69DD11814016F8AFC30F853DCF0B793E150C3B796CDE2B1B43B3E346E257302026A4B5934CC6A417A99706CF783722DC2663F469896FF8EB4CC741D531F3C32B41F0BC6DCD4A32786747BE120B33718A94639FB4D754E0508B0315990F31555D6C1DE281244E229377BB4FDB9CBB38AE483A3569F735AC438C492DFE94149EB3F4A4F9779A1AEFE60FA343AC04323795C9D33DE8AF95219B8711B1168A107EF83062F033203511E5663EFA0C45ACF54432C9D4EFB5678332B5E164092612E42C61560D9EEC768594F4E0E6AF10AC7B3DCD22D229AFA8C022EB00AFA626C63E8E96B72DF979586867B42B8FEDE446A0F6807F1F1C775595FB5DEAA3BE2A45570235BF1169F163501B400DB5A48D7FF08851543CA92A0E8448F98BE619F41FACBF13EE45A1F97C20748CDC3B4068D993D944D5A165FB858FDF4FBF88632FB826103B1276C7791C64195106635996700A71E299889131E533F7F060C7F96E7C54F02D2A32835106FEBE6D40CD4D56B57ED26A7431731B04A78CB5A4884F0CACDF007DA6E1C4195B2B59A53F31C48EF9FC33CC7F6BD147032A1B6313C7EEC43B1E46164BEBFEF16FADDB1A176FBFBE34DDA7C88AC9C1EEFD4F33B7960D847872B8B433AD5D1293EA480E6FA097BB9AE29A7C0270A062EF9BADDD796FD8EBB1502606E9262357EFCBCC9B7343ACBD03CFAE6907BE46BCD32C4C4C4722C8D3A9EBC76EE4CDCE71B049D688C42104B94A1F7FE6F945BDD02E3DCE0C345C047AB31E7E8051ADDD3DBCBD33699AD660C1CE3E25D203C4EA56368B19C77D498E67CFE083ECD3D36BDCDF29A148224623E0D70D060EC964B329186162C1567F7E7B5B6921CAC8894E88BD8BD6FBA1E8EC4081D35931ECA2BE1E72E32D7C986956EE9CFB07CE0B5091605780D9770A00252C92C4DEDD4D8B942E14C90DFC5BD612D85CE24C5CEFDB3EA964FFF256B20A4DC2C0EFD50DA4BAB56BC846B09DE27F341EE42E63C0C23B6C61D15F2C9FFEE5663E3CC74F7400D0645219751B70C916C03C0C67159F71BC0B3BFA0956F026B91F8C2419D671D3E00D7F633DBD2DBE88126DEEFC7733C2C926D1D8B0C8BFB1077A700BBF3892F0C4F3E30DF78BCE0A340A8F98EBA5BD384684D1E0081C1237440B3A6F117178C0DE4F19D05D4241240924D9EAF9CA45E3D4231AC903C8EE5298A3445F01961D6D3786E36D24875E6DF3EB1D6C1BE5EEA0E060D3E0EED1DB2D4E795D35A0DABE4A745764F05A858291993541AE149CECC5147FEF0F3A96B42F38963B9B29466FD66AD46CADA8F10E2D53BFC3B823CFED410147B5FD315FAA62ED06429D6D3FE6E5778A64B5C9BB06A8CF5561EB7A8B15838AA226DDFCFD4C31805D53A6EB7D2DB861451027CF84218C39078756B2911021C3EAFC2E82ABF792C5012CFCA3AAFB0A277A9C9E1E515CBC4439D95B2A54510318F5D6EBF97C8DE2AE0D4FF669493AA354C25460D3C15B1A57AC53D7E6C07CA407AB1EEC4A366A637AD4081F0343433C555DE72B71ABCD8ED3C043532A61125CC3CA06CAA634E5F75B750BF262756A57E3FD235FA9EF00CDD9553D37968DD680EBD5935FBDFE43A82E9DD39F96FD483AAB7F2D0517F23727E8F4DACBF144E3C9C3413B4497ABA623AFE3257572D979FD7234C04292B8EC507187752446AD11D10DE925035D368AF83D202AF6979123C7F3B7FCB8D83812728A890B5C09B482529FFC0737FB59C35B552AD7C5820E27332D2E44F2A31ED972E2E5C834FCC652204BB401557D6FEC656BD9F63B9226056E2D025988ED1312A2A767D418F1342BE489B463AA4BE823D471648D9893364758DACBAA63BED8B3D8D4DE1E4A76442D207EFD647078CA9CDF7800804012D4EC23BA14C99666610A22DA87523E4E5E41A6698E5235743A9B9E1C4795F38AE20CBE5C3A2111ABA307C3BA6E03F092E96AC6EF297548A3F144ECF7F643EF19024B2E98B51173450ED06ED68EFFA06EFD60721E73C9C6993F14C00E3E4BE441791C648110F699AB5089D7CD092AAD82AE007C0C3C8659506D5F2817E75EAE8B803734822A2526861036E35C3689EDCBA348A7A2E4BE2F1E291F63473988AFFE650C1BC49CDEA3875DF4E6B541727B5AA6F04C9C1E4D06BC5CC744D1B955958E2578C6176AFD7E3262CCBC0F6FA21596BDC36349BF9329BCBA08FFF934E31DC1FEDB7D7F6B459BB1A0165043B902D600C447792A618B77C1671E5793473DED54FB3322180F198873E306E1F8BD17BE04FCD3CF4D6A9201B9B804BBC772B742097663C42F0FEE3766B3B205F14A39D6ABA56963D03DCDF538ECFB8A7AE64DA3C116BFC09506BACF5E8B5754B220F7CF70C5AA4492AB72D20CF8F4966A114833B057662EC63B9570D9B2DCEAC86590569934F91A61A03E18835E31ADBC2EED3BE0BC148FF004675C9555C901B280BFB56FF8A1C079E1F290C67FD1B7E53A6C27A5C649ECA9EEF836621F9E708EB84B6F5C529ED2F07BF0A6160154F41F323DFF8A498177FD09D22DB15A273F787529852D898A6DF0FDBEBEFBA3F3B602B1E67352224860125216AD6D68CA891606E179FB415DE4B95484CA6907319438F69337316203F06AB1488A471924545C81A470D78E2EA29AAF89E94920AC4B0E7F2FE01092BC8CF3839480A02C0E8DAC1E864C9BFF5CBF46C0FC7B6A01FF0DBBCF96E3585496C392C6496D06C44765878B26B6DFF2C2FEC20F26A9A2706838A2048E579C65F3BDDEFC58C89D8830FB8C75FAF96788998DD200D48189C3B59B41501BD310420DB96F7CC5B61A2EAF88B498ACD890F7DF623A35479472694CDDA58C000D9BC04FD903E4AB88A2E757700FF3F460F075F9876DB3F76F17003E01DC96A92543DCDFCD7EFC86A5C0DF387A50ABB69953D6DC19A699CD225941F82438A8EB7889B212F65ECA7399F89CA0D9B9915E827D2E520B6D481C27D4CD833EE7D985B20FA5BF7A21E4DFCAD092628EC0A6E2DC876E4C5BF248F94C2ADB3D6C9F23C3E70D1F611A2041C7759317B8EC1696B2632CA10CEFA498D7571D016E102DAC10051DAD086BEC58AD5DDFD7988C5F433DE87C314E3930FFF937A6E0C81787F04B77F893287AB63125CAB8B7460F119D03BF3076A98FF029EA5022201DD54C854711B8BE718EE678544B51AB13B7ED0262C8180C2F36CBAB64D862D38AD7D8172AD8BA3380706D52048826CAC611B07468967CA4A4DB52628A2FD56DD3A323382E5DB171811EA861E2D46537D0A4E545C65F238380083A064421DC7CE13EC2F715580924D9B6EFBDBB0D45AD8952F602BDED6455C0BC2734CB135B79966464546A261D0A551DEB43E5AE111CD02D0F2F2E996454DE17B471C6103D851CCE2E1FEDBB828C7F4EE66053A57831C708C377FDC6FDF037F400A09E9A610350BE6C013239D7F1C42758CA84B428EB06C6A6A3E05F10FED769CEE2D8EDC3EEA29204605005468B0366B2E957A7A55FBCC7842598F55021E58DBEEF44C5313226E6E56A2D3837F2A098C94BEC791737F355E6CE5643C954C4719C6C1C939B7716A29191CF0530BC2E78CD028D526EC286FCF02B18A077C86BC54F078A19A529F6EAF69D5562D4B31E4CE3B953A24655429BDBAEB5378C13E5B404A138B2B5473A415EA236245B0541B6D92F384D4CE63680ED5A6C035FFFC663C893C8F51C5DEC6F90D33573A05CBAED63B69079EE77DBDD21AD7A778B37EA5E0543BBDCD47497F355B1B2D8AD93DF4BB96A5E85A2344192B782D54C4C8DF251BD5F72EC415621FCE91148DB266EE1BDA0885827E96E8A9AD9C50F43D947DFA8260661FC9326B9E76214D36B22172C026EC12E04ADE3C62D4E957AAAAE686D350793BC6E9C862D968C0E56B3160B5C70520E9AC7767AD2BD8D1D6DC951A23BE9FAF9DBFF407E7766C84CCC3F281C6383079DC3188FBE8F9675D0A26831EC44071AC6184AACBFA0A2326D7EF097650C1D4D1E58134408C11E839A0DBA17CAC9DE3B437E697663AC136380D0690DA4A52070A2DC552275BA09C01B601D55E97AD7DE83A32B962D0A9053C1533600FEFD1171C638A50922B9962C195551F81FE80BE28342A13ED0B25FF8986E0E9C39F3C2F29B9F40AADF8CF61E879A7FC863B32F02C5B5BE16F0E2CF00F30E312820E84D09BDF073E0B16B1F32C73F0E6031DCB3221DDC48670D0F2DF9A8065BD027C30DCF9F12782C812753F109615828997768C75660D469691278A111D50A72CEE9600124E3850507C0B963E9121C8B28262B6C82510AC69F4785752AE1F619E3D334170A4ADB4DAF3138AE90AAF8D82573E7AD25A16243E16650219C47F4CEBE6915B433B0ED0354EE62FABFD3E118AC777A63316637DA755A99AF97DFE9857B2F58A83ED70041EDBC49997EC93C03A7D55524CCFFF8018EE1A587AAB9FB5D3E33FE7BAF2642CF9421540C134F9BDE458A65E6B9BB209359F7FA47B95EBB79C83F329ECF88C7541446868CEF363218841F55D346A2B714DD48C711555BB25B1CCEFA6199A0E7646646B667634E486116C0AAD7E977C091A5EA356778C299EFFB7DBD3232C4B73B54C796BD1E33284CC8E4354C772DF1CCF762F615715FAA903D1551A67965FED6C7E1ED7BABB9325AC30F92305FC284724C59079B11D1A0E32F4665AD8390B34968D1885C9EB8BC5DDF63D7858E042CF7C66FF5E36365F1C7156C79CCDF596EFA551E203456E5BB22C2D9B742F490824B1D5EE482F335393E34E69C7820A639858C6EFFC2E8377876E461788FD2736A2D1BAAA432B008850BBB44FA193DC54757D8C75760638A12DFB614580A882EBD945716D7A3D3D29396D4A0D267B07B035EC001CF29C87E23D8446E21D604BCAB110869FFA98C32E35A9B6C878360FD7BF8D564B09384D5C52ED4FF586D6CC300F09F878FF5FDD7E7BFD0AC3AA2AEC0C223DE23D190C6F67AFF7C00001F7DE39C907235BF8D5EC16A34AD2D2E6DDC419F5B24EACE1A17BEF5CC52AAA05F04D5AA8BB018210354282E98DABB918100165E7D962A6F396F22753B1FB928AE3576A91CE62216E9E6214ABFF91FCA2E6E77611AD13F70CC87E67A1E6D886120CD2C2404E0312A57635D1C2524C97EC0BDD9DE011D158F8FCA7AD1A20C9BE0F45E814C954FBA214F3D3089AC4D01ACBCDB25B9331558FE1D29E67628E13BFC928F7A9A88D13E0759B77674C3F2795CDFE0C6617022F9C6A87B60C4B5A69E8D1706749FB0B4E086C94B5BFC16CC3B34FF3B7EC227A5CC646E9A003E5D897871067191AD1F8A8C33A0E567F4DF2D91D00FEA00B152183D202BD72DC0694F16ADFDD6E44A248D80FC6609E601CB91EE691C4535CD80BECFF9F23F32BAB5F106234A8867CAC0B5269CA2BC588E48AF922B5917BB6813E9D1005F35CCBFDFD419404B59A84497BCAD743384461F24267C497A932411B690BF405A7ADCA63858F439B123201F41AAAAA4D0A478101EDC6AD214E025B5DB6D24021464C53FB376503B6CAF4E4D4974E072F8C88A7C61957239581B589ED8D1753844ED928642CF96E5ACCA32E69B52CFA3AF54B9FF793E7553CBE16C4F9DD6114D1357E539C238AAA4434C5E540AB31FA584B82AFBF419DC51D6B08FEBE34B7991EBF2A82FF8E94990BFD02764F7D1DC049A635A08B7BFDB46A521170B6B8BD940883CD4505224D9DF930E33C5827E303083CAC4F846D9CB9A6E3FF57E755C7CCA541DF51819C5A52BDFDF005217000967A2776F51217813B2FFC509EE35F8AED6481BBFF5D5E61732BA17C90FBBCE1FC29E8DE849C146642845F982A2F766DFC0A703B5BB612E4C2B8CC426BB56196D714FC6F1BCAA0F19F32CBC06C3DD1406B591D2B0CD0E834D003CE56313B66C224594354866598118C87C1A86F7D247593846100395EE6303E54D130F91FDF81D0DFD021C274AA9567B9F9A500F35507519BCC25535407E419B52FA4D9ECD3D53F467B6295505DE979CBF6C7BC909812265ED65B30269FA1500264347FBCF1CB34AC5A405F208E73DD503D0D0E15FA474802F273C76C3D3DF98070BF3151D5D338DB368DA0D2280BD821880265763EAB2076766540EB9A51EAE647B96CA4326C82626DBCFCA1B3FF6DBA63DD64AEEA6741FA49E358E97D8F60C7F1A56248E8CE18933CD6F850E667134F69176DFBE2A4FC259994ADE12676F63D483FE16F7658F1003C1561B8D46FEA0888D2C82A4254AEB9E4104B9FBC973CF836BCAB5E263240ED9D87E9C434DC66E8F4A7B73EAEB30BB745F4094A4B82EC96CF99219F557ADEFA605DDE957CAD9D5343558A9A0904575A7A954948DC927E71786394DF40E9328C9B4382CF4FD8423B97088BB07CB4B257E5AC7B817088C3A6912441992153D374D477EA4EFD21C9F706D3619634AF7DB364F5FE73D12FF9623B665980B98E83991215E188462A57C4B3F653E11B4B1E16522CD421105A1FE67AD0F58F3D4AD34A8BDDEC13454EFD5FAC6146012476391769D4AAD22B1A0BD1CE9599600EEDD95DD265C4640CB064F92C22B0C45C64FC411375852E596F268EB415B03DA88ABF9A089EDCC5F06ABBD96E1BA461D4DFB3772938CCBE093AF922F5CE290295EBA2289660868ED4B6AE38B28B1ABAA06B66BB97A5396218691B13D099ACB89D6754517372564CAB054763190677139C9E2F0BA2FB19D0471E49BF6A0DFF2F951A414ED5D0F17C729891F4EF658F19FEB6D31F0BD8EC15DC9F9CC1FD73BBD7A6CA326AB06F55078D4F2F90CF185849567E8C78F2773938A916FDA23279FC3A9D62CE3C3AAD309264EA076635487EDE98CE79ED297D1BA99D96C84EB712CCE028298C8BAF5B5CB3EFB2EB8996EFFF6F7682D6EAFE498B886FFDC157AE3995D8493BC6B51541BE6862B41B5A35AC420D4D120957AC00B6E488AFA394C5C3F99DEDB4BC4AD4127082E44F22194654D3FEF9CFF3AFA66A764864D8344939255F4BD77942D6B2063FA9C0F82DD3B8D9ABF5C633B6CACB152AC09B9DF3BD12770444F99843FD913E2C815368910DECDB46DC4E13EF2E89AC3FC7D13749B88197F633BB6044E1EA0FF4CE060C7F426D01D0CE94833304CDEE3C857FC7258DB654F49E7C949C4D4B2DDD689DEA7E0C526E694B5EF77F8DBCC199F73D833C54C6C389C9C63A9E203FDF4389D83A4DF4AD86D7B36D3847C8DA829E04E31BD81791E403D6098AE9DA476D75B357A74FBE2F0C42FADDA27AC72B653FD87A8D1D72E72E2BAF5D852D1FD6DE10D5A6A600C795F65A4A59A00E2C503DA0BAD2344CD62FFFAF6761831AB2CA4055C18294DB1CCAF2BC6A13DB522CA1BFBA9DFCB930E4D6C32EC24DB5A8D5C15398CF2202878D240BEE11756559F26355C059A81765FD0D993FA64887D5CB6EDE1B379B2B8B5D5430F3D7A6ECB8259220DA7C9106CACBA69CF6444192275A2C6EDC588234E8D24985A0770607FE1C4AE8CC7559B3687522EBF7D3CEF0E19B229509D2A247E8650C3676B3B272340EB71C69064FD3CE931406569E7AC1603E49A13BEA93B2892704378ACB4796CEA77687C98E8AAEC3501143271E504408CA5D7ED271C45A1A7637CFABEA8EDFCB11DFF3F8324C8C2C7D9C73A26B8B1C05B6F18013E03928FFFBBB5068FCF4B29FBC21A5819EF85B91B19A5098883EF40D91B7E287749A578E7743680786FCA565BC4D19AAC06BF70C283E7649992BD6BC0305A0A093B75DCFAECD7E049E16F274AA9B017CAF3F5068FECB55C6FA6ED97F64E17CF1CDDDAEDB45036C6B2227A0AD5181AD7389B72C8967B8176E18CAA3506BECFCDFFF15B598C47D10E11E65D9AE8AF9AFC8B189562D98BBB02EE55D0A5C41EEFFD3D6E8EE69878B3A003DE7A52A98978892E51219387C24BAA7A773944F530816FB27BCDCA933370CB340781A70DB5724C597F72F7A34DC05B732FEB79A18171281AB7A94DFCDFC2C96DD00784F2E67D7E56D0F146F1585EAA1448BE1CCAFC6F334CAB07A27E524BEB95E19D426689B900176A70B21E32278F27EA3BAEE623F92B14696CFB1EABA0D90EDC414FAAB03AC0572B4B8836F071A375849BCF46E83A05979A4111167CE5C43F6FF48F386E3E8F92FCA1655E3ADF4C2123DA2C5551E252E9BFD93276B5B2BDADBC8F23C0406875614ABDE72C520002AFE6F55BF1D19ADB7F26D4F71842FC66335FF670C60583CE65DFA6442DC6DD49889C3DA3AAF0FB310C3AD990480EF12059DD23AE881D5A72603F50C7C61626AB2E0BF9C8C198CB0F637EF72954E04DF5956355147B5073EEF3848CE65EBA73E67955A1CFF187CCA758372FB67823E230B05EAA9982488E8D22F6DA1415A731BD0A2B036F858FE16FB4349149B507D9DF770B9F3D3B45ED752EE888F40FEE65C4F3EC6897906303A19863DD968C666AC1980F26D8B574D5A16C95747AA6DB218471551478BF36140DCC5C6B9AECD22944CD2B781A240C914D2BC4B37877709794CA33ABA878615050637B0A0B3F04DE2FCF37A2442A242E6C97398CF483260BE8A092F998EEA5FB5519EB25BB10B9350AC7F6948CE13DC282ADFD3A251C07E32A25A8A93276A563755B3164C0A9510260425ACDC093CBDBC6C8C5D0FEC94A6DDB415C80D45BF9A6D8DCDA606E3204EEF6AA291AAC9AF7122810A77E0E1160A461AED63687B3C137EC40897B972493F33636B2CFF07747A394747C0887C0402CC4F50E78F70785E5DA4C6084BFD7AE379F0AADBA0CBADF8C70C34FA7A6B0C14F32D52FE8AC726F750DDDA95C741131C7F692CAF7A3A80173479690A3CC0A93D1823BA1AFD5634A9D14E17E7858221497CE6934D7630E73D615127209FA239A190EB60B4D49770A1122DE7ED76708CB660EC4E52900D130C9A4638448CBFB16B1943D7C007D521F945D00D42CD0AE51FA89D5BBB9DC68360C2551D3A0E08CB0025B061057FEA0855305C0F6496903EC94DDF067E722AE07D06AD5AC67A1B5A9D1D036F4D157220087AB098F2C6A911F710332AC3AF782A6747B8E079F12A768B9372BAA222EF43084F65A46EFBDC5D8BE794084FEDD23BB2BE82A7FD1C5FCCCA0E10FFF7CD47FE805A43F82E73773670C4F43571767DB9F9A59A16B1C6DFF3AEB739FDFDCEE27D8699BC080B9D5973F30BD546DAC6DE594F91E5C2F0DF432099D949C5FD0E9ED66BA4FD37F77CBBA8D511A0D712DD62859D6E3C0177A264EDC37393FA86D8BB241B13A2023CECC4A8A57242DA1C7BB796DB4B50197F8E7DE6FD645C6B9099D6F76701B0A36CF2DBC1C9E2F56AC8CB222D37682E19D33A1728916687BE117E14BC7D137CE28948A0997FD9B25545316DC91AF2780D34EB5D9A262B327FE0E57AF30D9299C1CDD7FF92E3CF8C70A9CBA640A71425B164DE8D2D0D78A19853125F684FB1E94D7D02473BF12C6537595311354BAB832C69593F4195132C6552176CD781A04D4293BB9E329B78AE8929A249AAC01C5C81DC46DF707C914E08A642BF4B0277302BBFE3950EAB036CEABBDDED57D2AB2DAC00B61474150F0F641A571573A79C7CEFE5B1E08C2A0D7C144D69764BBAAA9DA45E8C1CE02AD4BDA14E86E6F4509823913D553117C25BA7727244D0A5F4106962D2441C4D3813A780757E169AB7DA6FAE572D7CB919DF7BA028ADD524236473F8CEC4509FA954310D970F13B8F57505F248413F93CCEB0D2A8B81A3B6B812422E630863D5F37142EC8B03444B7509B92C2C46E8B7DB79679EE93FFC1DF1B807E29773C0B9A280334CD97CFFA2AEAACDA2A662F8767A323DA9D48CBCD419ACB2EF27A01A26F7F2968B572B679155717F7AE7CF17987EEBF9B088B153D06F88F683CD8A53B1D69CA429BC5D17DFF465377F6895611C319A8C8BC23438BED492817703D83BDBB93CD491EA8C39122ACD809BA158D5951E0B78FA5409E63E7CC69B5B6BC9BC56349CAFB05B71BD8C8ACC90F929F58037617118351CC1E0E0B3CC4040BCAB505CA4AA36C06277B4D550922DC424A005854FEA6EBE6C833980D3F7D49F38F595E3B156B89809B65E62B57E0C79947B2EC463027DE21FECA9FBEE0CD5B8EC64BB776FC95D93232C53A5A5D8F5954AD65E6BA6A3677C62497C3F4DD408AB08F2B05E00F865CAC6983159D2E4EB54EC0B89384F890E6033F71C5C888A9EF25C2E5563F4B79CF7F80E221C59FCC0CBA7A56ACA182D6A22A77AFBDD2209D5BBE8400605B918912E1F8268EEA13534E86FE8B6588ACF64A1322DFBA8990E280AD5A2E185DC29AE3AB7AEDEBDFF8932A21ECB57071D2C6207740AB48DA0286EBABE44AB1566D845A6B231073076634B6493FF5F4669CE06BB0BEB477C3BF2F9173ED7A36C22EB347036E7358BB62192E4E7BF5B9515C6A433D21E47F56C886AF92422741D1CA07EEB3A67A027283E78A27B64C89AC0EDF6D3CA5AAB03AB2437B7813BC5E349434386F00F0C0D592256BB28E68D0ADD1F23F001F2F0DC867BE42CFB316FCC3AB7F2ADE8F262E2F2A817435D72D2B9F181E285F7D58C2E9D0ADCA7E67933CEE6F908BBF182523A0367EC978CAC6373140022E3B851EBAE9D7086C4191C0BB856FBA1C5785F57A555985D0060A4BD79FC0FBD7798CE46C543B3D26C62BF07B7FFC0C5CB00729D2F9DC75A8A308AD312EFDB71DCF069034FB4F970969B749BD6F487F5E77627FFA00F64DBCF819A4F8EC0681AC3816282EC1717DA96444B3EC00B32B8C07E806988EEE0B8CEAF0CEED4F400F27F1D79267AA4BA333E61B84E6F10222FDEAF05D3561F5796CD819C879A07E780BAE63E780C05F024F2880EBCAEA6C1C8258D94B753BEED298829CF221BEEFF249643A4915D5C0E8AEAD2C85ED170790074EEC22327260470E99DD940227A671D56A9204224861E56624244241513ED4AC7117ABD09523C29C4F23E0C41900011215540597EC1BF8516CD28C228D03F8C7A65E4FFE575C6F5FB1F833B04F3DD1FE2DA3F983FC8A6BEE8CD7FDCFBB4436D8E8F09D466CA0129B4080F5C4D2A078B1CA2BAB5B306B26B4F75F49335E128D5E27B6FE1D96B9B863268E813A092C5176087562125530D23E8F6D61D99ABF133B032021530A5FBD7CAA65063B17304B76498D90B0F3E6541534667952F6B31A74394000AA731CD42D2CAB1EF3AD7AADBAEC7541D04E60B843FD337D7D08B9991452889376EB57FFC5D2D454B35DE0BE42E0B04E5C21D950E809C5D499AC04DE0E4FF912237DD83AF0FFC5CB8E520493400C91235F9D49BB30724098295713F70ACB57194F53B656D4B3E5879E2E28734370A052FE51C8139021ADD0DFC6D3D8491AE9C7C8E3AEF6A5C1E119D65923212BFDC35792BB5E3109BC36003C17100DF5302C7FE73ADA012B36AFA5452CFE356C38E63C59E80C1F3FAA1735150F1F3CE87E7008281D125FE7627B3D6C8DB3A2101DD6D650656EE5B8E0E8F0CA1DBEE12303499B6CECE8AC80111C504804F9ABF9C616D22DF34FBDAF27290F4FE6675D4A1FBE8A93A91C6B09B1456828554CD0CDA039569E2C08430C3481E2970BA760DA29C31944AF18085694530E8A952B54516062CD9528A95D0772323B4B8E02C7DCBD71FFD2236E772268E25F6D4C622F07F5D437275B2FEBECE7605967771BFA2007FECA33154FB46A3B788E9E7702F38BCDF175EFE4611B61147D89195BE90840FB1E365A76840BD9B40C21949F2D41205A491C019B7F49139C +remain = 1099511627774 +max = 1099511627775 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-12_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-12_256.rsp new file mode 100644 index 0000000000..b5b876c43b --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-12_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHA2_60/12_256 + +pk = 000000089C3469640CD3578A98E9F9471F596649E45D969754FFE37395B79731156A1E2204562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 000000080000000000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A9C3469640CD3578A98E9F9471F596649E45D969754FFE37395B79731156A1E2204562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E704000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF54961000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113CD47F2466A56323209409FD7FCF7485A71CD8CE96D61298A20473D9ACBF99C010000000000019AB3950B30D3E7877159B364A25B214B41B8AA32E293E2DDD44AEB7DFC560A82020000000000019C359D104347B69607EB28A02E6924C24BD2A26DE4CFFF3FF98E48688E291E58030000000000011EC9B78F3B1189A5482238BCF700922D642E45D07E7EA10833E31A4CBC3CA08F0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019C1A7BFD8300283215BA57DB5CDD95EDCBD04E1C41419317BC2069C2AAAE22130100000000000143ED646E32FC21554D8DAD350C5732270CC220F7E264ECB5B7A8E8A4586D0CD002000000000001762D040EECA13E137753604D099809D946063368BFE1C7CF0E6549FCA746F7C6030000000000015FB7406F1B25A2B4A6A1666269772EB08D6FE78D8A8395C56AD80FE6924DF082040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044E3C9C3413B4497ABA623AFE3257572D979FD7234C04292B8EC507187752446AD11D10DE925035D368AF83D202AF6979123C7F3B7FCB8D83812728A890B5C09B482529FFC0737FB59C35B552AD7C5820E27332D2E44F2A31ED972E2E5C834FCC652204BB401557D6FEC656BD9F63B9226056E2D025988ED1312A2A767D418F1342BE489B463AA4BE823D471648D9893364758DACBAA63BED8B3D8D4DE1E4A7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017F7DF0085A4DAADCB03AB4E8241B0E6DC05E727E817C3B6FA27F05AE1FA2DE1601000000000001BCF2F650C31EFD6F2F09775A3B4F87BBB33AD0D51537DAF37E0D1C1AE8BE8DC00200000000000174F4FE7914F390776AF328164E738CA8EB0751EF9E535BB1B0E80B05762E683C03000000000001241535B940156367A4ABD922871FB10B37235B67CA38CD8B2B02AA8064C5CAC60400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D4FF586D6CC300F09F878FF5FDD7E7BFD0AC3AA2AEC0C223DE23D190C6F67AFF7C00001F7DE39C907235BF8D5EC16A34AD2D2E6DDC419F5B24EACE1A17BEF5CC52AAA05F04D5AA8BB018210354282E98DABB918100165E7D962A6F396F22753B1FB928AE3576A91CE62216E9E6214ABFF91FCA2E6E77611AD13F70CC87E67A1E6D886120CD2C2404E0312A57635D1C2524C97EC0BDD9DE011D158F8FCA7AD1A2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000186A69EB284CFC56C72C2C83351D5CCDBEC831992175BC2D2D91B3F9378E0DE9E010000000000010A318F954C197DF2DF39A85C4B322E7EB1B16B0B4EB8C8A492F4F3B904C47E7602000000000001A9204F8E84112663772797AF87ED34C559ED4D6D37E634EFACE6A18C700CD53A03000000000001D2E20083FA11E157A2E5B72C9A986D3F47348E54C1935F48A86F7A9D78B2BE600400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6442DC6DD49889C3DA3AAF0FB310C3AD990480EF12059DD23AE881D5A72603F50C7C61626AB2E0BF9C8C198CB0F637EF72954E04DF5956355147B5073EEF3848CE65EBA73E67955A1CFF187CCA758372FB67823E230B05EAA9982488E8D22F6DA1415A731BD0A2B036F858FE16FB4349149B507D9DF770B9F3D3B45ED752EE888F40FEE65C4F3EC6897906303A19863DD968C666AC1980F26D8B574D5A16C95000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100132C90901F97161C5614019A534B035942B26ADCEF40AB97BE258B03C87585010000000000012BB35E6F2C4AE0A3430CE207629C011B30E4C6F5D6BDFF2AB750EA0C69BE95C1020000000000019CAFA71D2E43D02FBB0C55294A6CD0AF3AF0816F6E6D1F4022AEFD413DBE8C1E03000000000001943191FF197E71722D961AF04F9570BBEC438A6D22058F1018F6C61F3CED67E50400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000290F4FE6675D4A1FBE8A93A91C6B09B1456828554CD0CDA039569E2C08430C3481E2970BA760DA29C31944AF18085694530E8A952B54516062CD9528A95D0772323B4B8E02C7DCBD71FFD2236E772268E25F6D4C622F07F5D437275B2FEBECE7605967771BFA2007FECA33154FB46A3B788E9E7702F38BCDF175EFE4611B61147D89195BE90840FB1E365A76840BD9B40C21949F2D41205A491C019B7F49139C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012A13FF51186CBFE9467BCAB51417E5129671EFD5D0D686D09E2C5BB683FD45450100000000000184D0629348E528473585F873A1929F01BB41F19090B770D155E497E4AFF30A990200000000000163EB4A114558605E9DDBDA75D10B78F28322197D1DF7FB4214438DA12328F8F203000000000001B86361D142F7F14ADAF4EC3E307CA82B6106FBDE3777E656781187D3558E3E1F04000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008AAD20F59A5E2539D3EA32A9A717691D72C2FF90173D53FDF598E4BC0790180A6CD182CDC6CA0B5FE69AD663506A6A43EF780D1F2B7E05E904271A587E0619EAB04598E3574C7F271892C3F482D2817BF74FABF9B63E43E74348386C624CD0A73AFF1C917D1DBB8D08BF504299C0DE3E5736BC9E3FAC872BFEBC1E5DDF68D69EB0572AF7243E531157C9EA81ED640B87BC14A959FBCC7658CB5BDF6E87F4E6770000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E203D0691CEA545CC43DCFBE161452022A98B0EE265DD051C66D4D40CB142EC70100000000000198AD7048E8F4A1AC6FE162435B004552EAD82ED6463EC081779E26B35577C7A202000000000001BEB756F3DA637E592811BCF2D4051971434CDDBA76FAD2E9BA59F8BDD7AD523903000000000001F5264362A5684064AAD87ED555D342E88F3DD3AD0D4CD54CDABCB2A33B347A5C0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CB4A42F0E5A9ACBBA9A6E6568753C7B8E4AEAB9B1DCE5052A2971003750085CB05B68E6E9E126AD5BE084FECDF62C8AEDC63A920DA15D1A3B4C5CAD650A2DB43D93EDAD2E498B0ABA4071B75F8DDE617299C990E6979D860461342EF7D52E632ED2C78AE41EB9ED9ECBDB9CEC925EF47CF57E413BD7A4B9A71E6236CAA1AAFFF8A8066E50E19D3CEA70F910537B76B350CC194B2804C1458A428BDEF11FD82470000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C59C0BECDDC4FC283AEFB2854FC4736C46F380627C810301EA77C23239780A100100000000000157A6050CCF22BE4B46B275064B9A7EA36848C9FACF2ADFC708F950326444E35C0200000000000179C1F7FF0B18868E800C6EBCB4BD4C88CF17A157A22A079435B5D8AF520D290203000000000001DD30F4FDD599D12004F8B06EB85EBE61659BD7CE19E28309A1F5D103154FE4260400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DA74B87E0ADF3119B9A2AD38D7679D60DF92CB86566B14AA71186C40C338B3A396579902434ED860428BBEF6BBA18121004411641C50A92EC832174AD38A679F5A49946EF241A8FA1D26974F9E465B1DB8C6F88D84B62A1507CAD3AF350DBAC43276A87D94FA1C7A9E8488B5E3A2EB66605C69AE4C2D7A551163F85877A81D5B0F988F48A6B2D06C9CB879DA0068CC2B3DBC36C5BD714E30A5021AB48AA57F830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DF4DA42AF634CA5BD15D0E372A2AC3B003D11DD9BFAE0B70E6E492E9661278CE0100000000000123BA7FBE99564830BF93790201B8BD29A47D288046D9E19DD1011CB8CD8470E502000000000001427455E428922B66D2C1F37EEA0B540B002E8989FE01F762D0523B5E22BC74D403000000000001CE06EA2927B35D814BA88A8222E3070EDA3149DA0FBB30A0B7EB1206B74E4487040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020468B089D5CAB0CD8F29FD284ED47E7546D39B4D6124B431B7190FE5D5489DF4C39914BFC951CCE080444FDB4D4BFDDDEBF80A22412911D5CB7DF5CCF5434E2E9C7094FF22B5924EB967324E73090832FB75FAB896104DABED028C4D096234B96BEFDEC7E669F850CD731ED2782B60512E2F83B3E063719F2A0F984C9EAB52C8BB7672F4A7E75231855BE3B541BE8BDF4638136802A83225ECB0020B956B6900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E7143B6E483C8094DFD75A5579E15E27298991073099C5103C6F44E17604725001000000000001C261BA3B2D08ABFCAB9362CCD93DC25527163262B29AD7AA14725737393423E902000000000001E990075F7BD30339EBF3E3034821B5794A5D5031F2842DDCEBBEAB049F3B5F41030000000000019415C6FC5645D2BCB5D37DE763D8A3038A00E8A5547CE9A4719C5DE467C12CBE0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009D550F851D023315BE35A69C83D099341F6BA69B6A40E224DC554A3489D33729C9EC8196BD665514030C26AAEF80CD6E1BB9EC739BAA2B8E4A63EE691AD2BFBABDDEE2B13CFFEEAB7C25273CAD45409B5270678CB1535AB800679906CE77189DCFE05BBF92FB5E31F184CECF3C427437958F695917E343ACF46DA2B9D988CFE316313FA9FAAD49EDB72B007A7F3D6FC55A88E6BA784FEBE9737803AF05B4801CE0C723C0D15CD8E7CA8E237D4A1C0BB1413D369FC3F21F69205D428069EABE626B971A2B5698ED05BAE54218300BE8C4BC9A52EE5FB296BAF2A9AA42F3C865DCC1DDA69969F085C91D3CC5934567476EB70461B942059AC0F83BA10DFE783F5FB405F159563419B3F5699179D6F33AD05E840EC9227C592E361A49E31D99445437D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB3844833CA9CC7907865878A01BCAE7DB72BA4F7701F20523E0E98B27AF08AA747B57DB1DAAA1B616DE469C7FC83CAA1DA1D6BA6F0C2B0F7F2CB7A4F58FBF7FFEC292AAA7FC3B87E797DCA067ED7672BA9B4CBC27FE9AAEEA63C8569A567129990E1E12A8D23039A877F7FA3EA9B9359A842A19E33CDBF284AF95FAE2A2DDEB80030A8245A7E51131D27EAE94B6C38A8C4818CA7EAE0A1C0841E7AACDDF68A4C4491EF97D5F3F6AD8CC47D2489DF1FF96B7DD444D31DD2FFFDC69C9ED7F750526B3CD81EDEEE2CBBFC0BCEBE875DBB644B3828795D2B81DFE37E0E4E68F9A798E09588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE596674368D1D405B742EE812FB88947D9F5DE52083777E54C2F0A1F605027BCA5A12BDBF9CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318ECCE515F732608A96D4E557ACCA60F144A212276CD52FAC0F12C39F7F45565346B6EE409558FF37D5C50280099C9D75B688C7D873EA7D07EC6C9305AB367ABC2FEAFF9200CAD14D71DE9E1F1DFFC4F15FD0908C6687F585D9721AA773BDECA4C7DBDA2D8275C59A2E90EE07ED6734A09566174D695356166041C646F18180DFC5ACCBA61F1672213C3CA6933A5ED65898AEB4BAF534751900D2CF25A7A94C273533B8694EEFB366F4B3E6D4DBE7FF5FC70EF5341217906FCEC863502598936A4A0D7DD4267B1C0C6E8175CFB3B9B6BA86CF3094D4677BD57712235CA8395A6914063B4E2849AFA406B7EC6E3AE39B343EE39348D2D29A0C2319BB34655A53E1A816CD5FBAD3A3796FEF2C7B67BE4507438E5AEB603B1A0796293A274A3F3D63C7C1F14297987085EC271F06E8DC986CE41DDA37ADBB39613E6790644A669594AF10B5D7C2DCDA7190B03F77E69D79A143E9B7D8B42E18E56D1D191DE05D58DC29F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA4C86ADE353F4AA57DE2220D13EAC9BC8FE02D625EBE3BF2761493F180F968DE438B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE8D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB07425116F11D430A927D45FBAC134C59EA8E5907C35A59E0CF2FA548F9AA27A3530AEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBE6FFF1A2A91E8DD23131A7840BF7CDEA3E18E706A324AB688A5866B82EC18082D89DB83F78DB30D5CE6EF134BBCE7628AC017E6D6974B1D82E4227235AEC9862899B7A4E0E8B10A8AD0B19A54DE7ECA861D6AFA1D91C9CAC7B8D6AE536C458E176AE68697912D7EC853D514AD4EDE982FA89400CE895D3241E5610D0AFB17AEFE51FBB41E2DE044A00D84BE759242476BC0099DFE159F0CAF2187BB311DF2342A59C003778A56907F086C8DC9309D8E41703779C8E1141070708E02B9F987ACF3214A8E442B76121374DD243643D64283D01279A49154760E3567E46ACE89898BCD67842223D5B8CAB03DC13930BE7210FAB7FB2318BDCD92B642F6BF178BC30B4F959F5D8BE15F67C5AC4A4C81F1E3E707AADF0B4CD02982ED4E4E52A81EA2FCB60ACB5817849D53C2FFFBF7906E290BF76E505071913AE0361FDFCA4B279897C9DECF546FB0366D65C9F81A9B51402F3694F0B5DC600B7E4F084383B643AABC755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E6C007F614D3C0A2E45486C2E457C2E6636BC1AFB76B2A7FA351FD88399098C64E379F99B64A3340473DD46C11564937DB9A28C4DE3745308433153B2BC6D5E0D515C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFF0116375D404211C3D3302D17DDD0390712E06CA05FB4BB2AF749D3439A5B30D3E9FF4731822AE6607BD96108BD229A4BDA5ACF50F7185BD1C0F56CC56D69C008077082C0869F237A6F19D73ADCF9844686E3C5583E7D8FFDA636E70E989B1742ACA4DCE98101BBAEDA8E852555033A46F8DF4E3DCA1B9A09E9F938E0C1E468C52F7DC695389C21D0F425B4DB554FD5BE1FDC2765B997FAB1F94D864DE1B4C8FB1323A8D90DC0CD7FA7363AB70728FDBF33C2325FF97C59ADC84C104E730C85CFBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272D144DEFA2E32DCBE8CF7843CBDB9A67EAD7892ABCE9B25A6B91AF0B893846ADDDB6C26354D4D8B77B14FC2FA2D8D589237C4BAF80344C306439619E5A4DDD4630B558BC9B3581AB842BC8B630F232BD18D4BB10FFA1DD3805B18635F6A9A22CE0D470FAA2AB813662EF63C784628138499A1A3648CC877300401E61DA9A379FDB3FC6DD985CA26EE8093A24879BEF107C4D6A38017BE3AA5CCE124259C42519C6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156771072191C21BC3190193111CD3BD0604EC5427C6D70B1BF21DB6E59ED636342BC417CD9F69B804EDB6359C9F8E347AD253370E065D500CAC64BFABE3E420E39C27D20CB93DA243BB3270F1EF2DE68AFB80842E8BE7C1FD48BF0F5622530CE84C1D30BC69EE1164CC602F2522FA39158D4D0D30ABE4FDE43213ABD6E4D65E62FBEC9AA1D485599FB7ADF5C2C97B90C82A1DCCD2C44ED66CCE79EFCEDCAD0CA1366FA51DD03DAC9BFC60B79719033B32247DDA9195233329F5AA36627FCEC5E42F078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DF657C03A3914FD3BF1E82EF96AD7EA46373B0A4DD0F5655F22F754DCD35ADA89358DDAF6AFF78EEEF21010DBC6556C2C3A018E4DA1D612CC3EF237BC2B1E9E600D923E2CE04FA27CE8EE63B969F6079FF8551B8C06018E99D84669C059AE08081E3A1C7ABC19272D7FA3F2704CCF6E491AF93C7CBD4660410389D86BBA47BD5A0E996F788FB9CE600AD76485D265628019B57FC69631D5266E8E46913ED9142FEFAD87E26DE53ECDF43B352EAC14BF6DA899058228C9414E7323430F9357D6244E7165F5CA2FF2DC9899AA6D8C2B8DDE8E2C5FB7C6E02BF74F578823CFA2355F2FCA1F776C6A87943344A5E53BFA39559EF98C397423C75EB318EA9B5F375C17E7B46A8D592651E7D50E70233224592389C1EBD1EB66678AC42C2862A2C660BACD03BA4064EA38D34A7D44B32DB9E75ABC6B5025B504DEC60512A80F78876C54D36324C7143FEA85ECB9E66800E8F4004061EA7607EAB964DE3F9A273D2C7A4CECC1B4270ECFF87A254A139DEA1E0F0B0F6366C02A0A790D46EAC94866A82DD8349F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DEA67846512E96901F78E601EE427F8B1A7986FB8832D091D575C277CB202E87602D670CE131CC6023A9E83AF41486A04D62616C1E912D4EAECD5DC815BAC1C0DBDB347F6B5DF06B0F58441FAB98B9511AC0423ACFA43E0422A62AE32A48E935C6288BD0D2314C6A739A7779BFE24DD7E2D66E9C4A4111E22481688EA39F256224531ED241A9D35D395F340421F2D8F5C05B873052D2128CEDF4ABE49E609176674363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D02AB14858954A117C6B6F2CDF4823BEEF1904FFB4D841B30537D57C577968CDF18EC8631C536AF09B54D5887FC0EB11A70E86B72EF315FD722FB680EF03A3487434215A0EEA412C0D78DB2EFE20061576237453927710860F0A49DE0ED0C42FDE2A5903D635B19D4F2001EE353D7B5210E1C01F50251ED6E753635A972EC8C1914E36522B1B41BA51E9F3F1CE83BB5F526FBEC31C21983736E42EB7880B9B27EF6CAE0618E57F881193714D3E8B38C9E9056378DD79E78422BD7C4CD57D230EF44B38F6A107ABC77B8D5A953D3A3969FBB7DAB145C4F4615FAF8F2172AA2BDEB35C4A0494100CB9CE188DA4318EA5B617EBACE910A32F0A280C82AF82121720569232D71AD065E45268B36F92DDA13673529F24E6B83A865F3E266635D9655C8000C06478530294DE092640DFB324E09DB3B87497C94502BD46092D72DAEDFA93A0353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB51691B3F0ACA92B02FE916D2AEB98BD9E23313F49A0F44394883A432523EB5B34B690EF9C16B4D60572EF2D791F2BF403255A28D9BC3352B02687AD9200D34C05259FE0C93B75455218E031D59A65D4F571CD7F8B130A0CA1363BAF2D9895A8E8925ED20ADBE8FE96C34A6A13B9318AC8A23A7EA320B83B7175FB54868DAFA9E233B0F4B18CF6FC7D85F7A2B28CEEC561222C5051572B092F2FB269ABF1CC7826675F09949FC443EF723AB476E9E5D670C5F05E46DAE93837AA0F65A4E83AE2C71DD02CAB1038086531F93E163AD65BD962ACB9497C0F268876B5AD3CBBFC4C24EB2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADB0A78B6C1C4ACB8B4C97EA8C4CC3F3778CBF761AA653D9531216588A46701366E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC4050CBFA6FEF6B9FE785A59511CCCE21EC5AE3F429A07B4626A4F0C555A15B42C26A5F353E7A479A700595689D5734C39D61177AAB2943775ADAC879B4ED7B8ED826CB43881D2C1B5734F64A5490A4F77ED4DCB9775B258C18182B42C560E6CEE89A329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB041A19053D3003420EC262BF0F45F1C7CF6E55BA9001E4BE097329CA460D335BA899503CAE0D617BB7FFF0AD37076C91B1659BD448C05C49D9360462B4BC601536844FF2C635BB654EC5749FBCEF3288E41B8A7835B645E0BB501FF805EA4B39785C203BE03F0B105D17E513D50B7738E78EC18AFAB3FE134FD551E754CAA189DC4FA2308B6EED1B8CE87EBCE212E15E72C9516B778C1F62819131E2EFA7AF63BCF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0A2979199F43F2F59FB2C62E8AF2EABAFE9B89B71E75AF029BEC77A6A56F86EF6A4A7212A7458986D2DAC9E00CF68EDB81CA05A297B522D3CB2E0AC3146E4638995B683EC201C67C911C83E6BA3567D31565DF914783F41077E2C31B06640446A6D403F9D46BB9D00B3C436FE1FFDA80AD0AC466AF0417D18D5E7DFEDD7D68987BA55F545F3B89A38908BCCA1DACE0B89FFB49FBA3A67EE7384DEE68FD05721483030ED53913A6CFA059DDB451C780877E919BB86DDCA9E18814123CCC822A8F30D0AB4602815D2279398ADEDE00B23AF4EE605A771AC616CAFFCD3AB12991023A6BE6BCEAFB1672ADA631C6CC29827088627EF9380FFF46FC479E2B586432B58F95A824C0D5F08704C2B596A7BD0A36A52BFD8C14D999F92E676C83EA62DE54C3ED7ABF290BF17C48DD69F949668E11D957299DB6920D740252A9AFB65179FDD62B69D2A1A339CEF805FD258D83FD2F406841565AEF5E42ED7687D9D466E6A4E513E072A9EF6181016DAD988F7C2305A77740F196465CE30A35BF3D098781DBA7285753A9438517AA7159A9C806A19CE8B8BA5F9C99250358404671F36214E8A7B5A04767FF8C094A3CD74751835BD896FAEFD1747DDFBBE79F48148D56BF585CB0CBBF34300CBFAB9DB32469814F107EF7822151D158CAD68F01418F88B181B092970DACAE4D5DEA7AE39965D1929CBAB7685E758206D309CADC07687274657F6EEF56A657D3FED4D34C7FF6C9CC5F344F0EF4F0E752F83E06B8A23DA0D65A2C10C2D675CB3A214F5D363C35E6E10A1323579803E4268F7D868F4716BF849B3C3D8EDA94476BE7322891C36D6DF146075F11AD02434D2216351CC26600662BE0D38E1DFEF9A832B9F066718FCB2134115F33717B57936CCD2DFA3A95C1D4C4C98BD09D64EC04912C06C7C6A2FFDCA2801628D873EE6D0D43EB67FF0AC93A7666C9ACBB9400593C00316E05F0F5706ABD923D85DE72A0D1CA9F0774F5180B65AA578B95BD20C1FCC322A5B23995ACC9DC97CE3043B1A723AA2815314637B7667DE02ED0FA0924C0791CA09FA028633CCC594429D6E7429930C7F01EB6A134952E89B8CCEC743A23C63CDD9E161B5A2D1F1E0D005F16727A3B0E8B90C20656B850A4F8B5D400B65E91E45AA25A880B76BE09F226DDD4F0E0AEA00259E19634EBAD387CCAB556997A153D1C1B87AA62E5B613A5E02C65E7EE7DDE2E19D965D27B42AF8542066549A6FEFF3E10A93B349EACB843759F5E4EECA76CF82277BD55C57FAD09BE938ABB47720E49CED626AC860446B290C7FE9BC83DB0C7FDCBD5CA2B8FF6C52B2CF2556040B3792BA99DD43EDF1FD4CBE38970D235E8BEE40DDCD2708E432008992D3F9DCD73AD594171092909019E9BBE7A5D4A21EADF82C5C22D877F422EBC64734717C93A027E9EA7EDADFFBB8A04B465E2F1BDDA54BA30963A41978562C27EE91E8ADD7A95B97A1F9F5C0494C3E44AC5422759F971200B1927F5C37B003499B213C1CEF1823847ED4A308D7D98FD5E42115D49B1FD42C7405B55437E1C8C0226884DD801CD89163AEE8D74105F621EF2CE222B13ABBD14078943CE054E3D68F7E8D763948CA83876F0AB7CA5123ABA8C5F68679FCD116D03391F2A53F637D26EC486FF6363F0C297E1A672EB717107ED9540C2AAD46038F8D4C2B5D1D918AF6BFBA7DE46E6628B2C217672257EB98F585A4E4CDD87729BA5ED16719F869FA1495302E8BD043F92ECF8799DAB7B9C501DC956EE3E55FF30E6D565E228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023E10A68B5275694C30FA7BE9BE2392EE6B18651980A01348A97C4BF091DE3501B30B528092599313ADC93C8407FB07E740F784E80461A23A1DCCD78BE8A72EE2AD69CC6E63F385963275DF49AF300E5D468285CA4457F090504D42056F571A8D453903B85D7E63F893431A5A1C8A66A8E4C999F0592D75717940E296C8275952C4A8DC6E97B3D5602408DF3644E8A1338C856296C37B1BA8445883CAFB408EFB9A545AB53CD632C40659DC607F4937A4F364F7E3B47A907BD30D8558C76A8EA9EB357177B8B2639477433604EB74F9C2E3528215459533C1A989FEF107944FC8A402E29495F72F2C210135FD836028B9E21E76C6F13096DBD2BE9721DD2C35504D648C474907FFB896B014CB022942F308C3263CFF227D4444763A483658E728EE6B7954C48E3FCAB1246CED1B1E2EA9CC4D5475BD4FA43FFEF56AB2A2D779E9D206E3E657A2244108BCF55C7F4F97666457CF5F796105ABC773C541173B9E338B4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F9338191406A4C257E6B7C058565272FB78A54A46007F5550234FE9B7952A82581C08AA6A1EA68E497D663F82C5D20E9D1134816EEA319EEAC8E431A0D82B6D62F7B93D121D8382F0EB3DDBB9FCD43901C8AF1AA019A7160B76B72D4E8CA1228E5E9DFD49E24F3154F4A914987FD0264ADA4C8D6FF9EBB91C59C03CBD484E9EE72F1A98C3F97B9F2479FFB79DFAFBC33C8ED249286369F003C471C8B64A9B1546B1F31BFDD0ACA06AAB3EFB61E49CDF5506AF8A4693A7591498D9D7F8B28A72A10EC60F806A9955D7EB41D2654EE5B37C284F41CFF3F591C227E3FD0CD524379DCB384ACF486CE7B1E658CC743293DCF546BE85382FC40CFDFDFA407A9EA33AC46468E060524BF06C9CC109A726CEAF0811D0F857C08A3D4AEA67CCC0B17B2C38C53DA9F860C99E3AA769EE27CB7C9229207ACAEFE6C62D3ECFCA201DDFAAEEE1EC7BFD40086AA922961198B53C94BCFA97EEC1DC0FB8FF1D9448B6770DE4F5703CAE179FB51CEAF935F666F398B74BDE9FC87B01AFB6EE8B47490453198F9B38AA2259D2194E9EBC42E1C57994921413D6327018B91538CCB0B90E965564171D133CCD9E7F65E851971FB71F2C47B4592C2A52A4101D2EE7A69DCAB3852A56C4DBC9295D2EEC5BAD1B8A13B7EDE84768C0AF5FF0B0253B44038C236412ADCEC91508A76BD8D16E6D6BD5CBB3179B34DB8902863056CC65A4DD40B6A1929F28DFAE1CEC64A74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7E8104E8D9DB129F0AEFF48177BE4EB60236851F6D0DF3EAF508CA7F97E4D5814F71ACBCF00471EF263D3B5CD58ADEEF11E3465C704D90101A5FCC1C8CAC25387B7D6B83C7CBEF04E05BBA1766C5C5D804642609AF84AF3FA7E4572393761664021A632DA048F2A10C2A349E2E1C260C1C3CA6184BEF6045F43D9C767E2328B9AF5E48EFE8298DF69599C49CFE153BF59010741DEE011FFFBFB4EFC5AA4B5DE409B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F83369497B16CBA6B3104624902242C468F89E89322D299123ECDD8ECC98FD5C53D99FDFBBADB056D1034CA39CBBFF29300769BFF634A38678FE7BF929676A43CD0FC3161391877F0623D9B59DF30E28F5B47C0445F83B36F0AA67F6A2DB8C0C3D3F45738A4DE393D8675E286F4530AC810D244C621963923BEB20810EE32909D5F79B7F944D0041C0130B7F59B0ADCCAD97670C92355CCC8F0FE34612A088BFAAB33542EBE8F3283AD67A79EECC3E7B7C5D4CCC29B6083AEDF7AABBFAC8281B7D7711DED8D4CA70C383C5042272379356BB80EC0A9BB8E4F1C73F2D2DE1676BF5AF43AF87AA2B2C4A6826DCDE46E599B2F31E9EA87A816EC5D8163952A7384603C8FEC20F58E1AAC52188E42774382077A35700EA5EA2FBD04135593A7E40ABA137FE400EB63BAC7F417252EF6AF6EA8FA9CB3BABE7718FAC4A756702AD64BF1F912E6ED44DC6D424CD15D3E45BC9F86ABF7CB2924D7B4E8AAF67D69401F5609B17D251140842D7A94FE5D911BF2FD37418208B716D2DC66320743B79E64CDAC6F2257AD34D112E22F977AE6034068C0E0F089FECA11DE03396BFBD365B1A788B2C550ACBED3643C1E4F13618F904B40031CA9E73F9B13293DC92102B33FBC16C9CDA02E511D49394D5DEFB95770E5CC750801623042B7113D385E8BE8FEDA1D7F9105D545B18AE98870B1326494F9BC31B33EC24CCA7CB8E53F9AF1A7E099B0D9A40CCF40B085C0D406B5F1DD7DCA794345FF98F272F7D9A11C30CC5448D2D311502B7F0F81437B52EB11CC5FF11C1FD62B9A34E2E102C5C59D14A3326702F6B6862383B5BA1041A59B2F4E009161857FEAAE3F0C4006926444BE77169E9963DF262BBACFC643F032414200B26840295326BA1983CF450DDABD0DEAF05B3AEE35CC029B1E67729517B6555FDC996782FE0CB275645E739BA0BC75A08869998C082BF6680E2DED0D643F06EED3947CB24E4D240CDAB6B07EB71762DB159BD8E8FEBFF190763906FAEE1D307115E7D6697AF3DB2192D37468806FD49ABAFFD157647B652B339A8912CAA3730EDB23593BE64CE9A50A1622D43538926E5B05D878029C5AE57DB40072EBB7889423A948257F9E8684E5B4F10C09A22AC506B5105246ADE89409D3AA78C4A88181FD562EB714E9402F8C4AB2129E73FD77BB64F3F6752E5AEEBC4DACC209D01A274E39A84857736671BD0604C153703CEC940CB0D79CC433D157EC5004ABA2F359B80DA9FC04267584B2897B594C494883185E613283B939DEBE0F324B3CB9F45A6FBF11AB1CF2704C5F83BE3B8CE1C38663757828909CA4AC49ACC134F533F5DAF470EC30D2E8FBC66C9B6C58CBD2ACBFBFA2842E78DEA2DCB820CCCBFB17454EFDB2B1D706B93B0254B3209CFFECDA9F52CFDC1CF312EAE3035C1A3D75D8764F693350C2301864EE1A3797F6574AE38F66B40F82904FFE6CBB34655B99959759EDB652F6A3BDC1D0F24E8EBE1761B43E876A6A7AA29E8B1158F1D150E25A742B5FBC7161234A85B35803FABBC0AEA40821E9990D48BA7EF7E1A50178ABB3CDBEE228B40C8B02C98C5E8B70CFF650E570988E64E6F4FB69DD11814016F8AFC30F853DCF0B793E150C3B796CDE2B1B43B3E346E257302026A4B5934CC6A417A99706CF783722DC2663F469896FF8EB4CC741D531F3C32B41F0BC6DCD4A32786747BE120B33718A94639FB4D754E0508B0315990F31555D6C1DE281244E229377BB4FDB9CBB38AE483A3569F735AC438C492DFE94149EB3F4A4F9779A1AEFE60FA343AC04323795C9D33DE8AF95219B8711B1168A107EF83062F033203511E5663EFA0C45ACF54432C9D4EFB5678332B5E164092612E42C61560D9EEC768594F4E0E6AF10AC7B3DCD22D229AFA8C022EB00AFA626C63E8E96B72DF979586867B42B8FEDE446A0F6807F1F1C775595FB5DEAA3BE2A45570235BF1169F163501B400DB5A48D7FF08851543CA92A0E8448F98BE619F41FACBF13EE45A1F97C20748CDC3B4068D993D944D5A165FB858FDF4FBF88632FB826103B1276C7791C64195106635996700A71E299889131E533F7F060C7F96E7C54F02D2A32835106FEBE6D40CD4D56B57ED26A7431731B04A78CB5A4884F0CACDF007DA6E1C4195B2B59A53F31C48EF9FC33CC7F6BD147032A1B6313C7EEC43B1E46164BEBFEF16FADDB1A176FBFBE34DDA7C88AC9C1EEFD4F33B7960D847872B8B433AD5D1293EA480E6FA097BB9AE29A7C0270A062EF9BADDD796FD8EBB1502606E9262357EFCBCC9B7343ACBD03CFAE6907BE46BCD32C4C4C4722C8D3A9EBC76EE4CDCE71B049D688C42104B94A1F7FE6F945BDD02E3DCE0C345C047AB31E7E8051ADDD3DBCBD33699AD660C1CE3E25D203C4EA56368B19C77D498E67CFE083ECD3D36BDCDF29A148224623E0D70D060EC964B329186162C1567F7E7B5B6921CAC8894E88BD8BD6FBA1E8EC4081D35931ECA2BE1E72E32D7C986956EE9CFB07CE0B5091605780D9770A00252C92C4DEDD4D8B942E14C90DFC5BD612D85CE24C5CEFDB3EA964FFF256B20A4DC2C0EFD50DA4BAB56BC846B09DE27F341EE42E63C0C23B6C61D15F2C9FFEE5663E3CC74F7400D0645219751B70C916C03C0C67159F71BC0B3BFA0956F026B91F8C2419D671D3E00D7F633DBD2DBE88126DEEFC7733C2C926D1D8B0C8BFB1077A700BBF3892F0C4F3E30DF78BCE0A340A8F98EBA5BD384684D1E0081C1237440B3A6F117178C0DE4F19D05D4241240924D9EAF9CA45E3D4231AC903C8EE5298A3445F01961D6D3786E36D24875E6DF3EB1D6C1BE5EEA0E060D3E0EED1DB2D4E795D35A0DABE4A745764F05A858291993541AE149CECC5147FEF0F3A96B42F38963B9B29466FD66AD46CADA8F10E2D53BFC3B823CFED410147B5FD315FAA62ED06429D6D3FE6E5778A64B5C9BB06A8CF5561EB7A8B15838AA226DDFCFD4C31805D53A6EB7D2DB861451027CF84218C39078756B2911021C3EAFC2E82ABF792C5012CFCA3AAFB0A277A9C9E1E515CBC4439D95B2A54510318F5D6EBF97C8DE2AE0D4FF669493AA354C25460D3C15B1A57AC53D7E6C07CA407AB1EEC4A366A637AD4081F0343433C555DE72B71ABCD8ED3C043532A61125CC3CA06CAA634E5F75B750BF262756A57E3FD235FA9EF00CDD9553D37968DD680EBD5935FBDFE43A82E9DD39F96FD483AAB7F2D0517F23727E8F4DACBF1442D207EFD647078CA9CDF7800804012D4EC23BA14C99666610A22DA87523E4E5E41A6698E5235743A9B9E1C4795F38AE20CBE5C3A2111ABA307C3BA6E03F092E96AC6EF297548A3F144ECF7F643EF19024B2E98B51173450ED06ED68EFFA06EFD60721E73C9C6993F14C00E3E4BE441791C648110F699AB5089D7CD092AAD82AE007C0C3C8659506D5F2817E75EAE8B803734822A2526861036E35C3689EDCBA348A7A2E4BE2F1E291F63473988AFFE650C1BC49CDEA3875DF4E6B541727B5AA6F04C9C1E4D06BC5CC744D1B955958E2578C6176AFD7E3262CCBC0F6FA21596BDC36349BF9329BCBA08FFF934E31DC1FEDB7D7F6B459BB1A0165043B902D600C447792A618B77C1671E5793473DED54FB3322180F198873E306E1F8BD17BE04FCD3CF4D6A9201B9B804BBC772B742097663C42F0FEE3766B3B205F14A39D6ABA56963D03DCDF538ECFB8A7AE64DA3C116BFC09506BACF5E8B5754B220F7CF70C5AA4492AB72D20CF8F4966A114833B057662EC63B9570D9B2DCEAC86590569934F91A61A03E18835E31ADBC2EED3BE0BC148FF004675C9555C901B280BFB56FF8A1C079E1F290C67FD1B7E53A6C27A5C649ECA9EEF836621F9E708EB84B6F5C529ED2F07BF0A6160154F41F323DFF8A498177FD09D22DB15A273F787529852D898A6DF0FDBEBEFBA3F3B602B1E67352224860125216AD6D68CA891606E179FB415DE4B95484CA6907319438F69337316203F06AB1488A471924545C81A470D78E2EA29AAF89E94920AC4B0E7F2FE01092BC8CF3839480A02C0E8DAC1E864C9BFF5CBF46C0FC7B6A01FF0DBBCF96E3585496C392C6496D06C44765878B26B6DFF2C2FEC20F26A9A2706838A2048E579C65F3BDDEFC58C89D8830FB8C75FAF96788998DD200D48189C3B59B41501BD310420DB96F7CC5B61A2EAF88B498ACD890F7DF623A35479472694CDDA58C000D9BC04FD903E4AB88A2E757700FF3F460F075F9876DB3F76F17003E01DC96A92543DCDFCD7EFC86A5C0DF387A50ABB69953D6DC19A699CD225941F82438A8EB7889B212F65ECA7399F89CA0D9B9915E827D2E520B6D481C27D4CD833EE7D985B20FA5BF7A21E4DFCAD092628EC0A6E2DC876E4C5BF248F94C2ADB3D6C9F23C3E70D1F611A2041C7759317B8EC1696B2632CA10CEFA498D7571D016E102DAC10051DAD086BEC58AD5DDFD7988C5F433DE87C314E3930FFF937A6E0C81787F04B77F893287AB63125CAB8B7460F119D03BF3076A98FF029EA5022201DD54C854711B8BE718EE678544B51AB13B7ED0262C8180C2F36CBAB64D862D38AD7D8172AD8BA3380706D52048826CAC611B07468967CA4A4DB52628A2FD56DD3A323382E5DB171811EA861E2D46537D0A4E545C65F238380083A064421DC7CE13EC2F715580924D9B6EFBDBB0D45AD8952F602BDED6455C0BC2734CB135B79966464546A261D0A551DEB43E5AE111CD02D0F2F2E996454DE17B471C6103D851CCE2E1FEDBB828C7F4EE66053A57831C708C377FDC6FDF037F400A09E9A610350BE6C013239D7F1C42758CA84B428EB06C6A6A3E05F10FED769CEE2D8EDC3EEA29204605005468B0366B2E957A7A55FBCC7842598F55021E58DBEEF44C5313226E6E56A2D3837F2A098C94BEC791737F355E6CE5643C954C4719C6C1C939B7716A29191CF0530BC2E78CD028D526EC286FCF02B18A077C86BC54F078A19A529F6EAF69D5562D4B31E4CE3B953A24655429BDBAEB5378C13E5B404A138B2B5473A415EA236245B0541B6D92F384D4CE63680ED5A6C035FFFC663C893C8F51C5DEC6F90D33573A05CBAED63B69079EE77DBDD21AD7A778B37EA5E0543BBDCD47497F355B1B2D8AD93DF4BB96A5E85A2344192B782D54C4C8DF251BD5F72EC415621FCE91148DB266EE1BDA0885827E96E8A9AD9C50F43D947DFA8260661FC9326B9E76214D36B22172C026EC12E04ADE3C62D4E957AAAAE686D350793BC6E9C862D968C0E56B3160B5C70520E9AC7767AD2BD8D1D6DC951A23BE9FAF9DBFF407E7766C84CCC3F281C6383079DC3188FBE8F9675D0A26831EC44071AC6184AACBFA0A2326D7EF097650C1D4D1E58134408C11E839A0DBA17CAC9DE3B437E697663AC136380D0690DA4A52070A2DC552275BA09C01B601D55E97AD7DE83A32B962D0A9053C1533600FEFD1171C638A50922B9962C195551F81FE80BE28342A13ED0B25FF8986E0E9C39F3C2F29B9F40AADF8CF61E879A7FC863B32F02C5B5BE16F0E2CF00F30E312820E84D09BDF073E0B16B1F32C73F0E6031DCB3221DDC48670D0F2DF9A8065BD027C30DCF9F12782C812753F109615828997768C75660D469691278A111D50A72CEE9600124E3850507C0B963E9121C8B28262B6C82510AC69F4785752AE1F619E3D334170A4ADB4DAF3138AE90AAF8D82573E7AD25A16243E16650219C47F4CEBE6915B433B0ED0354EE62FABFD3E118AC777A63316637DA755A99AF97DFE9857B2F58A83ED70041EDBC49997EC93C03A7D55524CCFFF8018EE1A587AAB9FB5D3E33FE7BAF2642CF9421540C134F9BDE458A65E6B9BB209359F7FA47B95EBB79C83F329ECF88C7541446868CEF363218841F55D346A2B714DD48C711555BB25B1CCEFA6199A0E7646646B667634E486116C0AAD7E977C091A5EA356778C299EFFB7DBD3232C4B73B54C796BD1E33284CC8E4354C772DF1CCF762F615715FAA903D1551A67965FED6C7E1ED7BABB9325AC30F92305FC284724C59079B11D1A0E32F4665AD8390B34968D1885C9EB8BC5DDF63D7858E042CF7C66FF5E36365F1C7156C79CCDF596EFA551E203456E5BB22C2D9B742F490824B1D5EE482F335393E34E69C7820A639858C6EFFC2E8377876E461788FD2736A2D1BAAA432B008850BBB44FA193DC54757D8C75760638A12DFB614580A882EBD945716D7A3D3D29396D4A0D267B07B035EC001CF29C87E23D8446E21D604BCAB110869FFA98C32E35A9B6C878360FD7BF8D564B09384D5C52E0C9BE0F45E814C954FBA214F3D3089AC4D01ACBCDB25B9331558FE1D29E67628E13BFC928F7A9A88D13E0759B77674C3F2795CDFE0C6617022F9C6A87B60C4B5A69E8D1706749FB0B4E086C94B5BFC16CC3B34FF3B7EC227A5CC646E9A003E5D897871067191AD1F8A8C33A0E567F4DF2D91D00FEA00B152183D202BD72DC0694F16ADFDD6E44A248D80FC6609E601CB91EE691C4535CD80BECFF9F23F32BAB5F106234A8867CAC0B5269CA2BC588E48AF922B5917BB6813E9D1005F35CCBFDFD419404B59A84497BCAD743384461F24267C497A932411B690BF405A7ADCA63858F439B123201F41AAAAA4D0A478101EDC6AD214E025B5DB6D24021464C53FB376503B6CAF4E4D4974E072F8C88A7C61957239581B589ED8D1753844ED928642CF96E5ACCA32E69B52CFA3AF54B9FF793E7553CBE16C4F9DD6114D1357E539C238AAA4434C5E540AB31FA584B82AFBF419DC51D6B08FEBE34B7991EBF2A82FF8E94990BFD02764F7D1DC049A635A08B7BFDB46A521170B6B8BD940883CD4505224D9DF930E33C5827E303083CAC4F846D9CB9A6E3FF57E755C7CCA541DF51819C5A52BDFDF005217000967A2776F51217813B2FFC509EE35F8AED6481BBFF5D5E61732BA17C90FBBCE1FC29E8DE849C146642845F982A2F766DFC0A703B5BB612E4C2B8CC426BB56196D714FC6F1BCAA0F19F32CBC06C3DD1406B591D2B0CD0E834D003CE56313B66C224594354866598118C87C1A86F7D247593846100395EE6303E54D130F91FDF81D0DFD021C274AA9567B9F9A500F35507519BCC25535407E419B52FA4D9ECD3D53F467B6295505DE979CBF6C7BC909812265ED65B30269FA1500264347FBCF1CB34AC5A405F208E73DD503D0D0E15FA474802F273C76C3D3DF98070BF3151D5D338DB368DA0D2280BD821880265763EAB2076766540EB9A51EAE647B96CA4326C82626DBCFCA1B3FF6DBA63DD64AEEA6741FA49E358E97D8F60C7F1A56248E8CE18933CD6F850E667134F69176DFBE2A4FC259994ADE12676F63D483FE16F7658F1003C1561B8D46FEA0888D2C82A4254AEB9E4104B9FBC973CF836BCAB5E263240ED9D87E9C434DC66E8F4A7B73EAEB30BB745F4094A4B82EC96CF99219F557ADEFA605DDE957CAD9D5343558A9A0904575A7A954948DC927E71786394DF40E9328C9B4382CF4FD8423B97088BB07CB4B257E5AC7B817088C3A6912441992153D374D477EA4EFD21C9F706D3619634AF7DB364F5FE73D12FF9623B665980B98E83991215E188462A57C4B3F653E11B4B1E16522CD421105A1FE67AD0F58F3D4AD34A8BDDEC13454EFD5FAC6146012476391769D4AAD22B1A0BD1CE9599600EEDD95DD265C4640CB064F92C22B0C45C64FC411375852E596F268EB415B03DA88ABF9A089EDCC5F06ABBD96E1BA461D4DFB3772938CCBE093AF922F5CE290295EBA2289660868ED4B6AE38B28B1ABAA06B66BB97A5396218691B13D099ACB89D6754517372564CAB054763190677139C9E2F0BA2FB19D0471E49BF6A0DFF2F951A414ED5D0F17C729891F4EF658F19FEB6D31F0BD8EC15DC9F9CC1FD73BBD7A6CA326AB06F55078D4F2F90CF185849567E8C78F2773938A916FDA23279FC3A9D62CE3C3AAD309264EA076635487EDE98CE79ED297D1BA99D96C84EB712CCE028298C8BAF5B5CB3EFB2EB8996EFFF6F7682D6EAFE498B886FFDC157AE3995D8493BC6B51541BE6862B41B5A35AC420D4D120957AC00B6E488AFA394C5C3F99DEDB4BC4AD4127082E44F22194654D3FEF9CFF3AFA66A764864D8344939255F4BD77942D6B2063FA9C0F82DD3B8D9ABF5C633B6CACB152AC09B9DF3BD12770444F99843FD913E2C815368910DECDB46DC4E13EF2E89AC3FC7D13749B88197F633BB6044E1EA0FF4CE060C7F426D01D0CE94833304CDEE3C857FC7258DB654F49E7C949C4D4B2DDD689DEA7E0C526E694B5EF77F8DBCC199F73D833C54C6C389C9C63A9E203FDF4389D83A4DF4AD86D7B36D3847C8DA829E04E31BD81791E403D6098AE9DA476D75B357A74FBE2F0C42FADDA27AC72B653FD87A8D1D72E72E2BAF5D852D1FD6DE10D5A6A600C795F65A4A59A00E2C503DA0BAD2344CD62FFFAF6761831AB2CA4055C18294DB1CCAF2BC6A13DB522CA1BFBA9DFCB930E4D6C32EC24DB5A8D5C15398CF2202878D240BEE11756559F26355C059A81765FD0D993FA64887D5CB6EDE1B379B2B8B5D5430F3D7A6ECB8259220DA7C9106CACBA69CF6444192275A2C6EDC588234E8D24985A0770607FE1C4AE8CC7559B3687522EBF7D3CEF0E19B229509D2A247E8650C3676B3B272340EB71C69064FD3CE931406569E7AC1603E49A13BEA93B2892704378ACB4796CEA77687C98E8AAEC3501143271E504408CA5D7ED271C45A1A7637CFABEA8EDFCB11DFF3F8324C8C2C7D9C73A26B8B1C05B6F18013E03928FFFBBB5068FCF4B29FBC21A5819EF85B91B19A5098883EF40D91B7E287749A578E7743680786FCA565BC4D19AAC06BF70C283E7649992BD6BC0305A0A093B75DCFAECD7E049E16F274AA9B017CAF3F5068FECB55C6FA6ED97F64E17CF1CDDDAEDB45036C6B2227A0AD5181AD7389B72C8967B8176E18CAA3506BECFCDFFF15B598C47D10E11E65D9AE8AF9AFC8B189562D98BBB02EE55D0A5C41EEFFD3D6E8EE69878B3A003DE7A52A98978892E51219387C24BAA7A773944F530816FB27BCDCA933370CB340781A70DB5724C597F72F7A34DC05B732FEB79A18171281AB7A94DFCDFC2C96DD00784F2E67D7E56D0F146F1585EAA1448BE1CCAFC6F334CAB07A27E524BEB95E19D426689B900176A70B21E32278F27EA3BAEE623F92B14696CFB1EABA0D90EDC414FAAB03AC0572B4B8836F071A375849BCF46E83A05979A4111167CE5C43F6FF48F386E3E8F92FCA1655E3ADF4C2123DA2C5551E252E9BFD93276B5B2BDADBC8F23C0406875614ABDE72C520002AFE6F55BF1D19ADB7F26D4F71842FC66335FF670C60583CE65DF747AA6DB218471551478BF36140DCC5C6B9AECD22944CD2B781A240C914D2BC4B37877709794CA33ABA878615050637B0A0B3F04DE2FCF37A2442A242E6C97398CF483260BE8A092F998EEA5FB5519EB25BB10B9350AC7F6948CE13DC282ADFD3A251C07E32A25A8A93276A563755B3164C0A9510260425ACDC093CBDBC6C8C5D0FEC94A6DDB415C80D45BF9A6D8DCDA606E3204EEF6AA291AAC9AF7122810A77E0E1160A461AED63687B3C137EC40897B972493F33636B2CFF07747A394747C0887C0402CC4F50E78F70785E5DA4C6084BFD7AE379F0AADBA0CBADF8C70C34FA7A6B0C14F32D52FE8AC726F750DDDA95C741131C7F692CAF7A3A80173479690A3CC0A93D1823BA1AFD5634A9D14E17E7858221497CE6934D7630E73D615127209FA239A190EB60B4D49770A1122DE7ED76708CB660EC4E52900D130C9A4638448CBFB16B1943D7C007D521F945D00D42CD0AE51FA89D5BBB9DC68360C2551D3A0E08CB0025B061057FEA0855305C0F6496903EC94DDF067E722AE07D06AD5AC67A1B5A9D1D036F4D157220087AB098F2C6A911F710332AC3AF782A6747B8E079F12A768B9372BAA222EF43084F65A46EFBDC5D8BE794084FEDD23BB2BE82A7FD1C5FCCCA0E10FFF7CD47FE805A43F82E73773670C4F43571767DB9F9A59A16B1C6DFF3AEB739FDFDCEE27D8699BC080B9D5973F30BD546DAC6DE594F91E5C2F0DF432099D949C5FD0E9ED66BA4FD37F77CBBA8D511A0D712DD62859D6E3C0177A264EDC37393FA86D8BB241B13A2023CECC4A8A57242DA1C7BB796DB4B50197F8E7DE6FD645C6B9099D6F76701B0A36CF2DBC1C9E2F56AC8CB222D37682E19D33A1728916687BE117E14BC7D137CE28948A0997FD9B25545316DC91AF2780D34EB5D9A262B327FE0E57AF30D9299C1CDD7FF92E3CF8C70A9CBA640A71425B164DE8D2D0D78A19853125F684FB1E94D7D02473BF12C6537595311354BAB832C69593F4195132C6552176CD781A04D4293BB9E329B78AE8929A249AAC01C5C81DC46DF707C914E08A642BF4B0277302BBFE3950EAB036CEABBDDED57D2AB2DAC00B61474150F0F641A571573A79C7CEFE5B1E08C2A0D7C144D69764BBAAA9DA45E8C1CE02AD4BDA14E86E6F4509823913D553117C25BA7727244D0A5F4106962D2441C4D3813A780757E169AB7DA6FAE572D7CB919DF7BA028ADD524236473F8CEC4509FA954310D970F13B8F57505F248413F93CCEB0D2A8B81A3B6B812422E630863D5F37142EC8B03444B7509B92C2C46E8B7DB79679EE93FFC1DF1B807E29773C0B9A280334CD97CFFA2AEAACDA2A662F8767A323DA9D48CBCD419ACB2EF27A01A26F7F2968B572B679155717F7AE7CF17987EEBF9B088B153D06F88F683CD8A53B1D69CA429BC5D17DFF465377F6895611C319A8C8BC23438BED492817703D83BDBB93CD491EA8C39122ACD809BA158D5951E0B78FA5409E63E7CC69B5B6BC9BC56349CAFB05B71BD8C8ACC90F929F58037617118351CC1E0E0B3CC4040BCAB505CA4AA36C06277B4D550922DC424A005854FEA6EBE6C833980D3F7D49F38F595E3B156B89809B65E62B57E0C79947B2EC463027DE21FECA9FBEE0CD5B8EC64BB776FC95D93232C53A5A5D8F5954AD65E6BA6A3677C62497C3F4DD408AB08F2B05E00F865CAC6983159D2E4EB54EC0B89384F890E6033F71C5C888A9EF25C2E5563F4B79CF7F80E221C59FCC0CBA7A56ACA182D6A22A77AFBDD2209D5BBE8400605B918912E1F8268EEA13534E86FE8B6588ACF64A1322DFBA8990E280AD5A2E185DC29AE3AB7AEDEBDFF8932A21ECB57071D2C6207740AB48DA0286EBABE44AB1566D845A6B231073076634B6493FF5F4669CE06BB0BEB477C3BF2F9173ED7A36C22EB347036E7358BB62192E4E7BF5B9515C6A433D21E47F56C886AF92422741D1CA07EEB3A67A027283E78A27B64C89AC0EDF6D3CA5AAB03AB2437B7813BC5E349434386F00F0C0D592256BB28E68D0ADD1F23F001F2F0DC867BE42CFB316FCC3AB7F2ADE8F262E2F2A817435D72D2B9F181E285F7D58C2E9D0ADCA7E67933CEE6F908BBF182523A0367EC978CAC6373140022E3B851EBAE9D7086C4191C0BB856FBA1C5785F57A555985D0060A4BD79FC0FBD7798CE46C543B3D26C62BF07B7FFC0C5CB00729D2F9DC75A8A308AD312EFDB71DCF069034FB4F970969B749BD6F487F5E77627FFA00F64DBCF819A4F8EC0681AC3816282EC1717DA96444B3EC00B32B8C07E806988EEE0B8CEAF0CEED4F400F27F1D79267AA4BA333E61B84E6F10222FDEAF05D3561F5796CD819C879A07E780BAE63E780C05F024F2880EBCAEA6C1C8258D94B753BEED298829CF221BEEFF249643A4915D5C0E8AEAD2C85ED170790074EEC22327260470E99DD940227A671D56A9204224861E56624244241513ED4AC7117ABD09523C29C4F23E0C41900011215540597EC1BF8516CD28C228D03F8C7A65E4FFE575C6F5FB1F833B04F3DD1FE2DA3F983FC8A6BEE8CD7FDCFBB4436D8E8F09D466CA0129B4080F5C4D2A078B1CA2BAB5B306B26B4F75F49335E128D5E27B6FE1D96B9B863268E813A092C5176087562125530D23E8F6D61D99ABF133B032021530A5FBD7CAA65063B17304B76498D90B0F3E6541534667952F6B31A74394000AA731CD42D2CAB1EF3AD7AADBAEC7541D04E60B843FD337D7D08B9991452889376EB57FFC5D2D454B35DE0BE42E0B04E5C21D950E809C5D499AC04DE0E4FF912237DD83AF0FFC5CB8E520493400C91235F9D49BB30724098295713F70ACB57194F53B656D4B3E5879E2E28734370A052FE51C8139021ADD0DFC6D3D8491AE9C7C8E3AEF6A5C1E119D65923212BFDC35792BB5E3109BC36003C17100DF5302C7FE73ADA012B36AFA5452CFE356C38E63C59E80C1F3FAA1735150F1F3CE87E7008281D125FE7627B3D6C8DB3A2101DD6D650656EE5B8E0E8F0CA1DBEE12303499B6CECE8AC80111C504804F9ABF9C616D22DF34FBDAF27C46002B5B7260F47253C1A5AC8745639F0E1833808F7CA27BD437569D38D2C4AFCC5293E6C221D9872EEA5B33A43C5217438DFADAAD8F243DDD779FBCF4E95C6E4CA4E11125F9FFA93A4F04D385175435E391A7DD4C026ACF110F0B0CCDEECB8DC1ED8C24AAC7B3499C0DFE478F292B8B46DBD70451F459D0C5487C973DB0D19E196A66DC3D611D3BE4DDE59128AA6229BA0CDD9077B20F9E03145EEA04CD0B2FBB5EF90D327C1030B15DC8B5CD259EBFBF04A5EC67C741F6D38180F9B0F1FFB97CA1D0C0C5C6C791CC92908B44374BE315D4545F5F7C10DEB4E94B676D47D08C4A0C7466803F767C8A42BB0B74B6E85E11C6BB5C7EC3A8D543C703095F2077FE89A6CD8F450DDAD4007C1EFF0E0CCE2ED78F8CBA8FA0724D395C8B7714EB2CD2BB4CCFF497F09661F28A04B7AE27C8324FB4840336EB48BDFAA240A39BE662A93F5B12682E80964A14E32F9513051FCACDFB4AF64D835A1BDC643D421C9C667F7EFF4E56A7988FB757281563991D1C6B5B0C97E1C38B9185D049B4A95124E6248DCE7073EE9544DBD370AEFD8291D1016D0995320B2675D300A28C061555D9F29925CB9BD253D214E1D4FF9141467FA3449674A71A800985A0656EA2EE415366F474DA24B9C899F26B072E7244E7CB2E76890A89D42E6B9B0AECBB5180D6EB2D34954D4098D10A36511465340E3245A716C3D37A619D0E36E129A92C205579A7AB47A6284C06E7984C714DA51CD825033C241C11CAA0F2A930DBA13A28BBEADE973C6E8A838A62E04B1A5AEC0C72A4A2B73EE9925DCFDEC7C65CCD3D4EB65621EB7C90BAC3D36D8BC3427E0DEB8F253E221605ACCD5F6DD73A50FE09215DAE82AAB23DF4B86910EC72E3EE515A746FFE7CF903077F4D13B59226DF6D94A528F57E13D741DF28C45A072A41C01CBE1EF6587D9664CDF4B8A3E2215F667E2970A841EE78F7E14CB1839199163AA591EE9A2B5AC639623254BA87A216FAA462C5F9F8A74E97C24FCBB3D53152ACDCAC8A32D5A18C890004471F9A43AFEB325C767807C66EEECA54A594567AD7D4E9135DFD212A01536B32D590B9F662C17AB9784D8603C618375383BE8FA258651259EFEC97CFC616C218E4BF54A8D84E4DB080BF25650D8F522CBC33DA5BAD3144C134547AE090930BADD38EE0EA02733B057F0CEC2AE05FAF9E494813DDC49DFBE8557E80650120EB1C9003A5F57D330888C56802199C89EBA3DC085ED5DE5C0E469686850AAA7C9DBFDB47C563AA9660B079A7E23187A2E8C57AEF291FA99B0EFFE67A6D43233D7F84A9E385403DC49997BCCC69F0CB3C6F707ADD2FE0CFCBA5410DF3735306F9D2029872992C772EC24635DA6C73628A1F5789ED2E5D91CB41F2C8DCDFE641A1361AB283A0BE8446A5CA187983E34434191C64DA727D6088F90430F1482FBD5B7493E15D3FFEE375680BDBCC812B93CE10FD51BA3A712C3130DE63A77A79DFAE2C946AB370F8700999B0EE37A1B06484CC4D3859A4308DF702D40590C5C14BF8CE6D6D2872A060190B14FA78592DE2D8B0766DDD09276BDBFE487FA6621A5E1108D01787969EB8043B236F8189D2FE9E60E95EC52E69D156E20B435C5DF5A98F25E829EF3C15464D1883277A5EA42AEDC83FEAC327FDD2EE1D9A0331F06DA74BADD8A9F80432CAB5CA1A81FFC79A1F23E604112DEF22E9854468592BD2291664517CB91C80035F1A8DC97A5C8A0501CBBA6F47213D8FE0C556842324BCA2ED74EEFE8F6CC896DD4794478C07BADDD3AF65E580664BF0609BBC243280C3641C9A5803E856525410755770BDA536F0C722612AEE5CB643DE530DDD0F7E68A8EA1FF9D1F08751BF99CB8ADE48089343C253794EF22037AC8EA20A28A22242EDB9F9A682F23D5E51E05CF68DEDC4E4BBF593DAEB24E2CC69A08F35106558D22DEFA9A696B6014DDD99FF8BC35E8DF6C2FE76F162F81682294A1D9444B9632F63144C0909890A934450E27DEB72E943076414576575834941A21152A535BF404B71F18CB4851C70FF3E167E65071236844BE4785D1AA773D641207323BEDAA64571D2EFEE19A59933F3EF8E7AF86C5C9C795E88322185CA8CEAD78CE097951B57CFFC98D9B4BC920AA3E67F502CA5C4A9DA541608647C8D7C6B8CF46C573F1C1EB086D416B2E20CE3B9F1F2C3193F9D3EED04E9AAE230EDADAF0ED5A297640AC642AB70494A6006DBE0F242DC002CEA1CA8C9578ABAFD7709B58C579E2A7C2DAEE05242D8F1A26F0B96442D65227084668FE64EBC1F31DC6D7EC5C0ED61307B70452A8B5B846B5CF3AA859F0B0ECABD6082429EC6C5C9F757BAA27F52693004B19D35A675CA00FD42ACEAE5AE07C6286F48AC02AE2E43BCA4DDB0982A40B411A23990864378836BEE832ACAF1A4BABFA6C3483A9CAA663ACE89844197AF9496D43FEB39053C4A03F04FD4E1DDCF130DC450C3AA99F85B34E54E4B7F372F8C6AFF5A17385B637169C396C230CBDC45B7452354F797446F75956ECE0CE4620EF515A6EDB2CBA3C01573E293A17A22A5C33EB367A8A9E331927DFC1697BEA0E9F6EC1303D6E63179A7ECF68B5865C5B12D79AB95B5E419C45EA2A117F233E6AB777BF3041268F9AF8F0337A989C1A24686B127A0AB21486A023E85C511351C7C5982B01484868342098EE2FEFFCF1339CA74F569E89F32EFDB11DCFD33EA1245ADC75BFBEA4D1CC707F7D52229A286A1BD4D4E69BCA878C62A8FFFCD096A741F8BE4B17E069899EC20C66C23DBB9571116C105814BF5CDBD71AFF209F55EA526D91858332457A486DCE7F4A5C46EB3FC8673D6CB46E2DE3098F22AE17745AB0BFD6A4E57CFE6D7317875912BE641651D98E70C940F7FE1BF9882AE12A52B76BA21255AA0CCF272F8215FDB211A506AFE5AAC69D951DD8449A5527DD2617DDA35CB1FCFDFAF6322DE113D48678405CA1E68B6DB9F005DD80FD447E045D6A5D3DC719EDB0223F14F92370E5DE7B22FD0189F6C7CA5FDAC1DFAC8C3525DA00707665040820A763DDB5406DF41C23BEBBE6011FACFEF3932CF353D6721124F8E8F2998DC06D262729071FD56F1FA76524815E4552548FD48EB6695B81C07A716E2D4BEB22348B4FD554A0A2ED702E6E2A51C1B621C6D6DF7C675D0169DE88A85F0E45BFC398D5FB2BEA9958DB9F05A82B5CC3CAD980B25415409DB4C0EA1B15F249A4ECE2CC71449C9219411CC81AF35468A8D4320B36328298CBEA852800113F9DC6A6E727B340FD8516277E3540A9950E5A8E64F0050AF7F9707389874BE4A616DDBD017CC0216DAF1D270EEF9605B26A588A285736B3574E6AA3B6F197DFD451FCC03F2B4F1788C1F4EC59BAC79BCEBA3253E8DB04357AACBB468E9C8A714366CA216EA44A764DE67989D504A8F721098CD0AB285456D21AD99BD11DA30A83054BA40BE695EF6C298E22F8D7269E995C5397DB95B5A56AF5D9BAAFEF08166AEFDE6612FB700BD797B26F6DAA7DA1A3ED773ADDFF19C592AE7C3FB87268406DB5B9BFD98D4C8CA02A18ECBAAF3FF88F7DB93E06A445BEA851E75CA4B8011F3A2E3F57286D691667E3C2DC11419B7DA22B5AED705CAF0B8EDC70F438D57D4D549D41F07955EC3E339042D11F17792EB71D8C3B9C464B54B35BE2D45A3E07EDCA62F86CCC96C6968C567730E3845D4C8B8D6675606C6994DFE5569260BD2943AA189AF3A3EFC8F63FEA89B71F2191A7BAB25BDDB5A02FABF7224243FE5C6CAAD0F7CC66A6C6FD9754F700E4DA2548843949C7F02CAD107FDCAB04204637D6714789155D2C61AD3930D6F8586EF5DB5515F673A8AEEEC8C9590598B16CBF84032545AD5C1BDFD11A92093B0B0B48DD98EA963E208A43E5857A0722C3A641E60C7C398D15084D8C4B35F4A3146E77AB439985209AD99296A12BAEE3C3F3E994E76387D15C2FAEBFF7B44BBCA08A9937E74F9CC01613A5A2745C3F3E0473373EB1E6B4E29188477CA96845A7B24C232F8FB9E405C715E3E8DB593B14FDBAB225165BF0B0612BE50214598D943BE032FE5D5D9A33C23BF8EA48A5FF6BFB80316B5314A9D73C07D8022D3431CDED66AE8326EF049B2DCA5E63C6354666D1656A46BD5C8B430A157A43FAB904BE87F7773F5683949A416510B361ED60D700387A5E1AF0DDBBE08017270673ECEA9FE1F59A4859E7C097B806B79019C7056E6B1B8C2B43D41F78389A1422EDD4FF13239F36C54673118333E1DCDEC960A524F3D9E3E4BA1DD9B62917E8820249A397DA3DFC9417652F02EC8995851FBBB668330EC8EF6F89F77928F54628F6E3AAF55940E6F73720533FC39AC2CAB0C8495FE09563D4A0B22C628DAA66D06855CC24E85F9BA30046A79BE4EFD1B9DCC6E098DF8EA4055B19871F55F71A07138F7ECE919D3F6EC059DE0A7A363C0E63A16FD8A9944150D65F56D4A0D1CE83CF4DFA3B79A87A3CA9D003CB578B0A862E8A8309A9F8617CD5D7D1634766ABA5CF5181B2DEFD4CAD9A1F8F2148FB137CE27EC8E62771F46E7A8AD1B370474B1BFF0A634408D56E33EBA8C4F4BA282D716E03FE0799D012C1B9D3F1EE3D223E3D30F3020C0E026604FF5BA9CA8F25CB0C6D1C7835F66BD1FECCB77B911C259394E8D6582ED0B83A44776DCCFD677E7CA0352569B227DAE57777BF15464A8C91A01547BF754178888EEE0274A0EAB6503A50905C3D04CBF80E39F5EDA193CBB574D9141AA553186CBF7934E9AD2A2FA730599D2910DC1CFC2AA8DAD926C58385BEE6F37203F94E5DF5688B9FE0DE1F67956CF2D7872A9A256382165A8572BDF85F083A94A94E4C08ED85FB17F2BFDDFCD4DCFC86CF4E608A6CE1E6615DD4EE79BEA7BEAB94B696F8EC236133067FA6417895B911914FC39971AABD1C5ADF8A1B46B34647599252EDB50610E4403CF05AEA437D1B23FC22BA4AFDC836FA167791D3703FE28BF015C7BA755FEE0FD33211AEA356FFCC38720D04F325DCBF5415037A0EACF799165D590D36F036E0778963F1B9B059A479E0E6A8BBF826B0D55399B8CFFFCAD4CCF859B7C226AAF04BBCF49260F242FE7665B72AE5B1AEBE3AD1C4FDE360C56F2A9F719E8B5A4679D3700F8483C54FC2CF99AF9814FBCCDF46A85A5359359040473A71AED3199AC0283983D8595ED6169FBEBCC92BF9CCC7A687B173193BBB636DC889ED448C942FD52BB8EE81BA817C800285CDBF370502BEE6273611ADC1EEB4EBF9A625AE0EFFA97DE9D0E5DE3BC4CE8B8CB1E07E79578BBB65984464F724E34FDD3E2B37D65886782874AEE3C700754D7EA76555F6A37BE99C25D3F7924B9F5C15D6D36E6F709AE41775902710A12E5568115101E6ECB68CEFC6C1E3EAFAD850677F925293937A7CBF1B545E56E20AF68ECB04595F8104D942BB3961B39997A8401107E938F74D6DA03821E8FC12D25B83958E720E544BC10D4DAF73F34BD23E19E52E2A3D675558BA09A6B9BF36EC3EB3EDA9E0F4CCA329BD2FE20482B7C424CD1A765DB6CDC7A5C3A0635A7F48F9FCAFF2245B13B6A91BB666DC0B131E4754C2D2C1E623122E73ED103B87DC55CB62A152DE41ECA29FF4DE07A3E3F85398A14FDF1FDB85C1A6202C0C5564C3F66796B7FB9D9481861271901B8281991A9F6F66DB8DD2ACA5B9E5FDF4197D61815E423A4C1DD61233E06C3499034CBD2490FB22660A966D4D7882FDE18CC041294B9758A5544F3A697CA7BCDAC81EF742221F56EEF86CC2999CE0C55503533CF7AC81EAE88AE83A835103E91F3AE125F46B3C7ED05B40737AE62DD89B82D90C22BBF36BD4C169A9D9D8FFE33E2E80D503FF0DC214D37EA4B81D9ED2704515C6E5B7CB57AEBB3A912109B8897E271B756C77D8B7C975E3F4697FCF8C1DD1CBBFD52C9F1BBD22E7DB82335E5A6FB849F5531AA9841B92FF1CBE5A34F4E9D5C41565145E2C69AB65196FEAB627BED94F77407F7A180F1AFC4E9D03988507831848F23AFD2CBAAA6422389D64C1667CCF290724D58E28B2B74D70771682F70492AFDB247A3C118572BA5DBAB9BB2E4ADA05E0D78C79F0A2F97AD053E87B43C8755A7B2C217340C81D5BAC243B9DC51236BB7977C2F84D6E765C579058C996960C0A548BD6BFF0959720C43E6AF1A94BEDBEB922A8B4A02E451E88D4FC8A29B92D66AC1F6BE6802B5CD979480264C1AACA5D6578F44BBE06230CE75105859584EA29D16C20ED4128A0EA85F4CA9A3EBDAD29D0B661D56784E0EC2F04EC2DA448FE96A3B9EAC31A9E53A2925701C52CDF1B19447F23C4BCD507909F3035D1F6BB9BB2074239D339492C6863337869B2855EE7CCDBCC6D4FD9131576DBD7B0B475C51970D3740D8F232724BF53C09325303CCC41645694D6A9F7A43A93464507BCA194F2E1C8159821D1DC950A3CB5E9D1FD829222E52ECB1AA5BE3FFB693766886FE328B33CF44ED3FECFA0D2EE91EC515A59B419D903524112CF788ECEBB117241C61FFB84E266905B4EADF0606D1F070C1FB0BAD9EE87EDABBAC32AFDEB276E3C63E1CF73C55FC76ECD8A275FC17BE731FD1983956B1454E5611192EE16996A744DBBDC88BB1E309425A23FD480477997C6A27B780396D4CE034063BD1684CDF49B42ED5D23FE2C36A8CFB0BCC4F8F3D029C5F233C9D28ECCB8EAD8ABBDDAC297371916B0F0025151DE512FBE03163D09E73776F09C5EB535A2C81CE454EFD21E27A51E8E746E018FD19B89B74923CB2C6136061B6F94ECF88BE57540FB784ED209BDF98BEFA822205B6EB9BA7C43DBF10E82A000DCEFB30E1B46ED4753F45F568368AF289D9B257609B81392354313ED12A0782ED0DA12049D4C3633639CE970D733B213C8D40A29BE5BF69EAE20F568BFC3E6755A423E22D68963FC2C85979FAA14F895FAE3A46ED30FF96D3ACE7B8A16B8527607915A8DFD7BC9ACB0B27E06A8F22E2FF223DF6826348E96F2D1F74995F0CE064B45B4944053E3FBAB1AB2336AB869C53B3CF65E3FED0C5B41B9B7860EF3427219FB2F47AECFEBBE00DA51FC22CD074FDD84990C1B70ABA87FE2FD5EEAA5A7E6D1B88CCF9AF31D6363DB8BF9728077B7D07B254CD768EB3E107C729BE3D2AD1146237B9FB53B4F9BFC4296099E94D35CD1B358123B1D28D78D010098ED1CADA99F82F5A0747DBF6D342922274658FBE819DB904D59977046F5636318DDE0CC440AC3C0474712B8FA488CA585DD81A7DE27EFE65EAB1BFA52A8CD16FBE2F56A131C86C7DD1F713BE0F5A6D0938891049CB452DCDD744665682C0E1F68EF9ACD4DE6776618492E822E5030D018443802B916A25A62DF68B95F847AD787C0848D2609487993893EA08733CFF496BE0FB34B21DD51F10A071C44837B9676A6F7343D5A2445F4B75314FAEF07E3E40EFEF20A32F8CDF8F82A1BDDBC7F96DCB3640F298C34D5DC72F7F262C8C8559066A4F0BBEC31B2AEC81F2BF690D4ABBDC56B7839666A5BE71743B38812645904BD1D1A9388FC18BD9EE7DD0C4DF20AF8AD4B50886867F0EE7B6C9ACAE5EE58ED2190D2C2637765F4D2784BC8DB292A12F297D2E905D1432DF48FA6F0EC3DB1612AF65B6BDC2B58EBADBF411C323CA09AE4B56ABBDA4452A2018FA5687720FF761AF1295968023628AED87B51716FF33AA80E4E931FBEABF76227337499829A6D79C7C6DACDAEF490CF021210DFFD0C27FAAA7F09BD37C5BC07B55A2E621C9AA9BE12598EA98AACBBAE1981C51F76C5D4E48693EAFC22BE0891F74BE3A115CD68FFBE55188A043D013B741044E59B3165C5A62BCEE94543B637E8E0808D64C228123E402CC047C45D9F63CB3E6F5CDE58F0199666F39280641623F48CB1EE9E76DBE6DE0986C71A3C91C8A82D51252D473A42CF4223B6045A73D9AA9F061BAA949660B1BA38BA3F4B9A2FAC838D2A386601DCFCD6F361DCFFF555FC9348735C1844E957DCFE0C7DDEA5EE03822A3A5E17D07419AACCA1E59E4E3B726D68E2EFE10394160B897C2CAA9A6AE2D7F9ABF852E7042B3B276941D5453909C2E9D80E0858769266731B99A4599B172A6CC20D7DC1F8478BBC5EC2EC8E387F88A63144DA10E09F17765C15694945C8496386AD0B83F7589DA9BA60888572B16ADF404D223FDE1B4D55E5D8B5D3CE2F5A492BF3B17748DA28B43216700BDB1352907E1AB5438AB1EE224749862D36524ED24C724940B38866C531CACDFFE38755A65375579021316511987CA6EF0B03F6E2D82A6B7D4CD8E310EF5FEA12B7D84A0CEADBAE39FAA04460E04FB2C4B1E759243B11A138063BA9C96242FAFA15FCE06ED9580E29B00F44F3E74A437C9D7541C5E4BDADD92D0179E86F84FA3DBAA8F1CEA1B4A329E56B0595C90B8670F63E942D42A47B30805D770D86F6412CC87AE063DCFCA9C353FDC3E8068E3E5A8E4C3D3B8E48E245B7728D6997FEBBE412C01406D869715AB2FE5432AB89577EFFA2C6FFA435FBA59958FCE9DCB9A3E9A748555AF0CB64D7F0D85ED5FB0AEFB361A411406AF6A34610CA9D280C5AD4ABC8F1B5CC4221FB6323930D8F0F2C7F1E79220144627D49B5D442FAE09A2033E1AEB858CE38A54D7FED0328A06F7075E206FE3434E00F09992C81F902742A2A0688AFFFBE257FDA551C2F0089C72F8B75FAD8787A4DEF71F6B39C2EF08E88A8BB0EDED81B001B29F8BFE1ECC36489135B3672C016052FBB824F4B3077E024794C3D1C1C11EB1C31D78A5F314A8CD10A228280C72E9D697598335D2EB05E256997FEB9977BE8A5F1472E5A7F361FF6520F58ACCB812C16FED197F4A967CDFAEE8DE32C65D6A8E176E776D80EB8069ACAB5DFDB3822EF8057E4222E2AA0A5E90D196DBB334EDAEF375D80D6220B069F0625CDF43727085BB9DD60DF31DBF16FDD02A1D3FD0932C4BC23586592F20C7A411225D44385E8CE6B17C43BB4FA6BC914218D88DD7815963120F630D178B34032FE24EE8C2D5F256D7005FD2FA005DF391923FFDD6B1A02DDE26D301AA91DF609967EFE772EEEA6D271F41F2623DD1096E8656DD44EF4AD4565CC8A6DB0FF5168C9552F9A08F84E91B335F3D18248B6F54F84121E17EF6BD48663A2EC9EAB0D20EF4BD6E27907F5D568F33659B2DCD64A10C82C82BCBDFF5296972DFD8369027198108E537D4F0F151D9E52D24360D38172FF8C77C03BFD97F904B50105E63FFAB45BCF5BD6D576C86115E90669BBA2CA946CBF8052D08C3C8F77333196822D3DD10B9955C4D1449F7E4EFC0AF27696929637533689D59BF3B03AE55C835A2AB28022A6738CC5F3FE43BB12DFB8BF1E0137A3CA5ACD5B0493ED71E9B575AFB0D25F8049731C85F50BE87DEBB3CD180077184EEFCC3233072E0A27A9918C0BB6B24E656559D2119391FDF74FA03BF6D982D156E54BCAB37A3F8C7367BA95DE2CB392E6B085E4AB974BADD8A55A4765F42C878E987782A59B9EC7419729869687DA4035147846B227E285AF50DDED91E9333B9EA118AF549280ADFCA75AD6C23B456CF7B222EDA5899E834BDBE2240C534B2ADFEF524AF4906BC66132EBEBCA911CFF0210B634767C0C163B94B169C178F0C7B40C641894A105F375758ED7BA6A1A2B6478F9E97A5D3ABE5F0097F6440F325793571FF212C4C53A38301C3E4D076878270DBFC080448E4BA5F048CCE407F963D2ED434A2AD17385557AEA88525E30E0C3A9D6228B72ED2761315A2EF649E8B483E231B9A21BFBF2F8F07BA5BF89C00E11C239F0C409C769419C748C506D878DF7D0E4F44DBF4900076FE304017BD3D6C87B4C20D92AE90729FC985BE4D9ED63C7FFA978957167E2197452392BD82CF4709A8DCF816C49C6588CECA3D0C1360BCA17F1F152DC439CCC3F153D2DE9771802841FC90943528B2D6FBDD00E88D091B11AF84CC4ED4F1E032180371037A94886F301ED534D63E1B92722954585CD167CAB7145AAC3FA46A692B8A3229D83FF6C34B64C92507F7433140480018374D78FF90BDBAA09354EC34B5AA399C5F2934EFF7131D6668371001A96168A0A8EBF49E6306D7AE4C624372677031109549F426108CA25085C2A40C808B405899C0CE905DAAF47B17617A99849605A619A03A104275AB9DEE9FF17AB747527B28539DDA5BBDD4341BE7B8613562A13CD37C3AE160B616D61C4E9D16ED85AACF2354D61A1506143BBAC9BD6958EF542C3641CEE7DB6A54A4D7251E653EB25E05B4C345FE6D06478E6FD39F73AEE17CDE073BCC7C19D4F239B84E5FD50CF04D928B7486ACF519C68904B838F1268F12C05FB40698585979C59C70AB2124BF99FB97E3CDA3441FDA18AF55DB4E5C39D3D75DE1F6E44950021288572D2F040253FABC31224798CE55E2BCB3BD976A8DCDD7C77A9797265187CD35777453C81286DB5FF66C6B9878619B45EE5BC62FB267615EB970B812A2B19A85B77F12B18D322DBFFE7FF462702C6ACBA478C0596972918F3054C7654A888879412FCE7232F084BC2818AEEC294E52980F854389367943F8C9D77B3050A71A475978C841CB373D37A3960B25BC7A257760C51133CDE7E50B78CF561F1EAB9E9A84B322DCB040FC246239F54DA7D7ADA41FB6026246E81D82E5E7C00487354C4525A8C2FA070963AA0FCE163AF71F5B522C64740D9DE5FD465E328C3F992BD53C2A66F44CD89AB53C19ED320CD6B1C3060A9DB6C3812818ECCDC7B02B9A854D07799F980566B8054045F656EF1989D6120A50395EB1EFDBEA3ED45ABDE671F2ADD8542A87B3727D3391E6125D1D950E0B15A595E23707F2FB9E7C597EBB3C571DD1A5E062A12BF9918DD7CFB06B80B71EE05283EBDA7A6CFE119079C10C55EF683F27CC9D06E85D26900F33188D39D2128B200E648ED30843460DFAEE006423B4D18F37D7AA70CD4209073C6EA812A67DA603A863BAD29A79C993C442BE5968A0DF0B7D26D56ACBD0AFB3ACAE7D42FD1400304AEF11E4D6B5AECD5CB77CC2C6E9FFF03CEBAC5DC54724FDCD47BD4A1D6EC45C6B5A0EFDBD97DCA8BAA7B6CE0F6323FFB6C0099A6414B5CE20A2F0109FC35EB142565EDDEF76754BA999672BCAD22B9849EAED945A7F112F46D9BDDBDE882A4E78DA96D38057DECA09C4BF232C0B89EC9743C6244CA2BFBF52A3285D758250EC4633063E0716962CDE9CD88E346E3579ED9D1F085909BA632EEFBD86536B205359A933F9FD148058D265FFF73902C85455339C92D178C6D26AEECA94375B0A4B7F293E101FF375E263B2561F971D7419983CF733C3BF50D77C4D33CAB9116E8F189A48C00C04AB7CAA471C360C696EEE43DFF6E33DC931ADB4E69806670F365FB97814E9367BE22919DBDE5016CE0F44E0465FBA667E751FCAF2DCDA33E5FC488BF1DD7748897D8C520E4A46FFA8F2A539453328E8C2BA6EAC0ADC1F1188F8D57EF7A28F44F7699CBE83D0E8F2E6AD098B921D1B770C1056BAD3B2B2B7D383E56C935400D84A50431FA94C88A53545656B62BDB67EB7B3E76E0E3BE35B99C529809F59C9FE65F0B19789F758B01C6BAB1A30A8A3FBB28B4EA3E14EC104B9046B70C228503D8E29291818F873DF242A3225C9DC7E1F2C27FFAD83C89C70D03ED21AA0C616137A2C2750A24B30EBBA9875A3074D922076F7D24ECA129549B33016182DE68A235C18AA78A9D27E6732684DAC97320984E441B9F65A5F5230C957B398454E2BA1ADE900CE36CD1A320F81E21FDD36A449A036BFE7410876E0880015BDD895D29AF0F0A9AEF2596BB022CEB44B5DDA25F5BF3EC0EE3AF476E28D5F60F1C8D104003BE1109792D3966DCE207109EF665552ECC29E3C0A887D0811BA980CA96EFDA9B823E1EB1F0E760F0BBB0DC9C8D2919402ACBE08F0E1522838ADAAC6B45CB71611ED85238D2E17907588715D328015A225B713F01300FA5AEF960DA36D4120722ECCBD6886DC08E57A0F68466769636712A361724FB2FBB4AC9775287BFAD7134D577C31170A8A9C39FD5F1557AFCC167B11DA412436F79946BE332F148A72351279E2E1E32522AA8C0731F2F312B893D4F24A35BF2C42279DB8872E70E987CA680DECFB29425A5C51709216A5F69C00166B9C971E9E02B52731AC8DA8988A8A7878CD368085244678777C7C1DC7B0C6340C71FAD6BE4EDB0ADD161D5F701B56E98CEC853AF23B3695AF8CA7493BCB3B405B2A3A5F247FED50EF3F0E5679C2AFA4C2F613AB73CCACDB655A97E00AD5F7F13 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 27688 +sm = 0000000000000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA70108E5D31084F6F9D247281E725410F388DC94BF47D8D65423953F7BD8B175D8050E7A09B0DC1E96F31870177ABDD7AB42345B9BF49CA7689F703557EECD4C9FF327EA11B8824D0E94B4E1403A982CD894D9A0E85436647AA74A97735EF614234C47A8D490A5464AF68854E65606D09C887C8A95A511E76865A1B432139E0C164EE80E6C6D99D6EA3C828A660B7FF33E894955E19F46E5831EB21C675466E458406E786CDC1C6D52560A46A26FCF335479AB9678525B94DCCAFDB7A9B6959E00CBDA47DBBDEF5D6D974CCCC04C88FCDC86B9C3DED226919419949E1EC94EF5B162F13C44767ECF866B44F6B8947CFB4608F5F72F394BFB430C1D9513D81B13B05B495B25FB9169A3460E4AC08509F6C41627AFB5261A8E5ED535C7D0FB4869E1FBBECA5F998274C2E153FFF3CEB473D81B551AB5F85CA351B4BC225D7942733BC8DC1F0B2FFBFB477F46826ED037A6E7378BFCDD20578442F9E92BD6B03C8077EA3E89B174D5C4892BFC0417F1640D61FE20E88DB05BB1ABFD542EE6C14ABF5D244746A457DB0CB019795E480CCE9C457DE66257271565E72D03BAD5A02D8311B494290DEE03A74DB1B3A62D2EC10EA3C3EF2DB3375893598133F36B5B8F2AD592972DE5049C743089529695B028F2F72BE0893E59169E9A2376C64BC5CCAC5482E13DECC3723604111446FA56B31CB301051AEDB4E1533567612ABB95A8099FF158ED0D5C695A662B0EA2B85270674FCD635917F4F10D577CCEBEB8877FED67DCDEAC83360CF8C638B6D57B943C63DA7BAF63F99ABBAD2C9B47977BB7A57BEB9410160A61FAFBD48649A3D2032C1679A67F348E3E25275FCD9AF650937FEB0A30F8953DDF5F0562A9D378DF36D061DCBEAAC8613034756516EBF622F21096E206442A9A24E79B7D98A56EF751FD1AAB89A95F99301932337C4E7820B84B1DE9CA2BA7A25D6C3E4B7D39A28A65A5628A93556FA9F54E273B583F9A197BFF4731E0429BA00E66D42A900F85130532F5303C7BE837860BC82BC2CF7CDF0ECEA942932151BE85B8E8195CC2F070BFD482702182B8A4A43ED942F6BD3CBF9DE7E8AEB17EC786BFE2AFD21BCB353A1F77030A18BAE47C0D2B9F396BD8E5FF560328AEDB20C718E8427DC76AEED4A3F38D853470B7271A968B537E0F60E1979BC257B0A6AD433C67673DF7EAC9BE29415E55FFB6629F621AA5970B4F58A93F52564E58BCC84F2453E034B68E21C492FAAD68E2E6795244F4D34028C14B65C23E9F23D5C2BA27F67484ADFCD6EFF8E13E7C1BFE7EE5879654357E6A6B98DB099093D34E793C96AA96BFC9E1D6A851663336861DA97A10FFC00A4D5A8E4F1CA04A8C91FAB90346DA60FC80299F79BA6F8FEDB4E1F705DE37AB2A10761A89127B9757D0F10001923A14E18828A59272060C3C7F7B4F17BB4D470B214ED52B31626F1ED62F1D003C9AF2D41510FE1D89C15CE442C7FCE52DD7AEF5B65923DD8CE7C031E6718825D1BDD7C324F7587D4412000A3EAF78333B65C00A8540790414E83288FF8D9C9F2E5B8879D61077A83925E92D1C3106A85A7815F9CC0A00D536475C5C63263C26CF37929B5F2D4827B72B8B27B64DC91EBAB724047EF3EE1D4304B98D74984EC5E78F5662510C632A8A493910BD6DCE3B1EF3FFBE4583513F2B8D6667ECB86448E01139D394D40C1C23243D2CE8EB2D6334EFA975B68A57940B01E7AE65A38E77903B47056A97A9DF915AB3C3887E2C77DA350F5F8C4EED477B97F822CE86F520C8354A3E599CB7217AE688647A72985606BBD0720F6FA5C5B6F70E88234EE54AD711158BFAEEB39C98014D0C1A172699F3C6D33C5D9DC9BE93C7F3A5780F02AE964D131157AA78711B1A1FE5FAC4D087B5ED235135112034CEE15D792A362D046199906ACBD18807371EE76F04E4DEA69A68B75074CFCEEE3B13ED977BFDF0DADE5F5BA26D69ED191B3B47599B1CF4E28004F8C1DA229C20EE36147369CE8C9949F7E5CE56323077490807321869B9D7DC329B0144EE11C2608142C9A29446242BA70019E737774335AC1C50A0CD6E13B06E3499CDE6E9DEA640B89DBC09B7D867FD5AB1546E60AAA06344D4610348BA58D8269AE23C87A3B0A08D3B8DEBF66198403A17E0C98C14AC4A5FD5DD6D543BD9888A96C54644ECAD9B108AA9F04474BE804FFC6B0D772DD5757BEDF361C340C9CA3D9449895E9AFAD2BF923436FC420E668D3FD58E175278BC30BB57C0880833CAB3C77F12E98C3550A8ABD94869EB5B3BFF85B945AAE0B740C2A1AB94861181379BAA1ABB3B04E3716F43BE1FCCF919998375C849D7658B8FB77DEA0A72A17F5CA24C878412709283F7FFF77EAB385CAD8DD6D937172EC79F4AA07698FF6A6E4C559893DC05EA367C2A717CE120A7E2CB455011B3E98F8CB3799F0B0600E74AC1214454C9F6D1DBAD9EABF89C0608AE5DE2ED5D631B575F59F445A94E79190E6640E42F2A3DCAAC94A1C6E3D522B9682AF0F8FFE84461F7BACEF360D279EDD9537AD2838851E97C564BD2AEA949AA9FBD8420530F63CD1638B988724A1E11888CB9A2B11411C221BA02F0ADCF54F6F0BFEB7D77B5227DB43AC1360C86DFEDA86872B28FA47CE1C78A4DA2508F214D75BD46109FC202692A3FE21B7739AA9C39BD1B24AB82C59373CC06D3F92D48B005BBEC6C139005A872F0D032278DDCFEE8E636303308F418F73E3FCB7B63464E41C65227E6F51D5EC56D93D19E1D3279F668A13A2B3599139B265111473D5F8F73022D8B7CF740D798573335CAA3B04CEE0BDCADCC2DFD20E920A0B83391E2CFA2E0441B6473EBD291791F09B4ADA70A5286EB05167BD59BFD8C46427413D609827DE664819C8CF4522000CFEDEA88B1CD2818254337A24515536513833D8DB9912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70DBB81517936455A05C964F54489323E7A18431AC4CDA3E320A38C51634DAE5EEE35A116A3A2C931019499E44907A8AAC00D621FE3639FE1C31F4316EE530D4009C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC9D550F851D023315BE35A69C83D099341F6BA69B6A40E224DC554A3489D33729C9EC8196BD665514030C26AAEF80CD6E1BB9EC739BAA2B8E4A63EE691AD2BFBABDDEE2B13CFFEEAB7C25273CAD45409B5270678CB1535AB800679906CE77189DCFE05BBF92FB5E31F184CECF3C427437958F695917E343ACF46DA2B9D988CFE316313FA9FAAD49EDB72B007A7F3D6FC55A88E6BA784FEBE9737803AF05B4801CE0C723C0D15CD8E7CA8E237D4A1C0BB1413D369FC3F21F69205D428069EABE626B971A2B5698ED05BAE54218300BE8C4BC9A52EE5FB296BAF2A9AA42F3C865DCC1DDA69969F085C91D3CC5934567476EB70461B942059AC0F83BA10DFE783F5FB405F159563419B3F5699179D6F33AD05E840EC9227C592E361A49E31D99445437D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB3844833CA9CC7907865878A01BCAE7DB72BA4F7701F20523E0E98B27AF08AA747B57DB1DAAA1B616DE469C7FC83CAA1DA1D6BA6F0C2B0F7F2CB7A4F58FBF7FFEC292AAA7FC3B87E797DCA067ED7672BA9B4CBC27FE9AAEEA63C8569A567129990E1E12A8D23039A877F7FA3EA9B9359A842A19E33CDBF284AF95FAE2A2DDEB80030A8245A7E51131D27EAE94B6C38A8C4818CA7EAE0A1C0841E7AACDDF68A4C4491EF97D5F3F6AD8CC47D2489DF1FF96B7DD444D31DD2FFFDC69C9ED7F750526B3CD81EDEEE2CBBFC0BCEBE875DBB644B3828795D2B81DFE37E0E4E68F9A798E09588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE596674368D1D405B742EE812FB88947D9F5DE52083777E54C2F0A1F605027BCA5A12BDBF9CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318ECCE515F732608A96D4E557ACCA60F144A212276CD52FAC0F12C39F7F45565346B6EE409558FF37D5C50280099C9D75B688C7D873EA7D07EC6C9305AB367ABC2FEAFF9200CAD14D71DE9E1F1DFFC4F15FD0908C6687F585D9721AA773BDECA4C7DBDA2D8275C59A2E90EE07ED6734A09566174D695356166041C646F18180DFC5ACCBA61F1672213C3CA6933A5ED65898AEB4BAF534751900D2CF25A7A94C273533B8694EEFB366F4B3E6D4DBE7FF5FC70EF5341217906FCEC863502598936A4A0D7DD4267B1C0C6E8175CFB3B9B6BA86CF3094D4677BD57712235CA8395A6914063B4E2849AFA406B7EC6E3AE39B343EE39348D2D29A0C2319BB34655A53E1A816CD5FBAD3A3796FEF2C7B67BE4507438E5AEB603B1A0796293A274A3F3D63C7C1F14297987085EC271F06E8DC986CE41DDA37ADBB39613E6790644A669594AF10B5D7C2DCDA7190B03F77E69D79A143E9B7D8B42E18E56D1D191DE05D58DC29F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA4C86ADE353F4AA57DE2220D13EAC9BC8FE02D625EBE3BF2761493F180F968DE438B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE8D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB07425116F11D430A927D45FBAC134C59EA8E5907C35A59E0CF2FA548F9AA27A3530AEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBE6FFF1A2A91E8DD23131A7840BF7CDEA3E18E706A324AB688A5866B82EC18082D89DB83F78DB30D5CE6EF134BBCE7628AC017E6D6974B1D82E4227235AEC9862899B7A4E0E8B10A8AD0B19A54DE7ECA861D6AFA1D91C9CAC7B8D6AE536C458E176AE68697912D7EC853D514AD4EDE982FA89400CE895D3241E5610D0AFB17AEFE51FBB41E2DE044A00D84BE759242476BC0099DFE159F0CAF2187BB311DF2342A59C003778A56907F086C8DC9309D8E41703779C8E1141070708E02B9F987ACF3214A8E442B76121374DD243643D64283D01279A49154760E3567E46ACE89898BCD67842223D5B8CAB03DC13930BE7210FAB7FB2318BDCD92B642F6BF178BC30B4F959F5D8BE15F67C5AC4A4C81F1E3E707AADF0B4CD02982ED4E4E52A81EA2FCB60ACB5817849D53C2FFFBF7906E290BF76E505071913AE0361FDFCA4B279897C9DECF546FB0366D65C9F81A9B51402F3694F0B5DC600B7E4F084383B643AABC755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E6C007F614D3C0A2E45486C2E457C2E6636BC1AFB76B2A7FA351FD88399098C64E379F99B64A3340473DD46C11564937DB9A28C4DE3745308433153B2BC6D5E0D515C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFF0116375D404211C3D3302D17DDD0390712E06CA05FB4BB2AF749D3439A5B30D3E9FF4731822AE6607BD96108BD229A4BDA5ACF50F7185BD1C0F56CC56D69C008077082C0869F237A6F19D73ADCF9844686E3C5583E7D8FFDA636E70E989B1742ACA4DCE98101BBAEDA8E852555033A46F8DF4E3DCA1B9A09E9F938E0C1E468C52F7DC695389C21D0F425B4DB554FD5BE1FDC2765B997FAB1F94D864DE1B4C8FB1323A8D90DC0CD7FA7363AB70728FDBF33C2325FF97C59ADC84C104E730C85CFBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272D144DEFA2E32DCBE8CF7843CBDB9A67EAD7892ABCE9B25A6B91AF0B893846ADDDB6C26354D4D8B77B14FC2FA2D8D589237C4BAF80344C306439619E5A4DDD4630B558BC9B3581AB842BC8B630F232BD18D4BB10FFA1DD3805B18635F6A9A22CE0D470FAA2AB813662EF63C784628138499A1A3648CC877300401E61DA9A379FDB3FC6DD985CA26EE8093A24879BEF107C4D6A38017BE3AA5CCE124259C42519C6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156771072191C21BC3190193111CD3BD0604EC5427C6D70B1BF21DB6E59ED636342BC417CD9F69B804EDB6359C9F8E347AD253370E065D500CAC64BFABE3E420E39000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D00C27D20CB93DA243BB3270F1EF2DE68AFB80842E8BE7C1FD48BF0F5622530CE84C1D30BC69EE1164CC602F2522FA39158D4D0D30ABE4FDE43213ABD6E4D65E62FBEC9AA1D485599FB7ADF5C2C97B90C82A1DCCD2C44ED66CCE79EFCEDCAD0CA1366FA51DD03DAC9BFC60B79719033B32247DDA9195233329F5AA36627FCEC5E42F078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DF657C03A3914FD3BF1E82EF96AD7EA46373B0A4DD0F5655F22F754DCD35ADA89358DDAF6AFF78EEEF21010DBC6556C2C3A018E4DA1D612CC3EF237BC2B1E9E600D923E2CE04FA27CE8EE63B969F6079FF8551B8C06018E99D84669C059AE08081E3A1C7ABC19272D7FA3F2704CCF6E491AF93C7CBD4660410389D86BBA47BD5A0E996F788FB9CE600AD76485D265628019B57FC69631D5266E8E46913ED9142FEFAD87E26DE53ECDF43B352EAC14BF6DA899058228C9414E7323430F9357D6244E7165F5CA2FF2DC9899AA6D8C2B8DDE8E2C5FB7C6E02BF74F578823CFA2355F2FCA1F776C6A87943344A5E53BFA39559EF98C397423C75EB318EA9B5F375C17E7B46A8D592651E7D50E70233224592389C1EBD1EB66678AC42C2862A2C660BACD03BA4064EA38D34A7D44B32DB9E75ABC6B5025B504DEC60512A80F78876C54D36324C7143FEA85ECB9E66800E8F4004061EA7607EAB964DE3F9A273D2C7A4CECC1B4270ECFF87A254A139DEA1E0F0B0F6366C02A0A790D46EAC94866A82DD8349F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DEA67846512E96901F78E601EE427F8B1A7986FB8832D091D575C277CB202E87602D670CE131CC6023A9E83AF41486A04D62616C1E912D4EAECD5DC815BAC1C0DBDB347F6B5DF06B0F58441FAB98B9511AC0423ACFA43E0422A62AE32A48E935C6288BD0D2314C6A739A7779BFE24DD7E2D66E9C4A4111E22481688EA39F256224531ED241A9D35D395F340421F2D8F5C05B873052D2128CEDF4ABE49E609176674363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D02AB14858954A117C6B6F2CDF4823BEEF1904FFB4D841B30537D57C577968CDF18EC8631C536AF09B54D5887FC0EB11A70E86B72EF315FD722FB680EF03A3487434215A0EEA412C0D78DB2EFE20061576237453927710860F0A49DE0ED0C42FDE2A5903D635B19D4F2001EE353D7B5210E1C01F50251ED6E753635A972EC8C1914E36522B1B41BA51E9F3F1CE83BB5F526FBEC31C21983736E42EB7880B9B27EF6CAE0618E57F881193714D3E8B38C9E9056378DD79E78422BD7C4CD57D230EF44B38F6A107ABC77B8D5A953D3A3969FBB7DAB145C4F4615FAF8F2172AA2BDEB35C4A0494100CB9CE188DA4318EA5B617EBACE910A32F0A280C82AF82121720569232D71AD065E45268B36F92DDA13673529F24E6B83A865F3E266635D9655C8000C06478530294DE092640DFB324E09DB3B87497C94502BD46092D72DAEDFA93A0353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB51691B3F0ACA92B02FE916D2AEB98BD9E23313F49A0F44394883A432523EB5B34B690EF9C16B4D60572EF2D791F2BF403255A28D9BC3352B02687AD9200D34C05259FE0C93B75455218E031D59A65D4F571CD7F8B130A0CA1363BAF2D9895A8E8925ED20ADBE8FE96C34A6A13B9318AC8A23A7EA320B83B7175FB54868DAFA9E233B0F4B18CF6FC7D85F7A2B28CEEC561222C5051572B092F2FB269ABF1CC7826675F09949FC443EF723AB476E9E5D670C5F05E46DAE93837AA0F65A4E83AE2C71DD02CAB1038086531F93E163AD65BD962ACB9497C0F268876B5AD3CBBFC4C24EB2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADB0A78B6C1C4ACB8B4C97EA8C4CC3F3778CBF761AA653D9531216588A46701366E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC4050CBFA6FEF6B9FE785A59511CCCE21EC5AE3F429A07B4626A4F0C555A15B42C26A5F353E7A479A700595689D5734C39D61177AAB2943775ADAC879B4ED7B8ED826CB43881D2C1B5734F64A5490A4F77ED4DCB9775B258C18182B42C560E6CEE89A329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB041A19053D3003420EC262BF0F45F1C7CF6E55BA9001E4BE097329CA460D335BA899503CAE0D617BB7FFF0AD37076C91B1659BD448C05C49D9360462B4BC601536844FF2C635BB654EC5749FBCEF3288E41B8A7835B645E0BB501FF805EA4B39785C203BE03F0B105D17E513D50B7738E78EC18AFAB3FE134FD551E754CAA189DC4FA2308B6EED1B8CE87EBCE212E15E72C9516B778C1F62819131E2EFA7AF63BCF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0A2979199F43F2F59FB2C62E8AF2EABAFE9B89B71E75AF029BEC77A6A56F86EF6A4A7212A7458986D2DAC9E00CF68EDB81CA05A297B522D3CB2E0AC3146E4638995B683EC201C67C911C83E6BA3567D31565DF914783F41077E2C31B06640446A6D403F9D46BB9D00B3C436FE1FFDA80AD0AC466AF0417D18D5E7DFEDD7D68987BA55F545F3B89A38908BCCA1DACE0B89FFB49FBA3A67EE7384DEE68FD05721483030ED53913A6CFA059DDB451C780877E919BB86DDCA9E18814123CCC822A8F30D0AB4602815D2279398ADEDE00B23AF4EE605A771AC616CAFFCD3AB12991023A6BE6BCEAFB1672ADA631C6CC29827088627EF9380FFF46FC479E2B586432B58F95A824C0D5F08704C2B596A7BD0A36A52BFD8C14D999F92E676C83EA62DE54C3ED7ABF290BF17C48DD69F949668E11D957299DB6920D740252A9AFB65179FDD62B69D2A1A339CEF805FD258D83FD2F406841565AEF5E42ED7687D9D466E6A4E513E072A9EF6181016DAD988F7C2305A77740F196465CE30A35BF3D098781DBA2F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549617285753A9438517AA7159A9C806A19CE8B8BA5F9C99250358404671F36214E8A7B5A04767FF8C094A3CD74751835BD896FAEFD1747DDFBBE79F48148D56BF585CB0CBBF34300CBFAB9DB32469814F107EF7822151D158CAD68F01418F88B181B092970DACAE4D5DEA7AE39965D1929CBAB7685E758206D309CADC07687274657F6EEF56A657D3FED4D34C7FF6C9CC5F344F0EF4F0E752F83E06B8A23DA0D65A2C10C2D675CB3A214F5D363C35E6E10A1323579803E4268F7D868F4716BF849B3C3D8EDA94476BE7322891C36D6DF146075F11AD02434D2216351CC26600662BE0D38E1DFEF9A832B9F066718FCB2134115F33717B57936CCD2DFA3A95C1D4C4C98BD09D64EC04912C06C7C6A2FFDCA2801628D873EE6D0D43EB67FF0AC93A7666C9ACBB9400593C00316E05F0F5706ABD923D85DE72A0D1CA9F0774F5180B65AA578B95BD20C1FCC322A5B23995ACC9DC97CE3043B1A723AA2815314637B7667DE02ED0FA0924C0791CA09FA028633CCC594429D6E7429930C7F01EB6A134952E89B8CCEC743A23C63CDD9E161B5A2D1F1E0D005F16727A3B0E8B90C20656B850A4F8B5D400B65E91E45AA25A880B76BE09F226DDD4F0E0AEA00259E19634EBAD387CCAB556997A153D1C1B87AA62E5B613A5E02C65E7EE7DDE2E19D965D27B42AF8542066549A6FEFF3E10A93B349EACB843759F5E4EECA76CF82277BD55C57FAD09BE938ABB47720E49CED626AC860446B290C7FE9BC83DB0C7FDCBD5CA2B8FF6C52B2CF2556040B3792BA99DD43EDF1FD4CBE38970D235E8BEE40DDCD2708E432008992D3F9DCD73AD594171092909019E9BBE7A5D4A21EADF82C5C22D877F422EBC64734717C93A027E9EA7EDADFFBB8A04B465E2F1BDDA54BA30963A41978562C27EE91E8ADD7A95B97A1F9F5C0494C3E44AC5422759F971200B1927F5C37B003499B213C1CEF1823847ED4A308D7D98FD5E42115D49B1FD42C7405B55437E1C8C0226884DD801CD89163AEE8D74105F621EF2CE222B13ABBD14078943CE054E3D68F7E8D763948CA83876F0AB7CA5123ABA8C5F68679FCD116D03391F2A53F637D26EC486FF6363F0C297E1A672EB717107ED9540C2AAD46038F8D4C2B5D1D918AF6BFBA7DE46E6628B2C217672257EB98F585A4E4CDD87729BA5ED16719F869FA1495302E8BD043F92ECF8799DAB7B9C501DC956EE3E55FF30E6D565E228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023E10A68B5275694C30FA7BE9BE2392EE6B18651980A01348A97C4BF091DE3501B30B528092599313ADC93C8407FB07E740F784E80461A23A1DCCD78BE8A72EE2AD69CC6E63F385963275DF49AF300E5D468285CA4457F090504D42056F571A8D453903B85D7E63F893431A5A1C8A66A8E4C999F0592D75717940E296C8275952C4A8DC6E97B3D5602408DF3644E8A1338C856296C37B1BA8445883CAFB408EFB9A545AB53CD632C40659DC607F4937A4F364F7E3B47A907BD30D8558C76A8EA9EB357177B8B2639477433604EB74F9C2E3528215459533C1A989FEF107944FC8A402E29495F72F2C210135FD836028B9E21E76C6F13096DBD2BE9721DD2C35504D648C474907FFB896B014CB022942F308C3263CFF227D4444763A483658E728EE6B7954C48E3FCAB1246CED1B1E2EA9CC4D5475BD4FA43FFEF56AB2A2D779E9D206E3E657A2244108BCF55C7F4F97666457CF5F796105ABC773C541173B9E338B4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F9338191406A4C257E6B7C058565272FB78A54A46007F5550234FE9B7952A82581C08AA6A1EA68E497D663F82C5D20E9D1134816EEA319EEAC8E431A0D82B6D62F7B93D121D8382F0EB3DDBB9FCD43901C8AF1AA019A7160B76B72D4E8CA1228E5E9DFD49E24F3154F4A914987FD0264ADA4C8D6FF9EBB91C59C03CBD484E9EE72F1A98C3F97B9F2479FFB79DFAFBC33C8ED249286369F003C471C8B64A9B1546B1F31BFDD0ACA06AAB3EFB61E49CDF5506AF8A4693A7591498D9D7F8B28A72A10EC60F806A9955D7EB41D2654EE5B37C284F41CFF3F591C227E3FD0CD524379DCB384ACF486CE7B1E658CC743293DCF546BE85382FC40CFDFDFA407A9EA33AC46468E060524BF06C9CC109A726CEAF0811D0F857C08A3D4AEA67CCC0B17B2C38C53DA9F860C99E3AA769EE27CB7C9229207ACAEFE6C62D3ECFCA201DDFAAEEE1EC7BFD40086AA922961198B53C94BCFA97EEC1DC0FB8FF1D9448B6770DE4F5703CAE179FB51CEAF935F666F398B74BDE9FC87B01AFB6EE8B47490453198F9B38AA2259D2194E9EBC42E1C57994921413D6327018B91538CCB0B90E965564171D133CCD9E7F65E851971FB71F2C47B4592C2A52A4101D2EE7A69DCAB3852A56C4DBC9295D2EEC5BAD1B8A13B7EDE84768C0AF5FF0B0253B44038C236412ADCEC91508A76BD8D16E6D6BD5CBB3179B34DB8902863056CC65A4DD40B6A1929F28DFAE1CEC64A74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7E8104E8D9DB129F0AEFF48177BE4EB60236851F6D0DF3EAF508CA7F97E4D5814F71ACBCF00471EF263D3B5CD58ADEEF11E3465C704D90101A5FCC1C8CAC25387B7D6B83C7CBEF04E05BBA1766C5C5D804642609AF84AF3FA7E4572393761664021A632DA048F2A10C2A349E2E1C260C1C3CA6184BEF6045F43D9C767E2328B9AF5E48EFE8298DF69599C49CFE153BF59010741DEE011FFFBFB4EFC5AA4B5DE409B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F83369497B16CBA6B3104624902242C468F89E89322D299123ECDD8ECC98FD5C53D99FDFBBADB056D1034CA39CBBFF29300769BFF634A38678FE7BF929676A43CD0FC3161391877F0623D9B59DF30E28F5B47C0445F83B36F0AA67F6A2DB8C0C3D3F45738A4DE393D8675E286F4530AC810D244C621963923BEB20810EE32909DC96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A35F79B7F944D0041C0130B7F59B0ADCCAD97670C92355CCC8F0FE34612A088BFAAB33542EBE8F3283AD67A79EECC3E7B7C5D4CCC29B6083AEDF7AABBFAC8281B7D7711DED8D4CA70C383C5042272379356BB80EC0A9BB8E4F1C73F2D2DE1676BF5AF43AF87AA2B2C4A6826DCDE46E599B2F31E9EA87A816EC5D8163952A7384603C8FEC20F58E1AAC52188E42774382077A35700EA5EA2FBD04135593A7E40ABA137FE400EB63BAC7F417252EF6AF6EA8FA9CB3BABE7718FAC4A756702AD64BF1F912E6ED44DC6D424CD15D3E45BC9F86ABF7CB2924D7B4E8AAF67D69401F5609B17D251140842D7A94FE5D911BF2FD37418208B716D2DC66320743B79E64CDAC6F2257AD34D112E22F977AE6034068C0E0F089FECA11DE03396BFBD365B1A788B2C550ACBED3643C1E4F13618F904B40031CA9E73F9B13293DC92102B33FBC16C9CDA02E511D49394D5DEFB95770E5CC750801623042B7113D385E8BE8FEDA1D7F9105D545B18AE98870B1326494F9BC31B33EC24CCA7CB8E53F9AF1A7E099B0D9A40CCF40B085C0D406B5F1DD7DCA794345FF98F272F7D9A11C30CC5448D2D311502B7F0F81437B52EB11CC5FF11C1FD62B9A34E2E102C5C59D14A3326702F6B6862383B5BA1041A59B2F4E009161857FEAAE3F0C4006926444BE77169E9963DF262BBACFC643F032414200B26840295326BA1983CF450DDABD0DEAF05B3AEE35CC029B1E67729517B6555FDC996782FE0CB275645E739BA0BC75A08869998C082BF6680E2DED0D643F06EED3947CB24E4D240CDAB6B07EB71762DB159BD8E8FEBFF190763906FAEE1D307115E7D6697AF3DB2192D37468806FD49ABAFFD157647B652B339A8912CAA3730EDB23593BE64CE9A50A1622D43538926E5B05D878029C5AE57DB40072EBB7889423A948257F9E8684E5B4F10C09A22AC506B5105246ADE89409D3AA78C4A88181FD562EB714E9402F8C4AB2129E73FD77BB64F3F6752E5AEEBC4DACC209D01A274E39A84857736671BD0604C153703CEC940CB0D79CC433D157EC5004ABA2F359B80DA9FC04267584B2897B594C494883185E613283B939DEBE0F324B3CB9F45A6FBF11AB1CF2704C5F83BE3B8CE1C38663757828909CA4AC49ACC134F533F5DAF470EC30D2E8FBC66C9B6C58CBD2ACBFBFA2842E78DEA2DCB820CCCBFB17454EFDB2B1D706B93B0254B3209CFFECDA9F52CFDC1CF312EAE3035C1A3D75D8764F693350C2301864EE1A3797F6574AE38F66B40F82904FFE6CBB34655B99959759EDB652F6A3BDC1D0F24E8EBE1761B43E876A6A7AA29E8B1158F1D150E25A742B5FBC7161234A85B35803FABBC0AEA40821E9990D48BA7EF7E1A50178ABB3CDBEE228B40C8B02C98C5E8B70CFF650E570988E64E6F4FB69DD11814016F8AFC30F853DCF0B793E150C3B796CDE2B1B43B3E346E257302026A4B5934CC6A417A99706CF783722DC2663F469896FF8EB4CC741D531F3C32B41F0BC6DCD4A32786747BE120B33718A94639FB4D754E0508B0315990F31555D6C1DE281244E229377BB4FDB9CBB38AE483A3569F735AC438C492DFE94149EB3F4A4F9779A1AEFE60FA343AC04323795C9D33DE8AF95219B8711B1168A107EF83062F033203511E5663EFA0C45ACF54432C9D4EFB5678332B5E164092612E42C61560D9EEC768594F4E0E6AF10AC7B3DCD22D229AFA8C022EB00AFA626C63E8E96B72DF979586867B42B8FEDE446A0F6807F1F1C775595FB5DEAA3BE2A45570235BF1169F163501B400DB5A48D7FF08851543CA92A0E8448F98BE619F41FACBF13EE45A1F97C20748CDC3B4068D993D944D5A165FB858FDF4FBF88632FB826103B1276C7791C64195106635996700A71E299889131E533F7F060C7F96E7C54F02D2A32835106FEBE6D40CD4D56B57ED26A7431731B04A78CB5A4884F0CACDF007DA6E1C4195B2B59A53F31C48EF9FC33CC7F6BD147032A1B6313C7EEC43B1E46164BEBFEF16FADDB1A176FBFBE34DDA7C88AC9C1EEFD4F33B7960D847872B8B433AD5D1293EA480E6FA097BB9AE29A7C0270A062EF9BADDD796FD8EBB1502606E9262357EFCBCC9B7343ACBD03CFAE6907BE46BCD32C4C4C4722C8D3A9EBC76EE4CDCE71B049D688C42104B94A1F7FE6F945BDD02E3DCE0C345C047AB31E7E8051ADDD3DBCBD33699AD660C1CE3E25D203C4EA56368B19C77D498E67CFE083ECD3D36BDCDF29A148224623E0D70D060EC964B329186162C1567F7E7B5B6921CAC8894E88BD8BD6FBA1E8EC4081D35931ECA2BE1E72E32D7C986956EE9CFB07CE0B5091605780D9770A00252C92C4DEDD4D8B942E14C90DFC5BD612D85CE24C5CEFDB3EA964FFF256B20A4DC2C0EFD50DA4BAB56BC846B09DE27F341EE42E63C0C23B6C61D15F2C9FFEE5663E3CC74F7400D0645219751B70C916C03C0C67159F71BC0B3BFA0956F026B91F8C2419D671D3E00D7F633DBD2DBE88126DEEFC7733C2C926D1D8B0C8BFB1077A700BBF3892F0C4F3E30DF78BCE0A340A8F98EBA5BD384684D1E0081C1237440B3A6F117178C0DE4F19D05D4241240924D9EAF9CA45E3D4231AC903C8EE5298A3445F01961D6D3786E36D24875E6DF3EB1D6C1BE5EEA0E060D3E0EED1DB2D4E795D35A0DABE4A745764F05A858291993541AE149CECC5147FEF0F3A96B42F38963B9B29466FD66AD46CADA8F10E2D53BFC3B823CFED410147B5FD315FAA62ED06429D6D3FE6E5778A64B5C9BB06A8CF5561EB7A8B15838AA226DDFCFD4C31805D53A6EB7D2DB861451027CF84218C39078756B2911021C3EAFC2E82ABF792C5012CFCA3AAFB0A277A9C9E1E515CBC4439D95B2A54510318F5D6EBF97C8DE2AE0D4FF669493AA354C25460D3C15B1A57AC53D7E6C07CA407AB1EEC4A366A637AD4081F0343433C555DE72B71ABCD8ED3C043532A61125CC3CA06CAA634E5F75B750BF262756A57E3FD235FA9EF00CDD9553D37968DD680EBD5935FBDFE43A82E9DD39F96FD483AAB7F2D0517F23727E8F4DACBF144E3C9C3413B4497ABA623AFE3257572D979FD7234C04292B8EC507187752446AD11D10DE925035D368AF83D202AF6979123C7F3B7FCB8D83812728A890B5C09B482529FFC0737FB59C35B552AD7C5820E27332D2E44F2A31ED972E2E5C834FCC652204BB401557D6FEC656BD9F63B9226056E2D025988ED1312A2A767D418F1342BE489B463AA4BE823D471648D9893364758DACBAA63BED8B3D8D4DE1E4A76442D207EFD647078CA9CDF7800804012D4EC23BA14C99666610A22DA87523E4E5E41A6698E5235743A9B9E1C4795F38AE20CBE5C3A2111ABA307C3BA6E03F092E96AC6EF297548A3F144ECF7F643EF19024B2E98B51173450ED06ED68EFFA06EFD60721E73C9C6993F14C00E3E4BE441791C648110F699AB5089D7CD092AAD82AE007C0C3C8659506D5F2817E75EAE8B803734822A2526861036E35C3689EDCBA348A7A2E4BE2F1E291F63473988AFFE650C1BC49CDEA3875DF4E6B541727B5AA6F04C9C1E4D06BC5CC744D1B955958E2578C6176AFD7E3262CCBC0F6FA21596BDC36349BF9329BCBA08FFF934E31DC1FEDB7D7F6B459BB1A0165043B902D600C447792A618B77C1671E5793473DED54FB3322180F198873E306E1F8BD17BE04FCD3CF4D6A9201B9B804BBC772B742097663C42F0FEE3766B3B205F14A39D6ABA56963D03DCDF538ECFB8A7AE64DA3C116BFC09506BACF5E8B5754B220F7CF70C5AA4492AB72D20CF8F4966A114833B057662EC63B9570D9B2DCEAC86590569934F91A61A03E18835E31ADBC2EED3BE0BC148FF004675C9555C901B280BFB56FF8A1C079E1F290C67FD1B7E53A6C27A5C649ECA9EEF836621F9E708EB84B6F5C529ED2F07BF0A6160154F41F323DFF8A498177FD09D22DB15A273F787529852D898A6DF0FDBEBEFBA3F3B602B1E67352224860125216AD6D68CA891606E179FB415DE4B95484CA6907319438F69337316203F06AB1488A471924545C81A470D78E2EA29AAF89E94920AC4B0E7F2FE01092BC8CF3839480A02C0E8DAC1E864C9BFF5CBF46C0FC7B6A01FF0DBBCF96E3585496C392C6496D06C44765878B26B6DFF2C2FEC20F26A9A2706838A2048E579C65F3BDDEFC58C89D8830FB8C75FAF96788998DD200D48189C3B59B41501BD310420DB96F7CC5B61A2EAF88B498ACD890F7DF623A35479472694CDDA58C000D9BC04FD903E4AB88A2E757700FF3F460F075F9876DB3F76F17003E01DC96A92543DCDFCD7EFC86A5C0DF387A50ABB69953D6DC19A699CD225941F82438A8EB7889B212F65ECA7399F89CA0D9B9915E827D2E520B6D481C27D4CD833EE7D985B20FA5BF7A21E4DFCAD092628EC0A6E2DC876E4C5BF248F94C2ADB3D6C9F23C3E70D1F611A2041C7759317B8EC1696B2632CA10CEFA498D7571D016E102DAC10051DAD086BEC58AD5DDFD7988C5F433DE87C314E3930FFF937A6E0C81787F04B77F893287AB63125CAB8B7460F119D03BF3076A98FF029EA5022201DD54C854711B8BE718EE678544B51AB13B7ED0262C8180C2F36CBAB64D862D38AD7D8172AD8BA3380706D52048826CAC611B07468967CA4A4DB52628A2FD56DD3A323382E5DB171811EA861E2D46537D0A4E545C65F238380083A064421DC7CE13EC2F715580924D9B6EFBDBB0D45AD8952F602BDED6455C0BC2734CB135B79966464546A261D0A551DEB43E5AE111CD02D0F2F2E996454DE17B471C6103D851CCE2E1FEDBB828C7F4EE66053A57831C708C377FDC6FDF037F400A09E9A610350BE6C013239D7F1C42758CA84B428EB06C6A6A3E05F10FED769CEE2D8EDC3EEA29204605005468B0366B2E957A7A55FBCC7842598F55021E58DBEEF44C5313226E6E56A2D3837F2A098C94BEC791737F355E6CE5643C954C4719C6C1C939B7716A29191CF0530BC2E78CD028D526EC286FCF02B18A077C86BC54F078A19A529F6EAF69D5562D4B31E4CE3B953A24655429BDBAEB5378C13E5B404A138B2B5473A415EA236245B0541B6D92F384D4CE63680ED5A6C035FFFC663C893C8F51C5DEC6F90D33573A05CBAED63B69079EE77DBDD21AD7A778B37EA5E0543BBDCD47497F355B1B2D8AD93DF4BB96A5E85A2344192B782D54C4C8DF251BD5F72EC415621FCE91148DB266EE1BDA0885827E96E8A9AD9C50F43D947DFA8260661FC9326B9E76214D36B22172C026EC12E04ADE3C62D4E957AAAAE686D350793BC6E9C862D968C0E56B3160B5C70520E9AC7767AD2BD8D1D6DC951A23BE9FAF9DBFF407E7766C84CCC3F281C6383079DC3188FBE8F9675D0A26831EC44071AC6184AACBFA0A2326D7EF097650C1D4D1E58134408C11E839A0DBA17CAC9DE3B437E697663AC136380D0690DA4A52070A2DC552275BA09C01B601D55E97AD7DE83A32B962D0A9053C1533600FEFD1171C638A50922B9962C195551F81FE80BE28342A13ED0B25FF8986E0E9C39F3C2F29B9F40AADF8CF61E879A7FC863B32F02C5B5BE16F0E2CF00F30E312820E84D09BDF073E0B16B1F32C73F0E6031DCB3221DDC48670D0F2DF9A8065BD027C30DCF9F12782C812753F109615828997768C75660D469691278A111D50A72CEE9600124E3850507C0B963E9121C8B28262B6C82510AC69F4785752AE1F619E3D334170A4ADB4DAF3138AE90AAF8D82573E7AD25A16243E16650219C47F4CEBE6915B433B0ED0354EE62FABFD3E118AC777A63316637DA755A99AF97DFE9857B2F58A83ED70041EDBC49997EC93C03A7D55524CCFFF8018EE1A587AAB9FB5D3E33FE7BAF2642CF9421540C134F9BDE458A65E6B9BB209359F7FA47B95EBB79C83F329ECF88C7541446868CEF363218841F55D346A2B714DD48C711555BB25B1CCEFA6199A0E7646646B667634E486116C0AAD7E977C091A5EA356778C299EFFB7DBD3232C4B73B54C796BD1E33284CC8E4354C772DF1CCF762F615715FAA903D1551A67965FED6C7E1ED7BABB9325AC30F92305FC284724C59079B11D1A0E32F4665AD8390B34968D1885C9EB8BC5DDF63D7858E042CF7C66FF5E36365F1C7156C79CCDF596EFA551E203456E5BB22C2D9B742F490824B1D5EE482F335393E34E69C7820A639858C6EFFC2E8377876E461788FD2736A2D1BAAA432B008850BBB44FA193DC54757D8C75760638A12DFB614580A882EBD945716D7A3D3D29396D4A0D267B07B035EC001CF29C87E23D8446E21D604BCAB110869FFA98C32E35A9B6C878360FD7BF8D564B09384D5C52ED4FF586D6CC300F09F878FF5FDD7E7BFD0AC3AA2AEC0C223DE23D190C6F67AFF7C00001F7DE39C907235BF8D5EC16A34AD2D2E6DDC419F5B24EACE1A17BEF5CC52AAA05F04D5AA8BB018210354282E98DABB918100165E7D962A6F396F22753B1FB928AE3576A91CE62216E9E6214ABFF91FCA2E6E77611AD13F70CC87E67A1E6D886120CD2C2404E0312A57635D1C2524C97EC0BDD9DE011D158F8FCA7AD1A20C9BE0F45E814C954FBA214F3D3089AC4D01ACBCDB25B9331558FE1D29E67628E13BFC928F7A9A88D13E0759B77674C3F2795CDFE0C6617022F9C6A87B60C4B5A69E8D1706749FB0B4E086C94B5BFC16CC3B34FF3B7EC227A5CC646E9A003E5D897871067191AD1F8A8C33A0E567F4DF2D91D00FEA00B152183D202BD72DC0694F16ADFDD6E44A248D80FC6609E601CB91EE691C4535CD80BECFF9F23F32BAB5F106234A8867CAC0B5269CA2BC588E48AF922B5917BB6813E9D1005F35CCBFDFD419404B59A84497BCAD743384461F24267C497A932411B690BF405A7ADCA63858F439B123201F41AAAAA4D0A478101EDC6AD214E025B5DB6D24021464C53FB376503B6CAF4E4D4974E072F8C88A7C61957239581B589ED8D1753844ED928642CF96E5ACCA32E69B52CFA3AF54B9FF793E7553CBE16C4F9DD6114D1357E539C238AAA4434C5E540AB31FA584B82AFBF419DC51D6B08FEBE34B7991EBF2A82FF8E94990BFD02764F7D1DC049A635A08B7BFDB46A521170B6B8BD940883CD4505224D9DF930E33C5827E303083CAC4F846D9CB9A6E3FF57E755C7CCA541DF51819C5A52BDFDF005217000967A2776F51217813B2FFC509EE35F8AED6481BBFF5D5E61732BA17C90FBBCE1FC29E8DE849C146642845F982A2F766DFC0A703B5BB612E4C2B8CC426BB56196D714FC6F1BCAA0F19F32CBC06C3DD1406B591D2B0CD0E834D003CE56313B66C224594354866598118C87C1A86F7D247593846100395EE6303E54D130F91FDF81D0DFD021C274AA9567B9F9A500F35507519BCC25535407E419B52FA4D9ECD3D53F467B6295505DE979CBF6C7BC909812265ED65B30269FA1500264347FBCF1CB34AC5A405F208E73DD503D0D0E15FA474802F273C76C3D3DF98070BF3151D5D338DB368DA0D2280BD821880265763EAB2076766540EB9A51EAE647B96CA4326C82626DBCFCA1B3FF6DBA63DD64AEEA6741FA49E358E97D8F60C7F1A56248E8CE18933CD6F850E667134F69176DFBE2A4FC259994ADE12676F63D483FE16F7658F1003C1561B8D46FEA0888D2C82A4254AEB9E4104B9FBC973CF836BCAB5E263240ED9D87E9C434DC66E8F4A7B73EAEB30BB745F4094A4B82EC96CF99219F557ADEFA605DDE957CAD9D5343558A9A0904575A7A954948DC927E71786394DF40E9328C9B4382CF4FD8423B97088BB07CB4B257E5AC7B817088C3A6912441992153D374D477EA4EFD21C9F706D3619634AF7DB364F5FE73D12FF9623B665980B98E83991215E188462A57C4B3F653E11B4B1E16522CD421105A1FE67AD0F58F3D4AD34A8BDDEC13454EFD5FAC6146012476391769D4AAD22B1A0BD1CE9599600EEDD95DD265C4640CB064F92C22B0C45C64FC411375852E596F268EB415B03DA88ABF9A089EDCC5F06ABBD96E1BA461D4DFB3772938CCBE093AF922F5CE290295EBA2289660868ED4B6AE38B28B1ABAA06B66BB97A5396218691B13D099ACB89D6754517372564CAB054763190677139C9E2F0BA2FB19D0471E49BF6A0DFF2F951A414ED5D0F17C729891F4EF658F19FEB6D31F0BD8EC15DC9F9CC1FD73BBD7A6CA326AB06F55078D4F2F90CF185849567E8C78F2773938A916FDA23279FC3A9D62CE3C3AAD309264EA076635487EDE98CE79ED297D1BA99D96C84EB712CCE028298C8BAF5B5CB3EFB2EB8996EFFF6F7682D6EAFE498B886FFDC157AE3995D8493BC6B51541BE6862B41B5A35AC420D4D120957AC00B6E488AFA394C5C3F99DEDB4BC4AD4127082E44F22194654D3FEF9CFF3AFA66A764864D8344939255F4BD77942D6B2063FA9C0F82DD3B8D9ABF5C633B6CACB152AC09B9DF3BD12770444F99843FD913E2C815368910DECDB46DC4E13EF2E89AC3FC7D13749B88197F633BB6044E1EA0FF4CE060C7F426D01D0CE94833304CDEE3C857FC7258DB654F49E7C949C4D4B2DDD689DEA7E0C526E694B5EF77F8DBCC199F73D833C54C6C389C9C63A9E203FDF4389D83A4DF4AD86D7B36D3847C8DA829E04E31BD81791E403D6098AE9DA476D75B357A74FBE2F0C42FADDA27AC72B653FD87A8D1D72E72E2BAF5D852D1FD6DE10D5A6A600C795F65A4A59A00E2C503DA0BAD2344CD62FFFAF6761831AB2CA4055C18294DB1CCAF2BC6A13DB522CA1BFBA9DFCB930E4D6C32EC24DB5A8D5C15398CF2202878D240BEE11756559F26355C059A81765FD0D993FA64887D5CB6EDE1B379B2B8B5D5430F3D7A6ECB8259220DA7C9106CACBA69CF6444192275A2C6EDC588234E8D24985A0770607FE1C4AE8CC7559B3687522EBF7D3CEF0E19B229509D2A247E8650C3676B3B272340EB71C69064FD3CE931406569E7AC1603E49A13BEA93B2892704378ACB4796CEA77687C98E8AAEC3501143271E504408CA5D7ED271C45A1A7637CFABEA8EDFCB11DFF3F8324C8C2C7D9C73A26B8B1C05B6F18013E03928FFFBBB5068FCF4B29FBC21A5819EF85B91B19A5098883EF40D91B7E287749A578E7743680786FCA565BC4D19AAC06BF70C283E7649992BD6BC0305A0A093B75DCFAECD7E049E16F274AA9B017CAF3F5068FECB55C6FA6ED97F64E17CF1CDDDAEDB45036C6B2227A0AD5181AD7389B72C8967B8176E18CAA3506BECFCDFFF15B598C47D10E11E65D9AE8AF9AFC8B189562D98BBB02EE55D0A5C41EEFFD3D6E8EE69878B3A003DE7A52A98978892E51219387C24BAA7A773944F530816FB27BCDCA933370CB340781A70DB5724C597F72F7A34DC05B732FEB79A18171281AB7A94DFCDFC2C96DD00784F2E67D7E56D0F146F1585EAA1448BE1CCAFC6F334CAB07A27E524BEB95E19D426689B900176A70B21E32278F27EA3BAEE623F92B14696CFB1EABA0D90EDC414FAAB03AC0572B4B8836F071A375849BCF46E83A05979A4111167CE5C43F6FF48F386E3E8F92FCA1655E3ADF4C2123DA2C5551E252E9BFD93276B5B2BDADBC8F23C0406875614ABDE72C520002AFE6F55BF1D19ADB7F26D4F71842FC66335FF670C60583CE65DFA6442DC6DD49889C3DA3AAF0FB310C3AD990480EF12059DD23AE881D5A72603F50C7C61626AB2E0BF9C8C198CB0F637EF72954E04DF5956355147B5073EEF3848CE65EBA73E67955A1CFF187CCA758372FB67823E230B05EAA9982488E8D22F6DA1415A731BD0A2B036F858FE16FB4349149B507D9DF770B9F3D3B45ED752EE888F40FEE65C4F3EC6897906303A19863DD968C666AC1980F26D8B574D5A16C95747AA6DB218471551478BF36140DCC5C6B9AECD22944CD2B781A240C914D2BC4B37877709794CA33ABA878615050637B0A0B3F04DE2FCF37A2442A242E6C97398CF483260BE8A092F998EEA5FB5519EB25BB10B9350AC7F6948CE13DC282ADFD3A251C07E32A25A8A93276A563755B3164C0A9510260425ACDC093CBDBC6C8C5D0FEC94A6DDB415C80D45BF9A6D8DCDA606E3204EEF6AA291AAC9AF7122810A77E0E1160A461AED63687B3C137EC40897B972493F33636B2CFF07747A394747C0887C0402CC4F50E78F70785E5DA4C6084BFD7AE379F0AADBA0CBADF8C70C34FA7A6B0C14F32D52FE8AC726F750DDDA95C741131C7F692CAF7A3A80173479690A3CC0A93D1823BA1AFD5634A9D14E17E7858221497CE6934D7630E73D615127209FA239A190EB60B4D49770A1122DE7ED76708CB660EC4E52900D130C9A4638448CBFB16B1943D7C007D521F945D00D42CD0AE51FA89D5BBB9DC68360C2551D3A0E08CB0025B061057FEA0855305C0F6496903EC94DDF067E722AE07D06AD5AC67A1B5A9D1D036F4D157220087AB098F2C6A911F710332AC3AF782A6747B8E079F12A768B9372BAA222EF43084F65A46EFBDC5D8BE794084FEDD23BB2BE82A7FD1C5FCCCA0E10FFF7CD47FE805A43F82E73773670C4F43571767DB9F9A59A16B1C6DFF3AEB739FDFDCEE27D8699BC080B9D5973F30BD546DAC6DE594F91E5C2F0DF432099D949C5FD0E9ED66BA4FD37F77CBBA8D511A0D712DD62859D6E3C0177A264EDC37393FA86D8BB241B13A2023CECC4A8A57242DA1C7BB796DB4B50197F8E7DE6FD645C6B9099D6F76701B0A36CF2DBC1C9E2F56AC8CB222D37682E19D33A1728916687BE117E14BC7D137CE28948A0997FD9B25545316DC91AF2780D34EB5D9A262B327FE0E57AF30D9299C1CDD7FF92E3CF8C70A9CBA640A71425B164DE8D2D0D78A19853125F684FB1E94D7D02473BF12C6537595311354BAB832C69593F4195132C6552176CD781A04D4293BB9E329B78AE8929A249AAC01C5C81DC46DF707C914E08A642BF4B0277302BBFE3950EAB036CEABBDDED57D2AB2DAC00B61474150F0F641A571573A79C7CEFE5B1E08C2A0D7C144D69764BBAAA9DA45E8C1CE02AD4BDA14E86E6F4509823913D553117C25BA7727244D0A5F4106962D2441C4D3813A780757E169AB7DA6FAE572D7CB919DF7BA028ADD524236473F8CEC4509FA954310D970F13B8F57505F248413F93CCEB0D2A8B81A3B6B812422E630863D5F37142EC8B03444B7509B92C2C46E8B7DB79679EE93FFC1DF1B807E29773C0B9A280334CD97CFFA2AEAACDA2A662F8767A323DA9D48CBCD419ACB2EF27A01A26F7F2968B572B679155717F7AE7CF17987EEBF9B088B153D06F88F683CD8A53B1D69CA429BC5D17DFF465377F6895611C319A8C8BC23438BED492817703D83BDBB93CD491EA8C39122ACD809BA158D5951E0B78FA5409E63E7CC69B5B6BC9BC56349CAFB05B71BD8C8ACC90F929F58037617118351CC1E0E0B3CC4040BCAB505CA4AA36C06277B4D550922DC424A005854FEA6EBE6C833980D3F7D49F38F595E3B156B89809B65E62B57E0C79947B2EC463027DE21FECA9FBEE0CD5B8EC64BB776FC95D93232C53A5A5D8F5954AD65E6BA6A3677C62497C3F4DD408AB08F2B05E00F865CAC6983159D2E4EB54EC0B89384F890E6033F71C5C888A9EF25C2E5563F4B79CF7F80E221C59FCC0CBA7A56ACA182D6A22A77AFBDD2209D5BBE8400605B918912E1F8268EEA13534E86FE8B6588ACF64A1322DFBA8990E280AD5A2E185DC29AE3AB7AEDEBDFF8932A21ECB57071D2C6207740AB48DA0286EBABE44AB1566D845A6B231073076634B6493FF5F4669CE06BB0BEB477C3BF2F9173ED7A36C22EB347036E7358BB62192E4E7BF5B9515C6A433D21E47F56C886AF92422741D1CA07EEB3A67A027283E78A27B64C89AC0EDF6D3CA5AAB03AB2437B7813BC5E349434386F00F0C0D592256BB28E68D0ADD1F23F001F2F0DC867BE42CFB316FCC3AB7F2ADE8F262E2F2A817435D72D2B9F181E285F7D58C2E9D0ADCA7E67933CEE6F908BBF182523A0367EC978CAC6373140022E3B851EBAE9D7086C4191C0BB856FBA1C5785F57A555985D0060A4BD79FC0FBD7798CE46C543B3D26C62BF07B7FFC0C5CB00729D2F9DC75A8A308AD312EFDB71DCF069034FB4F970969B749BD6F487F5E77627FFA00F64DBCF819A4F8EC0681AC3816282EC1717DA96444B3EC00B32B8C07E806988EEE0B8CEAF0CEED4F400F27F1D79267AA4BA333E61B84E6F10222FDEAF05D3561F5796CD819C879A07E780BAE63E780C05F024F2880EBCAEA6C1C8258D94B753BEED298829CF221BEEFF249643A4915D5C0E8AEAD2C85ED170790074EEC22327260470E99DD940227A671D56A9204224861E56624244241513ED4AC7117ABD09523C29C4F23E0C41900011215540597EC1BF8516CD28C228D03F8C7A65E4FFE575C6F5FB1F833B04F3DD1FE2DA3F983FC8A6BEE8CD7FDCFBB4436D8E8F09D466CA0129B4080F5C4D2A078B1CA2BAB5B306B26B4F75F49335E128D5E27B6FE1D96B9B863268E813A092C5176087562125530D23E8F6D61D99ABF133B032021530A5FBD7CAA65063B17304B76498D90B0F3E6541534667952F6B31A74394000AA731CD42D2CAB1EF3AD7AADBAEC7541D04E60B843FD337D7D08B9991452889376EB57FFC5D2D454B35DE0BE42E0B04E5C21D950E809C5D499AC04DE0E4FF912237DD83AF0FFC5CB8E520493400C91235F9D49BB30724098295713F70ACB57194F53B656D4B3E5879E2E28734370A052FE51C8139021ADD0DFC6D3D8491AE9C7C8E3AEF6A5C1E119D65923212BFDC35792BB5E3109BC36003C17100DF5302C7FE73ADA012B36AFA5452CFE356C38E63C59E80C1F3FAA1735150F1F3CE87E7008281D125FE7627B3D6C8DB3A2101DD6D650656EE5B8E0E8F0CA1DBEE12303499B6CECE8AC80111C504804F9ABF9C616D22DF34FBDAF27290F4FE6675D4A1FBE8A93A91C6B09B1456828554CD0CDA039569E2C08430C3481E2970BA760DA29C31944AF18085694530E8A952B54516062CD9528A95D0772323B4B8E02C7DCBD71FFD2236E772268E25F6D4C622F07F5D437275B2FEBECE7605967771BFA2007FECA33154FB46A3B788E9E7702F38BCDF175EFE4611B61147D89195BE90840FB1E365A76840BD9B40C21949F2D41205A491C019B7F49139CC46002B5B7260F47253C1A5AC8745639F0E1833808F7CA27BD437569D38D2C4AFCC5293E6C221D9872EEA5B33A43C5217438DFADAAD8F243DDD779FBCF4E95C6E4CA4E11125F9FFA93A4F04D385175435E391A7DD4C026ACF110F0B0CCDEECB8DC1ED8C24AAC7B3499C0DFE478F292B8B46DBD70451F459D0C5487C973DB0D19E196A66DC3D611D3BE4DDE59128AA6229BA0CDD9077B20F9E03145EEA04CD0B2FBB5EF90D327C1030B15DC8B5CD259EBFBF04A5EC67C741F6D38180F9B0F1FFB97CA1D0C0C5C6C791CC92908B44374BE315D4545F5F7C10DEB4E94B676D47D08C4A0C7466803F767C8A42BB0B74B6E85E11C6BB5C7EC3A8D543C703095F2077FE89A6CD8F450DDAD4007C1EFF0E0CCE2ED78F8CBA8FA0724D395C8B7714EB2CD2BB4CCFF497F09661F28A04B7AE27C8324FB4840336EB48BDFAA240A39BE662A93F5B12682E80964A14E32F9513051FCACDFB4AF64D835A1BDC643D421C9C667F7EFF4E56A7988FB757281563991D1C6B5B0C97E1C38B9185D049B4A95124E6248DCE7073EE9544DBD370AEFD8291D1016D0995320B2675D300A28C061555D9F29925CB9BD253D214E1D4FF9141467FA3449674A71A800985A0656EA2EE415366F474DA24B9C899F26B072E7244E7CB2E76890A89D42E6B9B0AECBB5180D6EB2D34954D4098D10A36511465340E3245A716C3D37A619D0E36E129A92C205579A7AB47A6284C06E7984C714DA51CD825033C241C11CAA0F2A930DBA13A28BBEADE973C6E8A838A62E04B1A5AEC0C72A4A2B73EE9925DCFDEC7C65CCD3D4EB65621EB7C90BAC3D36D8BC3427E0DEB8F253E221605ACCD5F6DD73A50FE09215DAE82AAB23DF4B86910EC72E3EE515A746FFE7CF903077F4D13B59226DF6D94A528F57E13D741DF28C45A072A41C01CBE1EF6587D9664CDF4B8A3E2215F667E2970A841EE78F7E14CB1839199163AA591EE9A2B5AC639623254BA87A216FAA462C5F9F8A74E97C24FCBB3D53152ACDCAC8A32D5A18C890004471F9A43AFEB325C767807C66EEECA54A594567AD7D4E9135DFD212A01536B32D590B9F662C17AB9784D8603C618375383BE8FA258651259EFEC97CFC616C218E4BF54A8D84E4DB080BF25650D8F522CBC33DA5BAD3144C134547AE090930BADD38EE0EA02733B057F0CEC2AE05FAF9E494813DDC49DFBE8557E80650120EB1C9003A5F57D330888C56802199C89EBA3DC085ED5DE5C0E469686850AAA7C9DBFDB47C563AA9660B079A7E23187A2E8C57AEF291FA99B0EFFE67A6D43233D7F84A9E385403DC49997BCCC69F0CB3C6F707ADD2FE0CFCBA5410DF3735306F9D2029872992C772EC24635DA6C73628A1F5789ED2E5D91CB41F2C8DCDFE641A1361AB283A0BE8446A5CA187983E34434191C64DA727D6088F90430F1482FBD5B7493E15D3FFEE375680BDBCC812B93CE10FD51BA3A712C3130DE63A77A79DFAE2C946AB370F8700999B0EE37A1B06484CC4D3859A4308DF702D40590C5C14BF8CE6D6D2872A060190B14FA78592DE2D8B0766DDD09276BDBFE487FA6621A5E1108D01787969EB8043B236F8189D2FE9E60E95EC52E69D156E20B435C5DF5A98F25E829EF3C15464D1883277A5EA42AEDC83FEAC327FDD2EE1D9A0331F06DA74BADD8A9F80432CAB5CA1A81FFC79A1F23E604112DEF22E9854468592BD2291664517CB91C80035F1A8DC97A5C8A0501CBBA6F47213D8FE0C556842324BCA2ED74EEFE8F6CC896DD4794478C07BADDD3AF65E580664BF0609BBC243280C3641C9A5803E856525410755770BDA536F0C722612AEE5CB643DE530DDD0F7E68A8EA1FF9D1F08751BF99CB8ADE48089343C253794EF22037AC8EA20A28A22242EDB9F9A682F23D5E51E05CF68DEDC4E4BBF593DAEB24E2CC69A08F35106558D22DEFA9A696B6014DDD99FF8BC35E8DF6C2FE76F162F81682294A1D9444B9632F63144C0909890A934450E27DEB72E943076414576575834941A21152A535BF404B71F18CB4851C70FF3E167E65071236844BE4785D1AA773D641207323BEDAA64571D2EFEE19A59933F3EF8E7AF86C5C9C795E88322185CA8CEAD78CE097951B57CFFC98D9B4BC920AA3E67F502CA5C4A9DA541608647C8D7C6B8CF46C573F1C1EB086D416B2E20CE3B9F1F2C3193F9D3EED04E9AAE230EDADAF0ED5A297640AC642AB70494A6006DBE0F242DC002CEA1CA8C9578ABAFD7709B58C579E2A7C2DAEE05242D8F1A26F0B96442D65227084668FE64EBC1F31DC6D7EC5C0ED61307B70452A8B5B846B5CF3AA859F0B0ECABD6082429EC6C5C9F757BAA27F52693004B19D35A675CA00FD42ACEAE5AE07C6286F48AC02AE2E43BCA4DDB0982A40B411A23990864378836BEE832ACAF1A4BABFA6C3483A9CAA663ACE89844197AF9496D43FEB39053C4A03F04FD4E1DDCF130DC450C3AA99F85B34E54E4B7F372F8C6AFF5A17385B637169C396C230CBDC45B7452354F797446F75956ECE0CE4620EF515A6EDB2CBA3C01573E293A17A22A5C33EB367A8A9E331927DFC1697BEA0E9F6EC1303D6E63179A7ECF68B5865C5B12D79AB95B5E419C45EA2A117F233E6AB777BF3041268F9AF8F0337A989C1A24686B127A0AB21486A023E85C511351C7C5982B01484868342098EE2FEFFCF1339CA74F569E89F32EFDB11DCFD33EA1245ADC75BFBEA4D1CC707F7D52229A286A1BD4D4E69BCA878C62A8FFFCD096A741F8BE4B17E069899EC20C66C23DBB9571116C105814BF5CDBD71AFF209F55EA526D91858332457A486DCE7F4A5C46EB3FC8673D6CB46E2DE3098F22AE17745AB0BFD6A4E57CFE6D7317875912BE641651D98E70C940F7FE1BF9882AE12A52B76BA21255AA0CCF272F8215FDB211A506AFE5AAC69D951DD8449A5527DD2617DDA35CB1FCFDFAF6322DE113D48678405CA1E68B6DB9F005DD80FD447E045D6A5D3DC719EDB0223F14F92370E5DE7B22FD0189F6C7CA5FDAC1DFAC8C3525DA00707665040820A763DDB5406DF41C23BEBBE68AAD20F59A5E2539D3EA32A9A717691D72C2FF90173D53FDF598E4BC0790180A6CD182CDC6CA0B5FE69AD663506A6A43EF780D1F2B7E05E904271A587E0619EAB04598E3574C7F271892C3F482D2817BF74FABF9B63E43E74348386C624CD0A73AFF1C917D1DBB8D08BF504299C0DE3E5736BC9E3FAC872BFEBC1E5DDF68D69EB0572AF7243E531157C9EA81ED640B87BC14A959FBCC7658CB5BDF6E87F4E677011FACFEF3932CF353D6721124F8E8F2998DC06D262729071FD56F1FA76524815E4552548FD48EB6695B81C07A716E2D4BEB22348B4FD554A0A2ED702E6E2A51C1B621C6D6DF7C675D0169DE88A85F0E45BFC398D5FB2BEA9958DB9F05A82B5CC3CAD980B25415409DB4C0EA1B15F249A4ECE2CC71449C9219411CC81AF35468A8D4320B36328298CBEA852800113F9DC6A6E727B340FD8516277E3540A9950E5A8E64F0050AF7F9707389874BE4A616DDBD017CC0216DAF1D270EEF9605B26A588A285736B3574E6AA3B6F197DFD451FCC03F2B4F1788C1F4EC59BAC79BCEBA3253E8DB04357AACBB468E9C8A714366CA216EA44A764DE67989D504A8F721098CD0AB285456D21AD99BD11DA30A83054BA40BE695EF6C298E22F8D7269E995C5397DB95B5A56AF5D9BAAFEF08166AEFDE6612FB700BD797B26F6DAA7DA1A3ED773ADDFF19C592AE7C3FB87268406DB5B9BFD98D4C8CA02A18ECBAAF3FF88F7DB93E06A445BEA851E75CA4B8011F3A2E3F57286D691667E3C2DC11419B7DA22B5AED705CAF0B8EDC70F438D57D4D549D41F07955EC3E339042D11F17792EB71D8C3B9C464B54B35BE2D45A3E07EDCA62F86CCC96C6968C567730E3845D4C8B8D6675606C6994DFE5569260BD2943AA189AF3A3EFC8F63FEA89B71F2191A7BAB25BDDB5A02FABF7224243FE5C6CAAD0F7CC66A6C6FD9754F700E4DA2548843949C7F02CAD107FDCAB04204637D6714789155D2C61AD3930D6F8586EF5DB5515F673A8AEEEC8C9590598B16CBF84032545AD5C1BDFD11A92093B0B0B48DD98EA963E208A43E5857A0722C3A641E60C7C398D15084D8C4B35F4A3146E77AB439985209AD99296A12BAEE3C3F3E994E76387D15C2FAEBFF7B44BBCA08A9937E74F9CC01613A5A2745C3F3E0473373EB1E6B4E29188477CA96845A7B24C232F8FB9E405C715E3E8DB593B14FDBAB225165BF0B0612BE50214598D943BE032FE5D5D9A33C23BF8EA48A5FF6BFB80316B5314A9D73C07D8022D3431CDED66AE8326EF049B2DCA5E63C6354666D1656A46BD5C8B430A157A43FAB904BE87F7773F5683949A416510B361ED60D700387A5E1AF0DDBBE08017270673ECEA9FE1F59A4859E7C097B806B79019C7056E6B1B8C2B43D41F78389A1422EDD4FF13239F36C54673118333E1DCDEC960A524F3D9E3E4BA1DD9B62917E8820249A397DA3DFC9417652F02EC8995851FBBB668330EC8EF6F89F77928F54628F6E3AAF55940E6F73720533FC39AC2CAB0C8495FE09563D4A0B22C628DAA66D06855CC24E85F9BA30046A79BE4EFD1B9DCC6E098DF8EA4055B19871F55F71A07138F7ECE919D3F6EC059DE0A7A363C0E63A16FD8A9944150D65F56D4A0D1CE83CF4DFA3B79A87A3CA9D003CB578B0A862E8A8309A9F8617CD5D7D1634766ABA5CF5181B2DEFD4CAD9A1F8F2148FB137CE27EC8E62771F46E7A8AD1B370474B1BFF0A634408D56E33EBA8C4F4BA282D716E03FE0799D012C1B9D3F1EE3D223E3D30F3020C0E026604FF5BA9CA8F25CB0C6D1C7835F66BD1FECCB77B911C259394E8D6582ED0B83A44776DCCFD677E7CA0352569B227DAE57777BF15464A8C91A01547BF754178888EEE0274A0EAB6503A50905C3D04CBF80E39F5EDA193CBB574D9141AA553186CBF7934E9AD2A2FA730599D2910DC1CFC2AA8DAD926C58385BEE6F37203F94E5DF5688B9FE0DE1F67956CF2D7872A9A256382165A8572BDF85F083A94A94E4C08ED85FB17F2BFDDFCD4DCFC86CF4E608A6CE1E6615DD4EE79BEA7BEAB94B696F8EC236133067FA6417895B911914FC39971AABD1C5ADF8A1B46B34647599252EDB50610E4403CF05AEA437D1B23FC22BA4AFDC836FA167791D3703FE28BF015C7BA755FEE0FD33211AEA356FFCC38720D04F325DCBF5415037A0EACF799165D590D36F036E0778963F1B9B059A479E0E6A8BBF826B0D55399B8CFFFCAD4CCF859B7C226AAF04BBCF49260F242FE7665B72AE5B1AEBE3AD1C4FDE360C56F2A9F719E8B5A4679D3700F8483C54FC2CF99AF9814FBCCDF46A85A5359359040473A71AED3199AC0283983D8595ED6169FBEBCC92BF9CCC7A687B173193BBB636DC889ED448C942FD52BB8EE81BA817C800285CDBF370502BEE6273611ADC1EEB4EBF9A625AE0EFFA97DE9D0E5DE3BC4CE8B8CB1E07E79578BBB65984464F724E34FDD3E2B37D65886782874AEE3C700754D7EA76555F6A37BE99C25D3F7924B9F5C15D6D36E6F709AE41775902710A12E5568115101E6ECB68CEFC6C1E3EAFAD850677F925293937A7CBF1B545E56E20AF68ECB04595F8104D942BB3961B39997A8401107E938F74D6DA03821E8FC12D25B83958E720E544BC10D4DAF73F34BD23E19E52E2A3D675558BA09A6B9BF36EC3EB3EDA9E0F4CCA329BD2FE20482B7C424CD1A765DB6CDC7A5C3A0635A7F48F9FCAFF2245B13B6A91BB666DC0B131E4754C2D2C1E623122E73ED103B87DC55CB62A152DE41ECA29FF4DE07A3E3F85398A14FDF1FDB85C1A6202C0C5564C3F66796B7FB9D9481861271901B8281991A9F6F66DB8DD2ACA5B9E5FDF4197D61815E423A4C1DD61233E06C3499034CBD2490FB22660A966D4D7882FDE18CC041294B9758A5544F3A697CA7BCDAC81EF742221F56EEF86CC2999CE0C55503533CF7AC81EAE88AE83A835103E91F3AE125F46B3C7ED05B40737AE62DD89B82D90C22BBF36BD4C169A9D9D8FFE33E2E80D503FF0DC214D37EA4B81D9ED2704515C6E5B7CB57AEBB3A912109B8897E271B756C77D8B7C975E3F4697FCF8C1DD1CBBFD52C9F1BBD22E7DB82335E5A6FB849F5531AA9841B92FF1CBE5A34F4E9D5C41565145E2C69AB65196FEAB627BED94F77407F7A180F1AFC4E9D03988507831848F23AFD2CBAAA6422389D64C1667CCF290724D58E28B2B74D70771682F70492AFDB247A3C118572BA5DBAB9BB2E4ADA05E0D78C79F0A2F97AD053E87B43C8755A7B2C217340C81D5BAC243B9DC51236BB7977C2F84D6E76CB4A42F0E5A9ACBBA9A6E6568753C7B8E4AEAB9B1DCE5052A2971003750085CB05B68E6E9E126AD5BE084FECDF62C8AEDC63A920DA15D1A3B4C5CAD650A2DB43D93EDAD2E498B0ABA4071B75F8DDE617299C990E6979D860461342EF7D52E632ED2C78AE41EB9ED9ECBDB9CEC925EF47CF57E413BD7A4B9A71E6236CAA1AAFFF8A8066E50E19D3CEA70F910537B76B350CC194B2804C1458A428BDEF11FD82475C579058C996960C0A548BD6BFF0959720C43E6AF1A94BEDBEB922A8B4A02E451E88D4FC8A29B92D66AC1F6BE6802B5CD979480264C1AACA5D6578F44BBE06230CE75105859584EA29D16C20ED4128A0EA85F4CA9A3EBDAD29D0B661D56784E0EC2F04EC2DA448FE96A3B9EAC31A9E53A2925701C52CDF1B19447F23C4BCD507909F3035D1F6BB9BB2074239D339492C6863337869B2855EE7CCDBCC6D4FD9131576DBD7B0B475C51970D3740D8F232724BF53C09325303CCC41645694D6A9F7A43A93464507BCA194F2E1C8159821D1DC950A3CB5E9D1FD829222E52ECB1AA5BE3FFB693766886FE328B33CF44ED3FECFA0D2EE91EC515A59B419D903524112CF788ECEBB117241C61FFB84E266905B4EADF0606D1F070C1FB0BAD9EE87EDABBAC32AFDEB276E3C63E1CF73C55FC76ECD8A275FC17BE731FD1983956B1454E5611192EE16996A744DBBDC88BB1E309425A23FD480477997C6A27B780396D4CE034063BD1684CDF49B42ED5D23FE2C36A8CFB0BCC4F8F3D029C5F233C9D28ECCB8EAD8ABBDDAC297371916B0F0025151DE512FBE03163D09E73776F09C5EB535A2C81CE454EFD21E27A51E8E746E018FD19B89B74923CB2C6136061B6F94ECF88BE57540FB784ED209BDF98BEFA822205B6EB9BA7C43DBF10E82A000DCEFB30E1B46ED4753F45F568368AF289D9B257609B81392354313ED12A0782ED0DA12049D4C3633639CE970D733B213C8D40A29BE5BF69EAE20F568BFC3E6755A423E22D68963FC2C85979FAA14F895FAE3A46ED30FF96D3ACE7B8A16B8527607915A8DFD7BC9ACB0B27E06A8F22E2FF223DF6826348E96F2D1F74995F0CE064B45B4944053E3FBAB1AB2336AB869C53B3CF65E3FED0C5B41B9B7860EF3427219FB2F47AECFEBBE00DA51FC22CD074FDD84990C1B70ABA87FE2FD5EEAA5A7E6D1B88CCF9AF31D6363DB8BF9728077B7D07B254CD768EB3E107C729BE3D2AD1146237B9FB53B4F9BFC4296099E94D35CD1B358123B1D28D78D010098ED1CADA99F82F5A0747DBF6D342922274658FBE819DB904D59977046F5636318DDE0CC440AC3C0474712B8FA488CA585DD81A7DE27EFE65EAB1BFA52A8CD16FBE2F56A131C86C7DD1F713BE0F5A6D0938891049CB452DCDD744665682C0E1F68EF9ACD4DE6776618492E822E5030D018443802B916A25A62DF68B95F847AD787C0848D2609487993893EA08733CFF496BE0FB34B21DD51F10A071C44837B9676A6F7343D5A2445F4B75314FAEF07E3E40EFEF20A32F8CDF8F82A1BDDBC7F96DCB3640F298C34D5DC72F7F262C8C8559066A4F0BBEC31B2AEC81F2BF690D4ABBDC56B7839666A5BE71743B38812645904BD1D1A9388FC18BD9EE7DD0C4DF20AF8AD4B50886867F0EE7B6C9ACAE5EE58ED2190D2C2637765F4D2784BC8DB292A12F297D2E905D1432DF48FA6F0EC3DB1612AF65B6BDC2B58EBADBF411C323CA09AE4B56ABBDA4452A2018FA5687720FF761AF1295968023628AED87B51716FF33AA80E4E931FBEABF76227337499829A6D79C7C6DACDAEF490CF021210DFFD0C27FAAA7F09BD37C5BC07B55A2E621C9AA9BE12598EA98AACBBAE1981C51F76C5D4E48693EAFC22BE0891F74BE3A115CD68FFBE55188A043D013B741044E59B3165C5A62BCEE94543B637E8E0808D64C228123E402CC047C45D9F63CB3E6F5CDE58F0199666F39280641623F48CB1EE9E76DBE6DE0986C71A3C91C8A82D51252D473A42CF4223B6045A73D9AA9F061BAA949660B1BA38BA3F4B9A2FAC838D2A386601DCFCD6F361DCFFF555FC9348735C1844E957DCFE0C7DDEA5EE03822A3A5E17D07419AACCA1E59E4E3B726D68E2EFE10394160B897C2CAA9A6AE2D7F9ABF852E7042B3B276941D5453909C2E9D80E0858769266731B99A4599B172A6CC20D7DC1F8478BBC5EC2EC8E387F88A63144DA10E09F17765C15694945C8496386AD0B83F7589DA9BA60888572B16ADF404D223FDE1B4D55E5D8B5D3CE2F5A492BF3B17748DA28B43216700BDB1352907E1AB5438AB1EE224749862D36524ED24C724940B38866C531CACDFFE38755A65375579021316511987CA6EF0B03F6E2D82A6B7D4CD8E310EF5FEA12B7D84A0CEADBAE39FAA04460E04FB2C4B1E759243B11A138063BA9C96242FAFA15FCE06ED9580E29B00F44F3E74A437C9D7541C5E4BDADD92D0179E86F84FA3DBAA8F1CEA1B4A329E56B0595C90B8670F63E942D42A47B30805D770D86F6412CC87AE063DCFCA9C353FDC3E8068E3E5A8E4C3D3B8E48E245B7728D6997FEBBE412C01406D869715AB2FE5432AB89577EFFA2C6FFA435FBA59958FCE9DCB9A3E9A748555AF0CB64D7F0D85ED5FB0AEFB361A411406AF6A34610CA9D280C5AD4ABC8F1B5CC4221FB6323930D8F0F2C7F1E79220144627D49B5D442FAE09A2033E1AEB858CE38A54D7FED0328A06F7075E206FE3434E00F09992C81F902742A2A0688AFFFBE257FDA551C2F0089C72F8B75FAD8787A4DEF71F6B39C2EF08E88A8BB0EDED81B001B29F8BFE1ECC36489135B3672C016052FBB824F4B3077E024794C3D1C1C11EB1C31D78A5F314A8CD10A228280C72E9D697598335D2EB05E256997FEB9977BE8A5F1472E5A7F361FF6520F58ACCB812C16FED197F4A967CDFAEE8DE32C65D6A8E176E776D80EB8069ACAB5DFDB3822EF8057E4222E2AA0A5E90D196DBB334EDAEF375D80D6220B069F0625CDF43727085BB9DD60DF31DBF16FDD02A1D3FD0932C4BC23586592F20C7A411225D44385E8CE6B17C43BB4FA6BC914218D88DD7815963120F630D178B34032FE24EE8C2D5F256D7005FD2FA005DF391923FFDD6B1A02DDE26D301AA91DF609967EFE772EEEA6D271F41F2623DD1096E8656DD44EF4AD4565CC8A6DB0FF5168C9552F9A08F84E91B335F3D18248B6F54F84121E17EF6BD48663A2EC9EAB0D20EF4BD6E27907F5D568F33659B2DCD64A10C82C82BCBDFF5296972DFD8369027198108E537D4F0F151D9E52D24360D381DA74B87E0ADF3119B9A2AD38D7679D60DF92CB86566B14AA71186C40C338B3A396579902434ED860428BBEF6BBA18121004411641C50A92EC832174AD38A679F5A49946EF241A8FA1D26974F9E465B1DB8C6F88D84B62A1507CAD3AF350DBAC43276A87D94FA1C7A9E8488B5E3A2EB66605C69AE4C2D7A551163F85877A81D5B0F988F48A6B2D06C9CB879DA0068CC2B3DBC36C5BD714E30A5021AB48AA57F8372FF8C77C03BFD97F904B50105E63FFAB45BCF5BD6D576C86115E90669BBA2CA946CBF8052D08C3C8F77333196822D3DD10B9955C4D1449F7E4EFC0AF27696929637533689D59BF3B03AE55C835A2AB28022A6738CC5F3FE43BB12DFB8BF1E0137A3CA5ACD5B0493ED71E9B575AFB0D25F8049731C85F50BE87DEBB3CD180077184EEFCC3233072E0A27A9918C0BB6B24E656559D2119391FDF74FA03BF6D982D156E54BCAB37A3F8C7367BA95DE2CB392E6B085E4AB974BADD8A55A4765F42C878E987782A59B9EC7419729869687DA4035147846B227E285AF50DDED91E9333B9EA118AF549280ADFCA75AD6C23B456CF7B222EDA5899E834BDBE2240C534B2ADFEF524AF4906BC66132EBEBCA911CFF0210B634767C0C163B94B169C178F0C7B40C641894A105F375758ED7BA6A1A2B6478F9E97A5D3ABE5F0097F6440F325793571FF212C4C53A38301C3E4D076878270DBFC080448E4BA5F048CCE407F963D2ED434A2AD17385557AEA88525E30E0C3A9D6228B72ED2761315A2EF649E8B483E231B9A21BFBF2F8F07BA5BF89C00E11C239F0C409C769419C748C506D878DF7D0E4F44DBF4900076FE304017BD3D6C87B4C20D92AE90729FC985BE4D9ED63C7FFA978957167E2197452392BD82CF4709A8DCF816C49C6588CECA3D0C1360BCA17F1F152DC439CCC3F153D2DE9771802841FC90943528B2D6FBDD00E88D091B11AF84CC4ED4F1E032180371037A94886F301ED534D63E1B92722954585CD167CAB7145AAC3FA46A692B8A3229D83FF6C34B64C92507F7433140480018374D78FF90BDBAA09354EC34B5AA399C5F2934EFF7131D6668371001A96168A0A8EBF49E6306D7AE4C624372677031109549F426108CA25085C2A40C808B405899C0CE905DAAF47B17617A99849605A619A03A104275AB9DEE9FF17AB747527B28539DDA5BBDD4341BE7B8613562A13CD37C3AE160B616D61C4E9D16ED85AACF2354D61A1506143BBAC9BD6958EF542C3641CEE7DB6A54A4D7251E653EB25E05B4C345FE6D06478E6FD39F73AEE17CDE073BCC7C19D4F239B84E5FD50CF04D928B7486ACF519C68904B838F1268F12C05FB40698585979C59C70AB2124BF99FB97E3CDA3441FDA18AF55DB4E5C39D3D75DE1F6E44950021288572D2F040253FABC31224798CE55E2BCB3BD976A8DCDD7C77A9797265187CD35777453C81286DB5FF66C6B9878619B45EE5BC62FB267615EB970B812A2B19A85B77F12B18D322DBFFE7FF462702C6ACBA478C0596972918F3054C7654A888879412FCE7232F084BC2818AEEC294E52980F854389367943F8C9D77B3050A71A475978C841CB373D37A3960B25BC7A257760C51133CDE7E50B78CF561F1EAB9E9A84B322DCB040FC246239F54DA7D7ADA41FB6026246E81D82E5E7C00487354C4525A8C2FA070963AA0FCE163AF71F5B522C64740D9DE5FD465E328C3F992BD53C2A66F44CD89AB53C19ED320CD6B1C3060A9DB6C3812818ECCDC7B02B9A854D07799F980566B8054045F656EF1989D6120A50395EB1EFDBEA3ED45ABDE671F2ADD8542A87B3727D3391E6125D1D950E0B15A595E23707F2FB9E7C597EBB3C571DD1A5E062A12BF9918DD7CFB06B80B71EE05283EBDA7A6CFE119079C10C55EF683F27CC9D06E85D26900F33188D39D2128B200E648ED30843460DFAEE006423B4D18F37D7AA70CD4209073C6EA812A67DA603A863BAD29A79C993C442BE5968A0DF0B7D26D56ACBD0AFB3ACAE7D42FD1400304AEF11E4D6B5AECD5CB77CC2C6E9FFF03CEBAC5DC54724FDCD47BD4A1D6EC45C6B5A0EFDBD97DCA8BAA7B6CE0F6323FFB6C0099A6414B5CE20A2F0109FC35EB142565EDDEF76754BA999672BCAD22B9849EAED945A7F112F46D9BDDBDE882A4E78DA96D38057DECA09C4BF232C0B89EC9743C6244CA2BFBF52A3285D758250EC4633063E0716962CDE9CD88E346E3579ED9D1F085909BA632EEFBD86536B205359A933F9FD148058D265FFF73902C85455339C92D178C6D26AEECA94375B0A4B7F293E101FF375E263B2561F971D7419983CF733C3BF50D77C4D33CAB9116E8F189A48C00C04AB7CAA471C360C696EEE43DFF6E33DC931ADB4E69806670F365FB97814E9367BE22919DBDE5016CE0F44E0465FBA667E751FCAF2DCDA33E5FC488BF1DD7748897D8C520E4A46FFA8F2A539453328E8C2BA6EAC0ADC1F1188F8D57EF7A28F44F7699CBE83D0E8F2E6AD098B921D1B770C1056BAD3B2B2B7D383E56C935400D84A50431FA94C88A53545656B62BDB67EB7B3E76E0E3BE35B99C529809F59C9FE65F0B19789F758B01C6BAB1A30A8A3FBB28B4EA3E14EC104B9046B70C228503D8E29291818F873DF242A3225C9DC7E1F2C27FFAD83C89C70D03ED21AA0C616137A2C2750A24B30EBBA9875A3074D922076F7D24ECA129549B33016182DE68A235C18AA78A9D27E6732684DAC97320984E441B9F65A5F5230C957B398454E2BA1ADE900CE36CD1A320F81E21FDD36A449A036BFE7410876E0880015BDD895D29AF0F0A9AEF2596BB022CEB44B5DDA25F5BF3EC0EE3AF476E28D5F60F1C8D104003BE1109792D3966DCE207109EF665552ECC29E3C0A887D0811BA980CA96EFDA9B823E1EB1F0E760F0BBB0DC9C8D2919402ACBE08F0E1522838ADAAC6B45CB71611ED85238D2E17907588715D328015A225B713F01300FA5AEF960DA36D4120722ECCBD6886DC08E57A0F68466769636712A361724FB2FBB4AC9775287BFAD7134D577C31170A8A9C39FD5F1557AFCC167B11DA412436F79946BE332F148A72351279E2E1E32522AA8C0731F2F312B893D4F24A35BF2C42279DB8872E70E987CA680DECFB29425A5C51709216A5F69C00166B9C971E9E02B52731AC8DA8988A8A7878CD368085244678777C7C1DC7B0C6340C71FAD6BE4EDB0ADD161D5F701B56E98CEC853AF23B3695AF8CA7493BCB3B405B2A3A5F247FED50EF3F0E5679C2AFA4C2F613AB73CCACDB655A97E00AD5F7F1320468B089D5CAB0CD8F29FD284ED47E7546D39B4D6124B431B7190FE5D5489DF4C39914BFC951CCE080444FDB4D4BFDDDEBF80A22412911D5CB7DF5CCF5434E2E9C7094FF22B5924EB967324E73090832FB75FAB896104DABED028C4D096234B96BEFDEC7E669F850CD731ED2782B60512E2F83B3E063719F2A0F984C9EAB52C8BB7672F4A7E75231855BE3B541BE8BDF4638136802A83225ECB0020B956B690 +remain = 1152921504606846974 +max = 1152921504606846975 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-3_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-3_256.rsp new file mode 100644 index 0000000000..7410c6ae5d --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-3_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHA2_60/3_256 + +pk = 000000065FC7351ADB3E5E78B0A1EA06ED988995BFD8960B36F604AC8F03600F0F15E05004562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 000000060000000000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A5FC7351ADB3E5E78B0A1EA06ED988995BFD8960B36F604AC8F03600F0F15E05004562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5832CE029A1A95FFCBD5C8B157282F7364E680C60B252C49483FCA03529693B074E0D2B1F6DFD6463B974DE6829A616F20C839B0D2B8BE5405623B5B722EF22F7A3BB78E91315F715D9DCDB0C8639CB8A90685BEE7969671789047083CACF24FBC4B601B1B23B2E79E42176B2438CB405BDF46369F4DE5F411B2ACD32BEE3065DF9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD09000000000001D5DA3370DA40FE4B2AA8D93A4C52E009ED16134083746A63365266ED868E33160A0000000000010EB7A75A56A1497F0FC1FE5B3F6B396014CC9357B7FE8A6D2BA1B553EE3518610B0000000000011B23B9B57C09E7B440346ACFAAB7028D8821AF52CA85D5CEEE66FA4E95B45CA40C0000000000016AC8FE7754C3CBB4F71F8514603EAE30A764437F404409A1283CFF4B7159C0F80D000000000001CC6FF52DE53BEBD4E1D3DD11D0BE5FFEB977CA63FF2ED1099705AD3D5BEB1AE90E0000000000019B6C3951BCA1748DC7B89630F962DEB3937A4F8D15BF5634741113C38D2699F10F000000000001F21F01A1F02A9D105C71E89A189791BDA7CFB7BC89003D2EEB2AC6E7DBC26814100000000000019CD3ED9E3D49C10FE36B3813045F452DD0B3CEB702EA9FD3DE2289FEA46C9E41110000000000010CD4EC639F5FA5159D505EFD1215E62E35B38AC9A8B36077EB263B10F5BB4B741200000000000111A178357024706621EF264E4A66422A6F5B9F4C24A35579CB17DC686277D0591300000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F7F8F9EAAA74A5C910DD60B2FA5179B3FC341BEDAB53B1E957F40AFFE59FD454EE839D34EE92ED029C1B5853A46CC8B48B58DC4F74EBE2164B7F867B17ACD180761BBD5017870DCC53B0ADDCBB8DD1A6F5D014B1A789493C53C3D7B304F6237F836AA9372B0CD7007588A7EE166C1F8BC1C7826CA9D6E2D73B1B217E238FFB65DA1671204B7137B3C91D19ED0DAA12A98AB71C239C6F0E6B29D3F61DE3F71688560646DCBB9846A8F28BD1E7606E2C93CC0CBAC8A85BB578671BB01347E7B2BA757AA92131B2693D7F9501E87FC7C1BBEE1B8BF15E28DAF9B74487ED12BE8A4075FDE22DA018C0531776136F0FAB5ABF372E160CF51685CD0B8FEC7D63D39F4A7EE635051E54EEBEC7E8C4A408EBE848B7255685201592E3730C4DCCC6E7DE956B4FF296E76D0052EC6C037ACACA6E6474CB17AB271FFCA98A688D224C3A25425F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E7040000000000017D93C20AE191054626B3138F02E186A4607EDEF6E32DD3B2D788325E88FB01E90500000000000159008B71F97B67D9710ACBCAD0DCEB434823D0DDE4E8526701AF9ADE23FBCDC406000000000001410E6F39D12638391198E1827F643E6547AD7438BE85774B713D8FF3D8CB682507000000000001030C34B96241353C81CD7DDEA97ED6CBED8C9F9FB86DB60A6B78E39A253C001B08000000000001B07CBF5330F3B30963D6B0A4AC7AC4DD77585E4EB8A08B62B9AF1FBF42B76FE509000000000001D62A2ECDA2D153580BB57CB3FC1EDFFE89B6C06DE234962509FDD49A5A2438EC0A0000000000013792F4A440FAC20AF31472E40F1E79BD1E1C5DADC93FCA0319589FC55A542CBF0B000000000001FC454756AAA4BF5A8163937BA2E80D39CEF46D765C11FD66664120A83A61838E0C0000000000015DD4A3768F248125F414048EBD3F6AA793AAE4CA471DEDF5A9890841DF6DD56B0D000000000001CF0D1BF19096E3DE0950E9EB4C435D0C6B3DB4604FEBB60342D5B7C30528D4730E0000000000016ADD9B858AD6562C3B812B026D9BCE050D5A40ED6D936B1034C036AA490CFF910F000000000001925FBBBD85D4CB4AA7F5D18D703449AEABB18A5D32CEF076C16B7131DCFC08D8100000000000018DBF8B67F11FF96E3229EF8CBDD85719101DC3D8E6F636CEC6D19E63ADF5679011000000000001AE3D1E12FA31B287D509FBE36C261650C199242799057289B96E8D67301B473312000000000001AB1B5ABFFCFA0D28692F1FE23A1C1C3C31133714D112C66E05A09912A1CE32C213000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549619B2CE208EEF551E81A9AE87029B4302D012853622BB3BCD47FBB055E048923FF9ACD043DD40211F720396E02E71DB06FCE4E8D757DC264B4F5AC3089FE49361710B3FEBAE56D82E67A6C29504D6B061DB48FFCD3AB91E7B6B870AF8042312735EA06532FA075BA5DCCF6C9E92AF59BAD50EF0A3797C335F50FC43DF22481EC203C13BEEEB42DC753BE45EC74C10D40CFB3D55B68602D288855C63FCE824A2F4A02E88916DC8ED98AFD66F79E221DEFBEE75A5F18AE06DE81B8FCB94F06AF90A6E36B516E95723A80EA6651490B492765305BACF3DD8EBE02F583A32BD1537CDB034B4DF991724F7B078E55124D36BED20F8846C7FACE620FC7ED376EBE80E7B7122931848C35D74251572804688C127A1AEDAD1003741525A657B5C2901A753E0D14EF5F9A0D5782597165DFA12CD98F310CB2C667C34350C4C5F8E3C31C295C79F9561C0CF3DCCAA0E146799F097185974B77D76EBD9C40646648BCBDD85F00BD7BE65EB0B86C45236BB3EF4FBEDF9063AB38DEACA2ABC25C316C62A8FC0AAB8804D54A84CA6602AC2415383AF59495ED3FB5238B5CAD3D30ED637A6F2D1AA90447647D9B1231825578EE75493A63DAFD2985E8363295A0F24F454C3D59464527CB63F05213AB34DF7B134BB172E3FCFF116BC5BBFBE3EBA5B09E652A4C023400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113CD47F2466A56323209409FD7FCF7485A71CD8CE96D61298A20473D9ACBF99C010000000000019AB3950B30D3E7877159B364A25B214B41B8AA32E293E2DDD44AEB7DFC560A82020000000000019C359D104347B69607EB28A02E6924C24BD2A26DE4CFFF3FF98E48688E291E58030000000000011EC9B78F3B1189A5482238BCF700922D642E45D07E7EA10833E31A4CBC3CA08F04000000000001F37353B4AAC3DE6FA6FA583102CC2F35D6CC95325A07AB88D9B0304EF6F8103305000000000001E087F84EB8A6A13A9581B22CDEEF8942E186FE62896C636D0503675B28692B72060000000000015FDAFB6EEAA60CDFFD2E2D1C034AF7306D60B106F145206FADB857BA565C66FA07000000000001CA463E7885C94740495E419265530662D2D8B0CF6C9E7C290FA86E8E136261DD08000000000001761CA5CF20BB11D4515629D8BEC9D72E02E0D3392C20084723610CE22260DF9209000000000001DAE3E662F52740958363C199EF0CB5F0828BA7D720A1C22E48024697A752BBE40A000000000001641A9FF6624F56629B9AC0BCA35CEEF5426CD40B73E5E6E976CD805B626351340B000000000001970701CEDDB32F91B1653BA5C933B6F57C7F1FF99BC31B459A16CD76024DACF00C000000000001BD84277343BEE7E83CAD70FDEFF5A5DFDD0F9A3AA1FF342DE85C27889AA6D5730D000000000001AD8BF136C3B7CEA71632789EE3D7E8FB2C3AA2548574A403838DDC313CCE97F20E000000000001B4135A97848AFDC9B96FBEDE4501CCBF1B855C542A7165D3EB5E3F0F2303ECB90F000000000001AC2898B9C17C21ED20A550122441FC4ED08A7D669CA1F3D8768DDAD0E2F6BD3310000000000001FF86FB42353270642E15587334A17E39AA7DC9CFBB4C829CB4B16510DAA83F6E11000000000001EBF5F05C9D7C61C2A99BAF7478A73E89B5CF10CD25174F1EE5FD61DA26DE7EEE12000000000001F9F5610037B38150D3AA10BA9EA0592CA0A21714CE0926F3D8D8BADEC020AB55130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087DFB8B692D4548E69E8F52A40B52D87261DAAEA3F734803A146D4622D4C8B17E1D98A7B04CF346B99E512072176F7A8811405EF38E007181DA3563CABBC577F41D6B8EEE36B0D67FF4AA525185A5821F2ACE2DD7F0607828ACF8AB08FE940D7FD268225449F5D20ABF61D2C7DB585A8513AEF60841E1BFD4AD3C47D3A00F68F71DCD9236D7E0FBC428C7095CA12D8D10B2E69C9FB6C976F4831246C9C0E2686091FB040E21C594960A1F6734A0B84BAAACE4EEC7FD1FABCA7F71373620EF656309B93B9D768970B0A03B9E07FA9C888A01D85B0B92F6550534E528BFF6289CC398003AC6A91CF86329B6BEB13854C20A8A75DCBE7A470B216C334CFE6AC120B8AA42EF5A9BC9FD224967218F17A334DB9364F966DA366BE08CA2D1C6DBAD769ED1537C3F5528CA849841BA495B78D07901481631E624DC0656F7F5D0B4820B6FC2269E404ABD245B49EB4FE7FB119E88663C8B8E75EC63C9C5A8EE478313B3B058DF1ACA81F65DB0F2E3E411A30158178585699BE52B6C11A2DC966753D7485AFBC75AB6EB6D0443DAD871D0BF43128A057593EBD325466AFCA3EA492311A31788F75372B5321217937AB4FF23D37D3A01E3578E758A2087941120E801C12F26FCC55D089C712C0A05E67122E28351745998168D1760B16D105D854BF2EFF369971D100CF448D3D00C2C34D5F6037A07522DE2EBE014E1E60D7A535B4CAC42EB69F7856E7A259627F4492A0CDA142D743D7BB90F78EDCC15B1EDF8DE7D0D4366367E581254AF959768265DAC9175E18F133DFFEF628CF769EE7E9BD0E07259AFD067AD441ABF81FA7726FEB1140C3146BB510185AF098DB53040DB97F1EF894CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318E413A87250637B5C4A4BF18A2D661BB2458CA7C7F9E320228FFFEE614E88838DE28767053DAF289E9BB8073D60114D20309CD17A6EBA5FF2FC47B49402DA3600DBC4323559761781818334D1C0CAF34FAB5A940C83D6A363433E390C3B589E1B6D09A2F4276547FB279D1F0E2D1ED91A3AFC953F9E7942BEFCF2AA66B19AE877A6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291D560067063A6EBCB1EABAF7FC12F66BD94F1BAD021254D0CE1F1F850B081262A446E84188C3A9A3CB89A80BC9E8F597EA247A39A6F59BE2D76CCDD6C96DDEB9EB0A272D02C5327DF20934FF8C0E26C71F6736FBD5B85A56F15E41F03DF2713DA70DEC489B962A1F7E119465FC8D72AD1DA559EE0F25FF661AD2F62C6BF172C4B7B0891FF05D0C985FBDCC4DEF2DFC3A73AEA39EAE9010A080DD47BC1268BBC1B5282DA83C62A9FE25CBC62E611951A411B03FA8832E227D761A35F4FB902E54083FD05142177B5D2987BE26FC4F9C5D13FFA21E7488F19245FD19D9FE2DA32608B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE5BCC31B508B8177B41775B459DB06F4AACB419F24EA979AA24C996554DEC91EBCB16E9E1B754DCD221E02231F10FBAABF79E362A514D54670DE7493B7CD7B66BAEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBB0A1E0563E934CB60493FD19327C71D824F361B1133A15E47857567979B5F8288D5FABC9D1D47402577CFAB60BF840EEF0D9173D47757BAF197EE10941704811690592F587BC7F532446BA10B875CB7994CA2613A25F65D16A6735E9CC0C4238036F68FFC1A893DDE19859CCE3F5ABA348F769D122DE567889C14924B243B1379AE65238446E7294F293F0DF1751C166CCF58B4F76A4A7A6178A136E3F72D120FCCFDD47311A340A0734C7DC77664B6D7BD87EA93215C69CA59F0DAD8E258637B49DF9864B84B76089E4F50B6C2BC496835D701C6F106B2B96CDA03A7F118AB5AC2F7073E7596BAE489C83FE68A8DB1E9A5427A31E8A6DC4E2962E5571FF061908EBBED929D64B2505C1C491CA277C2917E0A964218059309167716F47FF2699FEE7248ABFC6723085934D706ADBA0BE046CE3156EE682A5E0ED51534CFEBFE9B7118577F6D3157F31E8D849071E31A734BCC1DABDEF02B7D817FBFFF2CF120ACAF9BE403C35D92B960CDABB7242115FFBC4208977E19BFFBF250DE7C71814EC7206CB8F2E1D523E293E557D49801FA6D9E5AE279D396F91021690DF5EA153B3020CA3E08D8C53DC9DCD731315CB24C9394C6DEA84543806DF231011B086BE37A57CA2B888A74FBE7379EA346ADB56D932BA4B7B857A7918116B70987865FEAB8A42792F788F8CE13F75670B36029660F68A7E27FA23EBD2CC06C7CE9A51FC7B92220D44C4E9C7900E1FFD77D08D35B34B201EC5DCE6348FF7AA08F0DE5A4AE7C664F8E70D3531E181B4B5F7D74E8B6FCA7AE776AC73C4620B77C1C2397B987C241CC139C6407FEBF5B912A407695EE8AB6612C8C3D610D6E11E107E43AA6C638FF86104557546FD5CA0098C44C4EFEF0825DD5E8B33E5311238A32672242BD19ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDC05256E7B9EC23FA6F460956174696C9283AF19A615B7FD209C25EEA0587D15765808D7814EA792B7C31F469AA7004FB9A78EA5E59459C6E3F75E9E4DE961B5FABE5149967C9F97B1BC5DBF8E297DB4B25FC55241FDC189E9488FE06F71E9D1D4E19D50E7A3B81FCFA4799B127AA0D8C12FAF48811D52E4EA08D965813E20A7CB532F3EBEA5CB60601DDBFB1CD19FCE3F0A9CD1E452D1BCDDD215B91160F6EF5892280D847E32600F50E5DBB0DA83A650FD17E4A58EC02BC05DE23CD3B2C04172708C15A96A3D43A212FFD4401EEC87861C35351A0BE9D7D4D6AC5D60DA8AB5E1BBC7D943F4439AEBD7A6B022C8EFEB712BE5EAB7A1802CDD2FB9D93FA6E4383586E517A4D79D9FD2F6BBFEF8C65F1F3111067670E6A059A1308948697F5650C1C9BBD708D6DB1AB7F44BC2473A4897D83DAEA510BADD3ECC8C9F2E4F889D5AB483F7999C92CE3962C6527BCA9BCD8AA4BC4358E39DE5D52EAAB2FCDB3D23E5FDB643B9967374A140DC0813D252B1730B592100644AADEF3DD4BA506B4D4B95F3F95D2984783B7EFE70888FEDC2F8BA40338F5727171F1D799BD2E214D18AFDEF078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DFB179E6FE98B1C807944E610D3A1516646509316FB8E95E16D0E368B0E95370989BC1C46E6764AA8C8E2396E4FD1A65A171D9EEDB2B04843DD2845B5E5F5BB71410EB0ED1462BD35E503C47AC3DC9E9915C28E375719CCDC8F265898EFFB5A5B0212D18F96E473E185736ABF8B9C7DB9E75681B0CF51697CD4C44B0BE03C799CFC37EDADD455AB3C8EB0F334679EF94E6ED2E8BFACF20DECAC68B3AFF3979869B578E146EE63A9FC66C147592E35C3E7785F3883D458746E1FA6E05C928CEB6E4894CB9E2B7C860E4D2BD42D0053B2BC8C7F3C11FC0DAF6DECA58CA37526095779C2092E817BB119F33C436D107F97EE21363AA6D16A8D7C3735F4C9995180C4B5854FE73C1C961A0E178F047DE9EC62C589C2D7E30929DEA6CE37C4042F046151EEC6F1BC5A7CEE799165259DEA61A25806F16B82C0FCBD046ECC5597A92C4FA14B6BACA60BCC65AF37A12AA67AD84239FF680AED031EE172D1EC34231230960B5F7887F9E3E44FE4C156E7472EE8D9C327587A0704A8035E519B1C4A9D2E079FB5833EE071F22593511FEC1620797AD8A38BEC92A5C958A47CC030CEADB4E60CA548C946BD7B2D663B5A34F11E335ABADDE0126BB632F87518103815FB41C3B30C1162EBD9A23A40A2B1E47C1E8530C4E308BAA4EA544F5416D3C2B19B8D75B87396123DD962FCD143732645E3CBCC799D52A889ACC0397AC81405174220EDCDE3CE13663FCF49CD05018BCD4C8E085D8B055BD4A38386222164FEC91589493238047F1CFA07E7C2D8D34775BB61DAC79F301F0942127C6787CFD093620687E9A5C8E0B7146153759272866DD82A69A178D3BBB3AD2AE177DE91B44A0C0CE6C4DAFD78B7F2D3B3C54AE60062DDCEEC2BF3A579A53E27A72402BED5DA167815801985FB7A952CBE74331B6EF9F545A8D958BA7120898C02DAA3F7CC187C81DDF09B5E9F281CEC29A0F012F8EB726DFD7B193833CDA2B0CBEA378E6FB25C84C8CE85E7BAC610B75AE5CFA9DD39290DA4DADF4F61BEFE0F87959174D2BC28BD76B6C933E397A7153D950BD58C62E8233D1D1C276157386488A275508CEEEC7E9896F8B15726ECF4CF837328D80E8E1A4382B9029C26CD3D9205C66E8007EB5C07E51DFD1E90C612FADD09B2985D352FF0F423F45A9E35E4ECAB14E1FA851A060286A131ABDBC53DB24CAAABD058E356751BD847919A68991CDF865BC959F4F5106E21201360A7FD64CE70D102E0615086133262296E48308D05AB0310AEF2C07E169164ABD3DCB8B023145BDD480F927AF80D87E7A088568195585CE2D8BB484F70353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB517B9738E423B8A779C6AE71E3FA4D2396FAA0B00703FF9EB574FABF0A1EB8AE1E59CF6F87D1172094C9FC02F027A8383C25C1CB186D5F2CFBAFB208ECA37B1E5267527F8F29F91C0FA10CA75AC7FBBB397021A44DE7DFBE23D639DD1954190897EF00D981A0E12335FA7DD99C20C3DF0A8E35CE108180046AFDD4EBE56B2DDFC3872F128BCB4D131C339BFD52DC1694BE3CC63C390206DA62F597F54E69954C495DD683A25503F8E37F3CB9AD436FCCC3966D34430A5751D9EFCA4948E7A038D54A8443203C374F1F58A2203BACAA6A0C93783B0BFD8E85A869ECA37AE0FA0349B2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADBFBC26542CD0335EE21852C8CAE8DBE734028D2F6BF457CB086172F176456A64AA18B2C2162F8EBFCE0CECBB57C2516C1933D72FCE029413FFD07B9CD3B8A005C4DF20CFB4542C1B5EE33991EC20CDCA0348935CD698012F9D195DFA690C160FF58054B603119C0C986DBB69C2AD7FB64BA7EABBE0DA6E538B6DCE1097982BEF1676F2E1F6F82CE729BC38EC4CF9E04BBC1AB178040E055B421ED4EE8DA8CE1049037A1C8050AC7981609799BC7923C0BD995B0EA79E9567D192564AA11A88BC6459146968D0D70849C4C8FF6B7BE1E7EDF8DE8D2C3F12F5E6A86EDD30D0141F520FEC5E0695E7A806415B1140A5B29D4B8794A38ED6D2DC039574259ECF15E79FDE234C8C6614F347F9B07F8E5EDFF0B931CD68C5A5D711D4A69DD1193F67F56B66ADFA32C26E4D251D169ED47F769B061B9E9973AA5EEE68F8AB555277D164739D365D93D507B05707E400C7365EFCEA4282D3079F4504FC88CE9131AA9D8ECF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0F4D12EA7A891284AA94DC0A55154C7F4B33C6A0D905ADF95AEC20253E8477272C77465237E1EE73B675C37F656EBABF91BA91A79FC679C5566A637F6417B8981D6EECAFE8534E2538E22B627D3974100CD9F2633782F4799F7CF1D8A4454AED2C61452924632D0A4B78D9C88CC1E9DAA6A02FC37D49A4423B4FC5C52A82BAFEEA48D41FD835314AC901A6BEE00D5910C4A6F5BA8F375B8B2E0F9E9633BA894D16926C76D88E3256A3337829BF81245CF173801D3F964D96BB23EDD9772B1623D79DADCECAAFA80505AC2E0ECBBDBA3679A483BC7B92A54BDEAADFA7F386BA0AA9076B979D66AD9FCD914D0098092FC24DA2D956E1ADD473F5D5E97B81CBF9F42A45DD6CE06682BEB5B740C0872BCD90D6468129848CE45B8C70F176035CB05236795A369F5E6F910F706986E7F66A84B100C265BB5339972BBDF6B770B694B8D2DD8323E86A90E83EE039AE031A331E6D7B99E75FDE0E8E42AF855F52C925F1D21C64D6EB1AE468490B50A06C706D32CF44A483219FB45E14C654CD2ED13E0F3 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 8392 +sm = 0000000000000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA7010591AF601BF50208B6C5968D4F692F07279A9C6AA2E66590F7D2E54DCFB47261C040A14FD137EE498C24B0DC750905F56FED22A393C31815CAF6ECFA1D3BC458E8715C21A26FC1E7A951C54A30ABCDB7EC71AAD92F2662BC900F9E9A93054CF39ADF736B5C6988A42FAAAB94F7911C85A9B081A35349FACE8BC499CA287720E65AF6BD9DE79A988F24DF6B71B22E8E50F3DFD73CBEA35CBA762C7D846E79CE6D29562D5B58D74A5EBEC8F6AD3D6D8CDED91F9FA51CDA414D653852E50C13C0CF35BA4B0955661EA3FC882D9D64954405502E2BEF7D3063D36F993460D2557C79729E510FD11DA67C0C0D3B6448B88B96E0834210FDDA112F57C7B4FA60EC32332EF80BB3601C44E35C901ABEE1EE25BFAAB80639021377FDA25672D97ED4126B888B571BCF4A34CE363BF227A5830ACB4844CB17A942625686FEB09DBDA47AF755D050E219A6031573126971470E90C947BC06E3F76A8E7354D2A87114187F9CF92824C5D9F9938FD4E861397294A51035B91B14D9786762BB11AC06C6FD0C6285F48FA30DE2E92AD9D0EAC1F4B2F6B8DBA9D1F8CCB77367706BBBF6A04658E8BD775633D41470CCFEA9283AC792FB671F6E1BCDBCCA7600910D3127BCCAA772AEC184137C31D2F41DD1FB349EC1AC61FED09B068DD382CDE422B65FD5FA8E17247B0A3B8D1F115CE27C50B8BC81665A65D97C2991F5078F1A33ECB61CD11AA7F503DD53FB1B3AF7ACFE24C28A700632DD3934A56129B66BA60E6BE40B7EC27DA47D20C4427ECD55AF940037B6D3485F6D6C7B3CDF5A5C19C958655A51A34BA738D8CDAD826645020A0BC02F5F6F3B6BFD28319B84B5A9F3FD9D99DA363E0267D5B1F83087C603CA6D731A4AE32346FFBF5BBBE7FFCD206304CA468789748789EE3798D4CDD773DCB6E36B719EB4B6B164287FF5C6D837A25CD01DBC826399C54E3242BC1BA4078FE683767FF48114262E30C2D1B55C983DAFACADCD92552039F9209DECF6F1CD358590E9C0DE9CF1A5AE165FDB700A9B4B14C959CA89001BBE933F84F17D6C15B50AF1684C8F4044CA7BA2CC196C7F3CC9AC2603194A9A536347975AA3A6B8929A3E4EDC681AA1A0FC410C54CF1CF561C6741E245B269AE605C8460D5D3C427E39CD5AC141104D0FB6A3D09F71BD5D57EDAB310998EF776BA3E124B590A373920DB5A24CCD39D66562EF2909F19046FBFC0BA04D2CF7A9CA47D87BEA4D52FB263B57AE5ADD901CADE838B1D7347D9E47EAF6456148C6C4E44B0B3AF44E84EBA5997051F779812941DBDEC0309FE593B55963647CCC0954E8D57F85D73CB40792FF03F8F20427D951444990CA3976A71368A7DC1455E880722F0300029FD0D41FB427D0515FF9AA3344F5F3E4811431191A1AC406B7A16DA106310002B3D710DC236EC8D68027C56FA74F71482643230330B6FDF0306DA1A3980689E09376BF39F4C562ECB1A68E02D5D91318EC0C91D38E8E480B8A0E65F452500B9471B5BB0CBC8D62AA1AD1A74AC26884557924123193F3F7540906676F61AF2E5B8879D61077A83925E92D1C3106A85A7815F9CC0A00D536475C5C63263C255F9CA097AA6C3B65C5CD659AAE22F412427C2918AD8C309342C8369BB454C508B82F2761B1AC648469993DC8770D77AEC80AD8A05129D20EBF2AB9CF7D5739A4F0B796FA3E18D0B3C862254D2D1EF0C1141EF2A665FCBBEDA2BD28B70BD0C4123DCEE5A1D81F1E20ABD1DEA550546C1D13ACB5AAEA1E6F2304541F641343DDE809B1A99E617BF85395C38D7B367F2C2AB5E26A156437E7248DF2E9F2F617049A7ECAFE220784990CE695E1C32EAE4F10BC988CFC2B56742FA299C57394432DA7B7615487DE8858DB8A45448140CF4A9D2152E12279DC7A6AE1DE1239BF9B1ACA841B2EF96801D464F6EA1053BF96F6E69F495D45535AC3FD4411C27FF7DEE1ADC490D79B073A0D4A04A903D84921A5FA52859B9DED1F1EE674256F2A57DD5E6616AE1EE474D3F1C1DD7BC7F282E6DA92731914758830B8AF74345719259AC8398F56A7F9663EC9CE82C2C0864DCDDA13DC99CFC527C2F42F86DAE54811B29589E8CEE39FB9496CCB77190F052B8DC58C76C5ECE6F0FB81A47088D8AA2085533F7D6427AE4A09570D48AAB9446FB0A49A36AD6003420C9B64A27FA2DEEA97D1D4BE804FFC6B0D772DD5757BEDF361C340C9CA3D9449895E9AFAD2BF923436FC4EDD59550F149304B3F9D24448FEDC4593A0F94EDBBFEFA223EC3FEFE59A34E94B985DA3E652070EDD15A60D47A6C319D1CCB7129E77F28A9E6536AC00261E6BEF5AC25DCE824C508AA0403E063A8562FC21A25FF7F99D4C518A32A99D3E41C8DE7518484F9CBC19EAA901C9B4359152FCD7C0E51C82C962FF3F9A68B4F8B30440B23AD28725612F5FB98FF740AFB457915740084644120ADD17B445078AAF54123FDF28F3A9CA137DE547F35FBACBC8F23207A7A3E6BF9CD001E18BC590C757E05144C3D05918E358FFAECC0B51B2F0B06E3869667B1DBBAAAC4AB4167776CCC2FAD197BC60BC76BA35F1FF80A96013054323266E972FD51C1610F8C04E01E16266C271B3B10695A6321BBB5DFF292DE959CBF408916903F8E0C9CFD2A2744016E934D66314506B7B791F5F9071C60545022564D64D7DDC92EF9D6362A0CA8F7FF48AE9B71A3A14738A7AD925653951A1DEDBD16EEC484417E92496276CB73AEAB964842CCA5A527EB0787680648B9932927D7EB2627B3D73D254C1904139D8A2C764F72CC114E249FBADEB2B0F590830E8EEE33ACF36AAFB08E1A83C9FF28E6D6D623EE44A0B86713015BA15D74BA7431EB5BA91C739028B83133C5AB36CCF899E10440F06BC626856A2015DD832F087A72864D390131A760B46BFE305E3B4E9912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70D8A18A427BE88BF379EDAB2E45A1AE5F3199C5D6C0BDF55A8CD1EDEC7EAF92F0D011CBE8E48BFCBC428382A66B103B905C0CAB36A7511B1BD6E23F4C69073CBE6C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5832CE029A1A95FFCBD5C8B157282F7364E680C60B252C49483FCA03529693B074E0D2B1F6DFD6463B974DE6829A616F20C839B0D2B8BE5405623B5B722EF22F7A3BB78E91315F715D9DCDB0C8639CB8A90685BEE7969671789047083CACF24FBC4B601B1B23B2E79E42176B2438CB405BDF46369F4DE5F411B2ACD32BEE3065DF987DFB8B692D4548E69E8F52A40B52D87261DAAEA3F734803A146D4622D4C8B17E1D98A7B04CF346B99E512072176F7A8811405EF38E007181DA3563CABBC577F41D6B8EEE36B0D67FF4AA525185A5821F2ACE2DD7F0607828ACF8AB08FE940D7FD268225449F5D20ABF61D2C7DB585A8513AEF60841E1BFD4AD3C47D3A00F68F71DCD9236D7E0FBC428C7095CA12D8D10B2E69C9FB6C976F4831246C9C0E2686091FB040E21C594960A1F6734A0B84BAAACE4EEC7FD1FABCA7F71373620EF656309B93B9D768970B0A03B9E07FA9C888A01D85B0B92F6550534E528BFF6289CC398003AC6A91CF86329B6BEB13854C20A8A75DCBE7A470B216C334CFE6AC120B8AA42EF5A9BC9FD224967218F17A334DB9364F966DA366BE08CA2D1C6DBAD769ED1537C3F5528CA849841BA495B78D07901481631E624DC0656F7F5D0B4820B6FC2269E404ABD245B49EB4FE7FB119E88663C8B8E75EC63C9C5A8EE478313B3B058DF1ACA81F65DB0F2E3E411A30158178585699BE52B6C11A2DC966753D7485AFBC75AB6EB6D0443DAD871D0BF43128A057593EBD325466AFCA3EA492311A31788F75372B5321217937AB4FF23D37D3A01E3578E758A2087941120E801C12F26FCC55D089C712C0A05E67122E28351745998168D1760B16D105D854BF2EFF369971D100CF448D3D00C2C34D5F6037A07522DE2EBE014E1E60D7A535B4CAC42EB69F7856E7A259627F4492A0CDA142D743D7BB90F78EDCC15B1EDF8DE7D0D4366367E581254AF959768265DAC9175E18F133DFFEF628CF769EE7E9BD0E07259AFD067AD441ABF81FA7726FEB1140C3146BB510185AF098DB53040DB97F1EF894CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318E413A87250637B5C4A4BF18A2D661BB2458CA7C7F9E320228FFFEE614E88838DE28767053DAF289E9BB8073D60114D20309CD17A6EBA5FF2FC47B49402DA3600DBC4323559761781818334D1C0CAF34FAB5A940C83D6A363433E390C3B589E1B6D09A2F4276547FB279D1F0E2D1ED91A3AFC953F9E7942BEFCF2AA66B19AE877A6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291D560067063A6EBCB1EABAF7FC12F66BD94F1BAD021254D0CE1F1F850B081262A446E84188C3A9A3CB89A80BC9E8F597EA247A39A6F59BE2D76CCDD6C96DDEB9EB0A272D02C5327DF20934FF8C0E26C71F6736FBD5B85A56F15E41F03DF2713DA70DEC489B962A1F7E119465FC8D72AD1DA559EE0F25FF661AD2F62C6BF172C4B7B0891FF05D0C985FBDCC4DEF2DFC3A73AEA39EAE9010A080DD47BC1268BBC1B5282DA83C62A9FE25CBC62E611951A411B03FA8832E227D761A35F4FB902E54083FD05142177B5D2987BE26FC4F9C5D13FFA21E7488F19245FD19D9FE2DA32608B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE5BCC31B508B8177B41775B459DB06F4AACB419F24EA979AA24C996554DEC91EBCB16E9E1B754DCD221E02231F10FBAABF79E362A514D54670DE7493B7CD7B66BAEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBB0A1E0563E934CB60493FD19327C71D824F361B1133A15E47857567979B5F8288D5FABC9D1D47402577CFAB60BF840EEF0D9173D47757BAF197EE10941704811690592F587BC7F532446BA10B875CB7994CA2613A25F65D16A6735E9CC0C4238036F68FFC1A893DDE19859CCE3F5ABA348F769D122DE567889C14924B243B1379AE65238446E7294F293F0DF1751C166CCF58B4F76A4A7A6178A136E3F72D120FCCFDD47311A340A0734C7DC77664B6D7BD87EA93215C69CA59F0DAD8E258637B49DF9864B84B76089E4F50B6C2BC496835D701C6F106B2B96CDA03A7F118AB5AC2F7073E7596BAE489C83FE68A8DB1E9A5427A31E8A6DC4E2962E5571FF061908EBBED929D64B2505C1C491CA277C2917E0A964218059309167716F47FF2699FEE7248ABFC6723085934D706ADBA0BE046CE3156EE682A5E0ED51534CFEBFE9B7118577F6D3157F31E8D849071E31A734BCC1DABDEF02B7D817FBFFF2CF120ACAF9BE403C35D92B960CDABB7242115FFBC4208977E19BFFBF250DE7C71814EC7206CB8F2E1D523E293E557D49801FA6D9E5AE279D396F91021690DF5EA153B3020CA3E08D8C53DC9DCD731315CB24C9394C6DEA84543806DF231011B086BE37A57CA2B888A74FBE7379EA346ADB56D932BA4B7B857A7918116B70987865FEAB8A42792F788F8CE13F75670B36029660F68A7E27FA23EBD2CC06C7CE9A51FC7B92220D44C4E9C7900E1FFD77D08D35B34B201EC5DCE6348FF7AA08F0DE5A4AE7C664F8E70D3531E181B4B5F7D74E8B6FCA7AE776AC73C4620B77C1C2397B987C241CC139C6407FEBF5B912A407695EE8AB6612C8C3D610D6E11E107E43AA6C638FF86104557546FD5CA0098C44C4EFEF0825DD5E8B33E5311238A32672242BD19ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDC05256E7B9EC23FA6F460956174696C9283AF19A615B7FD209C25EEA0587D15765808D7814EA792B7C31F469AA7004FB9A78EA5E59459C6E3F75E9E4DE961B5FABE5149967C9F97B1BC5DBF8E297DB4B25FC55241FDC189E9488FE06F71E9D1D4E19D50E7A3B81FCFA4799B127AA0D8C12FAF48811D52E4EA08D965813E20A7CB532F3EBEA5CB60601DDBFB1CD19FCE3F0A9CD1E452D1BCDDD215B91160F6EF5892280D847E32600F50E5DBB0DA83A650FD17E4A58EC02BC05DE23CD3B2C04172708C15A96A3D43A212FFD4401EEC87861C35351A0BE9D7D4D6AC5D60DA8AB5E1BBC7D943F4439AEBD7A6B022C8EFEB712BE5EAB7A1802CDD2FB9D93FA6E4383586E517A4D79D9FD2F6BBFEF8C65F1F3111067670E6A059A1308948697F5650C000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F7F8F9EAAA74A5C910DD60B2FA5179B3FC341BEDAB53B1E957F40AFFE59FD454EE839D34EE92ED029C1B5853A46CC8B48B58DC4F74EBE2164B7F867B17ACD180761BBD5017870DCC53B0ADDCBB8DD1A6F5D014B1A789493C53C3D7B304F6237F836AA9372B0CD7007588A7EE166C1F8BC1C7826CA9D6E2D73B1B217E238FFB65DA1671204B7137B3C91D19ED0DAA12A98AB71C239C6F0E6B29D3F61DE3F71688560646DCBB9846A8F28BD1E7606E2C93CC0CBAC8A85BB578671BB01347E7B2BA757AA92131B2693D7F9501E87FC7C1BBEE1B8BF15E28DAF9B74487ED12BE8A4075FDE22DA018C0531776136F0FAB5ABF372E160CF51685CD0B8FEC7D63D39F4A7EE635051E54EEBEC7E8C4A408EBE848B7255685201592E3730C4DCCC6E7DE956B4FF296E76D0052EC6C037ACACA6E6474CB17AB271FFCA98A688D224C3A25425F1C9BBD708D6DB1AB7F44BC2473A4897D83DAEA510BADD3ECC8C9F2E4F889D5AB483F7999C92CE3962C6527BCA9BCD8AA4BC4358E39DE5D52EAAB2FCDB3D23E5FDB643B9967374A140DC0813D252B1730B592100644AADEF3DD4BA506B4D4B95F3F95D2984783B7EFE70888FEDC2F8BA40338F5727171F1D799BD2E214D18AFDEF078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DFB179E6FE98B1C807944E610D3A1516646509316FB8E95E16D0E368B0E95370989BC1C46E6764AA8C8E2396E4FD1A65A171D9EEDB2B04843DD2845B5E5F5BB71410EB0ED1462BD35E503C47AC3DC9E9915C28E375719CCDC8F265898EFFB5A5B0212D18F96E473E185736ABF8B9C7DB9E75681B0CF51697CD4C44B0BE03C799CFC37EDADD455AB3C8EB0F334679EF94E6ED2E8BFACF20DECAC68B3AFF3979869B578E146EE63A9FC66C147592E35C3E7785F3883D458746E1FA6E05C928CEB6E4894CB9E2B7C860E4D2BD42D0053B2BC8C7F3C11FC0DAF6DECA58CA37526095779C2092E817BB119F33C436D107F97EE21363AA6D16A8D7C3735F4C9995180C4B5854FE73C1C961A0E178F047DE9EC62C589C2D7E30929DEA6CE37C4042F046151EEC6F1BC5A7CEE799165259DEA61A25806F16B82C0FCBD046ECC5597A92C4FA14B6BACA60BCC65AF37A12AA67AD84239FF680AED031EE172D1EC34231230960B5F7887F9E3E44FE4C156E7472EE8D9C327587A0704A8035E519B1C4A9D2E079FB5833EE071F22593511FEC1620797AD8A38BEC92A5C958A47CC030CEADB4E60CA548C946BD7B2D663B5A34F11E335ABADDE0126BB632F87518103815FB41C3B30C1162EBD9A23A40A2B1E47C1E8530C4E308BAA4EA544F5416D3C2B19B8D75B87396123DD962FCD143732645E3CBCC799D52A889ACC0397AC81405174220EDCDE3CE13663FCF49CD05018BCD4C8E085D8B055BD4A38386222164FEC91589493238047F1CFA07E7C2D8D34775BB61DAC79F301F0942127C6787CFD093620687E9A5C8E0B7146153759272866DD82A69A178D3BBB3AD2AE177DE91B44A0C0CE6C4DAFD78B7F2D3B3C54AE60062DDCEEC2BF3A579A53E27A72402BED5DA167815801985FB7A952CBE74331B6EF9F545A8D958BA7120898C02DAA3F7CC187C81DDF09B5E9F281CEC29A0F012F8EB726DFD7B193833CDA2B0CBEA378E6FB25C84C8CE85E7BAC610B75AE5CFA9DD39290DA4DADF4F61BEFE0F87959174D2BC28BD76B6C933E397A7153D950BD58C62E8233D1D1C276157386488A275508CEEEC7E9896F8B15726ECF4CF837328D80E8E1A4382B9029C26CD3D9205C66E8007EB5C07E51DFD1E90C612FADD09B2985D352FF0F423F45A9E35E4ECAB14E1FA851A060286A131ABDBC53DB24CAAABD058E356751BD847919A68991CDF865BC959F4F5106E21201360A7FD64CE70D102E0615086133262296E48308D05AB0310AEF2C07E169164ABD3DCB8B023145BDD480F927AF80D87E7A088568195585CE2D8BB484F70353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB517B9738E423B8A779C6AE71E3FA4D2396FAA0B00703FF9EB574FABF0A1EB8AE1E59CF6F87D1172094C9FC02F027A8383C25C1CB186D5F2CFBAFB208ECA37B1E5267527F8F29F91C0FA10CA75AC7FBBB397021A44DE7DFBE23D639DD1954190897EF00D981A0E12335FA7DD99C20C3DF0A8E35CE108180046AFDD4EBE56B2DDFC3872F128BCB4D131C339BFD52DC1694BE3CC63C390206DA62F597F54E69954C495DD683A25503F8E37F3CB9AD436FCCC3966D34430A5751D9EFCA4948E7A038D54A8443203C374F1F58A2203BACAA6A0C93783B0BFD8E85A869ECA37AE0FA0349B2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADBFBC26542CD0335EE21852C8CAE8DBE734028D2F6BF457CB086172F176456A64AA18B2C2162F8EBFCE0CECBB57C2516C1933D72FCE029413FFD07B9CD3B8A005C4DF20CFB4542C1B5EE33991EC20CDCA0348935CD698012F9D195DFA690C160FF58054B603119C0C986DBB69C2AD7FB64BA7EABBE0DA6E538B6DCE1097982BEF1676F2E1F6F82CE729BC38EC4CF9E04BBC1AB178040E055B421ED4EE8DA8CE1049037A1C8050AC7981609799BC7923C0BD995B0EA79E9567D192564AA11A88BC6459146968D0D70849C4C8FF6B7BE1E7EDF8DE8D2C3F12F5E6A86EDD30D0141F520FEC5E0695E7A806415B1140A5B29D4B8794A38ED6D2DC039574259ECF15E79FDE234C8C6614F347F9B07F8E5EDFF0B931CD68C5A5D711D4A69DD1193F67F56B66ADFA32C26E4D251D169ED47F769B061B9E9973AA5EEE68F8AB555277D164739D365D93D507B05707E400C7365EFCEA4282D3079F4504FC88CE9131AA9D8ECF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0F4D12EA7A891284AA94DC0A55154C7F4B33C6A0D905ADF95AEC20253E8477272C77465237E1EE73B675C37F656EBABF91BA91A79FC679C5566A637F6417B8981D6EECAFE8534E2538E22B627D3974100CD9F2633782F4799F7CF1D8A4454AED2C61452924632D0A4B78D9C88CC1E9DAA6A02FC37D49A4423B4FC5C52A82BAFEEA48D41FD835314AC901A6BEE00D5910C4A6F5BA8F375B8B2E0F9E9633BA894D16926C76D88E3256A3337829BF81245CF173801D3F964D96BB23EDD9772B1623D79DADCECAAFA80505AC2E0ECBBDBA3679A483BC7B92A54BDEAADFA7F386BA0AA9076B979D66AD9FCD914D0098092FC24DA2D956E1ADD473F5D5E97B81CBF9F42A45DD6CE06682BEB5B740C0872BCD90D6468129848CE45B8C70F176035CB05236795A369F5E6F910F706986E7F66A84B100C265BB5339972BBDF6B770B694B8D2DD8323E86A90E83EE039AE031A331E6D7B99E75FDE0E8E42AF855F52C925F1D21C64D6EB1AE468490B50A06C706D32CF44A483219FB45E14C654CD2ED13E0F32F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549619B2CE208EEF551E81A9AE87029B4302D012853622BB3BCD47FBB055E048923FF9ACD043DD40211F720396E02E71DB06FCE4E8D757DC264B4F5AC3089FE49361710B3FEBAE56D82E67A6C29504D6B061DB48FFCD3AB91E7B6B870AF8042312735EA06532FA075BA5DCCF6C9E92AF59BAD50EF0A3797C335F50FC43DF22481EC203C13BEEEB42DC753BE45EC74C10D40CFB3D55B68602D288855C63FCE824A2F4A02E88916DC8ED98AFD66F79E221DEFBEE75A5F18AE06DE81B8FCB94F06AF90A6E36B516E95723A80EA6651490B492765305BACF3DD8EBE02F583A32BD1537CDB034B4DF991724F7B078E55124D36BED20F8846C7FACE620FC7ED376EBE80E7B7122931848C35D74251572804688C127A1AEDAD1003741525A657B5C2901A753E0D14EF5F9A0D5782597165DFA12CD98F310CB2C667C34350C4C5F8E3C31C295C79F9561C0CF3DCCAA0E146799F097185974B77D76EBD9C40646648BCBDD85F00BD7BE65EB0B86C45236BB3EF4FBEDF9063AB38DEACA2ABC25C316C62A8FC0AAB8804D54A84CA6602AC2415383AF59495ED3FB5238B5CAD3D30ED637A6F2D1AA90447647D9B1231825578EE75493A63DAFD2985E8363295A0F24F454C3D59464527CB63F05213AB34DF7B134BB172E3FCFF116BC5BBFBE3EBA5B09E652A4C0234 +remain = 1152921504606846974 +max = 1152921504606846975 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-6_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-6_256.rsp new file mode 100644 index 0000000000..98d33b6b08 --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-6_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHA2_60/6_256 + +pk = 000000076948691BBB3D39575B96EB00BBE25665738D3B70378EC25AB76CD8D200F9BFDB04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 000000070000000000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A6948691BBB3D39575B96EB00BBE25665738D3B70378EC25AB76CD8D200F9BFDB04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD0900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E7040000000000017D93C20AE191054626B3138F02E186A4607EDEF6E32DD3B2D788325E88FB01E90500000000000159008B71F97B67D9710ACBCAD0DCEB434823D0DDE4E8526701AF9ADE23FBCDC406000000000001410E6F39D12638391198E1827F643E6547AD7438BE85774B713D8FF3D8CB682507000000000001030C34B96241353C81CD7DDEA97ED6CBED8C9F9FB86DB60A6B78E39A253C001B08000000000001B07CBF5330F3B30963D6B0A4AC7AC4DD77585E4EB8A08B62B9AF1FBF42B76FE509000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549619B2CE208EEF551E81A9AE87029B4302D012853622BB3BCD47FBB055E048923FF9ACD043DD40211F720396E02E71DB06FCE4E8D757DC264B4F5AC3089FE49361710B3FEBAE56D82E67A6C29504D6B061DB48FFCD3AB91E7B6B870AF8042312735EA06532FA075BA5DCCF6C9E92AF59BAD50EF0A3797C335F50FC43DF22481EC203C13BEEEB42DC753BE45EC74C10D40CFB3D55B68602D288855C63FCE824A2F4A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113CD47F2466A56323209409FD7FCF7485A71CD8CE96D61298A20473D9ACBF99C010000000000019AB3950B30D3E7877159B364A25B214B41B8AA32E293E2DDD44AEB7DFC560A82020000000000019C359D104347B69607EB28A02E6924C24BD2A26DE4CFFF3FF98E48688E291E58030000000000011EC9B78F3B1189A5482238BCF700922D642E45D07E7EA10833E31A4CBC3CA08F04000000000001F37353B4AAC3DE6FA6FA583102CC2F35D6CC95325A07AB88D9B0304EF6F8103305000000000001E087F84EB8A6A13A9581B22CDEEF8942E186FE62896C636D0503675B28692B72060000000000015FDAFB6EEAA60CDFFD2E2D1C034AF7306D60B106F145206FADB857BA565C66FA07000000000001CA463E7885C94740495E419265530662D2D8B0CF6C9E7C290FA86E8E136261DD08000000000001761CA5CF20BB11D4515629D8BEC9D72E02E0D3392C20084723610CE22260DF920900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A3928351163E04D8BA817C168A0CE68CAA6FA744E7E30A2670B2BB88F27810C887E48E90EFAD40F9735B5767F60EC515C146D56EA534C970E04BDD10302D85A2317C478BD195FC93499C051F5AF61A6C5CECB89A1D67BF5BE2CA7EFBDCC20B884597EB2BB0799DB9B86E2EB8FD93389AB91A391F2D68A057FDE361AC97A87F4406F40A7EE2E7709E46DCD756617DCB0DBBF43E6BD4851F3D834BB53CB150D2FB7B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019C1A7BFD8300283215BA57DB5CDD95EDCBD04E1C41419317BC2069C2AAAE22130100000000000143ED646E32FC21554D8DAD350C5732270CC220F7E264ECB5B7A8E8A4586D0CD002000000000001762D040EECA13E137753604D099809D946063368BFE1C7CF0E6549FCA746F7C6030000000000015FB7406F1B25A2B4A6A1666269772EB08D6FE78D8A8395C56AD80FE6924DF08204000000000001207155BDC49069839D60C0C74C9F57C739D2F36E6AAD0F698CA840A48FB11EFE050000000000012B5052F4510570C5839D41287DA3BD24DE8CBD40BA9E159E783C5812A28606A7060000000000015C07001390BCC398A47CF40395338496D66003B5E0C1DD7187A5D605984F79ED07000000000001285C8B2D9B398B8A212B3CE0FA820CE44048C2105C067AB9FE6FA70B1E712C33080000000000016F81A741E38029A214AF0CDE4C75E79A618C7B4942F7819A53CBF8EAA263EE49090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044E3C9C3413B4497ABA623AFE3257572D979FD7234C04292B8EC507187752446AD11D10DE925035D368AF83D202AF6979123C7F3B7FCB8D83812728A890B5C09B482529FFC0737FB59C35B552AD7C5820E27332D2E44F2A31ED972E2E5C834FCC652204BB401557D6FEC656BD9F63B9226056E2D025988ED1312A2A767D418F1342BE489B463AA4BE823D471648D9893364758DACBAA63BED8B3D8D4DE1E4A768B07A9912E72515AC62BACB31DC0EBECCAA1360330949EAD48841D91C61B13E2EA79C1891C9290FEE2F779EA4EC57692960A91913AE591D6550BC59CFCC5EA68483E4066EBBF11C2D9647E7B5ECE7845996AAF856A1BC1458EA7C88E73B1C19FCE34B68DC2BB0EB2CEFD4506D674C92A2BE87429BC026542F6F8F48CB088F945D76C07477009F8F9D2B41552CD688E00D2A977C67003989D0A2FA7688B410C6C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017F7DF0085A4DAADCB03AB4E8241B0E6DC05E727E817C3B6FA27F05AE1FA2DE1601000000000001BCF2F650C31EFD6F2F09775A3B4F87BBB33AD0D51537DAF37E0D1C1AE8BE8DC00200000000000174F4FE7914F390776AF328164E738CA8EB0751EF9E535BB1B0E80B05762E683C03000000000001241535B940156367A4ABD922871FB10B37235B67CA38CD8B2B02AA8064C5CAC60400000000000158C4427DF89BCC228982E6BB71C9037890E11D302D9C0378108AFA067D58D55E05000000000001384D1A0B27013C6337247C54AA3DCCD045A950C606E556515E5055243CCE916E060000000000012318CF2B5CDD3ED1DAD6013254844671FBED69801D2017AB776CD63FA76F14E907000000000001179C26EF68F54F7CF842BAAA6E1D70CD828DECD748E792E5689C2BC065D3FE2D080000000000011085411CB66EC413039B45DC41D9098C2EE6981718081DE0A120AC81043DF7AA0900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D4FF586D6CC300F09F878FF5FDD7E7BFD0AC3AA2AEC0C223DE23D190C6F67AFF7C00001F7DE39C907235BF8D5EC16A34AD2D2E6DDC419F5B24EACE1A17BEF5CC52AAA05F04D5AA8BB018210354282E98DABB918100165E7D962A6F396F22753B1FB928AE3576A91CE62216E9E6214ABFF91FCA2E6E77611AD13F70CC87E67A1E6D886120CD2C2404E0312A57635D1C2524C97EC0BDD9DE011D158F8FCA7AD1A23B38A0E6201B3A52E5BD893BEF169D6E665829DCC297E9BF3DDE2974EF56B848D62499354AC81D756C3CEA6F0E5EED1E0E58EA69F3843B09E11F3BBF8898F1724E4BE566D1AC9AB166CA7D5CDC3BAC80652CC469E048BEDFF5444254926930835827E5FAF2CB16AF0E0CB13A3653AE4EE9C49D838F84D3464EC035DC31E025F30A12EA7630A6A630A351E06620774E7CD342027BB9AABFE167CBBA7D526F0767000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000186A69EB284CFC56C72C2C83351D5CCDBEC831992175BC2D2D91B3F9378E0DE9E010000000000010A318F954C197DF2DF39A85C4B322E7EB1B16B0B4EB8C8A492F4F3B904C47E7602000000000001A9204F8E84112663772797AF87ED34C559ED4D6D37E634EFACE6A18C700CD53A03000000000001D2E20083FA11E157A2E5B72C9A986D3F47348E54C1935F48A86F7A9D78B2BE600400000000000142D78126E30680B5A226E280A30E4A2F47AF1C173AE745B1A3BF3A129452BB9F05000000000001C63B321575E217F363A1936335817B6BE75E1776DE1123AD6737CC50F99C7876060000000000011CE036EA27D47B8F7AD9F59C21D3402E6026F55694410ACA06A2972ED23F24DB07000000000001B12F5BB6C6A34E4011BC807F2A09656EBFBDCFF75F962C93B647842AD5F390A008000000000001BA14498E89CD4B4DEB6E14FCB1E51605AB6B7899F804195839EF2E0BA9FE3759090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014BCBE4FA64052B0853EDE00CD41BF95B66DA2A519216FA1A0A8BA5F10B4EAFD8BE62C40DA2A76DFD8A5EE8EF42A8B808C55A533FC488A2B33A935A635E24F3E0C717E2320FF575ADDB18C567B1333DECB0855E069D5759C48FE6D8C6A9D217BFCB7A9D40735A3151382E3456CC4BEDF6C7EC94F186FCB6BF9398FEC934714E8E231402FC7BD5153981C7C789B26208DDD77E4796F70D6A72B7B9C5EC75E4E3CD122F72621E92B1AC515A33B12B1801B2C3E461AF788661815E6BAD2E6472116B89B941A0E68A232089C6F831229BE2EB0CD244BE4FED78C8371D2DC614445C76907F4A3EDF18722BF0998FD03209C31C348CC79A2AD06ABB1B3CC549E73B206A05345EC801A1C5C42D794BA1A35747493D76CA8567B62F0C2151923D8D9CD2F37D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB385C19D6AC3BDECA5BE59F322A17FBAFF466E945FBB943BFE35854802837FEFEA3937069240712886742E890428C0C21BC057E82D5BB961095A5A18DE149CD19F79E9DC3CF0FEB5149F856C5A7BB82B6AFD4B5310993D9E4E1D33B4CC601265906186B98CAB4AF1570CFDC928C0A221A3BBFFE8E566D580A689AB51BB69826FA60135F60C1A1EA97CCCC9AE96CC93B66942370BCF910D916CBB7F87A0BF5EF46DFEBB050637754B0E40509441E19465B238EA45270D7BF5E0610A89B4A47AA821D9A3BA58127DDCEE4E7204C38E0EEDDFF72B07FA5AD8EB1FA89554D940C2C88EF588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE5966743689380FD336A081B8C7F753B889BD73F10345B8C4988A7A4C865250E3707A8424B606059E3ACEA75F2F732058477097D5BF8F5A2DF82E4AF0EE9C4BB251A5657C15808B7EF26806E2F3D61137B44C9DF4196A9208065ED1C70F9DCE3C75AFD719F14D79818812360E4709E521E78B983F99B31863039069D3F86FFAAF318853EB4A1AFFC5E598ACB6B15198E016C779BB7D77C54971E4566C2071EDFC0D19B41827913C5F7EE5D8A9411AB2706F3C9DD8E2CF4AF497765A647C1AA42E3645485AD6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291B3530D6094FDEDB782E1C927C11235EE632F6C3FA150DE1BC1125FEB330079EDB0733B58F1CDD3D20904F85DE31C06FE375E7D1E20F4C79484C5431A026EF8F5C8AC47E7FEA2A80E17256ED956484E9004BD99AD8ECD0D1EE5790A83CF9A14827C3B5D5C25AA18255F5D512917BC1FA868AF35ED3540BF0C10CABB267F612C26AE27DEDB5665A4DE3913AA2631C034C1BD22E5A721194BE6D1E4337D1CF488E9F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA498B7DA996B2692EB8C3D1D8BC9BECCFECC8EC67EE3A87DF5B0B9C7C887DCB0CBA7F5E1372399F3A4F4CC7DF247752994CE0D024D2C6E620EDD0B8CD30891FAF58D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB074AA6092A1F23DCD01D8B8C70674D55670C07A6D0655CF37D0516E6E1102865F0C53C5AF80A45B09B078337D61AFBD12DA2820AE45CC4B213C00576FF3D5FC21D0DB8D877757226F81078653EB4C90C0D2C7D304A6E0C4265DC3C1DB343202664008385964C6C56FA11532D7CF41E93F92EF28F3DE2CA1D5817AF2114A97BDA7F6504EBB2A6EE6BF4753274BE064D3CE467673717AD7350DE4E83A1BA27306F11DF36A2E30572E3FEF2EF6B2518419395DA9B7D4B191C88F3A863A477A2D226E5BCC04E39AAF1AA042A7B115CA26BE8DA52A162FDCEC6E511B1497FFB8B8AD23D3C429F71236DCAF9DE275D7B1D2DBE83822FF7D8C9BC7BA3AB5CB517228AFE2E30C53E64C44D02CF9CB51CE371827CDBDF798B1723B418EC7CDF66CF09F444A06DDB94355F529337D6A3178D754D68BE658934FEABD4F4874B11E739F0EE4E95D2D23B41F037B9668C9F74D2B3D31027861779FF8516A29246D766D2A61A02CD5B8E338B9630E8E0ED5BDACB017A6D3B89C8A1108E525BAD96E203E7A0C0B7F2148274FD20F9B53601F2B38DF303D7F8785D06260485D7507782E11855EA62F44C755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E695CCF3818C69AE16DC71782D99440EC9AF4A9C33FFBC728C9C62C47E0D37CEA661064246A8B2BBA14ABF5767F33E490AEAD721929515F091663B4437BDC34F5B15C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFFBD90B13035960ABEF4E3CFF91B9871E49B16A6F0FF86445C441921D2E698117109D810C864F024F62F8D25C263CADA33916763373D76EC8955ED113F71C40834E79A1BD5E21CC2373598C66168492FFCD083D2A8E7E480F76274C048719AFF98C5E2774BB1039646BD25A240875655A77023B7F884F5852DCD9C5DA173DACEF7F01F6527CB7F5375FEC1FD2D5C90A46D3D0501715B2D4CF51166226D8F35DB7A9ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272AC230107F230E29845C2E2283763A5832809AF2428C304C07CB21A96D7B7CDADF857F54C91A22B8AE6E4EDC0DEE01FA60697269BB1299F9FD7D3699D4D865A25BF0F31F93DAE1D51C42FE755219BC2A4B2505487483A1B81BFA86BF6A99642C51AC3DC78D5E42FEA4ADCC51C0501A8FD543217134694262E0FF5957CE719766EB0CB34CA2E541992CC2619C65822A763FE6572E3B33C4C8C216B4A62A13BE7FE6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156D49ED44C7713B7A50EEEBC575166A1B6CC3AEC2CA98398971F648242C35E8EAA21257BFAC587485D48AC54BC306344EDEBBF2A42B7E37B6086B1D9F54255742F1C9BBD708D6DB1AB7F44BC2473A4897D83DAEA510BADD3ECC8C9F2E4F889D5AB62334F4B56AA20F9BB57C09EBF41BADB20D36485AD613C790428C382B437866A681635BB509C97D4AA12387C320F6CEFD1838459F0DABA3DA54684B83E3ED10C07B8CE62549A876A13D86D8F3D001504D939500462E64C94B6EEAEDDB8856D13AB345659CB16C8B977B6670208B70920BA34E31E6A10EC724CC6FB3C299ABE890047E1F6B3D5A69BF731EFE803088FC8D3B9E69DF3102AABBEBE90C3EE20DD829BC1C46E6764AA8C8E2396E4FD1A65A171D9EEDB2B04843DD2845B5E5F5BB714212BBF4237C6D69B1D61531257FAFB41BCD74462C292880AA396FDB392A42C4AAD9B5492EE4F2A076CEA42927C22BF7CA54FCA135A0FF512CAFDA620DA75DF70C37EDADD455AB3C8EB0F334679EF94E6ED2E8BFACF20DECAC68B3AFF3979869B755D1BA8476CF0553AA3B5049EB57DF8F00AC5DAC2C1DEF316793E5DDAF9F352894CB9E2B7C860E4D2BD42D0053B2BC8C7F3C11FC0DAF6DECA58CA37526095779A89119240A8E28D1D44AE57D7D3252B69192353D745AE1C066DB60F6C6E82F35854FE73C1C961A0E178F047DE9EC62C589C2D7E30929DEA6CE37C4042F04615F48FC178E8CD389A2DEA13C83E2534271AE7DB54D7C89B8714666381C388D37BEC8102F8497D8A820C70C47254582C5C27D3D97A6ECE379315D5520BA346E8F5B5F7887F9E3E44FE4C156E7472EE8D9C327587A0704A8035E519B1C4A9D2E07949F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DB9D6E9AB3A0926402DD8095AAFB46217FC41A2E0D7C5960C1FC814E461B1F1F219CBD0A97D50180BB017229AC9F884896F357900724A3A7A8E4D479CF6A093FC30778F755C63CF618073C40F6042FB2143DECEE8DC32CE9D3E0064EE378F78B8F945A05629C118D60A6AB5DE2DA55A06B7325FCCEE42C01A5C408F0291E3610C44684BE1F66D3FB8F6BE43EDAD2EA87FAD50C993CC447DCAF79AB19DD406B20974363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D024DAFD78B7F2D3B3C54AE60062DDCEEC2BF3A579A53E27A72402BED5DA1678158142C023B3C238A93F3D1CB8E48EF84C168E27E6645DC6DC6689E89CA0A74D07087B760743BB526662636725B7FB700BBC0B3A73793C291EBBBCD4970B27370C2E85E7BAC610B75AE5CFA9DD39290DA4DADF4F61BEFE0F87959174D2BC28BD76B780BF58A5656928CC6684D80B728FA0C1570B8268DFD57EC9168CF7D39997BC8458A5D4126FEB278B26769C4F55EE77EBCD778D00F836BFA6EB13307BA2D7417B0812FDA4CEEDA359BF73865982622728D7EA8BAE1620A63483DAC957E4F8E082588E12FFC57A2871119AED0B43DE4ED1EDC4AD6434A485C64D9FAFBFC7F01A8793E5649BF33A7186BDBDBA5DFEEBCC16F2CCB67E355774B8C32B932119DA7158A4D131F560491BB42B47C9EF1594FF6F09BF29E972502A7D62A2240FBBBE55C3D82050B374EB42E433CDBABC163A95A6492A7F7DA6824B5A20527C9D0933B97C753932ED9ED277E40CCB8C4A042FD5B88E9C5D569A48F512ABA1DE68C821BD20C1A995235727654ED6E59B063EBA5F4046E7D047B886A22A7D7C5BE009F3E14629FFB78F8555B7376AA2B7B4B360F0D3C295ABC2590CE1AA36943A46379C1085D66FFE0DCF3C37C89BBF1C7D76B6D62D5D2D265EAC52164E4799C52D9A7E67836B66532608870BCF43815BA0633B82CF8E92FDD0A4DF829039370202BBD93541D4D398C42900F96D70AB85AEE46D4AE2CDB5BC61B0E57DE8AF9BC4A366730CC4A8443203C374F1F58A2203BACAA6A0C93783B0BFD8E85A869ECA37AE0FA0349E9A943B50EA190BF7E28B4406FC4B14E77203739F8DF7D168EC43FE06D0645ADBFBC26542CD0335EE21852C8CAE8DBE734028D2F6BF457CB086172F176456A64E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC40509461C2CEE814F7E26684AB01D51A1385EA51162E9CE43172A1564809B328A45AA68BC14BF38692467DE23B8908FB07BA05C90DD44A372477233DEEC84BF89287B1F8E1FED4F275FAD98265AA76F0D798266081567140ADAF2A9C64F41E053D1F329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB03F8A842A1FF048CFCF92A8D77409DE43CA455C5ED59F89358559BE214EE1B531915180697A948C945A9924FD6864D9CFF00E1D47F38B54092E4CFF1F92A65CCABF206A7D71F25A66969E37EA7D52EFD74B80E93CD7A048F71EDDE1EAF82A24F20145528EC96BF1857E0F1D8F19812EAB34E07D4262D195D1BB4D20FF3E226C2468B90E951C8212023248340ED5B7E4EDF3C6AF6A6FEE63F8DE613EC6F1526E3F6A9327A17C2279BEF50B6CCF1569A86FA56DC4B8866C365DC5D16B9BA888234D6860885B2A420401C0E3F8A971BE2CCF46FB27EB58D6C8EDE207B703FB7EBFEAC77465237E1EE73B675C37F656EBABF91BA91A79FC679C5566A637F6417B8981C93D4B2B08DD6DD375D4C84791CE66913FD4E3D6B01287F258E8EB01A223CD222F81B1412BAD3DF60D89E29F4FCED352A1DC0D52A296D6D8145BB66BCC936BAC362F309AE4520552C369E4BBE918F20C4AEDF8F037EC9AE0A3BE8BA1BA0CBD40949CEB55F41C8728AA639789BD51539F1AFA46F71106F428C9FC659F34F6BAA879DADCECAAFA80505AC2E0ECBBDBA3679A483BC7B92A54BDEAADFA7F386BA0AA79EB4AB02F6134488DF1220F8FA56D2C14630DA6F79094DFEE7180D218C621A32C153D6E5AA82C318BCBEC16FD901CB860793B8B3E9E357D0F008EA80BADACA56795A369F5E6F910F706986E7F66A84B100C265BB5339972BBDF6B770B694B8D2DD8323E86A90E83EE039AE031A331E6D7B99E75FDE0E8E42AF855F52C925F1DE1A2B10D241ECAD1523291D88D5D0EFE1D5CA4DE89F22AB2605BB5AF0CC6564C0FEBBCAAE5A19E133CA77B6C4AFE98FA12CFEB1A87D38463C35DE33D5B7D2E08C3DAED2A32A25502AA2B4E2F2A330F06294E202466F0701D4B361C71DB74253ECA3148CC5E1119591830C19DE38FEF1A5F9302B766F68E4E6616611EA940522EE92E6625C8783357799CB4B9F6A56A84976EDB84939B94A676D4657DBD04F7D754A901CEE47AFF04327CF6E0193DD3EF8CD61ECAB28CE8CDE2A56ED422C47BBD5E4B1C005EFD6C982E1601461DFE8EFF46797FCA8B79156473C7A964515B4A0B4373513F5DE44B5088663F1B9D235681C2A0F31675B7BD215F95D42216FC76E5C93A2C8929163064A58FCAB39F6A8700820BBC9EB62588C0377C15BD74E5B7E4F11559E54EAA502404D245774A51F17A9CA804C570941434AE4464CA23D8CB2D042633395BB951DF71EFCE0FEB7AA66CB0EBC83321C73AAB08C45F89D8DD625753795B7BDABB1CC042A4EA7BEEBA6AD585ABE6849B63C9630142B7191742C772BEDBDA162F8B4101824D6F16D189D65446852A08B37F359617ED6B0F2DC1A5648983AFC78D3D4009BFBB088F85D85B551DFCB0C99B46C65130CF3A25EEA02FAD2159409FEA41A7F3BF71F020CE618D82E4A2D5DD005E1E8839EF6B43D864647D89502AC44A7517F0D0E9E06BF9F55BE677F11F7A4689D51E5DC4892181C32AB56A831AD8E8691C9DC7C8D59FB0098C7581BF682298C353CAE2242C7BDE5F5933B48E88624CFC605A87E401D4B01FCE73BCC86D9FDDE138A185AB4B79B2394FC0718A30D5B8FAB24C2A67DF7C57690E380B21B9BD08674E49328286D6CD82FD782FF7BABEE169FCEF38BD5DC8ED8ACB324A374F426B0D835A5A947627DD5D026DACB3669212EAE997EFA073A3800694A8470BA89780C06F034BD1ACA26229A7C13345B4514B3C48A810C8A017062BA454688349B3244A3022F86EBD132636D566A899C38D183C149E8C9EE50F7F254409A4FA45ABB9B74750B0FFE552845BD460BDB3FFBF6259FA6D048B59198B4FD2B135A9DD870881D24109F95CB1B0857B395683A40C358ADFBED50D70A8FA540F6006D2493B59AE4BEECC8BE3E70396BF298B2F49B468B64DDAF12FD0C594DC243A782FB8862B2B73BF1F59FF1B812DCE96AD72D73D928EDD5D6D384CF214C7EBBE25676FE612556461D465BD1D1C8AE96BD8F349371553AD9E9B80623B49D5C8C38489415ACE7DB17DEA495DB1CE9B68AE228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023C8C898A4A7D16063A2F7FB6F6C00EBEBADE4B5A79A9814803CDA526D542E0C4C44DAFAE06659E810969F48EAB6EB002F7938B62157E85E1BF258D2B81ABD9195EB828938D84BCD92C9793BDA17DCD6ECB92068BEA49626C4595EE621E192309156F9B0127FA44454075F7C73A94992400B22CAB60A056EED2E04045E74494017E601F044245A2B64B83EA8BFEF2A02A32029224D3C9F5DAE64E4A3298688C1E4205FD9038743CEF33B08CD9366560AB57EEE937008332B6A4224476A759B07D04DEB016DDB8EDF3665BA71053A894F98DBEBA95EFEE3F46AFB944601CC71C39315012B024E672E7CEBA843F35C6F435983AAB0F14BDB63B2D130A91AF9F72CDFD73EA39DC02AD3074F0E4B3780E81732B550B298998169B1640D80FD56474FF655A233E3ED6C48E5D94A4C6D31ECBB5257DC07F29D5A4C98177DE0A4DE1BE24D2CA3CEF4DD2A3FFBD818E75023732E1F1D3F9051AF6E8047081FE588E2492E5EB4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F933819140A786527AEFC7A872908B98E8356286485E2ADA68D8733129C32FE7E0D0B7AB63E890DE8AEC5DB2D52F88D328E1DB56FF586DC2026817A277844C18228D01C4A792C6D27D72D4E36AC852098685807B31A411B62DF550CE9C5080F1BA5CEB1634B8EE7CBBDA91DA660CECF740A502064AF7781F544A2A9F6527CB431A33A905262210B977C09374F03C360642BB200F00F13EFCAB19685DBAAAD7EFBD4D42A8B428342F44A61D9D58808B9E7620ACE2D4FA47D16FA98950485E67EA182414D9C7B78C51CAA4960A79B1BEF4B6BB5CBA79515042433C7505B5038C4DD0CC8805CB9C1AA93B2BF96402909E229C46A5C2C7CB18F0B7747642714BF204D42A8AF263AA6C8F1DED9414FD0E6586D7B680D4BF1CB6CB6DD90D63511150A76C2C40384A4F156E827A22D0D207611E84477254E492397A85643BE2EFA36371F9DF6119813B2CA7F31D099B0715927919FFABE384400D3AA0869AF2E95B525D9A1453679B1624C4F2718AF080BE493D1DF583843CB08C5FAC4587627805AF278A009530F8545958E7C04ECD445240A70C6D0450DE5A3F3CBE710E610D8EEEA17F97381119B8A53A62EF7F4B0D8F84BDC86BCA2245664DA120E7E36945038F7973099B1ED88113E6594EC0CBE05B5CF5ECEFD58D48FFE4C16E0F941FCFFFDE6D3E584584EC8A03AEDB6126EF5F479E4FE8C97BA01A4980F78D12717DF17BC4E9040B105B2D74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7566DC65863A7E07D0D8774305019C67D504E7FC4DF77A8821AECBFB762EF377DFDE75F24A9DEF9CA7997E8F4AF3B4E60071F11DBA6303A964B7F9C3FD443C766346B4B1E50EA1D79357CA76ACE991F4760184016A12C2368F7D4E6BAF0C8EFCF4A869F3973B41564F52D762BECBC7FA49B40D6FCA22052287E1B10DD8FA257423F984FF4CA38BD49F322C84CA37874056055B3A0C51060360F05BE3E1DA6E1829B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F3171151E6F5442468D000FA46F17DC7437B058242696056ACAAC06AF22742452798DA226D91074DEFCAC6C3D770DC54CF7ECE9ADFEDB3B421ABCD9DF305D412A71FC77801FAEA989C03A0D633C4B06766491F4C0DC67FF8DEB16AFC8BC7E3D41601BF7B964B91A8638DDB7CC08B68691D5D501B5D3D72915442F0D1B9EA4DE4A84F8D037672EA110B3F93C3AC7EDCC5B5211DCC6BF4685C2D711AF156B82961C5369170E2E76ACF126B3036492BA13A920E126E7CA29791835CFCE00B3EF7AE43ABA16123C386FC3AA80F7F55F094F1664D67FCB5B990A1B93AC8D9FD02595A6005B8CE100F00F9818D7C2313416A65FC916B102A019EB2C7DE91A346F6E3CBF7CD85D2E8FEBC968AE7CF4E6A64400C45C7F71CC17BDFCD337C726028AD4F1956D8AF94345E2FF8F1C9E57AEA206DEEC8A93010DE204CF6F3D9CDE952FB8E4955EE2708B8B19C5788865CACE48EAEAB016AEFCF9FCE16621401B9B14F01BAD76AB32105CFD3C5A3EC7E7CEDD9A64C0B2AF82072F95D2762333ADC34CCAD8B93DE773FDED0AF8569A4ED1032A10D522056894A78C45B0C1FADC66A29CBBA8AF0600B416497EA782E66C42A4B1B518B7DA3DFA17E2EC7BF70208F1911CADADF3173E26A9285466819AFA7E43CDA3E79C3379ADB9F88A8C460AECDEBCFED326E15F01E303A0BB62615B2A2CB097B045DEF6AB46F799A70EA5F4C54B215A0BA6BC2BDFE5846A65D620BCEBD2607DBFC74BCEFC9712B8AAE5BC6C179B2971829F9EA1EF896FE1F6EED7D4A3B6D04A0B96848599BBD3A5A4AE6431AF6921A26726EA8B5651B74CD5C5723D8610CCC9E9220532D22E4BEB538A7E7EA50B7FE7D21E4F7EDA1A6E232C8DA603BD8A40DD5A9E87778D5EE4E2711C229E5F66F7C19CC263A38A184B437846BA2945CFCED1C270FFCB2C9C03D8EBE37F9E2199FD4084E94A02F74C3C2E3D577470B3F3F4B0B7CDA7671722B1E900A49096AF21F74E327D4B9204FC3D7E3AD6DE2A5037A2FED9BDB1100870156824C3E2B736F55E200F84EF5C0B6D39FF0A929F20749413DB40418EA6A764BBAEA67EF31C107F7F23A1193BCD26297EA37CA92CF90973BCC7BC548C62EF44BD5FBAE7CA281C5447895061540CEC586CBAB07CC6835253C332BE03CD64CAF6CFBA2C5768AAEE682614AEDAE4CA6BF839963D13970AB2D37BBD203FC8F5197A62C183B76BCBA09E5E47D686ED98A652A176A90284D0034391003C5BF6E9C6A091108A3107E128BF3465BBB72CD50C374A343C714E7AE5599915411D31CCEDC7ACA1734B5F23783839CD46D0786814D52037477FFD7600129FE5AD39C8601C30088977D58C83B2D0B5B6AC14579F5C52BE795726F126ADBD2742BE107CEF59ACC94B78DC7A51AB01B4A3B212F10768D35C3CA5CE6D4EFC33995ACD07AFDA29782EB4D86447F622B2592F7D18E835D5F922FC7FCFCA5F12251B5A3DFAD7ED2B6C9F3C6B734F34991C30C700EE325CD9752D68D4DB9B5DD98F91348C1DFF570DD106D0CB457C4108580FB341BD44DA99F4AD058B064AE955B584627DCA083785EBC199607782B5B096DDCF3A0EC0C5F4FB69DD11814016F8AFC30F853DCF0B793E150C3B796CDE2B1B43B3E346E257331504D6571E35C7E2953D0B1EDBC4B1C48F21012DBDC773107FF4B459FCD253425217787310AE7D8F74F77E60A4511B8B23A6A1714BDDCEA8694F2A8508991C555D6C1DE281244E229377BB4FDB9CBB38AE483A3569F735AC438C492DFE9414F26D70F154CE91D99105D5E34340D34764482934F3F3145436CD3AA2DDCCEBA06D0439C960E7D16BB68113560CABB3611F2CBC43D79915CFF16CF0BB72EDFD858830AF8C790F7F1C18409C4C48601F24454BC986B12540B74EBE53F5F3AAED84C8DD523702B0492BC34B98F2AF02C856882F37D1234C04B42060DFDA8FE106CF570235BF1169F163501B400DB5A48D7FF08851543CA92A0E8448F98BE619F41F4C820CD5553B0132BDA47AE8C0A85874D1FF5D23AE2158B85206E9F95CBD6DE6F2092A31D700E8E86ED0009F9780B1D349E01944FD5FC58A95CCC7502C6B1385AB36D24C663C8316F2F453E88A98EA61D721FBD4B018F43B84DD5B5C83316488AF78ABBD005C15399B7F94F6AB6F5239B10CF44B82FA774ECCBB5CB932A51B1C5202F112198FF20A160DA0DD130510C4540AF4C9ECB078C38AFE183911E2116F130DAA83432E3B05F76DAFA8C9285CB7237B57407F2C4999D4ACBAA916D2887D2ABD50590B5F761D3995A3D484A632696156ED00346555A19AD569E80F2DC6FEF929F3AB753AC9F451D991D1F9C614CB562F9AD1B984E94BF00204B8E0411D9AD0D374A9752B6989CB7AD969B047E60F5D371FE4FC3D17B4DDE42878C758FF19EE3FA205FFA1E5A3ED709AF71DF3527F26F712462C0AB5815A447EF29BD1887D7CB8FF44C2752A9E1BC890A80A5444E8384BED9EFCD06F26C467FAFBB01B97EA07CE0B5091605780D9770A00252C92C4DEDD4D8B942E14C90DFC5BD612D85CE24C5CEFDB3EA964FFF256B20A4DC2C0EFD50DA4BAB56BC846B09DE27F341EE42EAF0545CD82BF62FC699298C98D9B9947D436D234DF8333E144C207D0DE124707A1A3262CBDF544C5C6FE70F2137EDF11BC8A3E2E7B6C35909DAC8C160CCBF3FF25275B7F97E5E0D56349A1AB617E944BBADEFDBBA8BD06B26468C961756F0E1506F5D2C5C332CB7D18155B3964343C682A5721C97BD5F6D675D44FBB9B5C9AE58A02BB327AD51C927CED9F3E27C8DCFA2EA7F4F20867DE29279B5DA09E70B6B6ED9C2C21502D185DAAE79A792F5D79C8814375643B4E69440EB7AED63285EE40ADB2A43111BB8E45D109B955B309FBDA17862D551F72C2EB06BABCFE4BCF46468789347AEA8FD0CF3E2938521DADC71D0EEE1F435B38023B69022FDF00B3D1AA0A456DCB917056F934240BD6C899E8E0D36E4F1C8135F74FFB493B7591BF9C2DD47E2C2B64A5CB0D34A0DDF8486DC9CDCF85E8D5FB8327A486076AC1AFB63681A253CC57B65DB36619DBDA966569822860B30D9DD55BE869766BB1986D254A1C486E6990EB6CC4D22E829230CC0B5CD80B6E0C3E4465CBF7AC3480BF67E671B31E38F24800A61B0C98589FC4D98BC896C27D4A9F8EAD8CA7D567AF1796A82C64F3A9876B921B4F9F009EC821DAC29B54AF75F0F5F59BA04AE753A786D0FDA22130A1036FC1AE46A86DA837812C7FD4539985A05346319FD809739255705BB1BBE7791F520D43F33F06493E50423C6418BF781834310AD40B92E396722B1C67EC08FB5FA918351C89574D5A47D31D7F6D25A30712BF53AE5410B587B9CDC0D652F993ABCADD6442E5F52229C5011D36980BB01D0053433DC64E02F535EB87F04F2FDFAD3A4378477E4A0BE652FC73E3604285CC0721796206461EC07608C4A8C0C913924525EC5DCF185891F1740E56E4E88E3C957D028D5BEBC5DC6AA9CFD3B6A94CA9B281DEB7FD816C7DD27AE5FECACB499A764C58CEF0EA4A18999B80D89D2074754894613FF9A019639CB6E1A31B91F6389894454B884F1F76BF3A20984E908C60BF36D3CCF439D9B200C3C97E076A75B5209C363FB23DF3FE4A8A792CC9FD93527667603AE461FCE62593DD7DAF62D1D78060E4AB4DC2424BCA29A0C96ED4978987C8D4F2791F61AFFD6300415F0E4DE0764AA88C672EBB55D765FD9382875CF67B176C8BC422F613D22605BFC24C2D69DA0E7CB76AF9378DD04C21E76BD30E9F923D724F6F3633928EAE801001F869B7BCCF9EF79B6FF8E8A741EFF812B31E140A7C798D8738D272068FE9A5468EA0CF60D339DD3D56A73D3BADF14504FF3FC2816A0BB816806B5CEE3164998712B9460C4227117261169E1B4C20AD79049980017BB1CACAE8EDFE29252C782485A5BAF0599796BB5004FBB2101CF98470B60E8140B828E7DDF8D3B561AA5A147739DC01970DEBFF008D85ACED07EA28D10E594E60A3569C6A13D9619FC2F76D279143D829383549772E09F3E275840913B08E0FD33C24CD38760D585FBAD94FF3B0355D247B1A5D8F22E67E34803F1D454D979BD9576F36F816005BE186FB6D58BDC8FA63935D7E4CB00A0F6752E1121241A67095E77A3231034C7D14649276638DFB1DBAF56AE7BBF54C64B817E10B6EB7E974208B16C658FBF3480BA6C86F5BDCFFD2F830801C95F5D9677EA593BA221A9E7D2F09E1E19FF70AA4A73E2FCB455583F3E21618A50CAA4B53EAF90F0AD1A47BB59B77EA66DE84A10E6D5FCB7A9CA221BA0DC44452E7074206ADE1C1B02E520B6D481C27D4CD833EE7D985B20FA5BF7A21E4DFCAD092628EC0A6E2DC8718EDA1408151C9F4C1FF4046A444CD0F8F10C82BF697013DA572E3EC04726E89BC96ED083C2387EF5DC80AC9D74144D0AD906BDCD4608974D57F515101973291804C5180C348EFD6C91AAF5433A6BFACACD657BB7C579A195C6EFEDBEF3E6746FAACF6AED5975115AF77843A5497EBBF4F254D13D82321B29A6EE275AD3389B828D1FA19FFFFE79123A579B45B78D3F0A5AF0EF44A19F07513426CBFFA519F93A4A4DB52628A2FD56DD3A323382E5DB171811EA861E2D46537D0A4E545C65F2310C2A4EFFE0851C1260C26F2ECB491BD2EFCC41F06EABF26B48E9E61FC3C550F6CCAB762B0FAB75DFF6353F814E55E98A3AAD5C82CF9A891AAAC5112D38C6687E30610AC3379222517D90CDF1AB77E96B16E4EBCA8B0E8719205FF3D308550E3BA58A9CCE5FC6BF05A4DBECFECEBF1F4B7722C6AAC9FBEC2EED1C90466147C022C4B2150D6DE9B76BE278F43197479C5D0CCBBF0CBEB22C31308982105A95A5841AA37DA3BF81F8F7602C9E68C059A36BD0DD395EBDE7616091E3753AA1397A0251EC887FB27A166DCA318DA3EDFF3E29320AFABB616813DC83D4641F3664407C3DABDACA9F5EC3FF32B6538624C2F10415019168777C2BF58D51E619C872F1FBCDC8363C69AF421E6B6C046B8EACB1233A634F492189D114FC3B17B3A6FAC0CB04BE2FB6CED8D3DBF570B66D7EA390C11D2FFE35A8F675CCA65026CD83809D8C60480A25536A9DFBAE0D1229F2D563FBA86229F6B7F7CE9A9C12E6CF024402A8DF251BD5F72EC415621FCE91148DB266EE1BDA0885827E96E8A9AD9C50F43D9B6462E6A24D508013457E7D4E3D7030DEE74216B3EB93C676CDB9F5E6754A10A635950D60C9916D00565C50A33EA1BBFEBF02BB60483B6DEDF0481C054710FDEA23BE9FAF9DBFF407E7766C84CCC3F281C6383079DC3188FBE8F9675D0A26831FE4090EE8C8E87DC459B1CE8480E64B78A5F15EB30FF165CC9F5F261B42E5EBF469A2319A405E8CBADD241C475A5AC949BF372A41B060353FA3EB8C79B969874223CC14B6E5B3EEFE72C0CB8C8E1B114AB6B7A435B786D8A8FCC935C8BAA5BAC879B50D8180B65FD0DE78CA05D750591F479FB953FD55BB00F1D50EB99AFE348B00A63DE9E79B12C5C32F257C97CA0CF00153C8C3D8AF3988200052059CF3C841296651EC607D910D661EAA1078FA7EEB6738A8484224A29CD0463649275D117997768C75660D469691278A111D50A72CEE9600124E3850507C0B963E9121C8BE1B269448FE8A4DF87DC1EED33FA1EAB13DCADDFD7F2BB0FFB042FDC6EA8C00A6379B640CA2855112F86F6FA5B2A622079AEA2EFB9D9063AC89D7F94AE3CD7551F3FF99B5A3C41D3770C44E9555969B97D719A3C5590B3D8A1F65995AB57BE3FA7D55524CCFFF8018EE1A587AAB9FB5D3E33FE7BAF2642CF9421540C134F9BDE97680458FFE5A18DD2D3CBF178E91629F050DBA86E31E5A42548E1582E271B399A6DC512CA068153BE53E78A5A6F83C8C39FA6F92626B000E8066A1BEAF2C21975B2FC29959C3AA239CDD2A4B47A55E0EC54495769A9293F33F23FE19A886DE5AAB35F3BC80C9CDD0FAD599DB6359B84F396E9DD06848EC5844B44AE00478C8C1FD5E964031EE21158F6FA1784A07A09E6173412180C5A0354B11480F780C1E3CC436BCF5D3FC2B5E094C1A45AE192369966B103D700B955D0FDC49733525BE13D82164C5A2996F0FF900DC890ADDE848305ED6D225460FB75CDC1453C513EDAB63E576CE7CDFA755055AC07036627843E640E20767EC35B45C69A28151210BC3F93EBB880C6419D545316029814C22D2872E8B0B4B4ADED8E44D0035CF687BAF0C593C2B947CEC9770E19E28B62537B3C463F582084CDAD9A704D8E4CCE851D + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 14824 +sm = 0000000000000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA70108B307B55E90F36943261B10F4D92A0F4AA0696D42E7766CB9EAA67647A56DEC2E7A09B0DC1E96F31870177ABDD7AB42345B9BF49CA7689F703557EECD4C9FF32076C999FFA0461054EA4A1E863A1FAB50E5FE03A9EA847E4A5B476A41885B53EB9A6E98D556765100FECE8CCAE704D7AE90AEABE735C2FF46DC9FB302D2A1F4CB21C6552D41F5F3865791CF993DD00FE3A036175178B6407E88A3F76605B5EAA96A944CC1878D4FBA0A59E308F18BB3A90F9704B0342262BB5FC542743D246CD503A2438B438344D55FAE0A0CBF3F6061F2AB5685E9C3210FC441B3DA673E3F029510438E87AB06D786CF52C18D7F9C95D7B82F4F0E1AEB59E4221D40C67EB131A23B8EE4F3EC419BA999054325BEB9B8BFCA6A2BBDF11FF7F8A170E9C5481D7CD71994D48CEDA477BF92043B7E7C743DFD9E32948D29632C6C47355A5701C0E3343E73C5FE2CC524A7FD21FA547675C86F6C8D4EADEB1AE29060EF687EF65344A45A5F1033DA0B50A5529AC43435DC3A8BBBC986F1ACC1AD60CC13F9BB26A1F7E6AA6D434BAB8FD8B67091BE465C3BFB21CA9D16D794635422DEF832911110F75CC152316E26583F4E3E9852B62D535029CF5E0F17381282F84B1D658B96F6047C813C1B4F4A16C6E7FE523D3397CD89A5A92D85813703EBC6F3FE6EE26DC55D4E6FC2CFF5A94DF26DA0C0170FD8713CFC44391EB96DA0957FD5066FD83C6A49B866653FAE1FE64ACAE482337978125F0DF84D9A85A5E932E940C2661A898DB130F0F2573F50D1FEBE92DC828BCBA9F7C01D56F6DB226890D911DDF82BD5D4240B66EBFAAE4552283904FC706E9B7683884AC5B893F4F81D2E14A0E4AC57BF98703DB7F13859B5137BCBA8FF977ED7AAD69BCBCF9F2CA845D008CBA0EB29D9C8155D3924964150439144860C1E5B6864506FE3EEC30FAA801B458516E35DDB4BA7A25D6C3E4B7D39A28A65A5628A93556FA9F54E273B583F9A197BFF4731E043ECFF72D42580294D9D3C8CF910D424C636850E61AC0CCF2AB7866EFF4913D36690C765230DCB89993C60885CB1850754DF50C48538A5EBA8AAB821F9B04C0A1EC786BFE2AFD21BCB353A1F77030A18BAE47C0D2B9F396BD8E5FF560328AEDB237F2717BD16C62163FA242D09159E03AAD5590CB151143CA16E6DB3F4C4BA5C64D08B9D0A5A3F6009F660E9B15456060AC696B025F2A874623DBF0B61F73C56AFFEB1227FD01AA4AE0CD5A4FA29EBCD6C0997EC7E973C3F98C4674370EF456F0FA3DFCF5C9CEC2D80AD509A65AEF0E3E663B7F31BCA437311BA799D4C2ACC138D97F323B19BB892BB18C8C530250B082F14BFB41EA7A1BEC5FEA64404E3C55617C0D7AE9E6AC7062BF0E32260C11266C4AEB1815B9D80CC2C7F5898A39D5C1CD115DAFADB4F258D8BBED23B21C65486E46D8BCA833B6967A09FC7DA038DE1464A993EBDD656682B6DF928AC9BC8079B08F9AE5E4921BA288D8234209C7E68091460A20EAA7AE055D8D71770CE9CCBE116CF81917E004306693A483A49459114295DF86CD25D3F8A716C4752F1276385906C5B141C267EE5C065802EEF3FC35AA6CF37929B5F2D4827B72B8B27B64DC91EBAB724047EF3EE1D4304B98D74984EC1CF561C5011B41F749403684937CF80B0A47392C9A1C0098C189DA2E070FAE819C907F1ABD8F0040B4BC30B0A5B8A1894B7140F8A41ED377CA4A4B94A19B762BC2205D49227CD8D9C500CFC32F70A4CF8D7188D73C377F57A9435B8BD01C875E0C8354A3E599CB7217AE688647A72985606BBD0720F6FA5C5B6F70E88234EE545A5A5DA495171254A7C4EEDBFF6C527D58C8B2010B0BD8AD0437D24E58D5DEA089B198A28F6AD355B74455297DDA5CBC8B88DEA9B7AB7D59E2C78363EC25A2602B45DE7A3F9E3C01FC51BC5D6A0E15B7B8B52A545154A2598B038C74F5873360386424FEC7650D8CC97CDD7D3E00F4C890614D359CD60FA0498E97F4AC282AA6EB56F968F9814E62F40C71033B32261344CD2269D7DCD62F7A9C9C14089C5F4966C65C61697E08F06B61AAFB4C247C6FC8412F815114AC9C3D9172C1B5CF2286CF987E323EB63EB61FB83F76123FD8CBE6155DD251E20F090991CD6489A6F4330D8D0BFD1C49F9B69A3D6A4325EA85EC2D7332D47FEB73B98F82EE9738E07F40119820C5F429E298EA348A200EB48C74CE2F0CD36756498B06C90F299FD52AF06FC80E0DD67566CD3E2651F4852A85CAE74D7D5F16E4AD53DA41D3932175FCB840A64ADC463ADADD53CE215AA2F0C4DEC4E0BB2155F874D7B60F46F671A8EAF31FC446ACA59071CC077F86F8C4723A9E227EB5E9091A504B641B459D38EB852295F33EB9706B28E8EE393710D80077306E5E83B1F23B621473F83F97BCAFB61F7E2CB455011B3E98F8CB3799F0B0600E74AC1214454C9F6D1DBAD9EABF89C060B05A54F710BB049155BD727BD117E934CADEAF3C118DD6C1CE927AA84675735E695731DDA77CCBE59CA2DEC2881046C519251731B60AA43EEE29D3F0FE2B0EAC2FAD197BC60BC76BA35F1FF80A96013054323266E972FD51C1610F8C04E01E16839CE80CEA428581B6CE720C459D6D2961C5A7FA8256FEC4951B69C04FD5383BA3FB66C2A40D85B41EE3F215A96F35898045E1DA96127C205C124C1C805814C3EFBA495E0499587494A9B6E4974C37F5C006A34FF102A23985FA9F660326DA3979A43BEB2A0C7CE97F1A180C300FEE0228AC673E5AF3D65BC5F01A722E03876D5608A8216E5C8E91E1E89EFEA60DC1306CFBC26529D23619E354A7F1332E790CD59271BECE083922C4E18B01560F9BD9C0AB1C891529371D295C1A524637A804FB84DF86BF95F7B65F3B54022725BCA40A65474F2ABBC9BF737F20BD12CFF5619912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70D8A18A427BE88BF379EDAB2E45A1AE5F3199C5D6C0BDF55A8CD1EDEC7EAF92F0DB2F3B18A2035973F56757DC09EC3CB32FCA024C6A0045077D4FC0AC0F6A26A1CC22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A14BCBE4FA64052B0853EDE00CD41BF95B66DA2A519216FA1A0A8BA5F10B4EAFD8BE62C40DA2A76DFD8A5EE8EF42A8B808C55A533FC488A2B33A935A635E24F3E0C717E2320FF575ADDB18C567B1333DECB0855E069D5759C48FE6D8C6A9D217BFCB7A9D40735A3151382E3456CC4BEDF6C7EC94F186FCB6BF9398FEC934714E8E231402FC7BD5153981C7C789B26208DDD77E4796F70D6A72B7B9C5EC75E4E3CD122F72621E92B1AC515A33B12B1801B2C3E461AF788661815E6BAD2E6472116B89B941A0E68A232089C6F831229BE2EB0CD244BE4FED78C8371D2DC614445C76907F4A3EDF18722BF0998FD03209C31C348CC79A2AD06ABB1B3CC549E73B206A05345EC801A1C5C42D794BA1A35747493D76CA8567B62F0C2151923D8D9CD2F37D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB385C19D6AC3BDECA5BE59F322A17FBAFF466E945FBB943BFE35854802837FEFEA3937069240712886742E890428C0C21BC057E82D5BB961095A5A18DE149CD19F79E9DC3CF0FEB5149F856C5A7BB82B6AFD4B5310993D9E4E1D33B4CC601265906186B98CAB4AF1570CFDC928C0A221A3BBFFE8E566D580A689AB51BB69826FA60135F60C1A1EA97CCCC9AE96CC93B66942370BCF910D916CBB7F87A0BF5EF46DFEBB050637754B0E40509441E19465B238EA45270D7BF5E0610A89B4A47AA821D9A3BA58127DDCEE4E7204C38E0EEDDFF72B07FA5AD8EB1FA89554D940C2C88EF588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE5966743689380FD336A081B8C7F753B889BD73F10345B8C4988A7A4C865250E3707A8424B606059E3ACEA75F2F732058477097D5BF8F5A2DF82E4AF0EE9C4BB251A5657C15808B7EF26806E2F3D61137B44C9DF4196A9208065ED1C70F9DCE3C75AFD719F14D79818812360E4709E521E78B983F99B31863039069D3F86FFAAF318853EB4A1AFFC5E598ACB6B15198E016C779BB7D77C54971E4566C2071EDFC0D19B41827913C5F7EE5D8A9411AB2706F3C9DD8E2CF4AF497765A647C1AA42E3645485AD6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291B3530D6094FDEDB782E1C927C11235EE632F6C3FA150DE1BC1125FEB330079EDB0733B58F1CDD3D20904F85DE31C06FE375E7D1E20F4C79484C5431A026EF8F5C8AC47E7FEA2A80E17256ED956484E9004BD99AD8ECD0D1EE5790A83CF9A14827C3B5D5C25AA18255F5D512917BC1FA868AF35ED3540BF0C10CABB267F612C26AE27DEDB5665A4DE3913AA2631C034C1BD22E5A721194BE6D1E4337D1CF488E9F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA498B7DA996B2692EB8C3D1D8BC9BECCFECC8EC67EE3A87DF5B0B9C7C887DCB0CBA7F5E1372399F3A4F4CC7DF247752994CE0D024D2C6E620EDD0B8CD30891FAF58D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB074AA6092A1F23DCD01D8B8C70674D55670C07A6D0655CF37D0516E6E1102865F0C53C5AF80A45B09B078337D61AFBD12DA2820AE45CC4B213C00576FF3D5FC21D0DB8D877757226F81078653EB4C90C0D2C7D304A6E0C4265DC3C1DB343202664008385964C6C56FA11532D7CF41E93F92EF28F3DE2CA1D5817AF2114A97BDA7F6504EBB2A6EE6BF4753274BE064D3CE467673717AD7350DE4E83A1BA27306F11DF36A2E30572E3FEF2EF6B2518419395DA9B7D4B191C88F3A863A477A2D226E5BCC04E39AAF1AA042A7B115CA26BE8DA52A162FDCEC6E511B1497FFB8B8AD23D3C429F71236DCAF9DE275D7B1D2DBE83822FF7D8C9BC7BA3AB5CB517228AFE2E30C53E64C44D02CF9CB51CE371827CDBDF798B1723B418EC7CDF66CF09F444A06DDB94355F529337D6A3178D754D68BE658934FEABD4F4874B11E739F0EE4E95D2D23B41F037B9668C9F74D2B3D31027861779FF8516A29246D766D2A61A02CD5B8E338B9630E8E0ED5BDACB017A6D3B89C8A1108E525BAD96E203E7A0C0B7F2148274FD20F9B53601F2B38DF303D7F8785D06260485D7507782E11855EA62F44C755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E695CCF3818C69AE16DC71782D99440EC9AF4A9C33FFBC728C9C62C47E0D37CEA661064246A8B2BBA14ABF5767F33E490AEAD721929515F091663B4437BDC34F5B15C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFFBD90B13035960ABEF4E3CFF91B9871E49B16A6F0FF86445C441921D2E698117109D810C864F024F62F8D25C263CADA33916763373D76EC8955ED113F71C40834E79A1BD5E21CC2373598C66168492FFCD083D2A8E7E480F76274C048719AFF98C5E2774BB1039646BD25A240875655A77023B7F884F5852DCD9C5DA173DACEF7F01F6527CB7F5375FEC1FD2D5C90A46D3D0501715B2D4CF51166226D8F35DB7A9ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272AC230107F230E29845C2E2283763A5832809AF2428C304C07CB21A96D7B7CDADF857F54C91A22B8AE6E4EDC0DEE01FA60697269BB1299F9FD7D3699D4D865A25BF0F31F93DAE1D51C42FE755219BC2A4B2505487483A1B81BFA86BF6A99642C51AC3DC78D5E42FEA4ADCC51C0501A8FD543217134694262E0FF5957CE719766EB0CB34CA2E541992CC2619C65822A763FE6572E3B33C4C8C216B4A62A13BE7FE6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156D49ED44C7713B7A50EEEBC575166A1B6CC3AEC2CA98398971F648242C35E8EAA21257BFAC587485D48AC54BC306344EDEBBF2A42B7E37B6086B1D9F54255742F000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F71C9BBD708D6DB1AB7F44BC2473A4897D83DAEA510BADD3ECC8C9F2E4F889D5AB62334F4B56AA20F9BB57C09EBF41BADB20D36485AD613C790428C382B437866A681635BB509C97D4AA12387C320F6CEFD1838459F0DABA3DA54684B83E3ED10C07B8CE62549A876A13D86D8F3D001504D939500462E64C94B6EEAEDDB8856D13AB345659CB16C8B977B6670208B70920BA34E31E6A10EC724CC6FB3C299ABE890047E1F6B3D5A69BF731EFE803088FC8D3B9E69DF3102AABBEBE90C3EE20DD829BC1C46E6764AA8C8E2396E4FD1A65A171D9EEDB2B04843DD2845B5E5F5BB714212BBF4237C6D69B1D61531257FAFB41BCD74462C292880AA396FDB392A42C4AAD9B5492EE4F2A076CEA42927C22BF7CA54FCA135A0FF512CAFDA620DA75DF70C37EDADD455AB3C8EB0F334679EF94E6ED2E8BFACF20DECAC68B3AFF3979869B755D1BA8476CF0553AA3B5049EB57DF8F00AC5DAC2C1DEF316793E5DDAF9F352894CB9E2B7C860E4D2BD42D0053B2BC8C7F3C11FC0DAF6DECA58CA37526095779A89119240A8E28D1D44AE57D7D3252B69192353D745AE1C066DB60F6C6E82F35854FE73C1C961A0E178F047DE9EC62C589C2D7E30929DEA6CE37C4042F04615F48FC178E8CD389A2DEA13C83E2534271AE7DB54D7C89B8714666381C388D37BEC8102F8497D8A820C70C47254582C5C27D3D97A6ECE379315D5520BA346E8F5B5F7887F9E3E44FE4C156E7472EE8D9C327587A0704A8035E519B1C4A9D2E07949F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DB9D6E9AB3A0926402DD8095AAFB46217FC41A2E0D7C5960C1FC814E461B1F1F219CBD0A97D50180BB017229AC9F884896F357900724A3A7A8E4D479CF6A093FC30778F755C63CF618073C40F6042FB2143DECEE8DC32CE9D3E0064EE378F78B8F945A05629C118D60A6AB5DE2DA55A06B7325FCCEE42C01A5C408F0291E3610C44684BE1F66D3FB8F6BE43EDAD2EA87FAD50C993CC447DCAF79AB19DD406B20974363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D024DAFD78B7F2D3B3C54AE60062DDCEEC2BF3A579A53E27A72402BED5DA1678158142C023B3C238A93F3D1CB8E48EF84C168E27E6645DC6DC6689E89CA0A74D07087B760743BB526662636725B7FB700BBC0B3A73793C291EBBBCD4970B27370C2E85E7BAC610B75AE5CFA9DD39290DA4DADF4F61BEFE0F87959174D2BC28BD76B780BF58A5656928CC6684D80B728FA0C1570B8268DFD57EC9168CF7D39997BC8458A5D4126FEB278B26769C4F55EE77EBCD778D00F836BFA6EB13307BA2D7417B0812FDA4CEEDA359BF73865982622728D7EA8BAE1620A63483DAC957E4F8E082588E12FFC57A2871119AED0B43DE4ED1EDC4AD6434A485C64D9FAFBFC7F01A8793E5649BF33A7186BDBDBA5DFEEBCC16F2CCB67E355774B8C32B932119DA7158A4D131F560491BB42B47C9EF1594FF6F09BF29E972502A7D62A2240FBBBE55C3D82050B374EB42E433CDBABC163A95A6492A7F7DA6824B5A20527C9D0933B97C753932ED9ED277E40CCB8C4A042FD5B88E9C5D569A48F512ABA1DE68C821BD20C1A995235727654ED6E59B063EBA5F4046E7D047B886A22A7D7C5BE009F3E14629FFB78F8555B7376AA2B7B4B360F0D3C295ABC2590CE1AA36943A46379C1085D66FFE0DCF3C37C89BBF1C7D76B6D62D5D2D265EAC52164E4799C52D9A7E67836B66532608870BCF43815BA0633B82CF8E92FDD0A4DF829039370202BBD93541D4D398C42900F96D70AB85AEE46D4AE2CDB5BC61B0E57DE8AF9BC4A366730CC4A8443203C374F1F58A2203BACAA6A0C93783B0BFD8E85A869ECA37AE0FA0349E9A943B50EA190BF7E28B4406FC4B14E77203739F8DF7D168EC43FE06D0645ADBFBC26542CD0335EE21852C8CAE8DBE734028D2F6BF457CB086172F176456A64E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC40509461C2CEE814F7E26684AB01D51A1385EA51162E9CE43172A1564809B328A45AA68BC14BF38692467DE23B8908FB07BA05C90DD44A372477233DEEC84BF89287B1F8E1FED4F275FAD98265AA76F0D798266081567140ADAF2A9C64F41E053D1F329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB03F8A842A1FF048CFCF92A8D77409DE43CA455C5ED59F89358559BE214EE1B531915180697A948C945A9924FD6864D9CFF00E1D47F38B54092E4CFF1F92A65CCABF206A7D71F25A66969E37EA7D52EFD74B80E93CD7A048F71EDDE1EAF82A24F20145528EC96BF1857E0F1D8F19812EAB34E07D4262D195D1BB4D20FF3E226C2468B90E951C8212023248340ED5B7E4EDF3C6AF6A6FEE63F8DE613EC6F1526E3F6A9327A17C2279BEF50B6CCF1569A86FA56DC4B8866C365DC5D16B9BA888234D6860885B2A420401C0E3F8A971BE2CCF46FB27EB58D6C8EDE207B703FB7EBFEAC77465237E1EE73B675C37F656EBABF91BA91A79FC679C5566A637F6417B8981C93D4B2B08DD6DD375D4C84791CE66913FD4E3D6B01287F258E8EB01A223CD222F81B1412BAD3DF60D89E29F4FCED352A1DC0D52A296D6D8145BB66BCC936BAC362F309AE4520552C369E4BBE918F20C4AEDF8F037EC9AE0A3BE8BA1BA0CBD40949CEB55F41C8728AA639789BD51539F1AFA46F71106F428C9FC659F34F6BAA879DADCECAAFA80505AC2E0ECBBDBA3679A483BC7B92A54BDEAADFA7F386BA0AA79EB4AB02F6134488DF1220F8FA56D2C14630DA6F79094DFEE7180D218C621A32C153D6E5AA82C318BCBEC16FD901CB860793B8B3E9E357D0F008EA80BADACA56795A369F5E6F910F706986E7F66A84B100C265BB5339972BBDF6B770B694B8D2DD8323E86A90E83EE039AE031A331E6D7B99E75FDE0E8E42AF855F52C925F1DE1A2B10D241ECAD1523291D88D5D0EFE1D5CA4DE89F22AB2605BB5AF0CC6564C2F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549619B2CE208EEF551E81A9AE87029B4302D012853622BB3BCD47FBB055E048923FF9ACD043DD40211F720396E02E71DB06FCE4E8D757DC264B4F5AC3089FE49361710B3FEBAE56D82E67A6C29504D6B061DB48FFCD3AB91E7B6B870AF8042312735EA06532FA075BA5DCCF6C9E92AF59BAD50EF0A3797C335F50FC43DF22481EC203C13BEEEB42DC753BE45EC74C10D40CFB3D55B68602D288855C63FCE824A2F4A0FEBBCAAE5A19E133CA77B6C4AFE98FA12CFEB1A87D38463C35DE33D5B7D2E08C3DAED2A32A25502AA2B4E2F2A330F06294E202466F0701D4B361C71DB74253ECA3148CC5E1119591830C19DE38FEF1A5F9302B766F68E4E6616611EA940522EE92E6625C8783357799CB4B9F6A56A84976EDB84939B94A676D4657DBD04F7D754A901CEE47AFF04327CF6E0193DD3EF8CD61ECAB28CE8CDE2A56ED422C47BBD5E4B1C005EFD6C982E1601461DFE8EFF46797FCA8B79156473C7A964515B4A0B4373513F5DE44B5088663F1B9D235681C2A0F31675B7BD215F95D42216FC76E5C93A2C8929163064A58FCAB39F6A8700820BBC9EB62588C0377C15BD74E5B7E4F11559E54EAA502404D245774A51F17A9CA804C570941434AE4464CA23D8CB2D042633395BB951DF71EFCE0FEB7AA66CB0EBC83321C73AAB08C45F89D8DD625753795B7BDABB1CC042A4EA7BEEBA6AD585ABE6849B63C9630142B7191742C772BEDBDA162F8B4101824D6F16D189D65446852A08B37F359617ED6B0F2DC1A5648983AFC78D3D4009BFBB088F85D85B551DFCB0C99B46C65130CF3A25EEA02FAD2159409FEA41A7F3BF71F020CE618D82E4A2D5DD005E1E8839EF6B43D864647D89502AC44A7517F0D0E9E06BF9F55BE677F11F7A4689D51E5DC4892181C32AB56A831AD8E8691C9DC7C8D59FB0098C7581BF682298C353CAE2242C7BDE5F5933B48E88624CFC605A87E401D4B01FCE73BCC86D9FDDE138A185AB4B79B2394FC0718A30D5B8FAB24C2A67DF7C57690E380B21B9BD08674E49328286D6CD82FD782FF7BABEE169FCEF38BD5DC8ED8ACB324A374F426B0D835A5A947627DD5D026DACB3669212EAE997EFA073A3800694A8470BA89780C06F034BD1ACA26229A7C13345B4514B3C48A810C8A017062BA454688349B3244A3022F86EBD132636D566A899C38D183C149E8C9EE50F7F254409A4FA45ABB9B74750B0FFE552845BD460BDB3FFBF6259FA6D048B59198B4FD2B135A9DD870881D24109F95CB1B0857B395683A40C358ADFBED50D70A8FA540F6006D2493B59AE4BEECC8BE3E70396BF298B2F49B468B64DDAF12FD0C594DC243A782FB8862B2B73BF1F59FF1B812DCE96AD72D73D928EDD5D6D384CF214C7EBBE25676FE612556461D465BD1D1C8AE96BD8F349371553AD9E9B80623B49D5C8C38489415ACE7DB17DEA495DB1CE9B68AE228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023C8C898A4A7D16063A2F7FB6F6C00EBEBADE4B5A79A9814803CDA526D542E0C4C44DAFAE06659E810969F48EAB6EB002F7938B62157E85E1BF258D2B81ABD9195EB828938D84BCD92C9793BDA17DCD6ECB92068BEA49626C4595EE621E192309156F9B0127FA44454075F7C73A94992400B22CAB60A056EED2E04045E74494017E601F044245A2B64B83EA8BFEF2A02A32029224D3C9F5DAE64E4A3298688C1E4205FD9038743CEF33B08CD9366560AB57EEE937008332B6A4224476A759B07D04DEB016DDB8EDF3665BA71053A894F98DBEBA95EFEE3F46AFB944601CC71C39315012B024E672E7CEBA843F35C6F435983AAB0F14BDB63B2D130A91AF9F72CDFD73EA39DC02AD3074F0E4B3780E81732B550B298998169B1640D80FD56474FF655A233E3ED6C48E5D94A4C6D31ECBB5257DC07F29D5A4C98177DE0A4DE1BE24D2CA3CEF4DD2A3FFBD818E75023732E1F1D3F9051AF6E8047081FE588E2492E5EB4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F933819140A786527AEFC7A872908B98E8356286485E2ADA68D8733129C32FE7E0D0B7AB63E890DE8AEC5DB2D52F88D328E1DB56FF586DC2026817A277844C18228D01C4A792C6D27D72D4E36AC852098685807B31A411B62DF550CE9C5080F1BA5CEB1634B8EE7CBBDA91DA660CECF740A502064AF7781F544A2A9F6527CB431A33A905262210B977C09374F03C360642BB200F00F13EFCAB19685DBAAAD7EFBD4D42A8B428342F44A61D9D58808B9E7620ACE2D4FA47D16FA98950485E67EA182414D9C7B78C51CAA4960A79B1BEF4B6BB5CBA79515042433C7505B5038C4DD0CC8805CB9C1AA93B2BF96402909E229C46A5C2C7CB18F0B7747642714BF204D42A8AF263AA6C8F1DED9414FD0E6586D7B680D4BF1CB6CB6DD90D63511150A76C2C40384A4F156E827A22D0D207611E84477254E492397A85643BE2EFA36371F9DF6119813B2CA7F31D099B0715927919FFABE384400D3AA0869AF2E95B525D9A1453679B1624C4F2718AF080BE493D1DF583843CB08C5FAC4587627805AF278A009530F8545958E7C04ECD445240A70C6D0450DE5A3F3CBE710E610D8EEEA17F97381119B8A53A62EF7F4B0D8F84BDC86BCA2245664DA120E7E36945038F7973099B1ED88113E6594EC0CBE05B5CF5ECEFD58D48FFE4C16E0F941FCFFFDE6D3E584584EC8A03AEDB6126EF5F479E4FE8C97BA01A4980F78D12717DF17BC4E9040B105B2D74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7566DC65863A7E07D0D8774305019C67D504E7FC4DF77A8821AECBFB762EF377DFDE75F24A9DEF9CA7997E8F4AF3B4E60071F11DBA6303A964B7F9C3FD443C766346B4B1E50EA1D79357CA76ACE991F4760184016A12C2368F7D4E6BAF0C8EFCF4A869F3973B41564F52D762BECBC7FA49B40D6FCA22052287E1B10DD8FA257423F984FF4CA38BD49F322C84CA37874056055B3A0C51060360F05BE3E1DA6E1829B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F3171151E6F5442468D000FA46F17DC7437B058242696056ACAAC06AF22742452798DA226D91074DEFCAC6C3D770DC54CF7ECE9ADFEDB3B421ABCD9DF305D412A71FC77801FAEA989C03A0D633C4B06766491F4C0DC67FF8DEB16AFC8BC7E3D41601BF7B964B91A8638DDB7CC08B68691D5D501B5D3D72915442F0D1B9EA4DE4AC96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A3928351163E04D8BA817C168A0CE68CAA6FA744E7E30A2670B2BB88F27810C887E48E90EFAD40F9735B5767F60EC515C146D56EA534C970E04BDD10302D85A2317C478BD195FC93499C051F5AF61A6C5CECB89A1D67BF5BE2CA7EFBDCC20B884597EB2BB0799DB9B86E2EB8FD93389AB91A391F2D68A057FDE361AC97A87F4406F40A7EE2E7709E46DCD756617DCB0DBBF43E6BD4851F3D834BB53CB150D2FB7B84F8D037672EA110B3F93C3AC7EDCC5B5211DCC6BF4685C2D711AF156B82961C5369170E2E76ACF126B3036492BA13A920E126E7CA29791835CFCE00B3EF7AE43ABA16123C386FC3AA80F7F55F094F1664D67FCB5B990A1B93AC8D9FD02595A6005B8CE100F00F9818D7C2313416A65FC916B102A019EB2C7DE91A346F6E3CBF7CD85D2E8FEBC968AE7CF4E6A64400C45C7F71CC17BDFCD337C726028AD4F1956D8AF94345E2FF8F1C9E57AEA206DEEC8A93010DE204CF6F3D9CDE952FB8E4955EE2708B8B19C5788865CACE48EAEAB016AEFCF9FCE16621401B9B14F01BAD76AB32105CFD3C5A3EC7E7CEDD9A64C0B2AF82072F95D2762333ADC34CCAD8B93DE773FDED0AF8569A4ED1032A10D522056894A78C45B0C1FADC66A29CBBA8AF0600B416497EA782E66C42A4B1B518B7DA3DFA17E2EC7BF70208F1911CADADF3173E26A9285466819AFA7E43CDA3E79C3379ADB9F88A8C460AECDEBCFED326E15F01E303A0BB62615B2A2CB097B045DEF6AB46F799A70EA5F4C54B215A0BA6BC2BDFE5846A65D620BCEBD2607DBFC74BCEFC9712B8AAE5BC6C179B2971829F9EA1EF896FE1F6EED7D4A3B6D04A0B96848599BBD3A5A4AE6431AF6921A26726EA8B5651B74CD5C5723D8610CCC9E9220532D22E4BEB538A7E7EA50B7FE7D21E4F7EDA1A6E232C8DA603BD8A40DD5A9E87778D5EE4E2711C229E5F66F7C19CC263A38A184B437846BA2945CFCED1C270FFCB2C9C03D8EBE37F9E2199FD4084E94A02F74C3C2E3D577470B3F3F4B0B7CDA7671722B1E900A49096AF21F74E327D4B9204FC3D7E3AD6DE2A5037A2FED9BDB1100870156824C3E2B736F55E200F84EF5C0B6D39FF0A929F20749413DB40418EA6A764BBAEA67EF31C107F7F23A1193BCD26297EA37CA92CF90973BCC7BC548C62EF44BD5FBAE7CA281C5447895061540CEC586CBAB07CC6835253C332BE03CD64CAF6CFBA2C5768AAEE682614AEDAE4CA6BF839963D13970AB2D37BBD203FC8F5197A62C183B76BCBA09E5E47D686ED98A652A176A90284D0034391003C5BF6E9C6A091108A3107E128BF3465BBB72CD50C374A343C714E7AE5599915411D31CCEDC7ACA1734B5F23783839CD46D0786814D52037477FFD7600129FE5AD39C8601C30088977D58C83B2D0B5B6AC14579F5C52BE795726F126ADBD2742BE107CEF59ACC94B78DC7A51AB01B4A3B212F10768D35C3CA5CE6D4EFC33995ACD07AFDA29782EB4D86447F622B2592F7D18E835D5F922FC7FCFCA5F12251B5A3DFAD7ED2B6C9F3C6B734F34991C30C700EE325CD9752D68D4DB9B5DD98F91348C1DFF570DD106D0CB457C4108580FB341BD44DA99F4AD058B064AE955B584627DCA083785EBC199607782B5B096DDCF3A0EC0C5F4FB69DD11814016F8AFC30F853DCF0B793E150C3B796CDE2B1B43B3E346E257331504D6571E35C7E2953D0B1EDBC4B1C48F21012DBDC773107FF4B459FCD253425217787310AE7D8F74F77E60A4511B8B23A6A1714BDDCEA8694F2A8508991C555D6C1DE281244E229377BB4FDB9CBB38AE483A3569F735AC438C492DFE9414F26D70F154CE91D99105D5E34340D34764482934F3F3145436CD3AA2DDCCEBA06D0439C960E7D16BB68113560CABB3611F2CBC43D79915CFF16CF0BB72EDFD858830AF8C790F7F1C18409C4C48601F24454BC986B12540B74EBE53F5F3AAED84C8DD523702B0492BC34B98F2AF02C856882F37D1234C04B42060DFDA8FE106CF570235BF1169F163501B400DB5A48D7FF08851543CA92A0E8448F98BE619F41F4C820CD5553B0132BDA47AE8C0A85874D1FF5D23AE2158B85206E9F95CBD6DE6F2092A31D700E8E86ED0009F9780B1D349E01944FD5FC58A95CCC7502C6B1385AB36D24C663C8316F2F453E88A98EA61D721FBD4B018F43B84DD5B5C83316488AF78ABBD005C15399B7F94F6AB6F5239B10CF44B82FA774ECCBB5CB932A51B1C5202F112198FF20A160DA0DD130510C4540AF4C9ECB078C38AFE183911E2116F130DAA83432E3B05F76DAFA8C9285CB7237B57407F2C4999D4ACBAA916D2887D2ABD50590B5F761D3995A3D484A632696156ED00346555A19AD569E80F2DC6FEF929F3AB753AC9F451D991D1F9C614CB562F9AD1B984E94BF00204B8E0411D9AD0D374A9752B6989CB7AD969B047E60F5D371FE4FC3D17B4DDE42878C758FF19EE3FA205FFA1E5A3ED709AF71DF3527F26F712462C0AB5815A447EF29BD1887D7CB8FF44C2752A9E1BC890A80A5444E8384BED9EFCD06F26C467FAFBB01B97EA07CE0B5091605780D9770A00252C92C4DEDD4D8B942E14C90DFC5BD612D85CE24C5CEFDB3EA964FFF256B20A4DC2C0EFD50DA4BAB56BC846B09DE27F341EE42EAF0545CD82BF62FC699298C98D9B9947D436D234DF8333E144C207D0DE124707A1A3262CBDF544C5C6FE70F2137EDF11BC8A3E2E7B6C35909DAC8C160CCBF3FF25275B7F97E5E0D56349A1AB617E944BBADEFDBBA8BD06B26468C961756F0E1506F5D2C5C332CB7D18155B3964343C682A5721C97BD5F6D675D44FBB9B5C9AE58A02BB327AD51C927CED9F3E27C8DCFA2EA7F4F20867DE29279B5DA09E70B6B6ED9C2C21502D185DAAE79A792F5D79C8814375643B4E69440EB7AED63285EE40ADB2A43111BB8E45D109B955B309FBDA17862D551F72C2EB06BABCFE4BCF46468789347AEA8FD0CF3E2938521DADC71D0EEE1F435B38023B69022FDF00B3D1AA0A456DCB917056F934240BD6C899E8E0D36E4F1C8135F74FFB493B7591BF9C2DD47E2C2B64A5CB0D34A0DDF8486DC9CDCF85E8D5FB8327A486076AC1AFB63681A253CC57B65DB36619DBDA966569822860B30D9DD55BE869766BB1986D254A1C486E6990EB6CC4D22E829230CC0B5CD80B6E0C3E4465CBF7AC3480BF67E671B31E38F24800A61B0C98589FC4D98BC896C27D4A9F8EAD8CA7D567AF1796A82C64F3A9876B921B4F9F009EC821DAC29B54AF75F0F5F59BA04AE753A786D0FDA22144E3C9C3413B4497ABA623AFE3257572D979FD7234C04292B8EC507187752446AD11D10DE925035D368AF83D202AF6979123C7F3B7FCB8D83812728A890B5C09B482529FFC0737FB59C35B552AD7C5820E27332D2E44F2A31ED972E2E5C834FCC652204BB401557D6FEC656BD9F63B9226056E2D025988ED1312A2A767D418F1342BE489B463AA4BE823D471648D9893364758DACBAA63BED8B3D8D4DE1E4A768B07A9912E72515AC62BACB31DC0EBECCAA1360330949EAD48841D91C61B13E2EA79C1891C9290FEE2F779EA4EC57692960A91913AE591D6550BC59CFCC5EA68483E4066EBBF11C2D9647E7B5ECE7845996AAF856A1BC1458EA7C88E73B1C19FCE34B68DC2BB0EB2CEFD4506D674C92A2BE87429BC026542F6F8F48CB088F945D76C07477009F8F9D2B41552CD688E00D2A977C67003989D0A2FA7688B410C6C30A1036FC1AE46A86DA837812C7FD4539985A05346319FD809739255705BB1BBE7791F520D43F33F06493E50423C6418BF781834310AD40B92E396722B1C67EC08FB5FA918351C89574D5A47D31D7F6D25A30712BF53AE5410B587B9CDC0D652F993ABCADD6442E5F52229C5011D36980BB01D0053433DC64E02F535EB87F04F2FDFAD3A4378477E4A0BE652FC73E3604285CC0721796206461EC07608C4A8C0C913924525EC5DCF185891F1740E56E4E88E3C957D028D5BEBC5DC6AA9CFD3B6A94CA9B281DEB7FD816C7DD27AE5FECACB499A764C58CEF0EA4A18999B80D89D2074754894613FF9A019639CB6E1A31B91F6389894454B884F1F76BF3A20984E908C60BF36D3CCF439D9B200C3C97E076A75B5209C363FB23DF3FE4A8A792CC9FD93527667603AE461FCE62593DD7DAF62D1D78060E4AB4DC2424BCA29A0C96ED4978987C8D4F2791F61AFFD6300415F0E4DE0764AA88C672EBB55D765FD9382875CF67B176C8BC422F613D22605BFC24C2D69DA0E7CB76AF9378DD04C21E76BD30E9F923D724F6F3633928EAE801001F869B7BCCF9EF79B6FF8E8A741EFF812B31E140A7C798D8738D272068FE9A5468EA0CF60D339DD3D56A73D3BADF14504FF3FC2816A0BB816806B5CEE3164998712B9460C4227117261169E1B4C20AD79049980017BB1CACAE8EDFE29252C782485A5BAF0599796BB5004FBB2101CF98470B60E8140B828E7DDF8D3B561AA5A147739DC01970DEBFF008D85ACED07EA28D10E594E60A3569C6A13D9619FC2F76D279143D829383549772E09F3E275840913B08E0FD33C24CD38760D585FBAD94FF3B0355D247B1A5D8F22E67E34803F1D454D979BD9576F36F816005BE186FB6D58BDC8FA63935D7E4CB00A0F6752E1121241A67095E77A3231034C7D14649276638DFB1DBAF56AE7BBF54C64B817E10B6EB7E974208B16C658FBF3480BA6C86F5BDCFFD2F830801C95F5D9677EA593BA221A9E7D2F09E1E19FF70AA4A73E2FCB455583F3E21618A50CAA4B53EAF90F0AD1A47BB59B77EA66DE84A10E6D5FCB7A9CA221BA0DC44452E7074206ADE1C1B02E520B6D481C27D4CD833EE7D985B20FA5BF7A21E4DFCAD092628EC0A6E2DC8718EDA1408151C9F4C1FF4046A444CD0F8F10C82BF697013DA572E3EC04726E89BC96ED083C2387EF5DC80AC9D74144D0AD906BDCD4608974D57F515101973291804C5180C348EFD6C91AAF5433A6BFACACD657BB7C579A195C6EFEDBEF3E6746FAACF6AED5975115AF77843A5497EBBF4F254D13D82321B29A6EE275AD3389B828D1FA19FFFFE79123A579B45B78D3F0A5AF0EF44A19F07513426CBFFA519F93A4A4DB52628A2FD56DD3A323382E5DB171811EA861E2D46537D0A4E545C65F2310C2A4EFFE0851C1260C26F2ECB491BD2EFCC41F06EABF26B48E9E61FC3C550F6CCAB762B0FAB75DFF6353F814E55E98A3AAD5C82CF9A891AAAC5112D38C6687E30610AC3379222517D90CDF1AB77E96B16E4EBCA8B0E8719205FF3D308550E3BA58A9CCE5FC6BF05A4DBECFECEBF1F4B7722C6AAC9FBEC2EED1C90466147C022C4B2150D6DE9B76BE278F43197479C5D0CCBBF0CBEB22C31308982105A95A5841AA37DA3BF81F8F7602C9E68C059A36BD0DD395EBDE7616091E3753AA1397A0251EC887FB27A166DCA318DA3EDFF3E29320AFABB616813DC83D4641F3664407C3DABDACA9F5EC3FF32B6538624C2F10415019168777C2BF58D51E619C872F1FBCDC8363C69AF421E6B6C046B8EACB1233A634F492189D114FC3B17B3A6FAC0CB04BE2FB6CED8D3DBF570B66D7EA390C11D2FFE35A8F675CCA65026CD83809D8C60480A25536A9DFBAE0D1229F2D563FBA86229F6B7F7CE9A9C12E6CF024402A8DF251BD5F72EC415621FCE91148DB266EE1BDA0885827E96E8A9AD9C50F43D9B6462E6A24D508013457E7D4E3D7030DEE74216B3EB93C676CDB9F5E6754A10A635950D60C9916D00565C50A33EA1BBFEBF02BB60483B6DEDF0481C054710FDEA23BE9FAF9DBFF407E7766C84CCC3F281C6383079DC3188FBE8F9675D0A26831FE4090EE8C8E87DC459B1CE8480E64B78A5F15EB30FF165CC9F5F261B42E5EBF469A2319A405E8CBADD241C475A5AC949BF372A41B060353FA3EB8C79B969874223CC14B6E5B3EEFE72C0CB8C8E1B114AB6B7A435B786D8A8FCC935C8BAA5BAC879B50D8180B65FD0DE78CA05D750591F479FB953FD55BB00F1D50EB99AFE348B00A63DE9E79B12C5C32F257C97CA0CF00153C8C3D8AF3988200052059CF3C841296651EC607D910D661EAA1078FA7EEB6738A8484224A29CD0463649275D117997768C75660D469691278A111D50A72CEE9600124E3850507C0B963E9121C8BE1B269448FE8A4DF87DC1EED33FA1EAB13DCADDFD7F2BB0FFB042FDC6EA8C00A6379B640CA2855112F86F6FA5B2A622079AEA2EFB9D9063AC89D7F94AE3CD7551F3FF99B5A3C41D3770C44E9555969B97D719A3C5590B3D8A1F65995AB57BE3FA7D55524CCFFF8018EE1A587AAB9FB5D3E33FE7BAF2642CF9421540C134F9BDE97680458FFE5A18DD2D3CBF178E91629F050DBA86E31E5A42548E1582E271B399A6DC512CA068153BE53E78A5A6F83C8C39FA6F92626B000E8066A1BEAF2C21975B2FC29959C3AA239CDD2A4B47A55E0EC54495769A9293F33F23FE19A886DE5AAB35F3BC80C9CDD0FAD599DB6359B84F396E9DD06848EC5844B44AE00478C8C1FD5E964031EE21158F6FA1784A07A09E6173412180C5A0354B11480F780C1E3CC436BCF5D3FC2B5E094C1A45AE192369966B103D700B955D0FDC49733525BE13D82164C5A2996F0FF900DC890ADDE848305ED6D225460FB75CDC1453C513EDAB63E576CE7CDFA755055AC07036627843E640E20767EC35B45C69A28151210BC3F93EBB880C6419D545316029814C22D2872E8B0B4B4ADED8E44D0035CF687BAF0C593C2B947CEC9770E19E28B62537B3C463F582084CDAD9A704D8E4CCE851DD4FF586D6CC300F09F878FF5FDD7E7BFD0AC3AA2AEC0C223DE23D190C6F67AFF7C00001F7DE39C907235BF8D5EC16A34AD2D2E6DDC419F5B24EACE1A17BEF5CC52AAA05F04D5AA8BB018210354282E98DABB918100165E7D962A6F396F22753B1FB928AE3576A91CE62216E9E6214ABFF91FCA2E6E77611AD13F70CC87E67A1E6D886120CD2C2404E0312A57635D1C2524C97EC0BDD9DE011D158F8FCA7AD1A23B38A0E6201B3A52E5BD893BEF169D6E665829DCC297E9BF3DDE2974EF56B848D62499354AC81D756C3CEA6F0E5EED1E0E58EA69F3843B09E11F3BBF8898F1724E4BE566D1AC9AB166CA7D5CDC3BAC80652CC469E048BEDFF5444254926930835827E5FAF2CB16AF0E0CB13A3653AE4EE9C49D838F84D3464EC035DC31E025F30A12EA7630A6A630A351E06620774E7CD342027BB9AABFE167CBBA7D526F0767 +remain = 1152921504606846974 +max = 1152921504606846975 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-2_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-2_256.rsp new file mode 100644 index 0000000000..bbf9b3b078 --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-2_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHAKE_20/2_256 + +pk = 00000011CC3CD3FEFBB5188AE538CEAFC0E64816F394C351FE22AA134A3EC20A6A25FB5004562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 00000011000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94ACC3CD3FEFBB5188AE538CEAFC0E64816F394C351FE22AA134A3EC20A6A25FB5004562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D933090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000018F224E19E61C8A7076585BF7780AD32D73D04D66A52F0B4CB6D35D9496906BFB05000000000001C0F7248E24BEA5635FD0F3F3411F1A20316CD29E2BDE6DCCBDEF8AFD463CADB306000000000001BFE2E0B4F4BD9B2B955C3CE73D4D0E703C44BE5168224D99756D865D86689E1607000000000001EB5D1F16948BBDEB3335E0F93C3DAC5C3FF7DCB33B16BB28D3826194192729F80800000000000194BC268989E8C957203F60EFD29089692A7FA0980912BCCB1FF3D6921B9805610900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB931516966BA24D9585F1C0B04D660E629B3A2A3F31AEB6AC3EE8DF4DB67DABB5C332B61CC10887A0A207201703DFC4C27B774468F2CD9C6EFC711426E248C33EF946923D4C1AFA7B608F9F080410AE8F9F08CB38D5C0F6664EA0F630D34DFC55462334F617F3E4AE640E6C2D27597D4967E08EDC91704B9E3EE49EC4F0506994C3DD1027F8BE7FC46589CC21F9BEAF4F4130BC7D8325FD638235372E12CBB84FC424BAFF7D301855839698FE2E38B63BE461E681B43A02F99E466319E808084BDEFF59DC9DA0BC5F523A21D4525D81501A83F357BAB3633C061D403C7ADD90CBF38C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A36918612009A7CF4A981971AB37B767BC120AA994494DA75CABF22D1FE63F1464E981A0FF2BA93D3AAF2CEEADAFCB80FB7D012A588D4E409051A44F7287EB74B23A7F9A4302D2E7EA81F9FFD74D72807123DC3529B24DA2AF50619784A32B75985FE5AF8191B1CCF65322E266C37555CC3A971BF53E46DFDBC336CE5DAB6A84AC0F17F219C1DB9BD42A4F9662C74AF602347DE8A4EF176A34EAA287C9615F90FC02ABB78D80A6327768932976729CC4BC564E870C58EE9889C877CE31BA913EA7E454C0868D80335CC063C57D0BC1FB3C5E09B3A20F8166F8BDC41B01A8EEB62127C5BF88686BB8D0350F7BE6B56E0CE6E66B0998140C6F839A1AB13D68EF718809E2973CBB24BF5D927E83DD6C16C292D94B6EFE4A1BC9E050E8D6992BFD1C6F906C0A7B81474293A86ED095FD785C5BBA70F51BA7D49E9A5FFCE8193DD10914F642178026F159AE536FC1FABC7B78A3C2DF55D0C8E1EF23883C6FDBC053B447825E75F945D8157A967B58B0574C6E0615387CE1652DC027B72C45A8E9A4287219D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF71E8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B1A8277D00D5F8C835AB2820DFCFC4C8AFB2CB247B6DACFCDFB3765002D7D6EBA358848E7C7C63DA066252A81CC95E38A556ACD239ACB010A8169696B347EE86AE99CC7386155ECC56277B39192742ED8C959F142209943A017FBCE130FBDC3A491E7F650C98DAA0497D6C9CCABFD02921ABE4CFF254FB1521C702FB19F3DBBA1B691F7E44003C618C1B0C1B68A840B9763D43295E0CB779A59EEF7ED63AA1020069B2EF88BBCAB1D03693FE34C4C497F7936878D4DAB7B75BFF0FD8A0509D9A3B0CF209C9B7D09732CA0914617778AD289AC2110692D502C8DC75316530280FC926A62D46620A91EB4C89377C47ACC72884CAE39545022290B0D0EFA74045E4FFE5B7950E421091808852738371BAF20E81ADEE43642303C0F979B8EDAF4B47ADFB135B60A3E4F0BD2340A03D9F774ED36135C7C7241A89B2E9C71979E6BAA1E4D272BEA996623E399F2DA2AAAF6D0CE10191BA0853C08743DF8F9C98575E4F398BC3F19CFCBDB00B6C71E6B2B86A0E3BB72811DA873A3A318F6F334B64992648C9DA43BE0DB9CBA43FB1191DB64EA575DB1FA7F5E345ED532AEFC9F878894723ACC25CFEA3765FD8B4445453AB184E6C5A33FE8C136C8B401ED890A840BCC8C13CE2560D86119D74B6258D4381A4813572B6AEE5DB91BFA38F1E36EFF3DE17E255F8302A3A8161AD44F095659EEBB8E99100B7A19BCB8842ED58C474D1FFC28FD87A032D583050C09C64D4AE5F937743FC5E4705D9EADC758DF2CE55F240A40267311278E9198452030917F0ADB64226D6D413BCCB02C9A5C830AE5F2DBF73BCD8161132CCF43553B8FBA8E5283C953AEE50DDCE4EB59D29E4A2E5DA0530B922286F3588848CAFE9182175706266C466D65F41C3C18B000789C74952E3E2FEE44CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D58C6E04B24FDA2C3239210393254B41DA390EE357C7C175EA1DFD32FE5AADE666337542E508FAD05AA818E37539322BE1320FB587B83E86AA18434C47CA39E9850984F7339BD164FD46557BE86FB71B18CCAB5C34449AA65150D6F47A8117453D706F30DEDEB127BBA56F23193113CCBEB626F61BC4EA2D5053B489414A7F9731010D4333E72690C936D00367C343DA301A455B4CA7DCFC4215B0EE5185F1DFEAD2F09542D42C8CC1BA6ACFA452C6237454C5D115C0F5E04479131F9F1ACCA098EF0ACDFEF6FA39E4AEE14B0823E911EF2DAE145E261AE05A117E5A52E9DEDAC73742F90B4EAA8AA944F14679B0F72AADF6B56B31F3A2AA0AFA243C3DCCF6FFD2799FFA1F9861A5C04B0A8F68CC1BC8C90703AB05FBE50C15F06B04570370DEBB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832121C0C078E6BA4A80F1A20BD16BA90FCD04D43A0927C164582A796C12545CBD0BE45745F9E0090A47F31AB9B11E1496EED876912B13A841C06B6A5E812B11EC912A83D6B8663FBA403442AB4C70D3CCB76BE6686CD55D831E8DCCD05594F47FD58A835E3132D95EF4B4E8EBC275280999BF68305531A7F9F5EF2E8ED77C42227D0ED07B337CEB70317037ADA07819791A04BBF73646CC89806912EB3E2BABA0C80C7EB7BBAB7CE68583B609A5152A39457D51EE0A3CB4E897EB6363CB767057ADD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C63F474F26E2917A9A1B025C28BAC7D53E4E150E981E0D5BA4129911F99588369CD97444E871D47141AA795560B9576AF7870E3F62BC6F010869F6CA393E48A0BF5BE7ED218D65D942EC0F815F2258A47F7A509B6BB999C17B28D46B7D3CA59061D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C09FB9C3782471D5185D98077B9CD560F0F2D8109B8F2DFA711892BAF0A4A828E506417EECDAD332975E49F3E9019CE173E2ED3985D7C241AB4F7AE082E8EF49FD + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 4963 +sm = 0000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6429AAFF05B285E06B6EDBBA11503F92E15E17C582FDE9CCF8FB0E5BDB90FCABD06FA41D595338274EF14442E5C967BA01C008D19237429ED719B99E0BA91D580C514F5DB69A428FCE3592C4928A1461E736B86804529D3AB6535C3DEB873B45873A5037153C910492CB49EACC2B24931700DDB0962B1AE245FEFB4345D58F90F62CA12C27CA2E25F5C1799AFC3C56C20D8763361A7AA8757AE5C1A90FA05D6625430682E22AC918051D97466B12D2FC559413DEFAAFC677C8351565ACC58D481ECE4C96410219AA2370A23C6E92E5322E0CD81840622A3C20D7243711074E19131246F16CC261A56C9F1903B0B4498B849B4598E5F8C73A6A1521F7D75628427099DB406303D3634EBA7F9EF84D42F8B59753B8C55B71DBC82E06F6D674B979C1F2E6BEAA7180B7DD54525F52523DE6F98A205A6866C5B7489000B5CE17FF49A645C1A7763F5BA271F9023A89DBFF7189CDFDDA48F112B14E7907795A7C92AA678727144332A7276950BC3A0548E270CBD4FC31004AF248BEA3BF61558946A2D26131D7D51C3221D6C24A9EA4C05827290AA1A66C9011153C120FC8F974620A2988266C9B2D49652CB8CDEC30866F81F41B8F6EB6C6F5DDAE07C5E405A42EC21383BEFDB77CEF1664E01F11EBA2513A4C3EC82362321C163730079A59933D9CB173C93ADEC1E111F387845B826C3523FC184B5F1D1D830191C88D1F9F3C3A81309BA06825E1A32451CA92D7B58785E22C755B2083EEEEBEB7071E62A3AC45C09151E1961C11F7D8CCCE4F08E9BADDA88E17BF2DB02A6D1E1D2827021DB4659211453388E6A2E01080743D9A836F20FC93663C7E4591849A616ACE98011E52BFDDA1D6A0C82EF62F0B0A9F1FBC427D200F636E66DE934401583B67DB03BB8492A8952B7DC0473151EC0D9571297FA6AB0793D3EBB4AD559E0E367DE90BD20B96ED7AD6F608976654F01E1DF2A5B7B7A54D448714D6E1BE40CC6C76564A8CFB5ED8D0859AC3B6541B286B5794C4B2AE7B4BB4C91ECF560E085C6626C9388E031F5CE2B09BCACBD1E67B946FA5CB736B2A641A0C5E8D152EBD752F4CA60C49827FD6EDAF3A6A71C48FA89786E1A76FE326B90AF058B1627040851A517242451CFC3194FD5C959E05BCA2B9B93B4A8EC90C078AD381B57075B5B4C83F0C17A67F8DF5901B4968C46EAA98D824B6A9FB2CA5E583E3AF6718C42B47420838BDFA070DD8350D320C2439D92BA252BC89405731261FFC9F2B5EF3AAC944770321193DA5EB16924C3108FDEDF07D7940CA3C8E46A5E76F5A358E7927976D16BF55B9E54965F8CC13A89E775AB6123C3A1D8301FBA857F30B65D1961FCCDF1C0A1E5410920E84B4C8BFE12E3B1B84721F6CFDB26FD8D39AB82756BC29725DE0B632F556C167705588C5D03A64E33DB87F0432B67C1AB69143592EAB3A832AD7375AE3397DDE149ED361E30C807C308875164B475E46CC14E278D7C129F0D909E2C06D5CDA851D6534AE73B220CA73A13917887367D055D38A65273890D1FB7A3AD50A7BEC306BEC9F246D6025499B69389AADF76741B4665031E74E1C836028D815ECFFEC3E974476860D49A2BA734DC223B46D2C25797CC55E16A37D56B5021A9413F7F651B894ED06E313F1B4BBA00F7D5DF43AB472D66CFE6CE3B96B4F37F3D7535603510353CFCE64882BE681C9C8046A403EC89BF47A3A4561226B84815C3661606210EC8AD191BF0B1D8C6D027A7C176BCE1CA7CBBA0C336D80411D9A61A5E4D093F5C27F1B5233F2C78E908DC396F097744D841C8BF1BD732255BC62E601A9E50DA36D18AFC8DAB6866EA201DB358B45AA0CDCA0959B4F0BF7ADDCDB0CF61ECC7FB075EFB21E937AD32E4FF503475CE0374E064460B5A0B4F955395D59C474CD9BD3250C92F063C641BE91C5D3820B9D2C39466B24BAFBF05001BBC0BC63E00D7EAB41CDBCDFFF1216F45CE0741C53B57059C2F55F8D2529C6B0E760FA3BB04A38130B3326F0BC0E59869282E6E6870A1435DE8D83D9174F2314B6D007A6FCF177661AAB80D756D36813FA06D86075306817D37856F1F60BC2DD52342AAAA26CA611EAB00BBEC675FF7EBC347B2B3078CFC8E827E04A3AAA3E5A2F06DE077D32C6D51A6AFBD1EF6E49CE8FD350DE872090DE73F0C124AE014920F104EC5BC7EA0FC49DBFDB3EB4E0FFC5AE893D46E0A98343B1C7D25EC74B9EF16BF54D211C3928852873CD0EA39D3A2527B72BF325B02D5A8AD1B50320FD2513D89D1A164F5F8E770B329BEDA67EC4F75441467D2D45A3F4BCD6051BC851CBFCCF7F1644C8462127BB68067FFC32F23B443864EC5104D7AD3A1B68FC59FF2C9775D4A9C1D0F25F084AB49FC4849D497AAEC8FA2A8C8DB244001F4348AE47425932E61A64C79846C4DD33F99680081AC5F25B0B3FD815ADC0DCF5AB104931F58860E77B4C620A8E18A68B3F068CA77CA14D60E815745802DBAA1E6650A2D337A8B8FC33217467F61AB87909D9D5B21508BBD0D5D3876F754FE9285CA3208CA501606F0EB6B7FA6720D9809A6799A6E7B2DDB84AC602BF3CF936E171E16F5B4EE3BB6F1F8D70A121E129ABDA16B2871303DA6FCEBED15C3340C072584C7F306AE44D7037C8EE5ED6935D675F308939045FB0522E5560262A425BA5D23AB0A7E3A26DD7930E88CC025293E48E8B72BFCD134B8C3613753A9AEA514B79BEB1828D08E928B94EFC93952D401D4FC5E97CD40B375D0F6302502B3BB83098A6BFA378373FB0042E15783729329225E1BCB7F680B66729BEAAB9C5AC5A2120C8D427E349F364F595BC1D72866A1A60777897D0636344B4A3A6D4B891BC5E066A422AD6CB0514D1E9D708885573A7CB1C938876CA58C9DEE64B7EDCB6BACA85C9E20AFAD6B68054B862DDFCEB991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EA1E51FDD737CB5103920F8B27DDFC3FBF47480793A68EBB780A1BAC9141D609EE1B40AFF393D6177502756D15DB5232BCD58ABDB633EFEA7390FF8BEA443BFB32F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD5894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB931516966BA24D9585F1C0B04D660E629B3A2A3F31AEB6AC3EE8DF4DB67DABB5C332B61CC10887A0A207201703DFC4C27B774468F2CD9C6EFC711426E248C33EF946923D4C1AFA7B608F9F080410AE8F9F08CB38D5C0F6664EA0F630D34DFC55462334F617F3E4AE640E6C2D27597D4967E08EDC91704B9E3EE49EC4F0506994C3DD1027F8BE7FC46589CC21F9BEAF4F4130BC7D8325FD638235372E12CBB84FC424BAFF7D301855839698FE2E38B63BE461E681B43A02F99E466319E808084BDEFF59DC9DA0BC5F523A21D4525D81501A83F357BAB3633C061D403C7ADD90CBF38C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A36918612009A7CF4A981971AB37B767BC120AA994494DA75CABF22D1FE63F1464E981A0FF2BA93D3AAF2CEEADAFCB80FB7D012A588D4E409051A44F7287EB74B23A7F9A4302D2E7EA81F9FFD74D72807123DC3529B24DA2AF50619784A32B75985FE5AF8191B1CCF65322E266C37555CC3A971BF53E46DFDBC336CE5DAB6A84AC0F17F219C1DB9BD42A4F9662C74AF602347DE8A4EF176A34EAA287C9615F90FC02ABB78D80A6327768932976729CC4BC564E870C58EE9889C877CE31BA913EA7E454C0868D80335CC063C57D0BC1FB3C5E09B3A20F8166F8BDC41B01A8EEB62127C5BF88686BB8D0350F7BE6B56E0CE6E66B0998140C6F839A1AB13D68EF718809E2973CBB24BF5D927E83DD6C16C292D94B6EFE4A1BC9E050E8D6992BFD1C6F906C0A7B81474293A86ED095FD785C5BBA70F51BA7D49E9A5FFCE8193DD10914F642178026F159AE536FC1FABC7B78A3C2DF55D0C8E1EF23883C6FDBC053B447825E75F945D8157A967B58B0574C6E0615387CE1652DC027B72C45A8E9A4287219D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF71E8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B1A8277D00D5F8C835AB2820DFCFC4C8AFB2CB247B6DACFCDFB3765002D7D6EBA358848E7C7C63DA066252A81CC95E38A556ACD239ACB010A8169696B347EE86AE99CC7386155ECC56277B39192742ED8C959F142209943A017FBCE130FBDC3A491E7F650C98DAA0497D6C9CCABFD02921ABE4CFF254FB1521C702FB19F3DBBA1B691F7E44003C618C1B0C1B68A840B9763D43295E0CB779A59EEF7ED63AA1020069B2EF88BBCAB1D03693FE34C4C497F7936878D4DAB7B75BFF0FD8A0509D9A3B0CF209C9B7D09732CA0914617778AD289AC2110692D502C8DC75316530280FC926A62D46620A91EB4C89377C47ACC72884CAE39545022290B0D0EFA74045E4FFE5B7950E421091808852738371BAF20E81ADEE43642303C0F979B8EDAF4B47ADFB135B60A3E4F0BD2340A03D9F774ED36135C7C7241A89B2E9C71979E6BAA1E4D272BEA996623E399F2DA2AAAF6D0CE10191BA0853C08743DF8F9C98575E4F398BC3F19CFCBDB00B6C71E6B2B86A0E3BB72811DA873A3A318F6F334B64992648C9DA43BE0DB9CBA43FB1191DB64EA575DB1FA7F5E345ED532AEFC9F878894723ACC25CFEA3765FD8B4445453AB184E6C5A33FE8C136C8B401ED890A840BCC8C13CE2560D86119D74B6258D4381A4813572B6AEE5DB91BFA38F1E36EFF3DE17E255F8302A3A8161AD44F095659EEBB8E99100B7A19BCB8842ED58C474D1FFC28FD87A032D583050C09C64D4AE5F937743FC5E4705D9EADC758DF2CE55F240A40267311278E9198452030917F0ADB64226D6D413BCCB02C9A5C830AE5F2DBF73BCD8161132CCF43553B8FBA8E5283C953AEE50DDCE4EB59D29E4A2E5DA0530B922286F3588848CAFE9182175706266C466D65F41C3C18B000789C74952E3E2FEE44CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D58C6E04B24FDA2C3239210393254B41DA390EE357C7C175EA1DFD32FE5AADE666337542E508FAD05AA818E37539322BE1320FB587B83E86AA18434C47CA39E9850984F7339BD164FD46557BE86FB71B18CCAB5C34449AA65150D6F47A8117453D706F30DEDEB127BBA56F23193113CCBEB626F61BC4EA2D5053B489414A7F9731010D4333E72690C936D00367C343DA301A455B4CA7DCFC4215B0EE5185F1DFEAD2F09542D42C8CC1BA6ACFA452C6237454C5D115C0F5E04479131F9F1ACCA098EF0ACDFEF6FA39E4AEE14B0823E911EF2DAE145E261AE05A117E5A52E9DEDAC73742F90B4EAA8AA944F14679B0F72AADF6B56B31F3A2AA0AFA243C3DCCF6FFD2799FFA1F9861A5C04B0A8F68CC1BC8C90703AB05FBE50C15F06B04570370DEBB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832121C0C078E6BA4A80F1A20BD16BA90FCD04D43A0927C164582A796C12545CBD0BE45745F9E0090A47F31AB9B11E1496EED876912B13A841C06B6A5E812B11EC912A83D6B8663FBA403442AB4C70D3CCB76BE6686CD55D831E8DCCD05594F47FD58A835E3132D95EF4B4E8EBC275280999BF68305531A7F9F5EF2E8ED77C42227D0ED07B337CEB70317037ADA07819791A04BBF73646CC89806912EB3E2BABA0C80C7EB7BBAB7CE68583B609A5152A39457D51EE0A3CB4E897EB6363CB767057ADD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C63F474F26E2917A9A1B025C28BAC7D53E4E150E981E0D5BA4129911F99588369CD97444E871D47141AA795560B9576AF7870E3F62BC6F010869F6CA393E48A0BF5BE7ED218D65D942EC0F815F2258A47F7A509B6BB999C17B28D46B7D3CA59061D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C09FB9C3782471D5185D98077B9CD560F0F2D8109B8F2DFA711892BAF0A4A828E506417EECDAD332975E49F3E9019CE173E2ED3985D7C241AB4F7AE082E8EF49FD22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A +remain = 1048574 +max = 1048575 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-4_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-4_256.rsp new file mode 100644 index 0000000000..7a37a6015f --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-4_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHAKE_20/4_256 + +pk = 0000001253040139BB0C869F0B49F12B2ACB6B6E78731BF48B976D5668CF38EA836868E404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 00000012000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A53040139BB0C869F0B49F12B2ACB6B6E78731BF48B976D5668CF38EA836868E404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001521B6795E3B31C6F469147CDE5776D1FAF80EE268B570DD87C1895E195F358E50100000000000135050ED1EAD3E799B63D5EDC01FDE9B7E3E8036A429C0AB56C909CC2B6378D6F020000000000010D93E097DE2D5330AA792D234007668B3E7F9E699621D298D2AB7577E8518A0703000000000001F2616B47D5F8376AF6A5FC658A75A52D032F7A1710630905C152957F41FA24010400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE5900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011420B60C54314ED8291B4F251FF32674EE6A3C3609140380F6B20865B7AE643401000000000001DA6EC89DAF2B01E86C06ABE8043C9A6EA0562A18C49B4A9497D347FAF8EB910002000000000001A0A42481338E08706BAC35F7B5F5D93432D40144F47A0F6790DF4B68525ED740030000000000014A9507DA8B4941DFD3D5E9A02EA050B97F9887A65D93FD8723FDC30C7E2AA4E0040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB939E6518A5122E37D4C257B0A0FD60CE0BA3BD55C9CBF369DD315A3C0609933D25DA403DF7E69FEB7EEE64DC3C13DC83217C2834B42876862CD48E99E69564B336506B85FDB493CF8FA87A7FE48DFE6778DDE8E8DD066FAA745C121480B5BF9D5F301B358D18FCCCBD24069E71836981F168FC49E6A4F27B00F6259B183B62CEAE0BF4AC0F53FCEBEB9052C0B48EB0666F361C5DA674B20B06AE2EA8783C2DD7EA74D98AC98C55748A368DF5B433C39538365EAE8DAE5E032A2008768FEB01F65D001AAC437781F742F536EFE2B3AE59EA12A6DC7F2712BA2D9D1C253D29B419A765985ACDB42BCCE5D64F6AF8368A5D122BB16B525A80C8BC5355A53917CC82262254378CFFDF1C7D6355F114E4FC013A5E4DD9AB373A0EFDC470854E20330BC00960ECBE882098D6D0D429A7AD19D3E5D4B78AC5E568C722A21877DA617190CB43123FB04333FAE5846953E33407080D04DF1417E740E7E7A14B0E3CA7D5B693F9615E1F7D417B9004F28D5002325B851C31F5EB31E1DAA80E6CFF22F11221E5180BB050888B6564A381E54401AF9409FE12A818B69BA34E1916092A0EBA24457EF994A1B0028649C9803045EC93CF416373F6A568856B771C3BB076AC265045ACE8E9BE3C3074D8806BEAA3B8B21F7E37F50B16221E14FE5503C615A13738CCDE39E2395E292119959CF686532CC3C9F9129E62ECFB43A091B06FD48ABE8C2CBE2D9691C8907881991CAB9D0D9CC7B2699F2261E5D799D26A7C8A4AEC40789B34CF5FE7BC8D24D6F0BBA7A5870E37F4D9B2605BB56ED9BAEB780CC74097DD8AA8741A97E22EC7B7434F81DE9D83CB9816A33C5A79D718C76A3442FE50C68FE1CE7AF728F2177F88E5168D4668518897AB050B57FF42AAC731E484B440D0D7B254383C74BE41C2AAEC02A8D8C7020355C4A1FAFAF4BBF56C74D78949D087259FE8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B179B32F9F94BBD8371B973B19E60C3CE2206A2061C7BCF159BC3A50163924774BB13C708A573472DA73B4C78DB30FEF310EA3643BC75D9155762D5B87809E2A727AC0428B746801D693074ED5245F29B8FF9FB782F2E57BDD89DD700EDBF12E8311946CAD9BCC98E3B1D581E678BEB1D0A6EFE15CF4052A1AECD328B2C4A8D5DDEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA36145D1653D108813E42654CB5350FFDB33BD2FDF4E416C6C0A61784E2327F42B2DA2AF040822C291D63645B0AC2377D0DE3FDBD99FF9CD9AAAE2B978C4DBEA95E330E90EAB0C4C34E88855C7C62C40B231AA1A9EB409D18CAA1C612A98F1B7BC25B18E3A89CAF96AA4BDF12F865EE7DB20273D7CA11970219BE997DD0EDE7A8ADFECFF1D90984694EF152346402207BD7D9166DC1B09F3C3520D109824442B8AB08869B0A4850BE3227E746998925CECCB422C4C05047D890E291B4E5478967A42BEEE34BA2765D86D183C71FB6A3CD86EAF457756FC000FAFDB24AF3C968E547A5223821BABF91B31B3F970D9F7C1FBFD16CC63D14243DB22CDBC266BFA4DE4B15D23B17D34C674649A695E80F84F6FEBAC0255BB155BD8B8D46FF7AFC532117E26985D99B0E23345F9A0247D834697804C6644501CA7D2726DA563C7F02371B5CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438DC67DF57A5B11025EDDC8915C57C8C72F6D6E71978496E206201184593506E39582DD2C803CE9204D2AC833C35BC683E0BD3CAD30BBCBF584AD38DAD30C9A400DE22F0CD6199FA6C622941E79F8C5C500389E9FBDEB8E1C926443B6FB0313DA9AABB163F5319C0164C1E58864827E38C18B7ECF6FB44274CCCB84B10F1A1BD76C8740F479777BDD7C557DBEFA9415B7FD50CA659E304EF4FA22680980D0FCEFC75E36231F740F38E9B4AC55BD8307F8AD9FE45B046B7BFF0F1B9FD5EEB82D474DC311A8418BB27CFE324426CD3311D65513B0A4D58515B94B8EE5ACC6815D6D1246527188E7B6C579CE42B28E1F273887FAFAA96D44FE6830E96081ED562FF4A08416DE4213A89CD666E2814FA290A5B1FA5AD6DB86B9E4DA85486E11BB36382C13607F50EDC83909F47A7D089CFEAF4680A6F2F10A2D9D9A679AE82D2DB387C5B7BCA11161E49E01C28D0FB7FEFE1C9A4BEDE994DEA4087F3B74906EA8E49153ABA49BE0F35C0572E9CE0C68B2267884C4BC4AD32BF28CE64DC7C825BDB2D8561C69161E075F48A40220159BFF1C4158187D4DE23C85979304DD4DBB98BAA57DBE6B7C55C271B134D61906F6ADBA4639BCAD3C1A70DA04A9409A4A35FEF1BC103D4F17BAFEC37C3F108B31327E0FB227E0E2C5B5410726ECC93B56D4D153572C2DB4EB4757F5B2232C475EB9802FEFB53EAC7BE6A090AAE98027AE13D2B338442FE6EF2DCF141C4D1AF00C7B3E973467FADDF6F1950ACF2BE908FED354EDFB147D6AC4B0740F87DE06E768293CC83AC995760FE0015CAC682036CCABA9C86B9B06924369E35688F7255F5D5422AB808D023B150D62D9A7DE4F7A5D28689EB038E9EF9D3366C3D777AB6D1C33878327018CC51EEDE65BB5FEEFDB1442B9006C76B10B6CE9EE1B6E43306DBB0D9030E3A191DA24634A80063F6A5269E77543525E11BCF02DF82E5921E3225EC97FC5F9174E0225E8C5D08B4C093EA28A19D03E908426578661E107E5E2C5371D79C31F11468112A6050703BB8FD9ACDEEF8D0BC31E82FB4F7DD0DFE8AE0216582E6C86FCBC1E7B3FFDD921F220702D827F145D79D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CE8D216DC6F19C3AC0A1017837C31D76ACDBD48F018A1CB14E98848B66A59F09AE557964888EBFCAD45C491A2A3C44B7085FCA7C983EA4AA22F62B99109F6E425CDFF5D87105EDC065810CA3E055F62FB80F5CAFEC57F7CB47A95B14A215714FB345FC73E57C1574E38657755CE991FCEEDC5ED84824E0E4AFD43205E126A3402910DCE16C59C8840FC7FC5ED9FE6379F9A388601D57B366FCF44FBD2D0C15A3D8A4A28D71ADE5965C137996748EFC7FB68ED165D2480FE34EF58A3169D03D0395D94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB08391412A812DBBE4FF09E10661B7DD604481AE6EB2F89A1FC04E393B3353F7547AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6222D7DC2F78B2E3FC4C8CEAE02E3FC9D7972CA803061F534D39E4F02809C7A18A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F9536829157F62BB003C2E45042DBEBA9622508F9AACA5FE89F665A5F35BA7C26D93A84F9DC744354C73885BC59EFB657317594D34B561FC2A789C919EE08D5D68185BFB2A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E1866ED93157270FB47C81CC3076E5B381E6B03127E7AE78C54F5F35B2474F18A2461297462FFAE651BDBF3D438E30420A3BA5686483DA2EACD874CC44102C09319C10FFE87AB2099A185DFD0FDDB6393B2F61490D65F93CE565C6575C877246044FD52ED475831AFE194BB163D0FE5A023BBC435497C3C16C8C7A85FF92426B59E588978E29EC0DAD032330035B797471B74BE366FA75D79D35228004D3231654D5F301D6597B83258DBE9284121A2BB21EF66F40C17FF135201D18092FA6A72B511A456786ECE1FCFC986A28C744DD4DEBCB552C638043B0602343CC796834B13660A86C5E3CCAAA1845C5165074AEFBA7C52190845A95DC59B1E8D6B052D253EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D1B478E24D9EDAC7EC8816FA54DFDAB0F181E9E1A8A6CD77A9EC29B3E35544898EAA311411BA22E8BA6418CF252675917A88572E0CE98CE03457996BA4FD86D07C4FA2D3487400E484F4CE0A83CF490C49588DB83ED1EE2A93B78101144586427FF43F434D3A40268920A4FA3C64C0F5F4600A8E52E01CD8210965C4B212DCC942C68D589D21FEF433904C26239698EA85C32423EF7AE1ADC90744996C956FD5D0683674010173EE4A110DA2642C8E1C4BF7B5DD3DE268A3AD0A261A30AFB6AD7D54210702C635C3E707CB1F17053D475A026EF57852DEC1FDA4252FDA2E69BA95C866BD432139CA8A4E367960F85B2FBC75420737CA4843B89F053192BB086BDC0D739B2753DBE42E1D45877097F3B97FCA6F43AC15DF883C3B42D9F472F910DE579301FF7F57D9857890651B64B6C1E8A7E2227ACAC7154D97252EACF8BC5FF430E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD637170756688D9AD3002B3148ACF0009CB1C0802EB04197FBD2FCE168B5FACDD052DD46F9F0B0A34295557CF741102E7592C24FA56DEDA63ECB7A2149E406C0943E5E554767D166EBC95FAF0E9B20C1E530633CF8BD7AB2A66CB105E108C1793B0D87ABBBBA9A4679A05C94BE6A698F4758B8BD38C51371C8043FC79E749D7E41C04DC6D815B0D32A779D0AC6E80C1D56B03C8EF30F6F6CB73A089B149F46BD4671D7C13B41A5B1BCAD94C0552C12CF23352200198CD876615EDDA7257E3CC94B732D75AF6D67A67929458E2639BA4A2967D05F76C4EAED429AC246CAB410B0FC8806B84EBFE1159C88D6E71EDDCC3B956F33739AD9FF6C43168B54FD592D845A54307AD16E42AAD4621D33A037D47D1002DE1AE0BCF2ADD9B01895EB0E63742FCBB5CFDA14EC9C63D94E3387E0FC22FB1B93D9065DF33D03AFA7D156BA719EB9DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF1DF5023719932492A5EE2B7A3B40B7C7F6814D179AEEFA584D317D536645921799727CED4C3D658D5A425D2D3EB1359C975FBE1A2FB2D11F37098B7234A19628624F07698EC3658799436DB5CCE6AC18702D4F27548F61BABC4807826E95D23889575EE119A88256D4326D4BBB48D0F589C6CB22E7F95D49F6607BE258753A6120CEFBC2E6C502138AEA689B4EDA13FDC39CC0759F392860168C2BA881FF70632D05E797A4F52453418035DFE9D072F0593E8029FFC25D75FC7DE13309B0AE4509D8A315C31F0FD0F480B598ADDB0D5A8F945FE6C28C2421DDB4A0DEB478478A49D5E628799ADC5E489FBDBC9DD38686EA7943969A5AC97497B2C380CAD367A8DF3DADD2E31F759AFA47A422D2A5F7C44CCB028AEC63EAA0727231A8BB4FAC096D19BA50AEC9522A00DDBEB86ED6DEB298AB433CDB7B4F15EA4AE08EB01782B70CD59C57D485848B16B9C55BCCECC876AA99071A9A7599868A9BB42F178BF3DD0FBB7EB52A796801D67E250148584C46F3E96898AA264BCC3826317B5BF7DFF55B6F3C3F3929FB552D79FFC1D014C52965F50B446DFC1CFB3302D8C7367A6F64C93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B787B24028E369C59743659E28980F3776146D88956F5E02B3E3116B8292C2E578C8708D4B518B95E8FCB7C7D5C3B16EF976B20FD0E53DCD6D92301061F2588F693A84052F8C776D033ED7A5EC71E928DD7CC7EED8DFC585AA94D8C9CF92D9694377C0268A53536DB64565FD9F5652B0A3634B381121BDA48C2D1FD9E189991D092178D79AEE8333BB0EC988417AD6CD9DD0DCBF6EFDB0E4E8D1B38E2A3DD01B3EAAD55E1CCB1291C87E2A835E86D2E0C0C3642166D2E9BC98CF354E28B6CD3F121606F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174BE4D5805F128D4A9B00266CB6CC792C45CA4E506C8B2504D13AC93044BF3FB332A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B275680E933FB83760E66AB8BBCD67108A95111001B9F8E85B6C96B4BBF952517D6330EB1C6AB68317C91468E90237214C46A5F496EE46E2E8069D65797581C01BA0B2DD1DFEE0F95C0AD7E426F877D0CD294CB0F3ECD1C65659D20594153630E46E4A32CA7D3B408B33227123C6449C4644192BAE44916FE60256703EAB9B2821973C8A37F2FC6B3B18FFE0E4C8036583B7E63E60A5EA8FE89401C8633BDC355FDDAD733A74922E73333FF9B2F9EAE2ABF957105197D92E7CAA56F91767E282E0910608FFA0E651B882398F8187E5203F8B56F788A4DE4130D211BAEDBE44B1DE0D729B926D5FBC98A1FA9EF01E415BE3795F085E28E1B32F86B0EC72DB22414EACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E947CA8092F4480FEC3CE1D8A6D8C4CBE3F7EB35919888B729C1CADAA559A42E1BBDA600C713EBB3487FAF3CCCC40CAFDEAE9B9C6EF40D5041B83973133A03156CE65E33173CC6EC41F0061D31797BF2D58C95B5B4E218AA783E09AAD39682072C6EAE7C52E3491E8B0345D3F6DD019D7DA6D9AE08FE40461B81D414B8D5BBE0672D892793121DDB345A2E5B1F8F3EECFFFEE5E425834717D59506DAC94BB9F31F00AC84767700A6FFBB6D93D4A9FC6F02C67F2710269A4162C284E0D9BF486ACFDB55A33CE915B41F167D533B268F96CE0C70A54377A5A76B1C8E992BD4908F6C9AE1B8A1129A6A94F2C1FA3EACE58297AB6E83568F0857FEBA399FAECFAC9FA94217BAD28BE66B04EF4EF7862DBFC7F9D86A69D63D84665C826910849A959626B2F95B16FBFAB29A97876BC2F43A43F841F6161648AA9D1689D67A4BEE2C859702320B726B0219DCC859A330C6C337AF2EFB0B9C8C689D2A7B92DC615BEF81F9488AC5E678E63D3E9C4CD4D2138F500D7967745773C58A8704107771E6AC93AA2307D387AF3CCF853E572E74624A7E40305FF4F57266A6BFBEEC78BC8CC981479D5A80F351588B5E378EC89F193C02A92E5BAB45E1C12BE0DBCAA00E85E73FF666690C4133023ACCD88989AD44530D63D54B090E115F6A25111B4F006B0EDBC73FFCA5B037240E88F9F4FDFF79F6874B6D6865B3B93037E272D66F1BB1EA9AD7952CE8F8F353C2910FBFC6F73626986970C6B1FA3F7D010A7DF2AD27ED28F727F9B6E10E08E9F23278C2C6ACA482528DFDD42021B690D777444DED9C912B2CD003DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D5023540D6CD04777ECAF4F4D58C64C158042656BCA7DFBBA61D7551154DC1535618FB3576C6A634E79E80BC56D4A77A32480711DCF387CC963BBC7A339C907928DBA6545BFEA6878A58236DC95D439F8F3061C099AEF80CB7128E0C1D3AC5841B65C0A738A16BA2EF4649CB510F512A819CD03BE1174182022DDBA30AE32DB5AB9ED29B2FCAF259886A4E479D5B5C118DFFA5529CF83978DBDC1B233C410279CC031E0EFD98F95DF6A32C1FB854F7DA54F12E0D0078F9287622542E551863DCB0B534DCA8EDE06545D0860957FF3A0C13495A47A669355FFF55DAC93C3357E5FC17274ACFCF9905705D6F32C7C6E6FCAE6086384B4939C70128CC73540E47ADC633EF01CD9E59A14EDC10AB0A9313ADC2123A4F3F3B4207CC9564D39F7CE86184505C432B568E4CCAEAA1BB93EFE4C696CA690F4B4EAC21A83E1860C5F26C6ACEE315F139E8C7543B2075D3FBF446058A1F0E0DC7893D9C78FB25914ACECE4664F58E03209D0EE1FCA892A9002B32FE67B0CD27E60F35706FC2BCE8A0F77E89FDD67DCAF4073DE5B72BFB56A87525875B0E27042175EAC158AB2D5A7B85C041FC13F81A9E78911686B33488DB258E31630B4D779F6F40E079F5094D31D70E74F2220ACCE407CB3491B80DCA95CF6126E9D2E955683F0B6BBA28885065E50309BD5E3429C626D547A87ED33769F9BFBB514F8792EB90F90C956F0148B9928189EE06BB40CE18932DB44AD96E226B6BB6A313DDC8CE4FB50C6C548BFA794FDD1EE7EAEA2F119CAA2E0DC7664B0136EE7F50B88FA4F4B1F0A665F36C56AAECC77D637637ABD7EE25BFC8B638430370B0F92FADBFE5C4F166A0B1FFDFDABA98EB3E5D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3C1578D7F6DFBFF09D46817D7C61EFDDFEC6AEB1A21EBD5AF1A0F399A2096C8E30821DCFD15298AB26911D40A97E78421AC35B6E8B47C483E1538E1C110540E6B23095AFAF8CCC9883C1BA2810AFDBC488849BF8E2BD2B63AA036BCE1BF9E6FE84C7C830C65CB9870A441512C55557F371276F3CA97910118271DC35F5A46454B02318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3FBF9F7DDEBC0995B90104C717FA2977F9559887204B56298813EAEFCE587F9D2DF49378B38F71833410D667351B1949CF406F18B0727666AA94DE7EA90B093CEEABA95EEE4D2DB043CFD3504F59CF36374C48E804535A76BB8BF67DFB39E03CE613D53D7515BBC8DF04062A185B7825FD3260B1B377B5D3CF470603B1900FC978329FE4F050A62A0440FA26E9B3D2CDA32E7F9FCFE6446B29FEC3639F068E56D446765B606D7B4FDA46826E8BB9E3FE9ADD93EBF3848B70C759922B63ADAFC8E71CA051A07FCDA3126BC8B4EAE41DB2031017A6794C6784FD8B93672BE6206ECC5F1396078719C45CEB31BDE4A3D503A56CD1BA60A875E2A5AC7CF340A79F261480A2A36EE4FE88106DD0976B8FD47010119D6D21982AF0E8E58AEF1BA68D4BF979DE633E719AAFC7A6C8AC6D127BDABFC3660711DAA2962D639D46747BC03BB269789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411923F9FC45FE90EEA617A4971AB81153088F58B488C507F5C230586CF967833C9A0DEA1CAD7FC139A9710382C46136E4F4007BBD729ACF06FBFEDFF5144533FBFE + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 9251 +sm = 0000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6FE5428C1B38A2155B8EF1FB9DE8440D993A1F197229DF83843A1615CACF924D4F7C034A07E8D99E7F548B998DBE686E6F146747163419D911CDF36891B5CE67FCE30A4EE54EC1D1BDA34E8F5BE6FC86445C4E732ED6A2F3717BCFDBF1EC5952AC6DFFEB95D5F828ACA606136DCA17F08C38DE5AEBF9CAC54646BF3B7809882E94D6C58C88F8FD5C2C018CB53B7BBDA343D9B0F76F9057BA0C56DE12931A55620810B03806BA5E0F9C9F764CF3EFC1772C1624A7C8D63A6295339488C2FDD9CBC4069AC1646996731948816530C43C82CC1346A5614222B29B4C635AAA4542F11023B3A0B4EE1A22D367CD4E000A7067C2C7DD162FA09E777CA9DFD3B331ED20810EEBCCE92C9FE28855527751A9567241135557CD840556FD141538AD228677F0EEBBE54BB463D23A3C7E6E71E1CC6DF3104CCEFC7124BE31C854ABF06071BBAFC55C8986FBEA375F95A3E2EEA5595322FC1079823D49731A6713DD270B3AD1DBBA724670050F31569813630709AB6A4E35D66684AB154CF647FD64DA3B2E5533BA26B80AF62D1328351A6E0045A82BFCEB153B0F6B8FD5AE3B2056006C5EAA15E87B7916E5FDE15BB2E41FF1A75C926AC7E64C93FE1451CD75F3AEDD49B1132383BEFDB77CEF1664E01F11EBA2513A4C3EC82362321C163730079A59933D9CB63937ABDAFC11529A49EA5BC69A0EE1C86D3E5FA6367170D2D5D45A4BF164D4DE3B8F7196A03D3E74AB3BDE2DE84D00D112D489E6133A0FCAE2ACC8DC59062CB45E8ACEEF3FACEC55B716E1D4FA8B926D7A96200B00AABB668752FDB0A7ADBC136279390A03AAA2D41CE2F40EA4005F1EA2A87D61354A932E70E8677BC0D6E67DA1D6A0C82EF62F0B0A9F1FBC427D200F636E66DE934401583B67DB03BB8492A8952B7DC0473151EC0D9571297FA6AB0793D3EBB4AD559E0E367DE90BD20B96E53891BCA1195D4B5CD305ACB28479FB1BE4550E16F85D9285EF98B1F325D755FB51E1749ABCEB67C4DBF13794C49CBA8259AECF2C8843C57521BA6AEE603516ACFF629B995D28350AB8417C87F07E31C622EDD406BAAFE489FB5443F93C9583EB8C510AE49205FB361487B47B63F0EE9CBBC9BF3983A75A1080CBC7FDCC58AD8490221F8F42CBE5DD49461942A233D7D9A4F4F121C14C1A48F90F4F39D6A32E8ED8C312FF9C43E4C1198E0B3EC0044EF37FF9A9EDAA4F4CCECD98E910022A8793A61C5997051349524161204FDCA085DB451FB0C3E67FCADE5E78EC0A356B2BDCA48B903DA92B5D86FA1C5E8DA5C12CD2C030F11A8F670E028AC1E3925B5D70EA2F7D8C162BA7F7F4601025685E59E261826B1D9E9A9AC5B4AA1DD947CDAE896AADECCE2E41880CD5D368ECA94F5AB91D24AE62880ED25ACBEE0AB61E9DE6E3CC31FCAB40497A4F5FE4F15BBFB53599D08806AC825A4E67B5B6352F1DD87241B5728E4A8CA6264070A7F1F09CD093CAD71FE3263B0E60C73F5F8641AFAF0767642B074B80978D810360C6461ED3EDF9472658F910B055DE3DA84C0F9D864887B06BEC9F246D6025499B69389AADF76741B4665031E74E1C836028D815ECFFEC31E016610038E514FD8C40543D51044F15914C46629E4AAFBB375263475D8CDFBBC16608AE86EF265A6F96C3DD8ED50EE43654691CEDD9D56D1953EE8E79FAB98B00C125CB7AB7263C045BC9C084DBE1082F5BF4185FCA92A8A86B02824FFB27908B08D008E6847395C57EC721BCA98DC0B83462956092D8420C6D8FE788AE977EBE07F8E35BF47CF0139F21D472E866AC90A0F9934D889720BDBB0B6758FE460E433065DA58947840B243B5C1D7DBB77B3F5647E6B1E5E431D7377E97A5BCF0F075EFB21E937AD32E4FF503475CE0374E064460B5A0B4F955395D59C474CD9BDC172757C4E8C43F87A05741B0454DA49A357EBDDBDE8BD4D5EEF757E273F78CA03D759940F88FAF5EB05BE1B90273FA0BC0048267B43376CDD718399A354E3B39AD1AAC43D9C2B70E451C8735865EAE9FE002A29CCF21E110FDC8143F7F6F6F561AAB80D756D36813FA06D86075306817D37856F1F60BC2DD52342AAAA26CA613E00A9115D57C1E17A0EE160B6594FA15A508BCCC75D4AB1A92550FC7D3EA97C95CA005C1A19AABB3CBDBA66D69363BC654DD41E108155EE7876EE35D0131231DC0C5363795788CEFC6210B502DB88C434099C46316476FB3FB07E701E29075AA3BEEE3253FB58D7B532C7885549593BF2984B3D6FCC2E70105FC34A1CD9A85B9B2A48FA806BB1FE35675ECD1BA10FD998068C0797A6874B02F3759F9DCD3B7702F687B52B7C266357544355534B01A42AD2C4D72F8BD9BDDBF19E907B4AAB42AFB9C50EA8B1C2D24086613B04E95C864564B0F144ADA774B34B26CD69629D0D2BCE8E0D611E1C6993589B529400771332F16F123352198A4D6872CF63F4401A69480FCD587D115B1D7951C75225493628CB4963EEF967CF17C509540AD2B76528A6512C270D08F57DE18F0604DF6A7F0FC6EA83D446EB3C281357147AFE5FB70D9809A6799A6E7B2DDB84AC602BF3CF936E171E16F5B4EE3BB6F1F8D70A121E2073DDE647EAB354AA4B41CA00B804C86C1F0E43E5B0121F340AD5B2AEE00092D931A5E3273F4F5BEC1CAB03D56A297B5EB5AF99C83F60C70873CB17A1ABB1668103E96C8FD9B5A2AA8B31BD9AC07C2EBFF610B224102C28626D812CA223F77817F11254DBE77FA55F77CE54550ACC8F6C4F725C5DB72F56BC4BB1AD86DBCF26C1D2120A35AA49657324A01423524C5A5311FD6D80ECA89B78221AF91A751637FD590293CDCAAD1BFB5BBD6473F1D3D600B9A921145B691088A88BCA7D1038BA83A7FCA224EC74713DA1B07688D053980AEF766325769F8AB513B03F813F5530B991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EAD16E1125A10C75C47056683C86956E741DA2772431C6436CF7B385DCE6509239E2CB3E61134E6B4CF5811150F4276945BA08D0779468902DB915F36620A54536F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D265894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB939E6518A5122E37D4C257B0A0FD60CE0BA3BD55C9CBF369DD315A3C0609933D25DA403DF7E69FEB7EEE64DC3C13DC83217C2834B42876862CD48E99E69564B336506B85FDB493CF8FA87A7FE48DFE6778DDE8E8DD066FAA745C121480B5BF9D5F301B358D18FCCCBD24069E71836981F168FC49E6A4F27B00F6259B183B62CEAE0BF4AC0F53FCEBEB9052C0B48EB0666F361C5DA674B20B06AE2EA8783C2DD7EA74D98AC98C55748A368DF5B433C39538365EAE8DAE5E032A2008768FEB01F65D001AAC437781F742F536EFE2B3AE59EA12A6DC7F2712BA2D9D1C253D29B419A765985ACDB42BCCE5D64F6AF8368A5D122BB16B525A80C8BC5355A53917CC82262254378CFFDF1C7D6355F114E4FC013A5E4DD9AB373A0EFDC470854E20330BC00960ECBE882098D6D0D429A7AD19D3E5D4B78AC5E568C722A21877DA617190CB43123FB04333FAE5846953E33407080D04DF1417E740E7E7A14B0E3CA7D5B693F9615E1F7D417B9004F28D5002325B851C31F5EB31E1DAA80E6CFF22F11221E5180BB050888B6564A381E54401AF9409FE12A818B69BA34E1916092A0EBA24457EF994A1B0028649C9803045EC93CF416373F6A568856B771C3BB076AC265045ACE8E9BE3C3074D8806BEAA3B8B21F7E37F50B16221E14FE5503C615A13738CCDE39E2395E292119959CF686532CC3C9F9129E62ECFB43A091B06FD48ABE8C2CBE2D9691C8907881991CAB9D0D9CC7B2699F2261E5D799D26A7C8A4AEC40789B34CF5FE7BC8D24D6F0BBA7A5870E37F4D9B2605BB56ED9BAEB780CC74097DD8AA8741A97E22EC7B7434F81DE9D83CB9816A33C5A79D718C76A3442FE50C68FE1CE7AF728F2177F88E5168D4668518897AB050B57FF42AAC731E484B440D0D7B254383C74BE41C2AAEC02A8D8C7020355C4A1FAFAF4BBF56C74D78949D087259FE8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B179B32F9F94BBD8371B973B19E60C3CE2206A2061C7BCF159BC3A50163924774BB13C708A573472DA73B4C78DB30FEF310EA3643BC75D9155762D5B87809E2A727AC0428B746801D693074ED5245F29B8FF9FB782F2E57BDD89DD700EDBF12E8311946CAD9BCC98E3B1D581E678BEB1D0A6EFE15CF4052A1AECD328B2C4A8D5DDEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA36145D1653D108813E42654CB5350FFDB33BD2FDF4E416C6C0A61784E2327F42B2DA2AF040822C291D63645B0AC2377D0DE3FDBD99FF9CD9AAAE2B978C4DBEA95E330E90EAB0C4C34E88855C7C62C40B231AA1A9EB409D18CAA1C612A98F1B7BC25B18E3A89CAF96AA4BDF12F865EE7DB20273D7CA11970219BE997DD0EDE7A8ADFECFF1D90984694EF152346402207BD7D9166DC1B09F3C3520D109824442B8AB08869B0A4850BE3227E746998925CECCB422C4C05047D890E291B4E5478967A42BEEE34BA2765D86D183C71FB6A3CD86EAF457756FC000FAFDB24AF3C968E547A5223821BABF91B31B3F970D9F7C1FBFD16CC63D14243DB22CDBC266BFA4DE4B15D23B17D34C674649A695E80F84F6FEBAC0255BB155BD8B8D46FF7AFC532117E26985D99B0E23345F9A0247D834697804C6644501CA7D2726DA563C7F02371B5CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438DC67DF57A5B11025EDDC8915C57C8C72F6D6E71978496E206201184593506E39582DD2C803CE9204D2AC833C35BC683E0BD3CAD30BBCBF584AD38DAD30C9A400DE22F0CD6199FA6C622941E79F8C5C500389E9FBDEB8E1C926443B6FB0313DA9AABB163F5319C0164C1E58864827E38C18B7ECF6FB44274CCCB84B10F1A1BD76C8740F479777BDD7C557DBEFA9415B7FD50CA659E304EF4FA22680980D0FCEFC75E36231F740F38E9B4AC55BD8307F8AD9FE45B046B7BFF0F1B9FD5EEB82D474DC311A8418BB27CFE324426CD3311D65513B0A4D58515B94B8EE5ACC6815D6D1246527188E7B6C579CE42B28E1F273887FAFAA96D44FE6830E96081ED562FF4A08416DE4213A89CD666E2814FA290A5B1FA5AD6DB86B9E4DA85486E11BB36382C13607F50EDC83909F47A7D089CFEAF4680A6F2F10A2D9D9A679AE82D2DB387C5B7BCA11161E49E01C28D0FB7FEFE1C9A4BEDE994DEA4087F3B74906EA8E49153ABA49BE0F35C0572E9CE0C68B2267884C4BC4AD32BF28CE64DC7C825BDB2D8561C69161E075F48A40220159BFF1C4158187D4DE23C85979304DD4DBB98BAA57DBE6B7C55C271B134D61906F6ADBA4639BCAD3C1A70DA04A9409A4A35FEF1BC103D4F17BAFEC37C3F108B31327E0FB227E0E2C5B5410726ECC93B56D4D153572C2DB4EB4757F5B2232C475EB9802FEFB53EAC7BE6A090AAE98027AE13D2B338442FE6EF2DCF141C4D1AF00C7B3E973467FADDF6F1950ACF2BE908FED354EDFB147D6AC4B0740F87DE06E768293CC83AC995760FE0015CAC682036CCABA9C86B9B06924369E35688F7255F5D5422AB808D023B150D62D9A7DE4F7A5D28689EB038E9EF9D3366C3D777AB6D1C33878327018CC51EEDE65BB5FEEFDB1442B9006C76B10B6CE9EE1B6E43306DBB0D9030E3A191DA24634A80063F6A5269E77543525E11BCF02DF82E5921E3225EC97FC5F9174E0225E8C5D08B4C093EA28A19D03E908426578661E107E5E2C5371D79C31F11468112A6050703BB8FD9ACDEEF8D0BC31E82FB4F7DD0DFE8AE0216582E6C86FCBC1E7B3FFDD921F220702D827F145D79D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CE8D216DC6F19C3AC0A1017837C31D76ACDBD48F018A1CB14E98848B66A59F09AE22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB96557964888EBFCAD45C491A2A3C44B7085FCA7C983EA4AA22F62B99109F6E425CDFF5D87105EDC065810CA3E055F62FB80F5CAFEC57F7CB47A95B14A215714FB345FC73E57C1574E38657755CE991FCEEDC5ED84824E0E4AFD43205E126A3402910DCE16C59C8840FC7FC5ED9FE6379F9A388601D57B366FCF44FBD2D0C15A3D8A4A28D71ADE5965C137996748EFC7FB68ED165D2480FE34EF58A3169D03D0395D94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB08391412A812DBBE4FF09E10661B7DD604481AE6EB2F89A1FC04E393B3353F7547AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6222D7DC2F78B2E3FC4C8CEAE02E3FC9D7972CA803061F534D39E4F02809C7A18A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F9536829157F62BB003C2E45042DBEBA9622508F9AACA5FE89F665A5F35BA7C26D93A84F9DC744354C73885BC59EFB657317594D34B561FC2A789C919EE08D5D68185BFB2A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E1866ED93157270FB47C81CC3076E5B381E6B03127E7AE78C54F5F35B2474F18A2461297462FFAE651BDBF3D438E30420A3BA5686483DA2EACD874CC44102C09319C10FFE87AB2099A185DFD0FDDB6393B2F61490D65F93CE565C6575C877246044FD52ED475831AFE194BB163D0FE5A023BBC435497C3C16C8C7A85FF92426B59E588978E29EC0DAD032330035B797471B74BE366FA75D79D35228004D3231654D5F301D6597B83258DBE9284121A2BB21EF66F40C17FF135201D18092FA6A72B511A456786ECE1FCFC986A28C744DD4DEBCB552C638043B0602343CC796834B13660A86C5E3CCAAA1845C5165074AEFBA7C52190845A95DC59B1E8D6B052D253EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D1B478E24D9EDAC7EC8816FA54DFDAB0F181E9E1A8A6CD77A9EC29B3E35544898EAA311411BA22E8BA6418CF252675917A88572E0CE98CE03457996BA4FD86D07C4FA2D3487400E484F4CE0A83CF490C49588DB83ED1EE2A93B78101144586427FF43F434D3A40268920A4FA3C64C0F5F4600A8E52E01CD8210965C4B212DCC942C68D589D21FEF433904C26239698EA85C32423EF7AE1ADC90744996C956FD5D0683674010173EE4A110DA2642C8E1C4BF7B5DD3DE268A3AD0A261A30AFB6AD7D54210702C635C3E707CB1F17053D475A026EF57852DEC1FDA4252FDA2E69BA95C866BD432139CA8A4E367960F85B2FBC75420737CA4843B89F053192BB086BDC0D739B2753DBE42E1D45877097F3B97FCA6F43AC15DF883C3B42D9F472F910DE579301FF7F57D9857890651B64B6C1E8A7E2227ACAC7154D97252EACF8BC5FF430E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD637170756688D9AD3002B3148ACF0009CB1C0802EB04197FBD2FCE168B5FACDD052DD46F9F0B0A34295557CF741102E7592C24FA56DEDA63ECB7A2149E406C0943E5E554767D166EBC95FAF0E9B20C1E530633CF8BD7AB2A66CB105E108C1793B0D87ABBBBA9A4679A05C94BE6A698F4758B8BD38C51371C8043FC79E749D7E41C04DC6D815B0D32A779D0AC6E80C1D56B03C8EF30F6F6CB73A089B149F46BD4671D7C13B41A5B1BCAD94C0552C12CF23352200198CD876615EDDA7257E3CC94B732D75AF6D67A67929458E2639BA4A2967D05F76C4EAED429AC246CAB410B0FC8806B84EBFE1159C88D6E71EDDCC3B956F33739AD9FF6C43168B54FD592D845A54307AD16E42AAD4621D33A037D47D1002DE1AE0BCF2ADD9B01895EB0E63742FCBB5CFDA14EC9C63D94E3387E0FC22FB1B93D9065DF33D03AFA7D156BA719EB9DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF1DF5023719932492A5EE2B7A3B40B7C7F6814D179AEEFA584D317D536645921799727CED4C3D658D5A425D2D3EB1359C975FBE1A2FB2D11F37098B7234A19628624F07698EC3658799436DB5CCE6AC18702D4F27548F61BABC4807826E95D23889575EE119A88256D4326D4BBB48D0F589C6CB22E7F95D49F6607BE258753A6120CEFBC2E6C502138AEA689B4EDA13FDC39CC0759F392860168C2BA881FF70632D05E797A4F52453418035DFE9D072F0593E8029FFC25D75FC7DE13309B0AE4509D8A315C31F0FD0F480B598ADDB0D5A8F945FE6C28C2421DDB4A0DEB478478A49D5E628799ADC5E489FBDBC9DD38686EA7943969A5AC97497B2C380CAD367A8DF3DADD2E31F759AFA47A422D2A5F7C44CCB028AEC63EAA0727231A8BB4FAC096D19BA50AEC9522A00DDBEB86ED6DEB298AB433CDB7B4F15EA4AE08EB01782B70CD59C57D485848B16B9C55BCCECC876AA99071A9A7599868A9BB42F178BF3DD0FBB7EB52A796801D67E250148584C46F3E96898AA264BCC3826317B5BF7DFF55B6F3C3F3929FB552D79FFC1D014C52965F50B446DFC1CFB3302D8C7367A6F64C93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B787B24028E369C59743659E28980F3776146D88956F5E02B3E3116B8292C2E578C8708D4B518B95E8FCB7C7D5C3B16EF976B20FD0E53DCD6D92301061F2588F693A84052F8C776D033ED7A5EC71E928DD7CC7EED8DFC585AA94D8C9CF92D9694377C0268A53536DB64565FD9F5652B0A3634B381121BDA48C2D1FD9E189991D092178D79AEE8333BB0EC988417AD6CD9DD0DCBF6EFDB0E4E8D1B38E2A3DD01B3EAAD55E1CCB1291C87E2A835E86D2E0C0C3642166D2E9BC98CF354E28B6CD3F121606F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174BE4D5805F128D4A9B00266CB6CC792C45CA4E506C8B2504D13AC93044BF3FB3357F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B82A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B275680E933FB83760E66AB8BBCD67108A95111001B9F8E85B6C96B4BBF952517D6330EB1C6AB68317C91468E90237214C46A5F496EE46E2E8069D65797581C01BA0B2DD1DFEE0F95C0AD7E426F877D0CD294CB0F3ECD1C65659D20594153630E46E4A32CA7D3B408B33227123C6449C4644192BAE44916FE60256703EAB9B2821973C8A37F2FC6B3B18FFE0E4C8036583B7E63E60A5EA8FE89401C8633BDC355FDDAD733A74922E73333FF9B2F9EAE2ABF957105197D92E7CAA56F91767E282E0910608FFA0E651B882398F8187E5203F8B56F788A4DE4130D211BAEDBE44B1DE0D729B926D5FBC98A1FA9EF01E415BE3795F085E28E1B32F86B0EC72DB22414EACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E947CA8092F4480FEC3CE1D8A6D8C4CBE3F7EB35919888B729C1CADAA559A42E1BBDA600C713EBB3487FAF3CCCC40CAFDEAE9B9C6EF40D5041B83973133A03156CE65E33173CC6EC41F0061D31797BF2D58C95B5B4E218AA783E09AAD39682072C6EAE7C52E3491E8B0345D3F6DD019D7DA6D9AE08FE40461B81D414B8D5BBE0672D892793121DDB345A2E5B1F8F3EECFFFEE5E425834717D59506DAC94BB9F31F00AC84767700A6FFBB6D93D4A9FC6F02C67F2710269A4162C284E0D9BF486ACFDB55A33CE915B41F167D533B268F96CE0C70A54377A5A76B1C8E992BD4908F6C9AE1B8A1129A6A94F2C1FA3EACE58297AB6E83568F0857FEBA399FAECFAC9FA94217BAD28BE66B04EF4EF7862DBFC7F9D86A69D63D84665C826910849A959626B2F95B16FBFAB29A97876BC2F43A43F841F6161648AA9D1689D67A4BEE2C859702320B726B0219DCC859A330C6C337AF2EFB0B9C8C689D2A7B92DC615BEF81F9488AC5E678E63D3E9C4CD4D2138F500D7967745773C58A8704107771E6AC93AA2307D387AF3CCF853E572E74624A7E40305FF4F57266A6BFBEEC78BC8CC981479D5A80F351588B5E378EC89F193C02A92E5BAB45E1C12BE0DBCAA00E85E73FF666690C4133023ACCD88989AD44530D63D54B090E115F6A25111B4F006B0EDBC73FFCA5B037240E88F9F4FDFF79F6874B6D6865B3B93037E272D66F1BB1EA9AD7952CE8F8F353C2910FBFC6F73626986970C6B1FA3F7D010A7DF2AD27ED28F727F9B6E10E08E9F23278C2C6ACA482528DFDD42021B690D777444DED9C912B2CD003DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D5023540D6CD04777ECAF4F4D58C64C158042656BCA7DFBBA61D7551154DC1535618FB3576C6A634E79E80BC56D4A77A32480711DCF387CC963BBC7A339C907928DBA6545BFEA6878A58236DC95D439F8F3061C099AEF80CB7128E0C1D3AC5841B65C0A738A16BA2EF4649CB510F512A819CD03BE1174182022DDBA30AE32DB5AB9ED29B2FCAF259886A4E479D5B5C118DFFA5529CF83978DBDC1B233C410279CC031E0EFD98F95DF6A32C1FB854F7DA54F12E0D0078F9287622542E551863DCB0B534DCA8EDE06545D0860957FF3A0C13495A47A669355FFF55DAC93C3357E5FC17274ACFCF9905705D6F32C7C6E6FCAE6086384B4939C70128CC73540E47ADC633EF01CD9E59A14EDC10AB0A9313ADC2123A4F3F3B4207CC9564D39F7CE86184505C432B568E4CCAEAA1BB93EFE4C696CA690F4B4EAC21A83E1860C5F26C6ACEE315F139E8C7543B2075D3FBF446058A1F0E0DC7893D9C78FB25914ACECE4664F58E03209D0EE1FCA892A9002B32FE67B0CD27E60F35706FC2BCE8A0F77E89FDD67DCAF4073DE5B72BFB56A87525875B0E27042175EAC158AB2D5A7B85C041FC13F81A9E78911686B33488DB258E31630B4D779F6F40E079F5094D31D70E74F2220ACCE407CB3491B80DCA95CF6126E9D2E955683F0B6BBA28885065E50309BD5E3429C626D547A87ED33769F9BFBB514F8792EB90F90C956F0148B9928189EE06BB40CE18932DB44AD96E226B6BB6A313DDC8CE4FB50C6C548BFA794FDD1EE7EAEA2F119CAA2E0DC7664B0136EE7F50B88FA4F4B1F0A665F36C56AAECC77D637637ABD7EE25BFC8B638430370B0F92FADBFE5C4F166A0B1FFDFDABA98EB3E5D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3C1578D7F6DFBFF09D46817D7C61EFDDFEC6AEB1A21EBD5AF1A0F399A2096C8E30821DCFD15298AB26911D40A97E78421AC35B6E8B47C483E1538E1C110540E6B23095AFAF8CCC9883C1BA2810AFDBC488849BF8E2BD2B63AA036BCE1BF9E6FE84C7C830C65CB9870A441512C55557F371276F3CA97910118271DC35F5A46454B02318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3FBF9F7DDEBC0995B90104C717FA2977F9559887204B56298813EAEFCE587F9D2DF49378B38F71833410D667351B1949CF406F18B0727666AA94DE7EA90B093CEEABA95EEE4D2DB043CFD3504F59CF36374C48E804535A76BB8BF67DFB39E03CE613D53D7515BBC8DF04062A185B7825FD3260B1B377B5D3CF470603B1900FC978329FE4F050A62A0440FA26E9B3D2CDA32E7F9FCFE6446B29FEC3639F068E56D446765B606D7B4FDA46826E8BB9E3FE9ADD93EBF3848B70C759922B63ADAFC8E71CA051A07FCDA3126BC8B4EAE41DB2031017A6794C6784FD8B93672BE6206ECC5F1396078719C45CEB31BDE4A3D503A56CD1BA60A875E2A5AC7CF340A79F261480A2A36EE4FE88106DD0976B8FD47010119D6D21982AF0E8E58AEF1BA68D4BF979DE633E719AAFC7A6C8AC6D127BDABFC3660711DAA2962D639D46747BC03BB269789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411923F9FC45FE90EEA617A4971AB81153088F58B488C507F5C230586CF967833C9A0DEA1CAD7FC139A9710382C46136E4F4007BBD729ACF06FBFEDFF5144533FBFED92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE59 +remain = 1048574 +max = 1048575 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-2_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-2_256.rsp new file mode 100644 index 0000000000..c9042e164a --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-2_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHAKE_40/2_256 + +pk = 000000139671F9E99FB4EC6B22DCD31B932FA6A76204CF58477B1B054F10C47913D088D804562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 000000130000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A9671F9E99FB4EC6B22DCD31B932FA6A76204CF58477B1B054F10C47913D088D804562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C7D176B37A7DC26214FBBF555DDEF8D970B6AA840AFCEE7B674EE05845118A6FB277ABEB1A792B61CA4D24646DBBFD623564F93B74C1277C1AE4CB326411850F0371D6A848ED0BBFB8B0BC3254398F513E630D075CDD277E0AE10D8D13EBDD0CC60AB0FFC61631C5D17989AD9DDF25BADAF0BB87FD0E32975EB673434812D58CC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D9330900000000000121C29A3D4E6C5DAA979424FCA26B0EBE6D3FEA8F078FA9A98B0F55503C2541CE0A0000000000015EB6FB8267689B81BC8E2C8950E5F59F4B43194AB167C4A60EC9BCDA7572E5980B000000000001F02838F27F104405AA4D9E111D3A0B1849F6725926BA5B3A6412DEF900E7259A0C000000000001BA1EE79A04487C5639BA096A60E3E17F7A0E9C0238FA049EA7AFF52FAF5890980D000000000001B63504B794C356EB44A98DE32960830E6B275526432F232A7729ADA72571E8D90E0000000000014DA82230B909123D34E30FE0722BDD93EB6D56243518275547CBA7C473744E6F0F0000000000017AD15652FFFF1B8B9E752AD4A07EA737B8D79DE25D7F194E19ACF003E62C48F610000000000001D6819E585CEA52B14299092F01E66E9A6E7AFC9613A69B89ADE061890A230145110000000000017FB1A159FFBC19461AD72D4E385722A08E9A942BDBC3CF8352CAECD938737D89120000000000017B2C7FC20B3305327D2F0FC3C4854B0053D00E56EE4E005E43CBE807A619BEA8130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A86CB037675575D46C48D89A7B644810666979BFDDE595E1A2362B9961A71D9F75A4A72ABF56BBE2C07844E774123A5DEED0116677B286BB3F8BCAF92D501A5FF375487D2694B089FAF47D8632DA9E213A9C914689D9FD8B0DA5320F6A89787E198248FA523B9B2E910FE55F6127ABFE1FF1EDFBAFF132A06AB9FF0F2E368AEFC6AFAAE9F61068AEEFCAF427D37CD93FC0B0D226CDCF6A7C1F007BE2E59568970AB644D475E62D7B8E7E5F7BBCEA4D007BDDAAFCF6B84E09BCBC5553F516E2E5DFFFEB66C9F5EF34559251705C736FF66A96AD2CA2C40A368602DF65045808D87B7E24CE23C67906BF64C90CF0E0F8621537D08A09290E431737F9C493DBADF98C9E250E094C6F0F7E850F5EF65E71967F69159ADD14974C1AF501C74F01D1C36AEBE604A32DC02B676BBD7CE4BC3967FA8899F3B1F654E7F3E425ADB5ACF59B6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000018F224E19E61C8A7076585BF7780AD32D73D04D66A52F0B4CB6D35D9496906BFB05000000000001C0F7248E24BEA5635FD0F3F3411F1A20316CD29E2BDE6DCCBDEF8AFD463CADB306000000000001BFE2E0B4F4BD9B2B955C3CE73D4D0E703C44BE5168224D99756D865D86689E1607000000000001EB5D1F16948BBDEB3335E0F93C3DAC5C3FF7DCB33B16BB28D3826194192729F80800000000000194BC268989E8C957203F60EFD29089692A7FA0980912BCCB1FF3D6921B9805610900000000000182B44F3F72EC96002984E059C46042E3085A35BBBA6A0CA79700D29DB34DF2FA0A000000000001174A1DED5F222EB3573B2A6CC27870F2FAB30A64FFB9601B5B8167314CD3C4AC0B000000000001CEC1E018C94D354F99802059603298AAB121FB0D1CE89A6C90B945D90A6233560C00000000000184D0355AC86A5E83CCA4300AD4EF13DCF7D6185ADD1B29F22FF24B446B6A184C0D000000000001EF0BF8DB8426844A322EACD3C79500078561868864057744206E70294F1B4FBF0E000000000001EA649E4FFD3B7A864E5C9177F8B14D91BE4CFDB050B6EBC86571996AFC1AF62C0F000000000001F80F14346EB4A8387798C08955A0CAF061B367B1F969D28F833140663D9A4B24100000000000010990AE38170C318A1CB81B1C8C6D980077F153C1C0403EC9645459C3C222225011000000000001DDF5AD2829966C243C523B4B91800973741F27929353122DFD2F0F9DE717F31D12000000000001254C2BE70DF73E405F76FFAA6BF442F41018C0C2D3823AC64CC175A601ECE527130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000665137D5D47667E1CA8F1B70A9029441013DB1E00D4FB39DE01E275ADE1AF6E6483B18C34D78AD814C71F370A0AF1E681C1041FFFACF9685BABB03923BDB41701F927F3316ED4DA8420A373F5471BE4A7215CFE5683EF16855C748D8FBD21DD9A6C36EBDA9BC5497F5C0C93DDBD40A717DCE151B87E8D5CCEFE5E8A0A66B3F92739B24915DA4B87BC7E555AE0554A8FC1D2514A7979DCC78E92D79C6908005648F90E5E4AB32CBDE27EF1BDE91C49C5184A3CE134D7AD33A1AC03F4A09CC245DAB6033C99636D9F6E9A723429F5EDFE118C045EDA721EB21387225EE2764A00D99625EB4FDDDAE398DBB4D8CD926310601CB34D38B7BA4BF60C66925B2E66B838C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A3692F3176BEC212C8CDDA63B223901AFF8E3CA0612978B7D97E8F2E1C000B0D2FB992BE80BE6906A967BE9949853BED6333CB070A1384B5A26ADF28D3BC5ED2236C6699909AC8EF3CE18997A672EFA2087DC9C0C38BB416613F206E136D3135C4E39F98C7C1F50DBBD69337069248EC64C3E5C6EE0EB7618396BFBC2BA26667426721DC84D3A53129AF465CAB586A54924BD35CA4BB250865AE0EFE67BDF060D8F947141B55502BD264BE2F24B40DA59C45FA59620F207E10FE94013B6A9F94182CFDA5694E19B1ADA22B18F183D7DF0A51AE2876A5D6B79D911B0B8A0D3EA283DDE8F0FC0DA1D77498ADC4DE901F89F11DE2753E8EF674622BF03110CB519AE4F6CD0ADC41A43D1929CBE5047D9B09FE60D9075C85CEAE9C825EA53585D180FB610BBA83BBA2E590AC5257DF858E7F11B8298C848F2F79D78C37F00474AEF9B5E9AEDBA4C81ABA062F24531171F8137F7FCF50FE09A38F60404B03CD1BAA934D6DB5CFCB1DC552BF873C6AA9B5FE76FAE92D4C3674E20DCA7BBF430C865F6E5FB5D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF710D288F760D8E6A64D9E2E53F680C21D30AC1439A4A90469D0C6271AB6EFBB90A4F4DBFF7D5F3875C6507DB321D81C3510D7E7F48B297881DB6FA0AFCE41645FC93A37FF04FCBA7FC19B9089BEABCF9BDF44E2C4614A73FEC80C1234162B41BDF1313F6E13AE2C48A6C4CABEF5EDE59AD461384DEFAF1935E23F5CAB3829A81E2DFFBBCF2FFB141D975EABF78FB4BD484F75E08318C08B2104A468E670786397EEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA360AB78FD9219EA890695CE44CC785A3A4DD39CB8F3C82FA5C6A3167055CF3309EB06EB90826159619E65C5E29D46D35E61C961AEC002F87B44A2B7D5C0E2111D17268FC3B147434264112A2E95AADA6ED860C50359372609ADB174741CC3AAAAD1FB50A42A560BB18D12C228F10D2776DED26752930890259A5C0F64C7D30C49383F92F1EAC6B1E8D6BA05423368AD3A8BD145D397389720E80F6EE11965E467D4D5864E164E51437277F698BEDA846AEB66DA3DEF39CA3288D30C001D3B0BCA113AFE8AD333A08D801A9E4C52DF0DDD4C63D8DF7EA938014336BDCDFA10E960DDDB4B5471263D096A49E3C83A188C46AD4EA8D2AEAAD3B1BA78CF6F116D0818BD2F38DB39D74D340546233ABC52278B381B7DEDC3A3B5DAADC8A4E7519AC9F3572A35C016CC7A8E0FABC029801012DD7454D7475E5D8B492A119AC583F4043D25CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438D81219D292421651600D48C2BD291766ABA14ADDC9186764DD212446D27C3738D2F606A9654BB310288F37CF0ECD5D38590E4D887D9D5C523527007F6501ACBE7CF36803727022D98CB15BCC0A88A509DF3B9A84E99B41843283FF2E10FBDA3C14CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D446D278BBC90D6A56B71D6DA6FCA49F332776F402F58D180482B2EBA5132D8ED67144DA06AAF952EF5B9BEBBF0CC8101E93F3BE05E58EB75D55B3CE72B9C8A07725C61C24C34DEB9A7349E51256EECB7DB61510D8BF55798B060EEDF9F9551AA615F1661F544B0779B2974A54BE8BBA388D6D7FB8E2C0956DCB23F834025CAE4BF26B798CBD5938A517C4C3B8FD3B8FE920558256C391433854481944BE487AFBD226853E385D942014B393488D554FBC143B44F7E9F348FB79920D4AB758CAEC55ED8CD388DCE4B4381D5C3A9FF36ACF9948993CF2B2E03030646852CB4193585AC6C56947193F96292D813FCF3671D46B9DF2D99D43E0AB4F1994B81235A50D5D977FA3560CA3D46CF60945C8D3E1103B6B1D13CCFAE43741BE65EAFFB9DCAB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832D381248D668B0A5ADC623F2529B02CCE42442E86382E03BA3FAF21F86FDE1C633C9A17426EF1F4923824A1E394BBAF5058C00950968357FEA01AFA8303DAA21BAE4617293B3B19A50C88C8F7D8A677A3314640452734E7FE4BA483C8AF87356E6822D943C23705352F458ED80B8375DA6F1F0DD7688CBC6101727F2AE7FE500C98A185F29DC71EE3506F8425B8D7EA94BE228679F42ACED5C9162D6A0E9AF148E5903C0ACC117C2BAAF1EC4A73A0BF73CDC646D1559EB1FA607044B5C7CA60FBDD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C6F2AE696330DD7C816130134AC101764D6B4FAFA1E71A404CEBA3406E1996391AC35A28F18E05DA188AA8FB52712696C986C25F70A31DA73957B238FAE89EE0BE4F77ED34ADFF62BB5C0838F9B645F6851BCA9241ACBCD3038BC40F40F076D1CCD8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CEC2A8424E383ACE82322B3629ADA77D454B677A60A2932B49F844A9389E73FCCB + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 5605 +sm = 00000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6DAC51184D2E4216B689657E98DE08E43946559C194B79D61BCAD87EED916B16CBBCC675AA586D085AAAE1C4C330ECCD5175C5DA952B32829871E231AB5DF21664BA023C2BCC5E6A8E23448E84431B33CBB812A458DD44EC9C2C10E7570B2657F30354434A7E3B1BF99467D1067CFB19264ACF52D2524511F0FB34AB02BF1266B66A0D5672F44DBB9632CE082C47A1191092030F878A87D3007016131038259D301FD9F8C8FC0CF2C5961F669207E6BBEE6F8BAD3B1AE3DF6E88C679BCD425CC1ECE4C96410219AA2370A23C6E92E5322E0CD81840622A3C20D7243711074E1914424E503C694D3360129ECDBE6ADA3F8D0FEF9BD08B3638B1B2076462013954855C6DD4C888FD4C8BDEF806EB73B632B3C27697F2410935EBD0B4EB7D4FE85D9961BA4254B0FBC7E8A37B1D610C74A511E52A8A50F4943217493F7EA4C92CF2591CF5AF0075C2B16BA82F2072C9419430FF672963FA85340B43818E9643DDC3CBBA724670050F31569813630709AB6A4E35D66684AB154CF647FD64DA3B2E5533B01944B68487B3A43C12094B7F4BDCE13FB2C882BE4EDF31F6CEAE8B8C9B0BE50BDFA63BE7C492FCD5E2A1A1334546D3937FB47D9673832B4E4015C43D199CD23FD99DA24210D8F5A4EE00D85FC2AE1F439009A21CADBEE4A699D5886ADB1A91DB87C1BEFDA40A6BAAF785B98971D733B5237497B86E89CCEFF4047BB0EE4AF2C0CCE36561758781EB57877CDA69BA5118EBF885452A682B2F650FB9C650884151E1961C11F7D8CCCE4F08E9BADDA88E17BF2DB02A6D1E1D2827021DB4659219A53F4F2C4C3512C48663CDF1EC31B6DDD6E35924EAA021247103348AEE988E84DF07EFD4A4BBDD190878F81047F477A4FF9B89DBA8ACA2B5058528061CC13CC21BE921E1C2CC0ECBA29139E304A0BDF7123670D3FF614F1F0E22C7C8E161E91167DE9D2380AB6D5B0807DE6032472D838B3F681E7ACBC75D71426F33ED97C79F1AB866C0EC37A66D86CED0DCAA7DAD8A4E71E08A856A7E8809F918430DD063868814754D5F91CBC9BB551E5663948A692D12D054D90840580C1D66423931FC56EDAF3A6A71C48FA89786E1A76FE326B90AF058B1627040851A517242451CFC337B7DEA5192657F498A96A2D405C7AAFD57EE39F6BE2C82A53FB2B744F8A003B689A394B8F61F7536B86985B684DA6C8C1C2B167481C309D1A85FCC85D1516138C86D028F556465D987D2F811892889E529E9ADA83956DC4741F939445B2711AA890B29BA3E9FC52C4881A9A34400B4B94126E07955BB03129FBDB971A00A45684921527E0431A3AB6B216B29F71296C1244DD9AD2D6D1A87E5CA6320CAA8EB347CE4D9F8AC77A5B3E43929F5F4847B4410A434B372FD317392AA7800C5E54946220CE06C2089E7CAA8F993A0A7C75FF2AC9137B272AB3CD4E320F03DD9B8E8EBF53B4A4B3E0A2AE1C07B14CDAB8F2BD7876E4D4FB45C950531E2ADCB7A4C41AB0ECFBD596F875E032C49705595F70A6A7B37A07484B5B173F9C611156BF564727E494572744D779FACB63A81CBFD2C18FDDF4883B35F19FAF86B48D5CD2DD91B565F6F3F7774A9CE75488FBA6FF0205FD45334A09906A3774718DDF36BB668C690438A5CC2F8313F8D8B35002CA267F3FAE2ACAED9FD4AC11F8388FF7CA27C3546763398E70BA97BF84F3DE6EE6C9C674772ABCC1D8FF097688E3BF3AAA181156E4FF135A1496F57BF70B4A953C9ECBB173E540EB285C140A6ED4CB5396B6958B799FAA589F3560CA7827B256A3001D465F3FA74BC5F397B5234A3D94DF962411DC97DBE8A6C554F9542FB6902B2D7E51B3D4B94559088F825C10A800FE6A1A8F56AFFFD51EA286DBB923E624FC7648B59CB8C78EFF8BED0E9B0DFE3E17CB1CF59658C0D73D1E63F8FAF0FBE8A8C2040111959D5A670BCC211CCAE5F5F687C59D558CB2D1DA9EE891F338DFF31CD3748B61CDE572EC77997A2BCD420E58ECBDAAFD9BDBA4BD815108B240DEA39524C501079A2815C04018C444AAC8AEC51B9271EC59D2C2647CC924B55E236369BA5C9F100EADE87928D10820D2C7B24CD9F76C8051F01577D24C318FEBC2762DEE56090A69FA567D0C5C78126420F1A05ADA26E940B72E6A1F9E107E8E42A9DC82FF74987C9C874B5C1714AD51AEACA48C79B0A6AD85F5CD06E4B59918DDA9C1EA1356480AB1D7254B2AAEEFBDC3AE61F995820C8D25218B7AB81957686E1BB2C02A72AD3B067589E7E454232E6D4AED6D531D31F29F7E297056681AEBDF65EDED3D6AF07161B5701231D7BF81A5ED366BFB24B287E1511840B5D4A91ED9317892FBF9E9684291E2A3D7F86C1B50F20EA98B41430AAC502011A616D454CA4673C0C3B3E188AFFAC0ADE22C470D99F216F912236252B0F1C3FAF39F5559E3D0172EAD6CDCF9300933A0B2C8CAE0C69503B978ED984A7657A5D9C1D1AB5F6ED5AB23FA6CC4941C8CE4B8C60E709C7AB5C4FC7D0D4679F9D78F4276DF36A375CB2C50BAD8BC2C807EFA5BC82B013E7126D008BAFA34C4701D464A9F05DCD14482A95871046B385D87F0CE6BE103A45B7E8F10E410548842655E088F270E443633B1A4515EEF5ACDA58551D97321492D14B0DE243A40813210D712442091D9A5624F353739618540511E6B51C9C5CB2798594AB428A87041F739E13504103A1A8324392800C0F640D6A7D75DCE2D69607864529B6A37750619565E885A3FEFBEA701E877A4095F1B519757A8543A598BBEB843CBAF01F3882AAD3C86F85E3256CDBE4209FE15ABAF88058FA199B21918C064B40EDAEA01CE9C99BAC79F55E0CCB1C03AF2EF2C56D45E06D33F9D3ABBC6CB4BE09793A386048112071548CF0A71C9991DBB3A11D93483E3716D9A8BAAF62BC5BB58E24D982E067547936FBB57F2C25218A230EFB1A665F3D948CDEAA9F8659900F10C43437C01BF081D2664641DB6FD5B0CBE2004A96DD26D999937817B3A8DFF742DDC33FADFE21A034F29F62E5EF6C502CEC5014A10A68A2DCD1998C74D620E84F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C7D176B37A7DC26214FBBF555DDEF8D970B6AA840AFCEE7B674EE05845118A6FB277ABEB1A792B61CA4D24646DBBFD623564F93B74C1277C1AE4CB326411850F0371D6A848ED0BBFB8B0BC3254398F513E630D075CDD277E0AE10D8D13EBDD0CC60AB0FFC61631C5D17989AD9DDF25BADAF0BB87FD0E32975EB673434812D58CC665137D5D47667E1CA8F1B70A9029441013DB1E00D4FB39DE01E275ADE1AF6E6483B18C34D78AD814C71F370A0AF1E681C1041FFFACF9685BABB03923BDB41701F927F3316ED4DA8420A373F5471BE4A7215CFE5683EF16855C748D8FBD21DD9A6C36EBDA9BC5497F5C0C93DDBD40A717DCE151B87E8D5CCEFE5E8A0A66B3F92739B24915DA4B87BC7E555AE0554A8FC1D2514A7979DCC78E92D79C6908005648F90E5E4AB32CBDE27EF1BDE91C49C5184A3CE134D7AD33A1AC03F4A09CC245DAB6033C99636D9F6E9A723429F5EDFE118C045EDA721EB21387225EE2764A00D99625EB4FDDDAE398DBB4D8CD926310601CB34D38B7BA4BF60C66925B2E66B838C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A3692F3176BEC212C8CDDA63B223901AFF8E3CA0612978B7D97E8F2E1C000B0D2FB992BE80BE6906A967BE9949853BED6333CB070A1384B5A26ADF28D3BC5ED2236C6699909AC8EF3CE18997A672EFA2087DC9C0C38BB416613F206E136D3135C4E39F98C7C1F50DBBD69337069248EC64C3E5C6EE0EB7618396BFBC2BA26667426721DC84D3A53129AF465CAB586A54924BD35CA4BB250865AE0EFE67BDF060D8F947141B55502BD264BE2F24B40DA59C45FA59620F207E10FE94013B6A9F94182CFDA5694E19B1ADA22B18F183D7DF0A51AE2876A5D6B79D911B0B8A0D3EA283DDE8F0FC0DA1D77498ADC4DE901F89F11DE2753E8EF674622BF03110CB519AE4F6CD0ADC41A43D1929CBE5047D9B09FE60D9075C85CEAE9C825EA53585D180FB610BBA83BBA2E590AC5257DF858E7F11B8298C848F2F79D78C37F00474AEF9B5E9AEDBA4C81ABA062F24531171F8137F7FCF50FE09A38F60404B03CD1BAA934D6DB5CFCB1DC552BF873C6AA9B5FE76FAE92D4C3674E20DCA7BBF430C865F6E5FB5D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF710D288F760D8E6A64D9E2E53F680C21D30AC1439A4A90469D0C6271AB6EFBB90A4F4DBFF7D5F3875C6507DB321D81C3510D7E7F48B297881DB6FA0AFCE41645FC93A37FF04FCBA7FC19B9089BEABCF9BDF44E2C4614A73FEC80C1234162B41BDF1313F6E13AE2C48A6C4CABEF5EDE59AD461384DEFAF1935E23F5CAB3829A81E2DFFBBCF2FFB141D975EABF78FB4BD484F75E08318C08B2104A468E670786397EEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA360AB78FD9219EA890695CE44CC785A3A4DD39CB8F3C82FA5C6A3167055CF3309EB06EB90826159619E65C5E29D46D35E61C961AEC002F87B44A2B7D5C0E2111D17268FC3B147434264112A2E95AADA6ED860C50359372609ADB174741CC3AAAAD1FB50A42A560BB18D12C228F10D2776DED26752930890259A5C0F64C7D30C49383F92F1EAC6B1E8D6BA05423368AD3A8BD145D397389720E80F6EE11965E467D4D5864E164E51437277F698BEDA846AEB66DA3DEF39CA3288D30C001D3B0BCA113AFE8AD333A08D801A9E4C52DF0DDD4C63D8DF7EA938014336BDCDFA10E960DDDB4B5471263D096A49E3C83A188C46AD4EA8D2AEAAD3B1BA78CF6F116D0818BD2F38DB39D74D340546233ABC52278B381B7DEDC3A3B5DAADC8A4E7519AC9F3572A35C016CC7A8E0FABC029801012DD7454D7475E5D8B492A119AC583F4043D25CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438D81219D292421651600D48C2BD291766ABA14ADDC9186764DD212446D27C3738D2F606A9654BB310288F37CF0ECD5D38590E4D887D9D5C523527007F6501ACBE7CF36803727022D98CB15BCC0A88A509DF3B9A84E99B41843283FF2E10FBDA3C14CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D446D278BBC90D6A56B71D6DA6FCA49F332776F402F58D180482B2EBA5132D8ED67144DA06AAF952EF5B9BEBBF0CC8101E93F3BE05E58EB75D55B3CE72B9C8A07725C61C24C34DEB9A7349E51256EECB7DB61510D8BF55798B060EEDF9F9551AA615F1661F544B0779B2974A54BE8BBA388D6D7FB8E2C0956DCB23F834025CAE4BF26B798CBD5938A517C4C3B8FD3B8FE920558256C391433854481944BE487AFBD226853E385D942014B393488D554FBC143B44F7E9F348FB79920D4AB758CAEC55ED8CD388DCE4B4381D5C3A9FF36ACF9948993CF2B2E03030646852CB4193585AC6C56947193F96292D813FCF3671D46B9DF2D99D43E0AB4F1994B81235A50D5D977FA3560CA3D46CF60945C8D3E1103B6B1D13CCFAE43741BE65EAFFB9DCAB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832D381248D668B0A5ADC623F2529B02CCE42442E86382E03BA3FAF21F86FDE1C633C9A17426EF1F4923824A1E394BBAF5058C00950968357FEA01AFA8303DAA21BAE4617293B3B19A50C88C8F7D8A677A3314640452734E7FE4BA483C8AF87356E6822D943C23705352F458ED80B8375DA6F1F0DD7688CBC6101727F2AE7FE500C98A185F29DC71EE3506F8425B8D7EA94BE228679F42ACED5C9162D6A0E9AF148E5903C0ACC117C2BAAF1EC4A73A0BF73CDC646D1559EB1FA607044B5C7CA60FBDD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C6F2AE696330DD7C816130134AC101764D6B4FAFA1E71A404CEBA3406E1996391AC35A28F18E05DA188AA8FB52712696C986C25F70A31DA73957B238FAE89EE0BE4F77ED34ADFF62BB5C0838F9B645F6851BCA9241ACBCD3038BC40F40F076D1CCD8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CEC2A8424E383ACE82322B3629ADA77D454B677A60A2932B49F844A9389E73FCCB22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A86CB037675575D46C48D89A7B644810666979BFDDE595E1A2362B9961A71D9F75A4A72ABF56BBE2C07844E774123A5DEED0116677B286BB3F8BCAF92D501A5FF375487D2694B089FAF47D8632DA9E213A9C914689D9FD8B0DA5320F6A89787E198248FA523B9B2E910FE55F6127ABFE1FF1EDFBAFF132A06AB9FF0F2E368AEFC6AFAAE9F61068AEEFCAF427D37CD93FC0B0D226CDCF6A7C1F007BE2E59568970AB644D475E62D7B8E7E5F7BBCEA4D007BDDAAFCF6B84E09BCBC5553F516E2E5DFFFEB66C9F5EF34559251705C736FF66A96AD2CA2C40A368602DF65045808D87B7E24CE23C67906BF64C90CF0E0F8621537D08A09290E431737F9C493DBADF98C9E250E094C6F0F7E850F5EF65E71967F69159ADD14974C1AF501C74F01D1C36AEBE604A32DC02B676BBD7CE4BC3967FA8899F3B1F654E7F3E425ADB5ACF59B6 +remain = 1099511627774 +max = 1099511627775 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-4_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-4_256.rsp new file mode 100644 index 0000000000..7f15d5b83b --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-4_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHAKE_40/4_256 + +pk = 00000014A855A0EF256ED6B3F83CB4938E1BCAB172AA13D2FF813E233B4C2E3DB18D27D804562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 000000140000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94AA855A0EF256ED6B3F83CB4938E1BCAB172AA13D2FF813E233B4C2E3DB18D27D804562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D933090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000018F224E19E61C8A7076585BF7780AD32D73D04D66A52F0B4CB6D35D9496906BFB05000000000001C0F7248E24BEA5635FD0F3F3411F1A20316CD29E2BDE6DCCBDEF8AFD463CADB306000000000001BFE2E0B4F4BD9B2B955C3CE73D4D0E703C44BE5168224D99756D865D86689E1607000000000001EB5D1F16948BBDEB3335E0F93C3DAC5C3FF7DCB33B16BB28D3826194192729F80800000000000194BC268989E8C957203F60EFD29089692A7FA0980912BCCB1FF3D6921B980561090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B832C73668D17AF4C29F2A72A1E8DC0D74C9F2446DE7A42F50A5DCA2F12EE84A91F75004E452A4E5FC799176A42B4D0A0A0CDAD9B44CC246872114650941B08315BA68E4B39A713B08A66F1715FE9300E5AAC533E37AE289B74341BC1DC7C75725C9838412E48A4CE312DEBC345B16A3A1F6388F350997448653448F6C7C91B7BE24118C3A0F4E431E88766E5A6C6113C8A2D1D2646B5EA5821C90CBE2CCB6CCA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001521B6795E3B31C6F469147CDE5776D1FAF80EE268B570DD87C1895E195F358E50100000000000135050ED1EAD3E799B63D5EDC01FDE9B7E3E8036A429C0AB56C909CC2B6378D6F020000000000010D93E097DE2D5330AA792D234007668B3E7F9E699621D298D2AB7577E8518A0703000000000001F2616B47D5F8376AF6A5FC658A75A52D032F7A1710630905C152957F41FA240104000000000001806EBD8412403D61AFCBD000376F11695F17BD253F82340C13342F750D09B2D205000000000001207581737977FDD59550FE1E0E62692061E1E37C554529C52E427434D2BC50AD060000000000012C3C45D74BE1C78902947B902756864EFD771DAF34009F91281FBAD0636A74EE070000000000014DC0E1A0DD7194009DC2FC5355C4D62179DA0010E19737654D7DC0E4C9761DFD0800000000000112F03C455D30919DCE22D2F8A0D4B5491A8188A32F17059A6AF994ADE911EF750900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE59F8968E30E844A031BC745FED8550EE78B1266A91694B967E66785403F9FDE097DBFF047A171318C43FB2472127512463FA79877B475C7F810D28AE0BA7C5966102673F9F55653D9E546E378D2BB17CD35FAD2F50C5372DF7871B1F1DE78A72FC84F2AD1BACFB45712FB13E3773B3565B021D30A31602528EF16FE6D83795A1A8620E06BE25AAB07A8F3F1EE979687840B7C863D0D8A547A5F7197FB72024DA7F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011420B60C54314ED8291B4F251FF32674EE6A3C3609140380F6B20865B7AE643401000000000001DA6EC89DAF2B01E86C06ABE8043C9A6EA0562A18C49B4A9497D347FAF8EB910002000000000001A0A42481338E08706BAC35F7B5F5D93432D40144F47A0F6790DF4B68525ED740030000000000014A9507DA8B4941DFD3D5E9A02EA050B97F9887A65D93FD8723FDC30C7E2AA4E004000000000001BDEA75F9BF80695B677BD7E643AAB0D6DEE791B64A29E66D796C51176B9F718C050000000000014F174AE6AE0AD2D1C856FD802C756287A8496B907E56C4BE48E85864F71DE7160600000000000131702A4AC2D7BD2722AD083379A254918CF9EE0656A5DAD6B07C11A74BBEC85207000000000001C2F54B401EC9CFC51F249ED76CF09A24665D8603D3747E67778075CC7817C4D708000000000001A1D56697DB12706AEF7EF31B1584DFB73FC269AEDE8C438FE9B6FE17C7A65986090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB931516966BA24D9585F1C0B04D660E629B3A2A3F31AEB6AC3EE8DF4DB67DABB5C332B61CC10887A0A207201703DFC4C27B774468F2CD9C6EFC711426E248C33EF946923D4C1AFA7B608F9F080410AE8F9F08CB38D5C0F6664EA0F630D34DFC55462334F617F3E4AE640E6C2D27597D4967E08EDC91704B9E3EE49EC4F0506994C3DD1027F8BE7FC46589CC21F9BEAF4F4130BC7D8325FD638235372E12CBB84FC424BAFF7D301855839698FE2E38B63BE461E681B43A02F99E466319E808084BDEFF59DC9DA0BC5F523A21D4525D81501A83F357BAB3633C061D403C7ADD90CBF38C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A36918612009A7CF4A981971AB37B767BC120AA994494DA75CABF22D1FE63F1464E981A0FF2BA93D3AAF2CEEADAFCB80FB7D012A588D4E409051A44F7287EB74B23A7F9A4302D2E7EA81F9FFD74D72807123DC3529B24DA2AF50619784A32B75985FE5AF8191B1CCF65322E266C37555CC3A971BF53E46DFDBC336CE5DAB6A84AC0F17F219C1DB9BD42A4F9662C74AF602347DE8A4EF176A34EAA287C9615F90FC02ABB78D80A6327768932976729CC4BC564E870C58EE9889C877CE31BA913EA7E454C0868D80335CC063C57D0BC1FB3C5E09B3A20F8166F8BDC41B01A8EEB62127C5BF88686BB8D0350F7BE6B56E0CE6E66B0998140C6F839A1AB13D68EF718809E2973CBB24BF5D927E83DD6C16C292D94B6EFE4A1BC9E050E8D6992BFD1C6F906C0A7B81474293A86ED095FD785C5BBA70F51BA7D49E9A5FFCE8193DD10914F642178026F159AE536FC1FABC7B78A3C2DF55D0C8E1EF23883C6FDBC053B447825E75F945D8157A967B58B0574C6E0615387CE1652DC027B72C45A8E9A4287219D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF71E8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B1A8277D00D5F8C835AB2820DFCFC4C8AFB2CB247B6DACFCDFB3765002D7D6EBA358848E7C7C63DA066252A81CC95E38A556ACD239ACB010A8169696B347EE86AE99CC7386155ECC56277B39192742ED8C959F142209943A017FBCE130FBDC3A491E7F650C98DAA0497D6C9CCABFD02921ABE4CFF254FB1521C702FB19F3DBBA1B691F7E44003C618C1B0C1B68A840B9763D43295E0CB779A59EEF7ED63AA1020069B2EF88BBCAB1D03693FE34C4C497F7936878D4DAB7B75BFF0FD8A0509D9A3B0CF209C9B7D09732CA0914617778AD289AC2110692D502C8DC75316530280FC926A62D46620A91EB4C89377C47ACC72884CAE39545022290B0D0EFA74045E4FFE5B7950E421091808852738371BAF20E81ADEE43642303C0F979B8EDAF4B47ADFB135B60A3E4F0BD2340A03D9F774ED36135C7C7241A89B2E9C71979E6BAA1E4D272BEA996623E399F2DA2AAAF6D0CE10191BA0853C08743DF8F9C98575E4F398BC3F19CFCBDB00B6C71E6B2B86A0E3BB72811DA873A3A318F6F334B64992648C9DA43BE0DB9CBA43FB1191DB64EA575DB1FA7F5E345ED532AEFC9F878894723ACC25CFEA3765FD8B4445453AB184E6C5A33FE8C136C8B401ED890A840BCC8C13CE2560D86119D74B6258D4381A4813572B6AEE5DB91BFA38F1E36EFF3DE17E255F8302A3A8161AD44F095659EEBB8E99100B7A19BCB8842ED58C474D1FFC28FD87A032D583050C09C64D4AE5F937743FC5E4705D9EADC758DF2CE55F240A40267311278E9198452030917F0ADB64226D6D413BCCB02C9A5C830AE5F2DBF73BCD8161132CCF43553B8FBA8E5283C953AEE50DDCE4EB59D29E4A2E5DA0530B922286F3588848CAFE9182175706266C466D65F41C3C18B000789C74952E3E2FEE44CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D58C6E04B24FDA2C3239210393254B41DA390EE357C7C175EA1DFD32FE5AADE666337542E508FAD05AA818E37539322BE1320FB587B83E86AA18434C47CA39E9850984F7339BD164FD46557BE86FB71B18CCAB5C34449AA65150D6F47A8117453D706F30DEDEB127BBA56F23193113CCBEB626F61BC4EA2D5053B489414A7F9731010D4333E72690C936D00367C343DA301A455B4CA7DCFC4215B0EE5185F1DFEAD2F09542D42C8CC1BA6ACFA452C6237454C5D115C0F5E04479131F9F1ACCA098EF0ACDFEF6FA39E4AEE14B0823E911EF2DAE145E261AE05A117E5A52E9DEDAC73742F90B4EAA8AA944F14679B0F72AADF6B56B31F3A2AA0AFA243C3DCCF6FFD2799FFA1F9861A5C04B0A8F68CC1BC8C90703AB05FBE50C15F06B04570370DEBB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832121C0C078E6BA4A80F1A20BD16BA90FCD04D43A0927C164582A796C12545CBD0BE45745F9E0090A47F31AB9B11E1496EED876912B13A841C06B6A5E812B11EC912A83D6B8663FBA403442AB4C70D3CCB76BE6686CD55D831E8DCCD05594F47FD58A835E3132D95EF4B4E8EBC275280999BF68305531A7F9F5EF2E8ED77C42227D0ED07B337CEB70317037ADA07819791A04BBF73646CC89806912EB3E2BABA0C80C7EB7BBAB7CE68583B609A5152A39457D51EE0A3CB4E897EB6363CB767057ADD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C63F474F26E2917A9A1B025C28BAC7D53E4E150E981E0D5BA4129911F99588369CD97444E871D47141AA795560B9576AF7870E3F62BC6F010869F6CA393E48A0BF5BE7ED218D65D942EC0F815F2258A47F7A509B6BB999C17B28D46B7D3CA59061D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C09FB9C3782471D5185D98077B9CD560F0F2D8109B8F2DFA711892BAF0A4A828E506417EECDAD332975E49F3E9019CE173E2ED3985D7C241AB4F7AE082E8EF49FD6E7D8241F8BAB4D68DE3288296539D0DDF68497D7634A964B76E82AF13767129B7FE5BF4C85685F9C1649B8A52FCBAA9B2AF0C0C2BE1904DEB98ADA34507734E7937BE5E686F6DDD4E57D5EEF9FDC2164D60CD06AB5C9D11B840625837703C3CEB44B6542B684CFC5EB9B3297D946E7F698FD75C5A824EEA9328EDBA65225623ECF3B1F560C0D9DD03CA404DDEB74F901FA06FF4D2B0972C31F94450036B01DDD94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB0AC0CF31A27014816177F79DBE703195F44C47205EC4A5CBE62146B5246AFD86660BB52A30FCC16AC9D773E97F581C7518D007FE0489C09FDFA334F49313FAC2B579C7AF47F9946A85247DC902ACD5E0B22949F45945DDD51DF6AB0FBC225603D7377F93D29F2DF9500194E614F93DEFECBCA3AFB03D22F8FD7661D9D41D62D3F34476EDB8FE887C37129998A21E92F020460D3AF85356DAA577666F5DC0BCC5986DAAF87F5A9E602BA73B7392923FDC5B81A6BAE67BDABA7F7D2E9410D160455BE2CC6A833BA1B0F8FE54852A576BCECECF9BDAEF1C9B426B3DBCA32353CEF2D782F9FF8C8DB114C65E259BD077E800BBF0AF92AE1083501FBCB6D736C848AFA2C836F2E20EAC0336B58D10000EE1E6FE4AF2C87B2DB73F0F695508E653A3755D0CF17516575A25E8960FFDB7B1A00FBED460A8BC7EDC370A52E214885B7DD496596F52B1697C11D5127906C27EEA91E5D3E948E752D54EDC1A8284B9330F1BAF79C2B31C41136602FB4D1A7418EE586E7386677F90D185CF9D61FD7178055651AAB6AFAF6B955469C05B619297155F922B97B7FD28FDA0C0FF3BF34081177EC83DC0433EFB8A1417D60691D76E15384DADDFE66566032B722D99F959653F5C68D4FACDEB4DB5F9CA52CAB9D78109D66D75ECA67FE82A790ADABA4C8F8EDC5663FE77361E78A43189D2B89D1F26535B1E860C9F18E7A3BC6892A68C68AF96C1F4730192CE3BF69D4E7048912FFAA309913C054E041306B4B0079D606F9EF3E08020379FC3A11CE22436F7C8BE6C5F5EE2C1C1778320456C18A68F306AD1B55954389F635A502169454E7C432BADF0A68F529903CA29C2B836DFF01B67CB745A77A9E7813A52B92C810B51BC3E71D7AAA9A9F31EE4542965AA0F6F9907D1595A31E720D4A7098FB2D72F01F8B83BF3A93D05157307E2B595F0609BF2C8B94EF6A5D60E53F20C1559A9476CD2391127B12D77357269359C424A769021D139860DCA4136B718B65880234089C1138705945AB76C815ECB06C01C73C60312FE6DE218F09C1607F528CEDD2898E077008FF6E47C4FB6B2C103BA92C399A24CC38B373B3D7F00D63E6A42412F710C62528106482F703ABC7CD198A24723A6BE730E6DC971D468EA20D76800F938E651FAFD425643ECCDE70BB4DC1D6FE4E9B3D3624C330E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD6847C7DCD156F805A9A513F17CFB60F16925F4C587744E4AD35C7127757AAD37B73E5277D6614F0C315BB9E3BE48F654AD2D343B3967FCCF5387EE8297F2F74214B7B154E1D715C8FEB898A1DA31D5A8ABAB9CDBAB991459E62BE9F0E0A69791265ACD8F7AEDAF736FB944D3CEA82A1B3F23ED9AC0025760D260009668580A7FED8B073D52EB9D1847445D2064669D9E03116C2D999F3274876F37552E2D8A04E4409EFB415FFD9571BBCCFDA01333286A5A934E32D7C6D7EF3A20DD86ED5391AF91188FC2BBA388067FA443275DF1C06B23BEBEB418CCF1A7CA0E4BAD57780AD7D5528BD18362F273F0D97C081E502F32EFE1508B343268F1D2EB3F12914313283E40F4EC9F02AA17AA8A310FF50DF2712F49896FE31BA07A188488E45EB59D6BD6B858D527BBC0892580637EE631FDE8EAC14EDEB1E73EC75C8C241294EA628DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF47606C4D632B57BF57812D2B2CB85C631F239710C05C7743C2F4515F6C64CBBC8109E7FFA421A5A637256FFE7F44413BBDE5787EB92060591282ED69794E9D64356A585D5E293E705EFC493596D08F3E68CA984532F71A20D81C4BE0CA989A19C2FC268CACE37F8F2D5B481F2A4F387043A4715FE805C6FE2D4AB89DEBE10CAFD406F37450F0E477859629CE2B957F3415CC4E2CDB795EB766193DB9CC1E5D34B022FF9C01B7ABAB66A08EA5A0983E6E85954C92A6D3B2AB9D45BA49B21D45A3468B53440BB45283D3251613D162A9CE508A5766740BC16F13842C2F89F2396E3363A1934E3AF2E7221957FDBC5F2BAA72B6E62BAEB9E6D33B248A5102714178A60CD3A02B6E121E1CE591185608500C11AAAEB039497472C12F766386647573D2974687D3B63D655D412B1DC0D3084791DC9CF5BC4A42D6D3787A187D4765E5C65894BA159FCFEE27FB3B36A54A9FA312C81EA09C6762770B9649872A738FA0111D745A1F9A0BC53FA819D6E7220FB07293058C8EE51270F86D956780BB52984745B68DA948F7F936345F770F38661F35198D5BED466C3E1C7A23DD56D543CFC93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B7871339ACAC858B546C9139F4B917CDA356F04B779BBF803351C1B452BD9EDD0E2DA226A5F930C3C97F43D4633BF11B8BCEBF646B8608685E36F0ECDE7C7FB5F977E4D61038C745DE151D832D47C979224CADCFDB0C82650055F1519B94680A840FA14B55B2190C71AC1F7A7AEED989BE8C8AC61149A0C809449B677AC353867D0185EB15322792A3A7E328FEE3DF2230E4B70551FD7F9BD57BBEAF02E40124C58F019EEB66602B9EA10094839EFA9070F5C2DA3AAB6CDE6EB58246A59AFFA0352106F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C013843CFEF1EDA266283A5CE4A6ACD7597519FBD097E9E460D9B071D34EDC61672D14E6D9D4F9A033B5B473A1B13476C3C447E884455A5D168DA793F9E2F09612A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B2BD0A2D4978F82258687586F9E6EE6AA21877D8A2C7AE37332573C420DB9C8754CC20EB937A8B94056D96EF571162B0106AEBFC344B5F28D52B8CD02F6168F45B321639DDDFBB333C5B872E80370F408EFFB5CC7394767F8CEC0CDCD7C9189E1B24FD29C7FBA4B14F30B8F5996155855C08A749B6AAED58C55271223A53D1E8714549EEA65B9A9245D9F5AD2EEBAE82637B9E3C78A24B5262873759CAE9AF9054C3230F88509E71CAE2238AA2DA1C25F0DCBFDE9BCC7B234BF1EA6697DD4E8B020B099CD92492855F1B528BA0B359BDEC1E77245432B7B1B2A5A7B969947A2FCFEAB2E94762E2F3F524E88E6FEFC4DBECED7EA550E6BCEDFF229E69D9C7C7803FACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E9847ED6D3A7874015F0AE87EE37FB6C478F7330A07D4C59E314847065E2F1F5F7F6DAE557F85B03FE6BB31B28A40263B64218FAD4572BC5FF2FD4E3F8F9A8894795658466BFB5DAFFCD99A69D532713CE072D81A42045933CDD30DD257F6C9848577D9F8B09B5D7BF71CF202AC4CF296E05C6A7ADF77D8FC670B88DAD02DE5A80D4168F7F72A7252B0E421F9734012AC8A8188677647D35ED6199EB300A6B71111D7CC77F04AF5E559A0D34CE1E1490576716A861E79902678C1241CB6F614176147ED88C82A99CCF2BBF62AE65572300CD4FB12DED4B6B0901D5F6BD02F036BF66B095215AAA76BAA4A07E2C0CAD2B2D76BEB56956C26ACDC11FDEFE9D42C6A698C09F0ECAC502F2F7E00233329DCA9595A191DF6C87B728E8F9B59105B9074992A62F2DFB38852C7F4BA5BF782395E906AF48136AB2DEAB4BBE7F0F79867696DDAA4176F14C9DC7A301B0DACA30332F73CA3356A62A4832A12DCCC3D696505F59E73148ED6401A34F6986428CB1CF18FD61DF1455A042455FBD97A76A404E65CD0BF41E26465281A0BA11EAA39CB48B99F2354BF5407629727B52DBA14B29C65083AE8B8891AECA5500BD15DE9E66E7D5C0104891C17A108B79D8D96D35F12170E2C930F8F16068AE3CA8511016203A1A4726CFEC7B6AAC959B67F3FF1E4AAEAD667487299703D38472B5085FC55B9BB775574AAA118BC81076CD53A4AA7E927482B1D617C09C6C24DEB07DD41C2C42B6A0BE168493CA5A40266AF5B992B9B2C65CFA82A2EFC515948A5FC521A7F49DC4BBAD296BB6FD4AA6FE1B7A7726229C03DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D973867CC37DAFE8FC39332DFD321B1ACA45587EB6D4727F5AFEC4178CDD8AF03FA0629DA84844B5131CC2AA07E2FBB8F80D3320AF5C1734031AEB68DB8B6C7358F775E8538C260FE6A79DDAE2BC7D40222B2942A2D8ADD3F295A135B5FBBA319FA3636F56D1BC8CBFA175EA61C1F53980664282E56291B4ECE5B5FF33C2141F04A3FF83EFC062CF6C635497FD03D6E56E405C43C4A31DDE872C4E277AA190D1D8350A298F16BE75BE305891F9D1084146199960A881C34318CFCF1366E82A487CEE95D5EC9F9756FFFC9DF3A1058E367160B321753C937D587130F9AAC766C19F033CCB2D886AB532683F50D360D10DF559AA16DA2C0E3203337B46EA1FCC1407675C5057052EDEFFF36BB2A6331522DC5CBC871C52CC35E95DF677771084A6E3E10A56111E6B9F7DAEB1FAA11B9CE5EA450A7D75F2B7266193CEA51A9532D8A32A2D4C275ECE75C3A59C3F02E3F9F40968642D6387F752C801A761F121A3EEF4F6B0AB83B7E815E5BB9D67EF85BF9DBF72E5E6DAEF4A6F7519130BD4F826A82D23332BC291A3D320CBFBE4BF1A143B78FAF7C1BF61F30801BCF715A05F2F7429F0D1A3B9F90D191754FE3D761A77CEA46082D3D2CA5BF26EF05257DBC8B72D156920EBCB1E064FBEC3CA43AF31CB2A53B246BA02E3F8AD4E07DE794CC1D8E3814DE61807A116F768CFFB159D16CB7214EAF1F52452B768380F4E16E2BCC10E82A027148477F2C717844DBB1677D6F2559AACA58E4759D40C7D62610399D6EDBC6DD4DA7904D2C53E4D9E07928FE181D503C5D45D6DE07E767025D9B0386F8C123C38CAEF00BE2223E8B1F46370B1D20FF0DBF78CB6A016D0F72F07820238885D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3A1E6EADFE7066FC6A5781AF310597B333977E34D01483A860E7D986357107DADB4F5D040550E524D9D1AA456CAED45FB5F6475160AB01C8AEC46EEA735384E4FBF205BB117F68C03F6D301E5C469033B05360DA23CF49DA36E050D627B2067B30983B2B426DCE0B78C0500BD15B3D2572537DC9B5F0BC0E1A12F533F58B2E21102318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3F5C33BF53D2A951EA7BE7FE2D487362EEC1DCB93920B266C5AD39FFA0FC6D4B335B1355A6D8AD3CFE51E9F69C8961A82831BD27F727C9030A816E817783DF89B519D6EC14C9CD88B73FD6152250E229BC6CD8C952777CC5D670051B18F5AFC99860FF7387C5880564703541C2883BC93C5C0EEFA57AF9E9D9D04EAB3BA87782807C37D299789C60C63CC2E86B5610ECA54D3949E17070B1978781F705E32042AFF28FA979979A511C5D14ADD08AFF7DDAE858415D7B0CBA138BF6D1C72C99A9564FE6CB5C9ED554B98D21CB796FC053CAFB4B3E8214F44643C99D9C92EA847A1B6DF3BC21FBF810F9D04B26771BC6DBAD0BDE30265D402E62EEE8ADC84CE8AF0FECBE8F68D13501515B8C28F68AD45D9D1A454904DE944A90C7500049FB74979AE952EBDCBA09DE543283CCA44D3F00EABF99DD714B8FDE3755D30105AC8CBC4569789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411935E2773E3B03C5E4959D9A2F7D55B05B8574768DF40B5EBF76FCAA69F463E0FAFC9F02B01C7B89C1AFB661B43AED07A9D54A6669DCD9022A4EA628CA69577EB1 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 9893 +sm = 00000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6AD447A5EA848807453245A18CC01A94E648515E259B4B02F4CB014A3064FACFB443FDD5FBE6890778BF1BFC187A67A07BF1296F0847C5F3CCA1A7FB1FD9023E9BCEFD889D3361070C554580F55CDC11D8572F0E0F241E24FF7A7AC9E3BFD197FB2D92D18C1A9520CC21A0A17908D121E1EA426738CFE364AB99172E83544AD0F868149F65E73EF30210B36E03DCD6257185F671F78904B3F11EC67EAF994D1B9D8E83842D91853C8E1A4E123A8BAA85CDC3BEF892DB683E3CFB4D60DF60CF4704069AC1646996731948816530C43C82CC1346A5614222B29B4C635AAA4542F11023B3A0B4EE1A22D367CD4E000A7067C2C7DD162FA09E777CA9DFD3B331ED208390BEAF62B72F91B502F69B6340B31F9D76A961DED774B471ADE78E037785CB71F2E6BEAA7180B7DD54525F52523DE6F98A205A6866C5B7489000B5CE17FF49A0F7DFD04029531B2B11444442249E7EC5E3AFC17C625C1518D4572F25A430957FA54D60EC4408C15DA7FC4B5BEC5120F1966279A400F0AF374CF6ACD439AB030AAC07D59B03A06086E043466BACB5E4DDAB7AC7F43409219F27561CA6168DD1793B0896752FCAE3699AF03C2E8C8725BE6073251317D1EEFB497336A32C511CA0B7C50EC84D8C0000D09632545965D732E921D01DAE77512180C12B01A2791BDA2E9D5A6B8D5DDBCDC0663306EF3064C548CE33CD8A644884C48ABCD720EFA3535EA50DC699D5233C7C07E22FA98EACB905820F49CB77A44374C0219D53B7570F655867F45720C67D422D5D284328E5439C2BE923E7F9C5307F30E5091A88A028D854EC9C6EDCA171B4E22C3510AE398B72498DDEC9A789612017CA366B164BE9E9FF5B29C0119111C7E194CC862333007578AC87C0A31254C758E96819FF2058952B7DC0473151EC0D9571297FA6AB0793D3EBB4AD559E0E367DE90BD20B96EC20ED1097E1670E2B93FA14EB1BA35D7B2C047E6BE110205B80B6F169695CDD43E5CAA8BC694B50F502DA1EE6CF34B148C124CB9F9A7C126FDAFAD4A5D7C10EC37376BAE08A0C313E5AE477A8DC6E0B54DD81E44E4E892F50EAB30D7978402C58B18890976C506E91D31F7FB3BC77EB0B08B99B12FF9572A673DEF5D64C16A1550E16E7027880D8853F1174E4B6A6E58BDD3277BC2B3E956FABCFA1633528BBD412D3E2F6C95AF02600C32B350543F091577CC486749C1ADD068F99DB36D8C4C59E35F94A4492867F7A94B9CBA5348F7071C5732563F8C1C008AD8C1767EC2D2ED2F3461E08EAD719760B6F43A811C31C2FFA680BE036C0982E60FBF9CF3FA705C58F3B2270A78E69A252FE4837E7E94DAD4842E9028DD986E5AAD6A8F16F9F138220F5672F8BEF56252D8E93E693A43FFC9AE96ED514D7405F080AC39BE1BC1F7BB117AB555E88AA0B934AF842719315E9C4CAC0FA685487177D3873EF1ADE626432E99402AF7ABD96CF8885DE3905BC9A2E4E755BE83AAD7C9280D0658507C51D6534AE73B220CA73A13917887367D055D38A65273890D1FB7A3AD50A7BEC3E7B693C41F717FEC260DC06486D04822DCD3BA1CEB89F12DFFE3534B51B107E75A3D5A0CB2436E8C9D8D85EA68ED5A5122F037785AEBAF31CA3BD4D001D8E9151B894ED06E313F1B4BBA00F7D5DF43AB472D66CFE6CE3B96B4F37F3D75356035546763398E70BA97BF84F3DE6EE6C9C674772ABCC1D8FF097688E3BF3AAA1811A2328704DFA7347CE5F938B3B4668994AD8A581E922DC72B14208BDB9671D73960B0747CFB99B09D25B1C0EBDDD5CE383A703FBE27C8A497B3C97FE7DF05CC6F36D18AFC8DAB6866EA201DB358B45AA0CDCA0959B4F0BF7ADDCDB0CF61ECC7FB7936AC13C35553CAB1747877424EC9FF34B7BF34172C1F65EF2D3F43DA07CF42D391577D3C7C28A0DE98276CDF9601CD0D4A8E79B7D27DFB2A31D57B86874B4E03D759940F88FAF5EB05BE1B90273FA0BC0048267B43376CDD718399A354E3B3AAFD9BDBA4BD815108B240DEA39524C501079A2815C04018C444AAC8AEC51B9243CBCAD6F5857BAAE18071F291C3D742C9FF3FC54A51D1CB8061D5A0ED4358E8AE0266816DEB0F3BA03299C533D554AFF476259527D312F3E6EB7E28290475F9E59C93E72BCDE6D87961B3185CA3ECD7D6A913D9F86EDB5017F5A1F28FBFF054D4058752C43C58B7599D697EE97FD109A46E627EBE3943B5044A18F1E08EC23E83B4146A39DB9ACA7CEEB0A93C4B5F1E625978CCA15C8C357DEF852277E400DC2D1BB52A35052545FA899B73D5DA8D6340B3C2794D4A24A4FD388C8581C384407EA9429D048B67D56B413B9002434DEFA4F2F025658778DFCF9BF148E70A2A70A185EB62720EDF55A36BA9C9359C49DD6ECED5E8CBCBFA03FE06416AF5AF976B8F33F4F73F6260DAAB08BF5A02A2F664E62BC3BFAA6A4800EEE8423D93ADB90859C7B9BD07FFF6433631AC5C062DDFE499E0C22DC5E3A10AB8D8D0C5D9A09833E106F1B8092E6A32B663C6EDC54366B5DFC4D1757DBDAE9F8E33B05A669DD692EF340F6C1BE587DFAED8EA010542245C17684A9944E53BB33C776507D940D699553C645E1E8AD6AC0BDFC48F9179909E135B6055FA9CBA44BA072D2A538BE604F88CAF5C2928BEF611C41113AD14CD4D92B45C3B9C0B8F339C7219E8982B9AC9C8063AEBC9FBF1978C1559D174EF9C55A74C7208114F94F2ECE9214B02D50834D401D4FC5E97CD40B375D0F6302502B3BB83098A6BFA378373FB0042E1578372BD4C2485B886668646E164CD67132C6D187490F3B18BD3A339FD5FB07DFA9F1F642E179872A32FEA44803F1728BD9EF3C177C047615E19B84BD6F8F61D368B32F78D2943AA14FCCB8D7551E69F02BCE1F438830583A0012B5A2B2A6AA8453208B991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EAF5C7A2FE46CF8DC6C729F18BDB361405C6D336725999A4CC76C94B5668A471861B40AFF393D6177502756D15DB5232BCD58ABDB633EFEA7390FF8BEA443BFB32F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD5894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB931516966BA24D9585F1C0B04D660E629B3A2A3F31AEB6AC3EE8DF4DB67DABB5C332B61CC10887A0A207201703DFC4C27B774468F2CD9C6EFC711426E248C33EF946923D4C1AFA7B608F9F080410AE8F9F08CB38D5C0F6664EA0F630D34DFC55462334F617F3E4AE640E6C2D27597D4967E08EDC91704B9E3EE49EC4F0506994C3DD1027F8BE7FC46589CC21F9BEAF4F4130BC7D8325FD638235372E12CBB84FC424BAFF7D301855839698FE2E38B63BE461E681B43A02F99E466319E808084BDEFF59DC9DA0BC5F523A21D4525D81501A83F357BAB3633C061D403C7ADD90CBF38C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A36918612009A7CF4A981971AB37B767BC120AA994494DA75CABF22D1FE63F1464E981A0FF2BA93D3AAF2CEEADAFCB80FB7D012A588D4E409051A44F7287EB74B23A7F9A4302D2E7EA81F9FFD74D72807123DC3529B24DA2AF50619784A32B75985FE5AF8191B1CCF65322E266C37555CC3A971BF53E46DFDBC336CE5DAB6A84AC0F17F219C1DB9BD42A4F9662C74AF602347DE8A4EF176A34EAA287C9615F90FC02ABB78D80A6327768932976729CC4BC564E870C58EE9889C877CE31BA913EA7E454C0868D80335CC063C57D0BC1FB3C5E09B3A20F8166F8BDC41B01A8EEB62127C5BF88686BB8D0350F7BE6B56E0CE6E66B0998140C6F839A1AB13D68EF718809E2973CBB24BF5D927E83DD6C16C292D94B6EFE4A1BC9E050E8D6992BFD1C6F906C0A7B81474293A86ED095FD785C5BBA70F51BA7D49E9A5FFCE8193DD10914F642178026F159AE536FC1FABC7B78A3C2DF55D0C8E1EF23883C6FDBC053B447825E75F945D8157A967B58B0574C6E0615387CE1652DC027B72C45A8E9A4287219D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF71E8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B1A8277D00D5F8C835AB2820DFCFC4C8AFB2CB247B6DACFCDFB3765002D7D6EBA358848E7C7C63DA066252A81CC95E38A556ACD239ACB010A8169696B347EE86AE99CC7386155ECC56277B39192742ED8C959F142209943A017FBCE130FBDC3A491E7F650C98DAA0497D6C9CCABFD02921ABE4CFF254FB1521C702FB19F3DBBA1B691F7E44003C618C1B0C1B68A840B9763D43295E0CB779A59EEF7ED63AA1020069B2EF88BBCAB1D03693FE34C4C497F7936878D4DAB7B75BFF0FD8A0509D9A3B0CF209C9B7D09732CA0914617778AD289AC2110692D502C8DC75316530280FC926A62D46620A91EB4C89377C47ACC72884CAE39545022290B0D0EFA74045E4FFE5B7950E421091808852738371BAF20E81ADEE43642303C0F979B8EDAF4B47ADFB135B60A3E4F0BD2340A03D9F774ED36135C7C7241A89B2E9C71979E6BAA1E4D272BEA996623E399F2DA2AAAF6D0CE10191BA0853C08743DF8F9C98575E4F398BC3F19CFCBDB00B6C71E6B2B86A0E3BB72811DA873A3A318F6F334B64992648C9DA43BE0DB9CBA43FB1191DB64EA575DB1FA7F5E345ED532AEFC9F878894723ACC25CFEA3765FD8B4445453AB184E6C5A33FE8C136C8B401ED890A840BCC8C13CE2560D86119D74B6258D4381A4813572B6AEE5DB91BFA38F1E36EFF3DE17E255F8302A3A8161AD44F095659EEBB8E99100B7A19BCB8842ED58C474D1FFC28FD87A032D583050C09C64D4AE5F937743FC5E4705D9EADC758DF2CE55F240A40267311278E9198452030917F0ADB64226D6D413BCCB02C9A5C830AE5F2DBF73BCD8161132CCF43553B8FBA8E5283C953AEE50DDCE4EB59D29E4A2E5DA0530B922286F3588848CAFE9182175706266C466D65F41C3C18B000789C74952E3E2FEE44CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D58C6E04B24FDA2C3239210393254B41DA390EE357C7C175EA1DFD32FE5AADE666337542E508FAD05AA818E37539322BE1320FB587B83E86AA18434C47CA39E9850984F7339BD164FD46557BE86FB71B18CCAB5C34449AA65150D6F47A8117453D706F30DEDEB127BBA56F23193113CCBEB626F61BC4EA2D5053B489414A7F9731010D4333E72690C936D00367C343DA301A455B4CA7DCFC4215B0EE5185F1DFEAD2F09542D42C8CC1BA6ACFA452C6237454C5D115C0F5E04479131F9F1ACCA098EF0ACDFEF6FA39E4AEE14B0823E911EF2DAE145E261AE05A117E5A52E9DEDAC73742F90B4EAA8AA944F14679B0F72AADF6B56B31F3A2AA0AFA243C3DCCF6FFD2799FFA1F9861A5C04B0A8F68CC1BC8C90703AB05FBE50C15F06B04570370DEBB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832121C0C078E6BA4A80F1A20BD16BA90FCD04D43A0927C164582A796C12545CBD0BE45745F9E0090A47F31AB9B11E1496EED876912B13A841C06B6A5E812B11EC912A83D6B8663FBA403442AB4C70D3CCB76BE6686CD55D831E8DCCD05594F47FD58A835E3132D95EF4B4E8EBC275280999BF68305531A7F9F5EF2E8ED77C42227D0ED07B337CEB70317037ADA07819791A04BBF73646CC89806912EB3E2BABA0C80C7EB7BBAB7CE68583B609A5152A39457D51EE0A3CB4E897EB6363CB767057ADD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C63F474F26E2917A9A1B025C28BAC7D53E4E150E981E0D5BA4129911F99588369CD97444E871D47141AA795560B9576AF7870E3F62BC6F010869F6CA393E48A0BF5BE7ED218D65D942EC0F815F2258A47F7A509B6BB999C17B28D46B7D3CA59061D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C09FB9C3782471D5185D98077B9CD560F0F2D8109B8F2DFA711892BAF0A4A828E506417EECDAD332975E49F3E9019CE173E2ED3985D7C241AB4F7AE082E8EF49FD22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A6E7D8241F8BAB4D68DE3288296539D0DDF68497D7634A964B76E82AF13767129B7FE5BF4C85685F9C1649B8A52FCBAA9B2AF0C0C2BE1904DEB98ADA34507734E7937BE5E686F6DDD4E57D5EEF9FDC2164D60CD06AB5C9D11B840625837703C3CEB44B6542B684CFC5EB9B3297D946E7F698FD75C5A824EEA9328EDBA65225623ECF3B1F560C0D9DD03CA404DDEB74F901FA06FF4D2B0972C31F94450036B01DDD94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB0AC0CF31A27014816177F79DBE703195F44C47205EC4A5CBE62146B5246AFD86660BB52A30FCC16AC9D773E97F581C7518D007FE0489C09FDFA334F49313FAC2B579C7AF47F9946A85247DC902ACD5E0B22949F45945DDD51DF6AB0FBC225603D7377F93D29F2DF9500194E614F93DEFECBCA3AFB03D22F8FD7661D9D41D62D3F34476EDB8FE887C37129998A21E92F020460D3AF85356DAA577666F5DC0BCC5986DAAF87F5A9E602BA73B7392923FDC5B81A6BAE67BDABA7F7D2E9410D160455BE2CC6A833BA1B0F8FE54852A576BCECECF9BDAEF1C9B426B3DBCA32353CEF2D782F9FF8C8DB114C65E259BD077E800BBF0AF92AE1083501FBCB6D736C848AFA2C836F2E20EAC0336B58D10000EE1E6FE4AF2C87B2DB73F0F695508E653A3755D0CF17516575A25E8960FFDB7B1A00FBED460A8BC7EDC370A52E214885B7DD496596F52B1697C11D5127906C27EEA91E5D3E948E752D54EDC1A8284B9330F1BAF79C2B31C41136602FB4D1A7418EE586E7386677F90D185CF9D61FD7178055651AAB6AFAF6B955469C05B619297155F922B97B7FD28FDA0C0FF3BF34081177EC83DC0433EFB8A1417D60691D76E15384DADDFE66566032B722D99F959653F5C68D4FACDEB4DB5F9CA52CAB9D78109D66D75ECA67FE82A790ADABA4C8F8EDC5663FE77361E78A43189D2B89D1F26535B1E860C9F18E7A3BC6892A68C68AF96C1F4730192CE3BF69D4E7048912FFAA309913C054E041306B4B0079D606F9EF3E08020379FC3A11CE22436F7C8BE6C5F5EE2C1C1778320456C18A68F306AD1B55954389F635A502169454E7C432BADF0A68F529903CA29C2B836DFF01B67CB745A77A9E7813A52B92C810B51BC3E71D7AAA9A9F31EE4542965AA0F6F9907D1595A31E720D4A7098FB2D72F01F8B83BF3A93D05157307E2B595F0609BF2C8B94EF6A5D60E53F20C1559A9476CD2391127B12D77357269359C424A769021D139860DCA4136B718B65880234089C1138705945AB76C815ECB06C01C73C60312FE6DE218F09C1607F528CEDD2898E077008FF6E47C4FB6B2C103BA92C399A24CC38B373B3D7F00D63E6A42412F710C62528106482F703ABC7CD198A24723A6BE730E6DC971D468EA20D76800F938E651FAFD425643ECCDE70BB4DC1D6FE4E9B3D3624C330E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD6847C7DCD156F805A9A513F17CFB60F16925F4C587744E4AD35C7127757AAD37B73E5277D6614F0C315BB9E3BE48F654AD2D343B3967FCCF5387EE8297F2F74214B7B154E1D715C8FEB898A1DA31D5A8ABAB9CDBAB991459E62BE9F0E0A69791265ACD8F7AEDAF736FB944D3CEA82A1B3F23ED9AC0025760D260009668580A7FED8B073D52EB9D1847445D2064669D9E03116C2D999F3274876F37552E2D8A04E4409EFB415FFD9571BBCCFDA01333286A5A934E32D7C6D7EF3A20DD86ED5391AF91188FC2BBA388067FA443275DF1C06B23BEBEB418CCF1A7CA0E4BAD57780AD7D5528BD18362F273F0D97C081E502F32EFE1508B343268F1D2EB3F12914313283E40F4EC9F02AA17AA8A310FF50DF2712F49896FE31BA07A188488E45EB59D6BD6B858D527BBC0892580637EE631FDE8EAC14EDEB1E73EC75C8C241294EA628DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF47606C4D632B57BF57812D2B2CB85C631F239710C05C7743C2F4515F6C64CBBC8109E7FFA421A5A637256FFE7F44413BBDE5787EB92060591282ED69794E9D64356A585D5E293E705EFC493596D08F3E68CA984532F71A20D81C4BE0CA989A19C2FC268CACE37F8F2D5B481F2A4F387043A4715FE805C6FE2D4AB89DEBE10CAFD406F37450F0E477859629CE2B957F3415CC4E2CDB795EB766193DB9CC1E5D34B022FF9C01B7ABAB66A08EA5A0983E6E85954C92A6D3B2AB9D45BA49B21D45A3468B53440BB45283D3251613D162A9CE508A5766740BC16F13842C2F89F2396E3363A1934E3AF2E7221957FDBC5F2BAA72B6E62BAEB9E6D33B248A5102714178A60CD3A02B6E121E1CE591185608500C11AAAEB039497472C12F766386647573D2974687D3B63D655D412B1DC0D3084791DC9CF5BC4A42D6D3787A187D4765E5C65894BA159FCFEE27FB3B36A54A9FA312C81EA09C6762770B9649872A738FA0111D745A1F9A0BC53FA819D6E7220FB07293058C8EE51270F86D956780BB52984745B68DA948F7F936345F770F38661F35198D5BED466C3E1C7A23DD56D543CFC93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B7871339ACAC858B546C9139F4B917CDA356F04B779BBF803351C1B452BD9EDD0E2DA226A5F930C3C97F43D4633BF11B8BCEBF646B8608685E36F0ECDE7C7FB5F977E4D61038C745DE151D832D47C979224CADCFDB0C82650055F1519B94680A840FA14B55B2190C71AC1F7A7AEED989BE8C8AC61149A0C809449B677AC353867D0185EB15322792A3A7E328FEE3DF2230E4B70551FD7F9BD57BBEAF02E40124C58F019EEB66602B9EA10094839EFA9070F5C2DA3AAB6CDE6EB58246A59AFFA0352106F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C013843CFEF1EDA266283A5CE4A6ACD7597519FBD097E9E460D9B071D34EDC61672D14E6D9D4F9A033B5B473A1B13476C3C447E884455A5D168DA793F9E2F096157F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B832C73668D17AF4C29F2A72A1E8DC0D74C9F2446DE7A42F50A5DCA2F12EE84A91F75004E452A4E5FC799176A42B4D0A0A0CDAD9B44CC246872114650941B08315BA68E4B39A713B08A66F1715FE9300E5AAC533E37AE289B74341BC1DC7C75725C9838412E48A4CE312DEBC345B16A3A1F6388F350997448653448F6C7C91B7BE24118C3A0F4E431E88766E5A6C6113C8A2D1D2646B5EA5821C90CBE2CCB6CCA02A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B2BD0A2D4978F82258687586F9E6EE6AA21877D8A2C7AE37332573C420DB9C8754CC20EB937A8B94056D96EF571162B0106AEBFC344B5F28D52B8CD02F6168F45B321639DDDFBB333C5B872E80370F408EFFB5CC7394767F8CEC0CDCD7C9189E1B24FD29C7FBA4B14F30B8F5996155855C08A749B6AAED58C55271223A53D1E8714549EEA65B9A9245D9F5AD2EEBAE82637B9E3C78A24B5262873759CAE9AF9054C3230F88509E71CAE2238AA2DA1C25F0DCBFDE9BCC7B234BF1EA6697DD4E8B020B099CD92492855F1B528BA0B359BDEC1E77245432B7B1B2A5A7B969947A2FCFEAB2E94762E2F3F524E88E6FEFC4DBECED7EA550E6BCEDFF229E69D9C7C7803FACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E9847ED6D3A7874015F0AE87EE37FB6C478F7330A07D4C59E314847065E2F1F5F7F6DAE557F85B03FE6BB31B28A40263B64218FAD4572BC5FF2FD4E3F8F9A8894795658466BFB5DAFFCD99A69D532713CE072D81A42045933CDD30DD257F6C9848577D9F8B09B5D7BF71CF202AC4CF296E05C6A7ADF77D8FC670B88DAD02DE5A80D4168F7F72A7252B0E421F9734012AC8A8188677647D35ED6199EB300A6B71111D7CC77F04AF5E559A0D34CE1E1490576716A861E79902678C1241CB6F614176147ED88C82A99CCF2BBF62AE65572300CD4FB12DED4B6B0901D5F6BD02F036BF66B095215AAA76BAA4A07E2C0CAD2B2D76BEB56956C26ACDC11FDEFE9D42C6A698C09F0ECAC502F2F7E00233329DCA9595A191DF6C87B728E8F9B59105B9074992A62F2DFB38852C7F4BA5BF782395E906AF48136AB2DEAB4BBE7F0F79867696DDAA4176F14C9DC7A301B0DACA30332F73CA3356A62A4832A12DCCC3D696505F59E73148ED6401A34F6986428CB1CF18FD61DF1455A042455FBD97A76A404E65CD0BF41E26465281A0BA11EAA39CB48B99F2354BF5407629727B52DBA14B29C65083AE8B8891AECA5500BD15DE9E66E7D5C0104891C17A108B79D8D96D35F12170E2C930F8F16068AE3CA8511016203A1A4726CFEC7B6AAC959B67F3FF1E4AAEAD667487299703D38472B5085FC55B9BB775574AAA118BC81076CD53A4AA7E927482B1D617C09C6C24DEB07DD41C2C42B6A0BE168493CA5A40266AF5B992B9B2C65CFA82A2EFC515948A5FC521A7F49DC4BBAD296BB6FD4AA6FE1B7A7726229C03DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D973867CC37DAFE8FC39332DFD321B1ACA45587EB6D4727F5AFEC4178CDD8AF03FA0629DA84844B5131CC2AA07E2FBB8F80D3320AF5C1734031AEB68DB8B6C7358F775E8538C260FE6A79DDAE2BC7D40222B2942A2D8ADD3F295A135B5FBBA319FA3636F56D1BC8CBFA175EA61C1F53980664282E56291B4ECE5B5FF33C2141F04A3FF83EFC062CF6C635497FD03D6E56E405C43C4A31DDE872C4E277AA190D1D8350A298F16BE75BE305891F9D1084146199960A881C34318CFCF1366E82A487CEE95D5EC9F9756FFFC9DF3A1058E367160B321753C937D587130F9AAC766C19F033CCB2D886AB532683F50D360D10DF559AA16DA2C0E3203337B46EA1FCC1407675C5057052EDEFFF36BB2A6331522DC5CBC871C52CC35E95DF677771084A6E3E10A56111E6B9F7DAEB1FAA11B9CE5EA450A7D75F2B7266193CEA51A9532D8A32A2D4C275ECE75C3A59C3F02E3F9F40968642D6387F752C801A761F121A3EEF4F6B0AB83B7E815E5BB9D67EF85BF9DBF72E5E6DAEF4A6F7519130BD4F826A82D23332BC291A3D320CBFBE4BF1A143B78FAF7C1BF61F30801BCF715A05F2F7429F0D1A3B9F90D191754FE3D761A77CEA46082D3D2CA5BF26EF05257DBC8B72D156920EBCB1E064FBEC3CA43AF31CB2A53B246BA02E3F8AD4E07DE794CC1D8E3814DE61807A116F768CFFB159D16CB7214EAF1F52452B768380F4E16E2BCC10E82A027148477F2C717844DBB1677D6F2559AACA58E4759D40C7D62610399D6EDBC6DD4DA7904D2C53E4D9E07928FE181D503C5D45D6DE07E767025D9B0386F8C123C38CAEF00BE2223E8B1F46370B1D20FF0DBF78CB6A016D0F72F07820238885D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3A1E6EADFE7066FC6A5781AF310597B333977E34D01483A860E7D986357107DADB4F5D040550E524D9D1AA456CAED45FB5F6475160AB01C8AEC46EEA735384E4FBF205BB117F68C03F6D301E5C469033B05360DA23CF49DA36E050D627B2067B30983B2B426DCE0B78C0500BD15B3D2572537DC9B5F0BC0E1A12F533F58B2E21102318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3F5C33BF53D2A951EA7BE7FE2D487362EEC1DCB93920B266C5AD39FFA0FC6D4B335B1355A6D8AD3CFE51E9F69C8961A82831BD27F727C9030A816E817783DF89B519D6EC14C9CD88B73FD6152250E229BC6CD8C952777CC5D670051B18F5AFC99860FF7387C5880564703541C2883BC93C5C0EEFA57AF9E9D9D04EAB3BA87782807C37D299789C60C63CC2E86B5610ECA54D3949E17070B1978781F705E32042AFF28FA979979A511C5D14ADD08AFF7DDAE858415D7B0CBA138BF6D1C72C99A9564FE6CB5C9ED554B98D21CB796FC053CAFB4B3E8214F44643C99D9C92EA847A1B6DF3BC21FBF810F9D04B26771BC6DBAD0BDE30265D402E62EEE8ADC84CE8AF0FECBE8F68D13501515B8C28F68AD45D9D1A454904DE944A90C7500049FB74979AE952EBDCBA09DE543283CCA44D3F00EABF99DD714B8FDE3755D30105AC8CBC4569789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411935E2773E3B03C5E4959D9A2F7D55B05B8574768DF40B5EBF76FCAA69F463E0FAFC9F02B01C7B89C1AFB661B43AED07A9D54A6669DCD9022A4EA628CA69577EB1D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE59F8968E30E844A031BC745FED8550EE78B1266A91694B967E66785403F9FDE097DBFF047A171318C43FB2472127512463FA79877B475C7F810D28AE0BA7C5966102673F9F55653D9E546E378D2BB17CD35FAD2F50C5372DF7871B1F1DE78A72FC84F2AD1BACFB45712FB13E3773B3565B021D30A31602528EF16FE6D83795A1A8620E06BE25AAB07A8F3F1EE979687840B7C863D0D8A547A5F7197FB72024DA7F +remain = 1099511627774 +max = 1099511627775 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-8_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-8_256.rsp new file mode 100644 index 0000000000..791dde71df --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-8_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHAKE_40/8_256 + +pk = 000000150C866CCF8B4C8031FC149A5B5C6C504B1DE97B1C9B8F84B9CE8BCF536E3BC15404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 000000150000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A0C866CCF8B4C8031FC149A5B5C6C504B1DE97B1C9B8F84B9CE8BCF536E3BC15404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001521B6795E3B31C6F469147CDE5776D1FAF80EE268B570DD87C1895E195F358E50100000000000135050ED1EAD3E799B63D5EDC01FDE9B7E3E8036A429C0AB56C909CC2B6378D6F020000000000010D93E097DE2D5330AA792D234007668B3E7F9E699621D298D2AB7577E8518A0703000000000001F2616B47D5F8376AF6A5FC658A75A52D032F7A1710630905C152957F41FA24010400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE5900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011420B60C54314ED8291B4F251FF32674EE6A3C3609140380F6B20865B7AE643401000000000001DA6EC89DAF2B01E86C06ABE8043C9A6EA0562A18C49B4A9497D347FAF8EB910002000000000001A0A42481338E08706BAC35F7B5F5D93432D40144F47A0F6790DF4B68525ED740030000000000014A9507DA8B4941DFD3D5E9A02EA050B97F9887A65D93FD8723FDC30C7E2AA4E00400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164A3FE6DFD83DBEFCE4CFEF2250893E21030934A382A288C69BF0FC7E9C92280906A4BA331C652BC4F904B9B54DCF3DB0651E43A6C83FB9843F85F0DBCA8D2E7F492200039906CF62A95D7B1830FDECAC0306B1A98B6F7B399E406A172202E29FA157E168F4B9C6979150F5AC2EF7769E4A729B6D59DD8F944E9A4A118FD06355D19B28ABDF256B4390DCD5C098DE989678AC25659763FC22E05FC4EB5860F400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018BB8E296C7509BC115ABB151E123D4E0343D51087A3A7321FD6406381792A7DA01000000000001166966BACD855719FD325B6CB7EEE8DEC0ABA7479BEEC9A71F451BD9EC1886B002000000000001E480EE1888B362F2F00B536DC0FB57F3AA94097DD543F05D299341633DEFE5FB03000000000001522E3D23E82223C8085779A58B7ECF45EB835F4B8FF5294923C95EEC4FCA5034040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096F5B92139A4B5768CDF2E35810BD1AB3BB40DCE3F38853783F6856552BF95A4A835590582BB7206044086C1CA3BD9B8ADFB09C40A838DEE80E1B3756F98073651454C1567EBB9BB8D9FEA16E9CB0F30FA5E7944CCFE2732FB90178A6F439EF2C83D0FD90FA196CBBECA9DE1DA63AB609F53BF11303F3AE2283195AD62587795E7CE13CCB19132890CE25B085F7AE282F8DE315DED51D9E7B4652285ECB3929B0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D10E76AEEA90CDFF9F15085B0834F5C0339E4C86D2CB52C234F6B18B472E8A020100000000000195C0CD14484D08075EDA691EE42CD999A552CA1A62318D9765CADAB553C1C5B90200000000000157A8A577120F2AD134FBF0E0E061E38A768CF935F4D2AA9A541C7A3D033A991503000000000001A467DDA3824B40F0D0D861A12328735CB8C23D1726982BE71F4CF68EEB4925500400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B07C872596E0E48193D8B6513232AE14EC985E19B27E231B2EDA344957695939677A09ECB8C65C93C63C6B08FE5DA691AD51D463012565EAE07805134DE6FD09BA7B3659089DB2B16DAB68A89406E67D63B3F0BC70C271C7D0295293CF5E174FE0609D593810EFAD6CD648BDF6D3253E64DCD6D2FA70FCDCEAF24B7C96A3E3E4B078E1668E5F6CB9A598FA202F0AE1DAD0AFC54BB46BEE1105C69C535390CD63000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151D5FD68390EB99D8038558DDDF270C7B6F86FB6880610C1958EC697B28F07030100000000000110E17383D0E375BD799216DC0666186C133435744D4C0B5160341DE623FB326A02000000000001446011ADFF0A4CDC66D4AD0938159A880A250A728A209F32F3AFA46A2FE4644303000000000001656C05D7A6E564380A829747834E40FABF67FCA7B2388E9EA19CB553E670F39D0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F1CBC0EAD4BFBAD01E0651103DD17A534A2CCD00CA53C713F3045B2389B81651E8E2C2B6629D127505EAE2ABD26F2086E9D6BD48CA6FC3BF98F99604F221DC203BCE9D61B756A89BB0B418249889529F7E8F070F35D35E572EFA012DABB16A98D0AC8A99E596A91468A1AAC939629FE780A45D8406B60D04C8E2B31EB7E28294FB2595F4E7071CD906FDFEC3EC3CBB02B03E38AF71EBE9EBCAE3DFC9A37E6B540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001FC2D9E83F622B942A7AB522F9BBA979A17180C4905EC5D9373BA8CFB20522714010000000000016319A9C8C78226547F3DCA6A70375F911BE4AE9028FDCCA6D161C5E3698EF41C02000000000001B15AA0B323C0B86CC6F8D84E17A54A6198649F962EADC06CE71C2D0FCE0F3F57030000000000016849136962E7C523775EF2B7BFA1967E4C45FD1B5FA9927D5068CB7045F945F804000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB939E6518A5122E37D4C257B0A0FD60CE0BA3BD55C9CBF369DD315A3C0609933D25DA403DF7E69FEB7EEE64DC3C13DC83217C2834B42876862CD48E99E69564B336506B85FDB493CF8FA87A7FE48DFE6778DDE8E8DD066FAA745C121480B5BF9D5F301B358D18FCCCBD24069E71836981F168FC49E6A4F27B00F6259B183B62CEAE0BF4AC0F53FCEBEB9052C0B48EB0666F361C5DA674B20B06AE2EA8783C2DD7EA74D98AC98C55748A368DF5B433C39538365EAE8DAE5E032A2008768FEB01F65D001AAC437781F742F536EFE2B3AE59EA12A6DC7F2712BA2D9D1C253D29B419A765985ACDB42BCCE5D64F6AF8368A5D122BB16B525A80C8BC5355A53917CC82262254378CFFDF1C7D6355F114E4FC013A5E4DD9AB373A0EFDC470854E20330BC00960ECBE882098D6D0D429A7AD19D3E5D4B78AC5E568C722A21877DA617190CB43123FB04333FAE5846953E33407080D04DF1417E740E7E7A14B0E3CA7D5B693F9615E1F7D417B9004F28D5002325B851C31F5EB31E1DAA80E6CFF22F11221E5180BB050888B6564A381E54401AF9409FE12A818B69BA34E1916092A0EBA24457EF994A1B0028649C9803045EC93CF416373F6A568856B771C3BB076AC265045ACE8E9BE3C3074D8806BEAA3B8B21F7E37F50B16221E14FE5503C615A13738CCDE39E2395E292119959CF686532CC3C9F9129E62ECFB43A091B06FD48ABE8C2CBE2D9691C8907881991CAB9D0D9CC7B2699F2261E5D799D26A7C8A4AEC40789B34CF5FE7BC8D24D6F0BBA7A5870E37F4D9B2605BB56ED9BAEB780CC74097DD8AA8741A97E22EC7B7434F81DE9D83CB9816A33C5A79D718C76A3442FE50C68FE1CE7AF728F2177F88E5168D4668518897AB050B57FF42AAC731E484B440D0D7B254383C74BE41C2AAEC02A8D8C7020355C4A1FAFAF4BBF56C74D78949D087259FE8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B179B32F9F94BBD8371B973B19E60C3CE2206A2061C7BCF159BC3A50163924774BB13C708A573472DA73B4C78DB30FEF310EA3643BC75D9155762D5B87809E2A727AC0428B746801D693074ED5245F29B8FF9FB782F2E57BDD89DD700EDBF12E8311946CAD9BCC98E3B1D581E678BEB1D0A6EFE15CF4052A1AECD328B2C4A8D5DDEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA36145D1653D108813E42654CB5350FFDB33BD2FDF4E416C6C0A61784E2327F42B2DA2AF040822C291D63645B0AC2377D0DE3FDBD99FF9CD9AAAE2B978C4DBEA95E330E90EAB0C4C34E88855C7C62C40B231AA1A9EB409D18CAA1C612A98F1B7BC25B18E3A89CAF96AA4BDF12F865EE7DB20273D7CA11970219BE997DD0EDE7A8ADFECFF1D90984694EF152346402207BD7D9166DC1B09F3C3520D109824442B8AB08869B0A4850BE3227E746998925CECCB422C4C05047D890E291B4E5478967A42BEEE34BA2765D86D183C71FB6A3CD86EAF457756FC000FAFDB24AF3C968E547A5223821BABF91B31B3F970D9F7C1FBFD16CC63D14243DB22CDBC266BFA4DE4B15D23B17D34C674649A695E80F84F6FEBAC0255BB155BD8B8D46FF7AFC532117E26985D99B0E23345F9A0247D834697804C6644501CA7D2726DA563C7F02371B5CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438DC67DF57A5B11025EDDC8915C57C8C72F6D6E71978496E206201184593506E39582DD2C803CE9204D2AC833C35BC683E0BD3CAD30BBCBF584AD38DAD30C9A400DE22F0CD6199FA6C622941E79F8C5C500389E9FBDEB8E1C926443B6FB0313DA9AABB163F5319C0164C1E58864827E38C18B7ECF6FB44274CCCB84B10F1A1BD76C8740F479777BDD7C557DBEFA9415B7FD50CA659E304EF4FA22680980D0FCEFC75E36231F740F38E9B4AC55BD8307F8AD9FE45B046B7BFF0F1B9FD5EEB82D474DC311A8418BB27CFE324426CD3311D65513B0A4D58515B94B8EE5ACC6815D6D1246527188E7B6C579CE42B28E1F273887FAFAA96D44FE6830E96081ED562FF4A08416DE4213A89CD666E2814FA290A5B1FA5AD6DB86B9E4DA85486E11BB36382C13607F50EDC83909F47A7D089CFEAF4680A6F2F10A2D9D9A679AE82D2DB387C5B7BCA11161E49E01C28D0FB7FEFE1C9A4BEDE994DEA4087F3B74906EA8E49153ABA49BE0F35C0572E9CE0C68B2267884C4BC4AD32BF28CE64DC7C825BDB2D8561C69161E075F48A40220159BFF1C4158187D4DE23C85979304DD4DBB98BAA57DBE6B7C55C271B134D61906F6ADBA4639BCAD3C1A70DA04A9409A4A35FEF1BC103D4F17BAFEC37C3F108B31327E0FB227E0E2C5B5410726ECC93B56D4D153572C2DB4EB4757F5B2232C475EB9802FEFB53EAC7BE6A090AAE98027AE13D2B338442FE6EF2DCF141C4D1AF00C7B3E973467FADDF6F1950ACF2BE908FED354EDFB147D6AC4B0740F87DE06E768293CC83AC995760FE0015CAC682036CCABA9C86B9B06924369E35688F7255F5D5422AB808D023B150D62D9A7DE4F7A5D28689EB038E9EF9D3366C3D777AB6D1C33878327018CC51EEDE65BB5FEEFDB1442B9006C76B10B6CE9EE1B6E43306DBB0D9030E3A191DA24634A80063F6A5269E77543525E11BCF02DF82E5921E3225EC97FC5F9174E0225E8C5D08B4C093EA28A19D03E908426578661E107E5E2C5371D79C31F11468112A6050703BB8FD9ACDEEF8D0BC31E82FB4F7DD0DFE8AE0216582E6C86FCBC1E7B3FFDD921F220702D827F145D79D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CE8D216DC6F19C3AC0A1017837C31D76ACDBD48F018A1CB14E98848B66A59F09AE557964888EBFCAD45C491A2A3C44B7085FCA7C983EA4AA22F62B99109F6E425CDFF5D87105EDC065810CA3E055F62FB80F5CAFEC57F7CB47A95B14A215714FB345FC73E57C1574E38657755CE991FCEEDC5ED84824E0E4AFD43205E126A3402910DCE16C59C8840FC7FC5ED9FE6379F9A388601D57B366FCF44FBD2D0C15A3D8A4A28D71ADE5965C137996748EFC7FB68ED165D2480FE34EF58A3169D03D0395D94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB08391412A812DBBE4FF09E10661B7DD604481AE6EB2F89A1FC04E393B3353F7547AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6222D7DC2F78B2E3FC4C8CEAE02E3FC9D7972CA803061F534D39E4F02809C7A18A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F9536829157F62BB003C2E45042DBEBA9622508F9AACA5FE89F665A5F35BA7C26D93A84F9DC744354C73885BC59EFB657317594D34B561FC2A789C919EE08D5D68185BFB2A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E1866ED93157270FB47C81CC3076E5B381E6B03127E7AE78C54F5F35B2474F18A2461297462FFAE651BDBF3D438E30420A3BA5686483DA2EACD874CC44102C09319C10FFE87AB2099A185DFD0FDDB6393B2F61490D65F93CE565C6575C877246044FD52ED475831AFE194BB163D0FE5A023BBC435497C3C16C8C7A85FF92426B59E588978E29EC0DAD032330035B797471B74BE366FA75D79D35228004D3231654D5F301D6597B83258DBE9284121A2BB21EF66F40C17FF135201D18092FA6A72B511A456786ECE1FCFC986A28C744DD4DEBCB552C638043B0602343CC796834B13660A86C5E3CCAAA1845C5165074AEFBA7C52190845A95DC59B1E8D6B052D253EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D1B478E24D9EDAC7EC8816FA54DFDAB0F181E9E1A8A6CD77A9EC29B3E35544898EAA311411BA22E8BA6418CF252675917A88572E0CE98CE03457996BA4FD86D07C4FA2D3487400E484F4CE0A83CF490C49588DB83ED1EE2A93B78101144586427FF43F434D3A40268920A4FA3C64C0F5F4600A8E52E01CD8210965C4B212DCC942C68D589D21FEF433904C26239698EA85C32423EF7AE1ADC90744996C956FD5D0683674010173EE4A110DA2642C8E1C4BF7B5DD3DE268A3AD0A261A30AFB6AD7D54210702C635C3E707CB1F17053D475A026EF57852DEC1FDA4252FDA2E69BA95C866BD432139CA8A4E367960F85B2FBC75420737CA4843B89F053192BB086BDC0D739B2753DBE42E1D45877097F3B97FCA6F43AC15DF883C3B42D9F472F910DE579301FF7F57D9857890651B64B6C1E8A7E2227ACAC7154D97252EACF8BC5FF430E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD637170756688D9AD3002B3148ACF0009CB1C0802EB04197FBD2FCE168B5FACDD052DD46F9F0B0A34295557CF741102E7592C24FA56DEDA63ECB7A2149E406C0943E5E554767D166EBC95FAF0E9B20C1E530633CF8BD7AB2A66CB105E108C1793B0D87ABBBBA9A4679A05C94BE6A698F4758B8BD38C51371C8043FC79E749D7E41C04DC6D815B0D32A779D0AC6E80C1D56B03C8EF30F6F6CB73A089B149F46BD4671D7C13B41A5B1BCAD94C0552C12CF23352200198CD876615EDDA7257E3CC94B732D75AF6D67A67929458E2639BA4A2967D05F76C4EAED429AC246CAB410B0FC8806B84EBFE1159C88D6E71EDDCC3B956F33739AD9FF6C43168B54FD592D845A54307AD16E42AAD4621D33A037D47D1002DE1AE0BCF2ADD9B01895EB0E63742FCBB5CFDA14EC9C63D94E3387E0FC22FB1B93D9065DF33D03AFA7D156BA719EB9DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF1DF5023719932492A5EE2B7A3B40B7C7F6814D179AEEFA584D317D536645921799727CED4C3D658D5A425D2D3EB1359C975FBE1A2FB2D11F37098B7234A19628624F07698EC3658799436DB5CCE6AC18702D4F27548F61BABC4807826E95D23889575EE119A88256D4326D4BBB48D0F589C6CB22E7F95D49F6607BE258753A6120CEFBC2E6C502138AEA689B4EDA13FDC39CC0759F392860168C2BA881FF70632D05E797A4F52453418035DFE9D072F0593E8029FFC25D75FC7DE13309B0AE4509D8A315C31F0FD0F480B598ADDB0D5A8F945FE6C28C2421DDB4A0DEB478478A49D5E628799ADC5E489FBDBC9DD38686EA7943969A5AC97497B2C380CAD367A8DF3DADD2E31F759AFA47A422D2A5F7C44CCB028AEC63EAA0727231A8BB4FAC096D19BA50AEC9522A00DDBEB86ED6DEB298AB433CDB7B4F15EA4AE08EB01782B70CD59C57D485848B16B9C55BCCECC876AA99071A9A7599868A9BB42F178BF3DD0FBB7EB52A796801D67E250148584C46F3E96898AA264BCC3826317B5BF7DFF55B6F3C3F3929FB552D79FFC1D014C52965F50B446DFC1CFB3302D8C7367A6F64C93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B787B24028E369C59743659E28980F3776146D88956F5E02B3E3116B8292C2E578C8708D4B518B95E8FCB7C7D5C3B16EF976B20FD0E53DCD6D92301061F2588F693A84052F8C776D033ED7A5EC71E928DD7CC7EED8DFC585AA94D8C9CF92D9694377C0268A53536DB64565FD9F5652B0A3634B381121BDA48C2D1FD9E189991D092178D79AEE8333BB0EC988417AD6CD9DD0DCBF6EFDB0E4E8D1B38E2A3DD01B3EAAD55E1CCB1291C87E2A835E86D2E0C0C3642166D2E9BC98CF354E28B6CD3F121606F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174BE4D5805F128D4A9B00266CB6CC792C45CA4E506C8B2504D13AC93044BF3FB332A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B275680E933FB83760E66AB8BBCD67108A95111001B9F8E85B6C96B4BBF952517D6330EB1C6AB68317C91468E90237214C46A5F496EE46E2E8069D65797581C01BA0B2DD1DFEE0F95C0AD7E426F877D0CD294CB0F3ECD1C65659D20594153630E46E4A32CA7D3B408B33227123C6449C4644192BAE44916FE60256703EAB9B2821973C8A37F2FC6B3B18FFE0E4C8036583B7E63E60A5EA8FE89401C8633BDC355FDDAD733A74922E73333FF9B2F9EAE2ABF957105197D92E7CAA56F91767E282E0910608FFA0E651B882398F8187E5203F8B56F788A4DE4130D211BAEDBE44B1DE0D729B926D5FBC98A1FA9EF01E415BE3795F085E28E1B32F86B0EC72DB22414EACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E947CA8092F4480FEC3CE1D8A6D8C4CBE3F7EB35919888B729C1CADAA559A42E1BBDA600C713EBB3487FAF3CCCC40CAFDEAE9B9C6EF40D5041B83973133A03156CE65E33173CC6EC41F0061D31797BF2D58C95B5B4E218AA783E09AAD39682072C6EAE7C52E3491E8B0345D3F6DD019D7DA6D9AE08FE40461B81D414B8D5BBE0672D892793121DDB345A2E5B1F8F3EECFFFEE5E425834717D59506DAC94BB9F31F00AC84767700A6FFBB6D93D4A9FC6F02C67F2710269A4162C284E0D9BF486ACFDB55A33CE915B41F167D533B268F96CE0C70A54377A5A76B1C8E992BD4908F6C9AE1B8A1129A6A94F2C1FA3EACE58297AB6E83568F0857FEBA399FAECFAC9FA94217BAD28BE66B04EF4EF7862DBFC7F9D86A69D63D84665C826910849A959626B2F95B16FBFAB29A97876BC2F43A43F841F6161648AA9D1689D67A4BEE2C859702320B726B0219DCC859A330C6C337AF2EFB0B9C8C689D2A7B92DC615BEF81F9488AC5E678E63D3E9C4CD4D2138F500D7967745773C58A8704107771E6AC93AA2307D387AF3CCF853E572E74624A7E40305FF4F57266A6BFBEEC78BC8CC981479D5A80F351588B5E378EC89F193C02A92E5BAB45E1C12BE0DBCAA00E85E73FF666690C4133023ACCD88989AD44530D63D54B090E115F6A25111B4F006B0EDBC73FFCA5B037240E88F9F4FDFF79F6874B6D6865B3B93037E272D66F1BB1EA9AD7952CE8F8F353C2910FBFC6F73626986970C6B1FA3F7D010A7DF2AD27ED28F727F9B6E10E08E9F23278C2C6ACA482528DFDD42021B690D777444DED9C912B2CD003DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D5023540D6CD04777ECAF4F4D58C64C158042656BCA7DFBBA61D7551154DC1535618FB3576C6A634E79E80BC56D4A77A32480711DCF387CC963BBC7A339C907928DBA6545BFEA6878A58236DC95D439F8F3061C099AEF80CB7128E0C1D3AC5841B65C0A738A16BA2EF4649CB510F512A819CD03BE1174182022DDBA30AE32DB5AB9ED29B2FCAF259886A4E479D5B5C118DFFA5529CF83978DBDC1B233C410279CC031E0EFD98F95DF6A32C1FB854F7DA54F12E0D0078F9287622542E551863DCB0B534DCA8EDE06545D0860957FF3A0C13495A47A669355FFF55DAC93C3357E5FC17274ACFCF9905705D6F32C7C6E6FCAE6086384B4939C70128CC73540E47ADC633EF01CD9E59A14EDC10AB0A9313ADC2123A4F3F3B4207CC9564D39F7CE86184505C432B568E4CCAEAA1BB93EFE4C696CA690F4B4EAC21A83E1860C5F26C6ACEE315F139E8C7543B2075D3FBF446058A1F0E0DC7893D9C78FB25914ACECE4664F58E03209D0EE1FCA892A9002B32FE67B0CD27E60F35706FC2BCE8A0F77E89FDD67DCAF4073DE5B72BFB56A87525875B0E27042175EAC158AB2D5A7B85C041FC13F81A9E78911686B33488DB258E31630B4D779F6F40E079F5094D31D70E74F2220ACCE407CB3491B80DCA95CF6126E9D2E955683F0B6BBA28885065E50309BD5E3429C626D547A87ED33769F9BFBB514F8792EB90F90C956F0148B9928189EE06BB40CE18932DB44AD96E226B6BB6A313DDC8CE4FB50C6C548BFA794FDD1EE7EAEA2F119CAA2E0DC7664B0136EE7F50B88FA4F4B1F0A665F36C56AAECC77D637637ABD7EE25BFC8B638430370B0F92FADBFE5C4F166A0B1FFDFDABA98EB3E5D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3C1578D7F6DFBFF09D46817D7C61EFDDFEC6AEB1A21EBD5AF1A0F399A2096C8E30821DCFD15298AB26911D40A97E78421AC35B6E8B47C483E1538E1C110540E6B23095AFAF8CCC9883C1BA2810AFDBC488849BF8E2BD2B63AA036BCE1BF9E6FE84C7C830C65CB9870A441512C55557F371276F3CA97910118271DC35F5A46454B02318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3FBF9F7DDEBC0995B90104C717FA2977F9559887204B56298813EAEFCE587F9D2DF49378B38F71833410D667351B1949CF406F18B0727666AA94DE7EA90B093CEEABA95EEE4D2DB043CFD3504F59CF36374C48E804535A76BB8BF67DFB39E03CE613D53D7515BBC8DF04062A185B7825FD3260B1B377B5D3CF470603B1900FC978329FE4F050A62A0440FA26E9B3D2CDA32E7F9FCFE6446B29FEC3639F068E56D446765B606D7B4FDA46826E8BB9E3FE9ADD93EBF3848B70C759922B63ADAFC8E71CA051A07FCDA3126BC8B4EAE41DB2031017A6794C6784FD8B93672BE6206ECC5F1396078719C45CEB31BDE4A3D503A56CD1BA60A875E2A5AC7CF340A79F261480A2A36EE4FE88106DD0976B8FD47010119D6D21982AF0E8E58AEF1BA68D4BF979DE633E719AAFC7A6C8AC6D127BDABFC3660711DAA2962D639D46747BC03BB269789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411923F9FC45FE90EEA617A4971AB81153088F58B488C507F5C230586CF967833C9A0DEA1CAD7FC139A9710382C46136E4F4007BBD729ACF06FBFEDFF5144533FBFE8186E4905539B32F01DF3F0FA65E08B09F4F16719DAE9A987DAC3A28B2B9E001FAAAD0F03810E525D26529CBA1829D42796B65515D55BCD2315DDDB342591BE8E217286002741AD99A1565D106690A5D6277539266747D8632686C5C9061D5119998BAF8B6C09E61D13B2D91426AB98DDECE3EBC2CCA03A8B6591E2A1712FE71F847F486D6E177932521D9196CF0F637314E2329A86F733D95CAA0C2F7F08FA45A993F52B44077712B70116CA4A7DB6587E24BFEB70AFBF3A6F1A33F469D98278A6603810F6664B9BDF27388FA8C69CDD4127B39AD97A6E2432E3C2B6E0087EEBCCC54DA43837F112E61409D225BF5E5222DC107D698C0E571EE8D532C99C6CA353C02F2BC7233F1636D14FAE126DD4433CCBB5DA1C5BD079804FC920E7A7906C9579B18D7B78824CB39614E28A2091D1194C26DFBE86462EE24FA1FE24ACA85F912404458AE8DDCC5B03A0E0402BB689ECE763D0825A8D566713A013923627115705098D63351D22772A01D57BD39566F1EF058044281C3275AAB8C44F905DEA89F9D1ACD8FC3C5E9F2DF429637D635359D0A3D91D765C71E5DA37C2BCF29F1EA9AEE40BCF69C70168BC10F1E9576CD541325A8A729566CAD7C0483ACC8E23DDCEBD1114559AAA8C6621F7A7AD11AD19D6312097C99841A84C35772FF6ACF5E1028BD5885C73C78A719FE0D63D52E9F55509B7AEB252865C6720285208786A2439382CD03CA0BFA2FF1A45B734943CA586AAD35DDCFB075538B0850551967EE7D7E1261DEDE7016BAC7E1B447BED75C565A09D3F173B5F9DF4CBD86780F35E9D7D62E54A2FEFFA0FCFC5CBAB99D2F5EF5784EC92C6A9C8DF06FD4491E197B153B084BB9A5F629E4E7923220EA7981AEDC10CCBE387725C16BCD5A4CFFB3566525CB00B5295DEFA64574065D1173DAC40340878BDAED7D71811FF8EB1B55C9E3C8BB8BEB2D011A9D6DBA1522C969314EA2A7FF20000EEFAC8F760CD24975B2CD9D37FFF352B4B13CEC723C68A595E301D02E0FD881D3286582D5472DB230F77C644E02E4FD2118592D323D93CD22E55EDAEC15693758CA10E3F215E6814BC13E2DACC05A226ACAF6DACA3B9EE91B0CD0740A5B50E6E10013407A7AC9A58F2C2D41A8CC0BD39BEB52BB643AA89A1194312A69D6245A1844A03D0EE0BD92C46B5D8EA77927C48D23107C3D498427E8DCEAEAA36E368A58EABA0E06B97532BD8D2B17A03933D6BB6E00C1AA62CFEF7C7834BB0705A50205C4EF8D3270C4A0716A59CAF17D13F6E01699B1ED376095D3F6850ED50053CB56D83A15DF12887CC06E7B45D143CF738881A322557FBAA2381B355638DEC332B690F7A2C91AD96C5102819AC027304301756A1B970378FC0C627135DB8D5F6B0B75316DCF93F0955E37193575DD0C14961D776379DAC58F5FC1150785BBBA92D1009E1B49D7E3362CFA468D539203E53FE2EDF38BA68448A3520CCF623D8427DE666CFB05E0BC25452E528FC4BAE4FCB020F4ED5EF4F2A71B9D225F7B7E6655E60877D7B7F3DCFFD8C4C77A3A3B36073A69EEE8B35F49BFA43AEC19ADE9CC7DFBB1F6A7AAFC69B3210DD8B9D2D54268336896CC79F76B441391662909A9261AE1A5D75C4F9C360AB0C19A94F3930B33ABF6EF6D5AD18ECADDB1B477C019334C76E553210D4C89E4C32DB11EC281F61A34DC4C3FA81C4C11ABA995BD4EBF44373AB98B000C9F53E39A9E09607A88AAC7AE6A1AB1E735E1D0F8F8D34253718687CFE01212B0B818030EC3F1C8F79574580A44C571456C431C52BA9DD336B1A5F8753263FFBBF6005A7AC41B11814D8CCE8CA7C6B68C4F9A56845611FD6D46C35562176A9E14B357EE8DF2B3F76950986449C0AD69B0BFEF0641CFFEE6CA5112F71E1978592018BE903F66F340EDDDF09089FB1DA7C60F76B3D92527D470E11455137D94A80082FC1AB8DFA33F518E348D50068DC6BFA59015590904AE41CAE8E6A05F2A1296D97077A04DABEC3E27E25173C60F955161EA514178875427F4018AE8CE74578E79E80310F069A611AE281EA56517083EE94B5B37A1493E614AE495D28CC5D8E5A6EA4119FF599BC8DAC4167880FB7EC2FF09007E874ACBF9CAF516CBD6E305EA8492B3FEAF23BC6571A5B800489E07BDB1F2C800BAF3E7D35B4EC997B21A3C29960A9FAA177344E6F9B9C59489A67E782B630D9CB44FB0F82922839403A85C7AD53A9F32D163A64DC226EAA21E0994B218DB931E50BC31C0E1B5651CF2098EB00153DC510E086B1FEB74661932A95116E04BF13E9E302A4CD3783C572CF52249F5FDA51AEE054682E7D3E9BE99FA215853668F015F5F788BC6DE4261C7E53A2FB9B46FAAF6C821BC64ECE7AB00F059A65EA3EA9AC7C64971F504F26D97B48817B3DF9DC46B3C106C041D1A136B4731AA2922B97DEB83A3AD798A719BAA1CC2ADDE4A34D5EA63188A0CFBD3407F3930647C3993848154841EEEAEBCDC2149D942FB644A671D50A1B51ED937765C0C2AAB1B35FC6E4E6DE85E82B4D87727BF30085AD56A27A796F53CB4D3609F07BD7645F7B32EC8B72E51592714D78514941E217E6A8A393F91A907BBEBF9804CAF5925756BB3EB09D32E125469D4413DA437C8BB4CFF2F9C23C6ABA4B90395F55E94E0113E372FDFB37E7801F0AF52AACA367BF4BF90C58D093771AF0991244B91BE5C251F9380444AA86C221D06D0BC12BD1C2DB949E7DB4A5DF1EFA0A4BD339B8F1B937F2AF48072CF8F69E47BC2E20286D2524A59F271852286AF9B8BB57C5FED3E3010743E81629BD1C366D9350DC9329BC839F7B8AD5B7E570C85EF644413F0A6974DA2CE7FD7194C30A43780D5146942339CE2B186698B8CFA564998F0DA458E36F2B66CEDA779C9E9957D987676AD23A507730959ECC0016FF3A53167DB27B2F226A2B4B5EB7A409915DD46A882362462CB5BB7C3D2A75998AF280055E9105EF6A91BFDF40FC5FD0E6E97EDF27F96872351DD3E8C28F46AAC52365CF914A32E5C21626BE9E13BF80A1E7E616022639DB2A5ED92A119EFF891AF7D33883382B554819C5CBBA093B55E335D550DACD6AFF9DF70A2A92C1BA88F210224F8F1DFF0B420B6C2F673497B86A156F5F1C675D301F55D69E5D275BD43C850F39D321DBC76B0F153EF703DEF0FE7480D5C83EB1535F0FF92A37EB637DC3AB8D7C7965C8517131F5273B10A2B5E64C16C85791D41854E43BD503F0E52180E9C29499C45CE64BD97C0BA486377BFBE1C6EA2A84AE249C8AE40CF3E86989F0379B9D02694DA77F9E73560E0F38AFD05744E0A30FEC0D8DFF8A1CA3A0EC629144E96B590FD5F75D92F40E0FC0A1127486133218B844D932E038CD1B04DF12E1EC6CEC249345EAF4DACF0D38453A533E5193257BB55AA785666C64B91491B0A5DB93688FBE07D66D926759B669E18521210CAD05EF3F8972754DEA64BCA926D661B145AF5B8090D1A4E51D9CBF8818A4EBFC8FF1BD6CF2C76B914B8A7BEE0EB33F37ECA54E2DA3CBC29F1720DBF0A024C969D4B1E36326FB6F63C9195608C68A3D7C87AC394210D0F4CB7D858A88168FCC25B79E29197E2EA3B3D4A862B70A1D7F3251C75F02D476926DD863B778059B83198414E0672AA1F27898C8A6F035D26AA117F838EC83D453A0D5C49AA350B288F1FBCE59D86C8CCC99F14A221AA18A9F300DA266DCF084910890994ABCBD8185D28BAE4CCA4BD68D4D5790FEFBD7A6D56B8C78974F9A8675E6C410F6D5F7F6D254F1C7885F48F0391E1BEEAEC7437553D480FBA79F55DD5B19C596DC2089BCF9980959958F7FB7E6DB0358093379414F67BCE670BDDBC67BC8ACE419C2E48C5B57EC624C5693562B719C7E6B09F3A309D255D0B7A8B8430F7E9544A881EEB694C7282E20EA3E1ADEA50564B935D528C0372397F26B1497DFA3D0F117F7A6797C1626D1AACEC708302CB0C0E406BEF60B7F6578623EA59A005B804C009A38E0A615F1FEDABBCDA5269C9C48E148A143562E1A372C0DB9D8F249FB5A7ABE5928B4BBB17DBD747A57D9438774BAE2550A5B205FEA96912A2FFE3FBEF1D6DF372A31B1084F0715829C141B845551C086DCF8FB9BEFB43B417AF3426BAF6007DC2EFC3B4999D2A658B5A19CC61FCB3E2ED5EB14D1ADEF650C7254F5163A2FC01B987E3000517DCD878B3D9268E912CA3675000B10E53F5B8172477AF6FE3778CB0E5D279309245647970C216E2E608E25F1C4FAED708E98E1D88193FF5DE2D33B178BCD345DAAA3ADEB8B1B6D7C3E9C2468F943A4AF0596B0AA480A159BB882857360DD34CEB848F5CF3481A660F70E49916F9A952B001E60F11A31CEFB39D3F49BF76159FF3E8B3570BBF5D759F5626B1FACEDF4AD03E261A7E095044665CE61C3359BA5A046E44C8E5506E2BD7E5C5C61EC2EC722ACD680BA597A47ED44E937AA64C0E3523F1EA891BF01E2B92D54EE9A3684A122D33ACD2A6D14133A8DC35EBE37F49D59BB4BB5F24940C18E0B4B5F1349AB813E994AC43DD0420A52527147C9A0F4729F8BCFF0941B934253B98628403937D1E2DEA8BD23A2EDE0A7BCF3A2D66FFC7049C8D2D3D52B4F9479F6652462AC2D18DEBBA361721EF71168CC59501174444B5A2E58AF71E8DFC4E9F836156C1C844EE12FCA65ED97F8189FF34B8EED18C26508B5ABD7DC94DBFD37F18A514F66BEA2AB8F02DFBEF4D54850B589898EBBE0E68E9F864D4468C96BAA0BDF1C074AAF51CD47B20784CDD20DCFC3444802DF292D0B21D32A93F2DCF3154860EE0F469CF0E8BCB4BB474C2C0F6E2F97EE8C155EF5B270FAD06AEB3336087B314915E7CC95153698BC2E486441D1484052BBD641183C9F5495CE45B270E5D085F4DF45707C7615CC89197B2646196A2F382EFBB8436E3B0A09CB2384FA6D3D7E436D19DBCAF897D8A2B3B41D17163C52CCCCE010274A70B6B985545072CC776AA5DCD1D7D1F191AB56003FCCA1F90F9488AC0C010A6FBCF7CCC51AFC15BA2F9E678B9B2D2B44DE9B7C841C386126135E1871324C9C7D3648DCB8213473E4D006FBDD976D2854DBC257DC1C21E0199C10AA0FADFBFAEE03693930F970285460EAC6BCCDB873F2AE73A173F17CF6C07C26B3FEDC0E81E8EA4FF7D68CAACE34340EF1990F3BF44E23BF65CAC9F65B50E4AB2ED67F01DE310314B56B351691609FD835399C51AD9B35E4118BF3B26AD5DAA9A0609CE6A24C8D2A1244709F770A655DF9E80C0C7441917C8329446EB8FB371C506EADD1DFBF6646E0790637395A2C1429C60252D485BD99EB641F0FBCA951DF3698F69DA2B8E751BB02BA592AEA7DD21E7B961499C0238B93F6AC1FC73DD562C80D39493800D0A0A594F26D16FE54EE71B5AA5CCD70B5F1ABC79687AA87DD986F10FDE0002EF9D964E80940FFC39C5F2FDFB81C190A83B0AAB7BB176476712EDE00F6F97973B9FC6061EB404C24993B85BD7BDB4582903BE253ECC3C10C0B65232F5F681953B179E19D4246B0799477359E0496BE7925D46065E4AC4B5EACFA466A8DB0A62F1D1AD326063C89539BBD517FC53ED562D98D20D8A7CE4FC1404B3BCEC7D500F4573EF14C99BCD70F290E6F4206E9BF9E4052A8DF39BF57BAC1969CB4D85E43FEFC1907449AAD6475CD2A7B9F962C315ED6DCFE913A2FAE5E1A695C5BCBC0568797F5154AAC68A30E0EBB8D2F73E6975440421D001AE2076AD1C65F3ACA6C05144A65D535C89243D6F099CD26C54760517EDB1CE98AB4F9E0B6E3A06B3765D62E7812C38B23D6A92ADC6CAF95A256FB750DBAFAA6D3E937BCA9314331C3EC2BFB571E0D54D3A98D5D28522326681F2B91E5BCF4ED462CC90B4CC27225742E5C2286AD1FFADD8418B9B3FD71B3CAB178F34703FDB8ABDD8F5C1461F89446ADB1175E35428091CC0A3B5705C3BC66A1916D1424D631E588FCFA838C2BF8BFE2CA2F5F6648E79942E3DA4B064A22AD6A9BB05C15228E1D20D4A4E8D041BEF83790E9707A581DBB7689E032A083381899EEF508E4B2A897FFAB447F821C848EED8CA09616CE2EFD13966C479F17E1A29D5B6F18387D15E7AB024AAD60E6D68869726EC117084D8E0C42A3A18FEE5FE427610B9311F4173A555CC3D534439D074BB8153F99EF5C62288F9CD393B0C257FDF1AFA64BB68F3DCE632BF81FDFCFBFF93A4CF99D8D50805B18EDAFD09D086D586BF8A5D6A2026084C7DBDDE343F74C964ED3011E29C8683300EFBD9E93C68EE571CD156D8FE815579D8E5AEDB483103BED689A4CEB7EA73CB8E19A6994A01838E173EFE68E816CA53CE578B87754CB34961D83A611466478E9325529D6D15C156B2E2E06E1F624139D230DD3A32A90AD2C7097F43119E10A2E788F15795548B5470728DDDB77CFD86A6C3C6669B9A2217BC37B15B8EA558D2B9E99EEB37E105700A324FD17A5A00803F41C5317FC2445C7216FE28DD0F15BEF50566BFED945796D4F3DBB97D53204D5BD64478A75484912749D9407C09D01CCDC391BEC54A4D43C9157D0A871195C731EB746F61A3F82D6F1A9807C2BD3B275553AA6CDAAE509A3A350DA3F119521A3DF789E011E59EE8138C17EDFA2AEA5C15841D25DF2E3A1FBEE40A3CD98C275AE4FCAD2708F31D7354E4059D43FC5625858721409E990F1DAE7D7FF6B3084897B817D88A99C149497599957A667750E1CF446F5D24409E3CD2AE7F13197FA6705BFAE8C1BF36AA626D524EC10CC50F77B359D718734797BA0154CBC3CCCD88030C97386483EFFACEBA41E5061B95BEF6324AC98FD576AA2A8D264D05596B20200496C54C58146883B62C9051E5F52224294C996EA6B44F84EE277D029766D66AEA021467747DB5CE0597E5D91D92903B74DEF2A7100BFF8201F70D009B0963454C25351D8D43AF77A3E70C95BA5FF34747F55049243C06C036984C5C303378D475F841749BCB2DDE91A25C105501EEF479F2B6C68A60EB8F1A308E74EDEEF93E1E34A50CB272AC278ED9263C0DAE162B7C1FD035421A2CDA9774ADAF21B292C252B94398DF63894C88C4B5529FC5AA5A18E788D74EB6126C7FDEBE4D650E2871B25F37DB9EA8AB64FD4806121F4509D4FF190439B7A8690A81275D9C03CF2B51832B32DE2967485BF84E915F7BCA7647E09863CA48B37131815DF9E5F5A88535186C40F177A06B657B4437728EFA50AA22C45E49026053B3C2A3C554F1B2613EBE50F27CEBD3BB03C8CA17B22EE76C4200A0E85A70B6DFF7F511FA2265BB7D858556213C48436D573F120D4222BB1A5C924B2EF1605B4A1ED717EFAF63AE53B070D7C62B2F8CFDFFBD18DECB0C405E7575C6AD8CAEF4789D6164039F963F807C3B978CEFE718A83A68378F9156BF52F6A3F76E411CFFD88448BFB452ECC10CE99AE5F5E303EB099B89765A377868B0B2B3A0D631264AEE47BDA8FF3A92483D27CC269B16390B3ACCE3350DAA649AB53B9C1CFF2872B6C1F9BA67D9D22C6FBE01424A7DC815F968C77BE937563456A273992579C8E6AD585A0B3D38AAE13ED13B81D58599A43E86C4B4AE7825B358C6FB94BAD7F552544790377714DFAC7F17B9B6B3BAF2E5D6E87AE0D0769A39A5580D5347C78067D7D7C375A91B066A61E124E754549CF27779D43109D8E167423F13D05093CD1D31B7E6B76A89C6BA817D852775ACA8B385138C6CC73639FDA3AB6FDC5F84CD46DA221B2D437A51B54D43D98E6D77E31B07FF420AA12FD6FA8892C4220AFE432664F946E738DFF89EEBBFC16CB168CE1721738B4A1174265AEB27FF3808A80D3BFB6CB893D1B6B33DC27239E96108C6D0D20C912BC1EBBE7E245056220BE957E7B9D49EEE6C4D341AD73932D304798F0A0F04F31D8F70DB5E06E3ED2DA627D47E0AF1C2E14E56054A87AC9810B617A52D0DB5145FE4C2BF6D0D4AFB0F9314FE15167A5AD0FBA0C1454FBAB0705FB6BBFE5F7E39824E59DA24CC67B3AAD9491E7A40906487BF895E90F63CFE6D7C0984F1D2747676B82D09DFCCD2A8F6DD158C917DB81FDBE6213FE43780DDE17ADB969B3D64CD6BA6EF1F9ECC7D6F6207280078B10DBEBAD7581A2E8C2F83E4AAE8A26F8D1DF0F8CB45C690615EA304E5CE30D2A96C55696C6B1D82D274E9D5765C3E5D2D7D05EC6A202BFD0211B534B7C9FC684C7A72C2D619E9DEC4175477792BB930EB5888FB37198A6E1DCEEE6651038F5C0A15DEDCE6D1833CDA5CE4EE61CC144E7C5202FE532E0B274F2CE4E90D91F2BAF7808D0656D5A106EE157491277F92A36239D1CA7D26150C118F9ABCEDD5470A2A0069AC1BA97ED1CA9885FDF2B6750157AA5B72DB5E7C1140E1FDF78DC7FA04773F4570F4544281C2E9627E5F59CA9740A38B452C9F3A930956187079B4EE4C91B3E3D9F0F502F8558A092630BBA965FD8900E738FD1498FAC10E6AFDF58F32DC0824B405C0E1D962CB213D4D834D7D26199B9172CCA1A36D7A76DA603FE07CE0EB070AFD90E7A30D937A32D26419A002A32AD9043B1735AD3D0696AEDA5F47046F8A3134B8D45C090C0A54C70AE992A0916A49AE7F3006165FBC71CBA5F0611FA5140FC304CF49DF3081CEB754E9E87E4FB637D7E701D930EE23B6E7A739274EC3AEB90736D91745A92DCDC5FAEF42918E63079E07316C2F9E59D8B79062F1D816C536E8323F501A20A11D6FAA241A5CB4A04F8384206C1D4BA5BD2DC0DF41A69CCD6390270FF0451211B36B489AC95476493D812ADE03FD8EA165053401587F7A18C2F3FBF4960C82B30E9C7C30EA830FE7D052DB5A191C0F8DB73833839F0D7AE822027E19C3A899EDBB02AD49EA87E1A2D55EA6B010BD984FC6C5B12289B41264F9F2F23B8761F262598692F57DE1277F48B3EBD06762F791DAC23F5A5846795B4C4806EE0909163CF27111BE948EE0CB673F0B744707BE8189B059F6D33E52AC33BEC99DB223FD42F64BE1C3E8D505592A78D5F7D3E465A5E34C1FC7D7ADD80752A83CA5CFBDD7AE15AFFE7BC0A4BF3722EEC05E54482A88287D9850672C2DCDE120E0C7AF377659E5A3313D0FEAD9B350A80F0A5A4A480346AF02414FAD52E5108B911B7A4B877215E400B3FCD4E8786E962704A50EC2B2D2D7256777111EA6646AE8A57C84B56C30D704C4B914EBFCA60FC07CEE5DB943630C0A2BE448CFD70112A56A74AFEDC4CB48BD579FEE9039DF705869A1623B1596F77D7420B59F32801106F6AD8A16DB40B1ACD82415BBEADE36585C3BB47F37BFA7162C255542E8284D8EF8CFF88DB68A47249DCD14C1D2E8E5C44E258E9BA867902ADCD588A5A382A60A580458C8C59BD5F182742CA1BD6A52F35FAC26893D74C3D74429401712918098CCC493BD226EA8A9F8C7700123924131913453EF8069237ABCC4B851B0A868015162AB8B7B63B3110906B267DCCE5659F4FCA5298C4073BAAF392C5649B429D5E378557D5CA03C9A52B6208936AE2CFF83D7E28A3274398CB3586BEE9694A14396FA1D67BFA90524574B7DCF0E8C7B86C86A69FC0C2263B437016842743E7E1743802C4542DAC8E6A23D03A158BEE47F010F71E5D9A7063E26FE8C40B208160936B5CD4D13ACD22F928352902BF25A8C8D294B493907F6794A4DCC0E7CE621FE45CC6E5F33199D798FC6E833F9EA4EA54FF6A465EACF2EAC6864D3CD0057429D789466CC60CD853B829679FCC639446CB0657C15B869BFDF27AFB572303E17FF826F8C4EE2C747AE330858830F70879FC8FD6F8D7CA2BA986E5D4DA1B613DF88CE09212B99BA77FB3E3AF7AEFD4FACB02B3E3172AD43BA87A4433CE38E45C1DA3ACE463315CF5A87B14CF4745D5282B17B613A033A9FBF52A40D8265B49A49DFFFC6C71377C20F4B3EB43FE7D89D829477619A7E5B2F7CC9FD0299C838419661773087C7BB3573568DB256F94E57423B1AC21C0662B60F526AF49629B7A8F7E833F858E5C7423437ED22E6E704EA66B26E79878EDCE376E8BB682EF83EB4B9600015217C1219224381665C140C78374B80F47511C48B5238937464F3B0A5612D2F1FDCC91B74CD861CE655CBCF22B68F657EB7D8806DDDB03B4F08E52089938121B0F6B3ECDD2D23003C889FD2F9A4F6D3D4358976641511DDF513181B1C86DE10522AC021B6A301249FB9E6DB19DF42C5BA6D53F1FBF9A7A2249C516513522F8702636F688145B52B1FB6172CA96F59B9F845760677D91996B38371DAAC111D6BC59BF28F19B4E00B5E312191087255D008FEE158A8E1619CC0674E12DCAB593EAF6C99C9CBE9C700B498697A725E2F30EA74365F3CD3318AA1D0D7C07DCA4F2F6C3AC8EFF0501F8F65A07363621059517EF1BA27310ED930A1A1B0D4DA322D5FD13EF522D21A3A7D623FC499AB8648C1AA0CE2EF94316B2965A246AD7C8869E9C489AF1FD2DA40E3D688531CF77F083F281E012ECF83C4ADC97B5AE47CC38FDB41C7ECBF402AD42716821AE404A1D224363958B9E71DD4B3E77A16FC80598A3065E8E00F36F2DF940F4E99902A1D62D73470FB4923D3A46EF07E65D02963E1B5308121675F1C1973C656549030DCE1BAE145C7712A4879E2F3E219B72B673243BD71442B699F3A4E366C7B88C1266330282D0D9357FBCEC2F95AE54D87A50C8581597B0C24C2F77763B326A55EE924C4A492307610526A864CCDDF6FFC64321D570589BBC5F9CFBCDD95D0C7AD62DEC853875BA2F3C5E3FC20CFF99FF86539F37EDC56643EF7D70D0025B395061B83A100E1BE1D6096D007DC42082D4E793CCFB79CC5A06242518998D835B32B7E579AA14806AEB8A4F19E554FD72D2899617541C6B86B63AC60BD7B6185A7A86BC7702CCB91069ADA68EB4F117E239BB7A9581A56CAD59A618449EE02E2089CE3A1B97B22AE34BBB421F2194B00B80F1841480577415436FCC20FD60731E6E28138A320C9237FF656A5366890E492A318EFDAB7F22CDF81AE5CE56539034A8790E942E58118A8F141B2FC6E4559A04B9EF8827BB7C11D5A4CDAC22E42660082AEE184078053860369D354552F1CB9D798F3FDF657648A7D5BE4F41E6141FBD80732B6D3AB57C0F60D38848FD33F7E468BF7600E16F25B9552688D3AAE33DA731DFA536059D24AAD21AE940CF31E18A40508DD1623FC89EC11BE4B852EEEFD56C002C1388DCD5C54E0524BB681A25E076CFFF94EA7B5E0A0B7DA1DED8DBE3F9770536FFD43BB48C9E55E33554E5C0411BB823FE16AE3CFE51DFC9177764955DB39B08C627F74A7B9A16DCDCAAB1CC31E37B0D3B90ABA2F1EC00FD2EF6E4FF3A15358C551BACB93EF59361567E0834E72383F4EA2E8F76F000EE38B179F7F0F9A3351C5BFF81B49E8A5119C6CB5CFCF49A6875B3A99CF14E6CBABAC0F4F38FC97CBADE13BB807CEADF726AD565D65334539E879575702D58462BB2A7C7F322A16F3F1C4FE116CEDBA6094EB4712D774B8207189B700C8B84FC7D0DB49B02F7AF17A6270BD75AA54F8A79E4A1A6D588FEDF94C0829EC1496988507C8C5BB87A70DFC3FF6C7F985ED38CF6C23E04FFC8001C2958B5E0920B284A4A3A55023D13D4FB99D392A0F61281E6DE6AD1F907788504F80477B8C21454E4FF16236E42DF95C85E20DEC39B2920ED49AA540BF504E74627B678097B4EC800A37698C32118BFF564BDE9BE0E4B16A3D91A9A83FBE991DD88E7341BA96976F7694323E523B76DFE3C52F28188C8D64DFB1341EAFC98C9A28CE446C4983AC52A1C38F9CC5D8CAAABA4E8BF9B7E45E3521567A46AE5166642E89F8503F892F522A447B2FCB1BCE2EF4EC86E22F48FA99555DC193F080D3F0096A47BE3C2597FE83A27E8132D28EB55AE87B36C93F31A9E371BEF51E405037DBED6CC4916E5A855116586F7C34F33B3EE626DF600644EC881246E32B5716E9580A1733ABCB22346C4414E5FF2C085E2CBFB45BC77168F4164B7CECC874DA5594F6E8D0B7B6B36EDEEDA1342672A4D6925CA2864B93BC7F63994F8449929C3206E086738FADF14B1872973A6093B5916E565DC3B354FC544A44202598AC2326C5EB9F305C448CF68323DE4C5BD28472B340E43DEDCA0DC290CAA47238A7A26713869C6B4237D40EE2743BFCE74E5CADFC183B14075FC8088943F3B2E93FD3A96ACA364B9292413B2B67B43C855A898F877683FFA238C05E6F789ACCCC40C434FFFA494F2710C3DFA213DA7B56D5A4C273603ECE648F3E9D6E + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 18469 +sm = 00000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E651324F8D245291EFF735334671EFFD85F3A823D972D2D49DF408A2AE09590B2477731B03EA3F8D0196A27D1C42405953F3CAD196E2AF5F897CB89A61F544FAD4AAC5D5560820714B57DEE68B1FC7BC9320D4E9ED476C79C8257B34570798C59A944B9F2B22F2D9419B5B5DB6301DDEA449F184552E9EF0F4B80893CE0D38184D0F8F2424E5B39E783D8CF5D3E40F8B822A5CB770E7C793EF70EC55F2DB527489D8E83842D91853C8E1A4E123A8BAA85CDC3BEF892DB683E3CFB4D60DF60CF4705644534E0F86ADE3417BE364CACDF76C0C906F64BD58A7B363C52870995A9DDE6826811C4DD77FD89B17FB35E2EA7C907A056063335AE03884B54E791EFC5B6855C6DD4C888FD4C8BDEF806EB73B632B3C27697F2410935EBD0B4EB7D4FE85D94F4EE29447A8424917FD3EBBE24F5128280697659EBE4569087D96AD8F0AC7B632EEDC65E0D807DEF82C028FF4DD9B179B761A6BBA1DD80F395A524036A7D50A786294AF71A1CC7783E789CA5E8DE21B1E3F771C5E9A256A2D0D12F911285E9F3BA26B80AF62D1328351A6E0045A82BFCEB153B0F6B8FD5AE3B2056006C5EAA1773CEEF4C7B3AD10BC12FDEA7DCC1891BCBDC9CD83ABD7DE6012ED3F07F1CE670B7C50EC84D8C0000D09632545965D732E921D01DAE77512180C12B01A2791BD0A32F4705C98818ACAC9A62F3421985687FC5107199B035FFCFFF5103D7B169AD346BCCD523B98475B92F9EE6DD954A6534913AD07DB45E620589AAE5F70A7B20F37D62442F711363C3AFF1F571B2A6471E08DB2CECF405676A1B73B7D768543B818B7E31A574796497C2AD22C79CDFF65DE6D4E12F165710A69D1474BC7FB5E34D64263543B02918CDFA271F53EB8B07A9859107D88153FD989ECAEF350E5F8572280261A6EBB9AE8A0D3777BE70BBA24CD737407541AEFF0EEA79C1FC0E73F167DE9D2380AB6D5B0807DE6032472D838B3F681E7ACBC75D71426F33ED97C7968EFB4FCE7D560363BC9F3A5A0086D87169AAB81B9736674E598CB301F84E7F0DBAE6B747B79B8F437746C713E1FBFA24DA920A4F3F3E92E914C271E3EA483D6BD7A4880B86A916605F059916F9D115C41A1BFE270D0C39D3C48B44ED9056712E0DA6F355D31666557247B6BB8AB41EA0201599F1EB9441E4B23284B8BE53B6BBBACF025A2BF597FCAE269E8B86FE4755B4692E0179281ACF62EBE8CD644B11159E35F94A4492867F7A94B9CBA5348F7071C5732563F8C1C008AD8C1767EC2D2A1C5F71AF0F2B8A6A8F9C2E4C8BBEA834A94F34114CEE3ED19E514449946DAEF5C58F3B2270A78E69A252FE4837E7E94DAD4842E9028DD986E5AAD6A8F16F9F138220F5672F8BEF56252D8E93E693A43FFC9AE96ED514D7405F080AC39BE1BC1E7052026B1FB0D65335FB7CBDE8E0EAAA2E29F28846C562EB741204CA105FACEE149ED361E30C807C308875164B475E46CC14E278D7C129F0D909E2C06D5CDA83303D57841E55DBA04C02702E226161DE69093472D07A2408DD87057A1E25D363CCF0B32025BF24DCBF54A0F54D62D6CFC870BBBCBFFFD1AF85A1EEE4532928FF130814E363AA0FD5ABB68BE0BC2CE6D0EB362BE0C106A017196F1295969EDB23739D139D5E629140BE6778F0C912343373F637A516E029047FCCECD7C99A59681772B981C48A3005D5F95D4EFCD6B17FA570122F2A68AC1E9EB11934578DD965D4FA0ECC39C94887E71903538BE9408E8DD1AF757ABC63097ED308C7F0EDF78E138ABA2002AE12DD317205ABE4FA332FDDFB4AAE669A71A0A6A402D3E8DB7E409A5FBEA41C86474057F5D46ACF35032AC331BC0F33FF002D23A7ED791C642D202019E62520710B50C76A82229A1075E52F918DB230C481D0350A33EA0E6C8A2C4672459266931B482AAAC2ACBB4542B22D3D25E2E279700167CD7AF03866E60CAA9A880DE5055A80E48A4EDC261C705EBECE13DF4F9AE7D8E33016A83B6A05DEEC44A0F6C123B8CF162E2814638BE4E22E8C65A8E9B2C6593EF39B915A86C7D43CBCAD6F5857BAAE18071F291C3D742C9FF3FC54A51D1CB8061D5A0ED4358E82CF93CA9750450352C4326F2B9B20F3D091528FD46A0ED40077C79EA0B12E70EC73A8CABF27E1CC7B33448B947CD339BDFFC9F377952D6249911F099F535E6FFB0A6AD85F5CD06E4B59918DDA9C1EA1356480AB1D7254B2AAEEFBDC3AE61F99552873CD0EA39D3A2527B72BF325B02D5A8AD1B50320FD2513D89D1A164F5F8E7C034CBD4718AE2C9C6D2839C144C47418636455CA4B9E674B3296AEDBD92C793091C4EB95FCB9EEC69656DBF47ACD54F0045644E95BC75168F17C797F9E54C420F05C6E45A5DA109F6A0EFB313ACBA155CB69F94F21439FAA4821B43A1CAC7172BCE8E0D611E1C6993589B529400771332F16F123352198A4D6872CF63F4401ACB9B5299A74E06FA83EA57797B29DC131C00B7E475927AA0970648E69CEE30ECF7D7D4162727D1A252794C85BE791A4DA538EF8B855182EAB0A724E0E68601A10D9809A6799A6E7B2DDB84AC602BF3CF936E171E16F5B4EE3BB6F1F8D70A121E76910CCDD79F252D4FA6DB1D4FA2AFF6D1F4A0246688F24B24114E97C1B758F96C485A679499AC15C89843802B844E9E5A280057C9A5DCE4D75B14DCB8CF4475E4619DE0734946BF920F58EA7C967CD268E287E9D1F8DCE855F5FCFBFEC88A8D7ECDED07030F6A3CF16B95CA2CA5635B17418D411C233930DB488CA4F7E287B255DA30A254D0B3C2EF633F5E04CDB10A20311D2846AB24749D78FAB6EC47F89E66A1A60777897D0636344B4A3A6D4B891BC5E066A422AD6CB0514D1E9D70888593A386048112071548CF0A71C9991DBB3A11D93483E3716D9A8BAAF62BC5BB58B991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EA6E323ED6E8A520C761F371CF760445A3E865E4B2524DEC48F47386A1E6CE55612DDC33FADFE21A034F29F62E5EF6C502CEC5014A10A68A2DCD1998C74D620E84F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D265894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB939E6518A5122E37D4C257B0A0FD60CE0BA3BD55C9CBF369DD315A3C0609933D25DA403DF7E69FEB7EEE64DC3C13DC83217C2834B42876862CD48E99E69564B336506B85FDB493CF8FA87A7FE48DFE6778DDE8E8DD066FAA745C121480B5BF9D5F301B358D18FCCCBD24069E71836981F168FC49E6A4F27B00F6259B183B62CEAE0BF4AC0F53FCEBEB9052C0B48EB0666F361C5DA674B20B06AE2EA8783C2DD7EA74D98AC98C55748A368DF5B433C39538365EAE8DAE5E032A2008768FEB01F65D001AAC437781F742F536EFE2B3AE59EA12A6DC7F2712BA2D9D1C253D29B419A765985ACDB42BCCE5D64F6AF8368A5D122BB16B525A80C8BC5355A53917CC82262254378CFFDF1C7D6355F114E4FC013A5E4DD9AB373A0EFDC470854E20330BC00960ECBE882098D6D0D429A7AD19D3E5D4B78AC5E568C722A21877DA617190CB43123FB04333FAE5846953E33407080D04DF1417E740E7E7A14B0E3CA7D5B693F9615E1F7D417B9004F28D5002325B851C31F5EB31E1DAA80E6CFF22F11221E5180BB050888B6564A381E54401AF9409FE12A818B69BA34E1916092A0EBA24457EF994A1B0028649C9803045EC93CF416373F6A568856B771C3BB076AC265045ACE8E9BE3C3074D8806BEAA3B8B21F7E37F50B16221E14FE5503C615A13738CCDE39E2395E292119959CF686532CC3C9F9129E62ECFB43A091B06FD48ABE8C2CBE2D9691C8907881991CAB9D0D9CC7B2699F2261E5D799D26A7C8A4AEC40789B34CF5FE7BC8D24D6F0BBA7A5870E37F4D9B2605BB56ED9BAEB780CC74097DD8AA8741A97E22EC7B7434F81DE9D83CB9816A33C5A79D718C76A3442FE50C68FE1CE7AF728F2177F88E5168D4668518897AB050B57FF42AAC731E484B440D0D7B254383C74BE41C2AAEC02A8D8C7020355C4A1FAFAF4BBF56C74D78949D087259FE8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B179B32F9F94BBD8371B973B19E60C3CE2206A2061C7BCF159BC3A50163924774BB13C708A573472DA73B4C78DB30FEF310EA3643BC75D9155762D5B87809E2A727AC0428B746801D693074ED5245F29B8FF9FB782F2E57BDD89DD700EDBF12E8311946CAD9BCC98E3B1D581E678BEB1D0A6EFE15CF4052A1AECD328B2C4A8D5DDEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA36145D1653D108813E42654CB5350FFDB33BD2FDF4E416C6C0A61784E2327F42B2DA2AF040822C291D63645B0AC2377D0DE3FDBD99FF9CD9AAAE2B978C4DBEA95E330E90EAB0C4C34E88855C7C62C40B231AA1A9EB409D18CAA1C612A98F1B7BC25B18E3A89CAF96AA4BDF12F865EE7DB20273D7CA11970219BE997DD0EDE7A8ADFECFF1D90984694EF152346402207BD7D9166DC1B09F3C3520D109824442B8AB08869B0A4850BE3227E746998925CECCB422C4C05047D890E291B4E5478967A42BEEE34BA2765D86D183C71FB6A3CD86EAF457756FC000FAFDB24AF3C968E547A5223821BABF91B31B3F970D9F7C1FBFD16CC63D14243DB22CDBC266BFA4DE4B15D23B17D34C674649A695E80F84F6FEBAC0255BB155BD8B8D46FF7AFC532117E26985D99B0E23345F9A0247D834697804C6644501CA7D2726DA563C7F02371B5CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438DC67DF57A5B11025EDDC8915C57C8C72F6D6E71978496E206201184593506E39582DD2C803CE9204D2AC833C35BC683E0BD3CAD30BBCBF584AD38DAD30C9A400DE22F0CD6199FA6C622941E79F8C5C500389E9FBDEB8E1C926443B6FB0313DA9AABB163F5319C0164C1E58864827E38C18B7ECF6FB44274CCCB84B10F1A1BD76C8740F479777BDD7C557DBEFA9415B7FD50CA659E304EF4FA22680980D0FCEFC75E36231F740F38E9B4AC55BD8307F8AD9FE45B046B7BFF0F1B9FD5EEB82D474DC311A8418BB27CFE324426CD3311D65513B0A4D58515B94B8EE5ACC6815D6D1246527188E7B6C579CE42B28E1F273887FAFAA96D44FE6830E96081ED562FF4A08416DE4213A89CD666E2814FA290A5B1FA5AD6DB86B9E4DA85486E11BB36382C13607F50EDC83909F47A7D089CFEAF4680A6F2F10A2D9D9A679AE82D2DB387C5B7BCA11161E49E01C28D0FB7FEFE1C9A4BEDE994DEA4087F3B74906EA8E49153ABA49BE0F35C0572E9CE0C68B2267884C4BC4AD32BF28CE64DC7C825BDB2D8561C69161E075F48A40220159BFF1C4158187D4DE23C85979304DD4DBB98BAA57DBE6B7C55C271B134D61906F6ADBA4639BCAD3C1A70DA04A9409A4A35FEF1BC103D4F17BAFEC37C3F108B31327E0FB227E0E2C5B5410726ECC93B56D4D153572C2DB4EB4757F5B2232C475EB9802FEFB53EAC7BE6A090AAE98027AE13D2B338442FE6EF2DCF141C4D1AF00C7B3E973467FADDF6F1950ACF2BE908FED354EDFB147D6AC4B0740F87DE06E768293CC83AC995760FE0015CAC682036CCABA9C86B9B06924369E35688F7255F5D5422AB808D023B150D62D9A7DE4F7A5D28689EB038E9EF9D3366C3D777AB6D1C33878327018CC51EEDE65BB5FEEFDB1442B9006C76B10B6CE9EE1B6E43306DBB0D9030E3A191DA24634A80063F6A5269E77543525E11BCF02DF82E5921E3225EC97FC5F9174E0225E8C5D08B4C093EA28A19D03E908426578661E107E5E2C5371D79C31F11468112A6050703BB8FD9ACDEEF8D0BC31E82FB4F7DD0DFE8AE0216582E6C86FCBC1E7B3FFDD921F220702D827F145D79D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CE8D216DC6F19C3AC0A1017837C31D76ACDBD48F018A1CB14E98848B66A59F09AE22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB96557964888EBFCAD45C491A2A3C44B7085FCA7C983EA4AA22F62B99109F6E425CDFF5D87105EDC065810CA3E055F62FB80F5CAFEC57F7CB47A95B14A215714FB345FC73E57C1574E38657755CE991FCEEDC5ED84824E0E4AFD43205E126A3402910DCE16C59C8840FC7FC5ED9FE6379F9A388601D57B366FCF44FBD2D0C15A3D8A4A28D71ADE5965C137996748EFC7FB68ED165D2480FE34EF58A3169D03D0395D94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB08391412A812DBBE4FF09E10661B7DD604481AE6EB2F89A1FC04E393B3353F7547AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6222D7DC2F78B2E3FC4C8CEAE02E3FC9D7972CA803061F534D39E4F02809C7A18A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F9536829157F62BB003C2E45042DBEBA9622508F9AACA5FE89F665A5F35BA7C26D93A84F9DC744354C73885BC59EFB657317594D34B561FC2A789C919EE08D5D68185BFB2A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E1866ED93157270FB47C81CC3076E5B381E6B03127E7AE78C54F5F35B2474F18A2461297462FFAE651BDBF3D438E30420A3BA5686483DA2EACD874CC44102C09319C10FFE87AB2099A185DFD0FDDB6393B2F61490D65F93CE565C6575C877246044FD52ED475831AFE194BB163D0FE5A023BBC435497C3C16C8C7A85FF92426B59E588978E29EC0DAD032330035B797471B74BE366FA75D79D35228004D3231654D5F301D6597B83258DBE9284121A2BB21EF66F40C17FF135201D18092FA6A72B511A456786ECE1FCFC986A28C744DD4DEBCB552C638043B0602343CC796834B13660A86C5E3CCAAA1845C5165074AEFBA7C52190845A95DC59B1E8D6B052D253EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D1B478E24D9EDAC7EC8816FA54DFDAB0F181E9E1A8A6CD77A9EC29B3E35544898EAA311411BA22E8BA6418CF252675917A88572E0CE98CE03457996BA4FD86D07C4FA2D3487400E484F4CE0A83CF490C49588DB83ED1EE2A93B78101144586427FF43F434D3A40268920A4FA3C64C0F5F4600A8E52E01CD8210965C4B212DCC942C68D589D21FEF433904C26239698EA85C32423EF7AE1ADC90744996C956FD5D0683674010173EE4A110DA2642C8E1C4BF7B5DD3DE268A3AD0A261A30AFB6AD7D54210702C635C3E707CB1F17053D475A026EF57852DEC1FDA4252FDA2E69BA95C866BD432139CA8A4E367960F85B2FBC75420737CA4843B89F053192BB086BDC0D739B2753DBE42E1D45877097F3B97FCA6F43AC15DF883C3B42D9F472F910DE579301FF7F57D9857890651B64B6C1E8A7E2227ACAC7154D97252EACF8BC5FF430E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD637170756688D9AD3002B3148ACF0009CB1C0802EB04197FBD2FCE168B5FACDD052DD46F9F0B0A34295557CF741102E7592C24FA56DEDA63ECB7A2149E406C0943E5E554767D166EBC95FAF0E9B20C1E530633CF8BD7AB2A66CB105E108C1793B0D87ABBBBA9A4679A05C94BE6A698F4758B8BD38C51371C8043FC79E749D7E41C04DC6D815B0D32A779D0AC6E80C1D56B03C8EF30F6F6CB73A089B149F46BD4671D7C13B41A5B1BCAD94C0552C12CF23352200198CD876615EDDA7257E3CC94B732D75AF6D67A67929458E2639BA4A2967D05F76C4EAED429AC246CAB410B0FC8806B84EBFE1159C88D6E71EDDCC3B956F33739AD9FF6C43168B54FD592D845A54307AD16E42AAD4621D33A037D47D1002DE1AE0BCF2ADD9B01895EB0E63742FCBB5CFDA14EC9C63D94E3387E0FC22FB1B93D9065DF33D03AFA7D156BA719EB9DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF1DF5023719932492A5EE2B7A3B40B7C7F6814D179AEEFA584D317D536645921799727CED4C3D658D5A425D2D3EB1359C975FBE1A2FB2D11F37098B7234A19628624F07698EC3658799436DB5CCE6AC18702D4F27548F61BABC4807826E95D23889575EE119A88256D4326D4BBB48D0F589C6CB22E7F95D49F6607BE258753A6120CEFBC2E6C502138AEA689B4EDA13FDC39CC0759F392860168C2BA881FF70632D05E797A4F52453418035DFE9D072F0593E8029FFC25D75FC7DE13309B0AE4509D8A315C31F0FD0F480B598ADDB0D5A8F945FE6C28C2421DDB4A0DEB478478A49D5E628799ADC5E489FBDBC9DD38686EA7943969A5AC97497B2C380CAD367A8DF3DADD2E31F759AFA47A422D2A5F7C44CCB028AEC63EAA0727231A8BB4FAC096D19BA50AEC9522A00DDBEB86ED6DEB298AB433CDB7B4F15EA4AE08EB01782B70CD59C57D485848B16B9C55BCCECC876AA99071A9A7599868A9BB42F178BF3DD0FBB7EB52A796801D67E250148584C46F3E96898AA264BCC3826317B5BF7DFF55B6F3C3F3929FB552D79FFC1D014C52965F50B446DFC1CFB3302D8C7367A6F64C93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B787B24028E369C59743659E28980F3776146D88956F5E02B3E3116B8292C2E578C8708D4B518B95E8FCB7C7D5C3B16EF976B20FD0E53DCD6D92301061F2588F693A84052F8C776D033ED7A5EC71E928DD7CC7EED8DFC585AA94D8C9CF92D9694377C0268A53536DB64565FD9F5652B0A3634B381121BDA48C2D1FD9E189991D092178D79AEE8333BB0EC988417AD6CD9DD0DCBF6EFDB0E4E8D1B38E2A3DD01B3EAAD55E1CCB1291C87E2A835E86D2E0C0C3642166D2E9BC98CF354E28B6CD3F121606F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174BE4D5805F128D4A9B00266CB6CC792C45CA4E506C8B2504D13AC93044BF3FB3357F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B82A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B275680E933FB83760E66AB8BBCD67108A95111001B9F8E85B6C96B4BBF952517D6330EB1C6AB68317C91468E90237214C46A5F496EE46E2E8069D65797581C01BA0B2DD1DFEE0F95C0AD7E426F877D0CD294CB0F3ECD1C65659D20594153630E46E4A32CA7D3B408B33227123C6449C4644192BAE44916FE60256703EAB9B2821973C8A37F2FC6B3B18FFE0E4C8036583B7E63E60A5EA8FE89401C8633BDC355FDDAD733A74922E73333FF9B2F9EAE2ABF957105197D92E7CAA56F91767E282E0910608FFA0E651B882398F8187E5203F8B56F788A4DE4130D211BAEDBE44B1DE0D729B926D5FBC98A1FA9EF01E415BE3795F085E28E1B32F86B0EC72DB22414EACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E947CA8092F4480FEC3CE1D8A6D8C4CBE3F7EB35919888B729C1CADAA559A42E1BBDA600C713EBB3487FAF3CCCC40CAFDEAE9B9C6EF40D5041B83973133A03156CE65E33173CC6EC41F0061D31797BF2D58C95B5B4E218AA783E09AAD39682072C6EAE7C52E3491E8B0345D3F6DD019D7DA6D9AE08FE40461B81D414B8D5BBE0672D892793121DDB345A2E5B1F8F3EECFFFEE5E425834717D59506DAC94BB9F31F00AC84767700A6FFBB6D93D4A9FC6F02C67F2710269A4162C284E0D9BF486ACFDB55A33CE915B41F167D533B268F96CE0C70A54377A5A76B1C8E992BD4908F6C9AE1B8A1129A6A94F2C1FA3EACE58297AB6E83568F0857FEBA399FAECFAC9FA94217BAD28BE66B04EF4EF7862DBFC7F9D86A69D63D84665C826910849A959626B2F95B16FBFAB29A97876BC2F43A43F841F6161648AA9D1689D67A4BEE2C859702320B726B0219DCC859A330C6C337AF2EFB0B9C8C689D2A7B92DC615BEF81F9488AC5E678E63D3E9C4CD4D2138F500D7967745773C58A8704107771E6AC93AA2307D387AF3CCF853E572E74624A7E40305FF4F57266A6BFBEEC78BC8CC981479D5A80F351588B5E378EC89F193C02A92E5BAB45E1C12BE0DBCAA00E85E73FF666690C4133023ACCD88989AD44530D63D54B090E115F6A25111B4F006B0EDBC73FFCA5B037240E88F9F4FDFF79F6874B6D6865B3B93037E272D66F1BB1EA9AD7952CE8F8F353C2910FBFC6F73626986970C6B1FA3F7D010A7DF2AD27ED28F727F9B6E10E08E9F23278C2C6ACA482528DFDD42021B690D777444DED9C912B2CD003DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D5023540D6CD04777ECAF4F4D58C64C158042656BCA7DFBBA61D7551154DC1535618FB3576C6A634E79E80BC56D4A77A32480711DCF387CC963BBC7A339C907928DBA6545BFEA6878A58236DC95D439F8F3061C099AEF80CB7128E0C1D3AC5841B65C0A738A16BA2EF4649CB510F512A819CD03BE1174182022DDBA30AE32DB5AB9ED29B2FCAF259886A4E479D5B5C118DFFA5529CF83978DBDC1B233C410279CC031E0EFD98F95DF6A32C1FB854F7DA54F12E0D0078F9287622542E551863DCB0B534DCA8EDE06545D0860957FF3A0C13495A47A669355FFF55DAC93C3357E5FC17274ACFCF9905705D6F32C7C6E6FCAE6086384B4939C70128CC73540E47ADC633EF01CD9E59A14EDC10AB0A9313ADC2123A4F3F3B4207CC9564D39F7CE86184505C432B568E4CCAEAA1BB93EFE4C696CA690F4B4EAC21A83E1860C5F26C6ACEE315F139E8C7543B2075D3FBF446058A1F0E0DC7893D9C78FB25914ACECE4664F58E03209D0EE1FCA892A9002B32FE67B0CD27E60F35706FC2BCE8A0F77E89FDD67DCAF4073DE5B72BFB56A87525875B0E27042175EAC158AB2D5A7B85C041FC13F81A9E78911686B33488DB258E31630B4D779F6F40E079F5094D31D70E74F2220ACCE407CB3491B80DCA95CF6126E9D2E955683F0B6BBA28885065E50309BD5E3429C626D547A87ED33769F9BFBB514F8792EB90F90C956F0148B9928189EE06BB40CE18932DB44AD96E226B6BB6A313DDC8CE4FB50C6C548BFA794FDD1EE7EAEA2F119CAA2E0DC7664B0136EE7F50B88FA4F4B1F0A665F36C56AAECC77D637637ABD7EE25BFC8B638430370B0F92FADBFE5C4F166A0B1FFDFDABA98EB3E5D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3C1578D7F6DFBFF09D46817D7C61EFDDFEC6AEB1A21EBD5AF1A0F399A2096C8E30821DCFD15298AB26911D40A97E78421AC35B6E8B47C483E1538E1C110540E6B23095AFAF8CCC9883C1BA2810AFDBC488849BF8E2BD2B63AA036BCE1BF9E6FE84C7C830C65CB9870A441512C55557F371276F3CA97910118271DC35F5A46454B02318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3FBF9F7DDEBC0995B90104C717FA2977F9559887204B56298813EAEFCE587F9D2DF49378B38F71833410D667351B1949CF406F18B0727666AA94DE7EA90B093CEEABA95EEE4D2DB043CFD3504F59CF36374C48E804535A76BB8BF67DFB39E03CE613D53D7515BBC8DF04062A185B7825FD3260B1B377B5D3CF470603B1900FC978329FE4F050A62A0440FA26E9B3D2CDA32E7F9FCFE6446B29FEC3639F068E56D446765B606D7B4FDA46826E8BB9E3FE9ADD93EBF3848B70C759922B63ADAFC8E71CA051A07FCDA3126BC8B4EAE41DB2031017A6794C6784FD8B93672BE6206ECC5F1396078719C45CEB31BDE4A3D503A56CD1BA60A875E2A5AC7CF340A79F261480A2A36EE4FE88106DD0976B8FD47010119D6D21982AF0E8E58AEF1BA68D4BF979DE633E719AAFC7A6C8AC6D127BDABFC3660711DAA2962D639D46747BC03BB269789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411923F9FC45FE90EEA617A4971AB81153088F58B488C507F5C230586CF967833C9A0DEA1CAD7FC139A9710382C46136E4F4007BBD729ACF06FBFEDFF5144533FBFED92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE598186E4905539B32F01DF3F0FA65E08B09F4F16719DAE9A987DAC3A28B2B9E001FAAAD0F03810E525D26529CBA1829D42796B65515D55BCD2315DDDB342591BE8E217286002741AD99A1565D106690A5D6277539266747D8632686C5C9061D5119998BAF8B6C09E61D13B2D91426AB98DDECE3EBC2CCA03A8B6591E2A1712FE71F847F486D6E177932521D9196CF0F637314E2329A86F733D95CAA0C2F7F08FA45A993F52B44077712B70116CA4A7DB6587E24BFEB70AFBF3A6F1A33F469D98278A6603810F6664B9BDF27388FA8C69CDD4127B39AD97A6E2432E3C2B6E0087EEBCCC54DA43837F112E61409D225BF5E5222DC107D698C0E571EE8D532C99C6CA353C02F2BC7233F1636D14FAE126DD4433CCBB5DA1C5BD079804FC920E7A7906C9579B18D7B78824CB39614E28A2091D1194C26DFBE86462EE24FA1FE24ACA85F912404458AE8DDCC5B03A0E0402BB689ECE763D0825A8D566713A013923627115705098D63351D22772A01D57BD39566F1EF058044281C3275AAB8C44F905DEA89F9D1ACD8FC3C5E9F2DF429637D635359D0A3D91D765C71E5DA37C2BCF29F1EA9AEE40BCF69C70168BC10F1E9576CD541325A8A729566CAD7C0483ACC8E23DDCEBD1114559AAA8C6621F7A7AD11AD19D6312097C99841A84C35772FF6ACF5E1028BD5885C73C78A719FE0D63D52E9F55509B7AEB252865C6720285208786A2439382CD03CA0BFA2FF1A45B734943CA586AAD35DDCFB075538B0850551967EE7D7E1261DEDE7016BAC7E1B447BED75C565A09D3F173B5F9DF4CBD86780F35E9D7D62E54A2FEFFA0FCFC5CBAB99D2F5EF5784EC92C6A9C8DF06FD4491E197B153B084BB9A5F629E4E7923220EA7981AEDC10CCBE387725C16BCD5A4CFFB3566525CB00B5295DEFA64574065D1173DAC40340878BDAED7D71811FF8EB1B55C9E3C8BB8BEB2D011A9D6DBA1522C969314EA2A7FF20000EEFAC8F760CD24975B2CD9D37FFF352B4B13CEC723C68A595E301D02E0FD881D3286582D5472DB230F77C644E02E4FD2118592D323D93CD22E55EDAEC15693758CA10E3F215E6814BC13E2DACC05A226ACAF6DACA3B9EE91B0CD0740A5B50E6E10013407A7AC9A58F2C2D41A8CC0BD39BEB52BB643AA89A1194312A69D6245A1844A03D0EE0BD92C46B5D8EA77927C48D23107C3D498427E8DCEAEAA36E368A58EABA0E06B97532BD8D2B17A03933D6BB6E00C1AA62CFEF7C7834BB0705A50205C4EF8D3270C4A0716A59CAF17D13F6E01699B1ED376095D3F6850ED50053CB56D83A15DF12887CC06E7B45D143CF738881A322557FBAA2381B355638DEC332B690F7A2C91AD96C5102819AC027304301756A1B970378FC0C627135DB8D5F6B0B75316DCF93F0955E37193575DD0C14961D776379DAC58F5FC1150785BBBA92D1009E1B49D7E3362CFA468D539203E53FE2EDF38BA68448A3520CCF623D8427DE666CFB05E0BC25452E528FC4BAE4FCB020F4ED5EF4F2A71B9D225F7B7E6655E60877D7B7F3DCFFD8C4C77A3A3B36073A69EEE8B35F49BFA43AEC19ADE9CC7DFBB1F6A7AAFC69B3210DD8B9D2D54268336896CC79F76B441391662909A9261AE1A5D75C4F9C360AB0C19A94F3930B33ABF6EF6D5AD18ECADDB1B477C019334C76E553210D4C89E4C32DB11EC281F61A34DC4C3FA81C4C11ABA995BD4EBF44373AB98B000C9F53E39A9E09607A88AAC7AE6A1AB1E735E1D0F8F8D34253718687CFE01212B0B818030EC3F1C8F79574580A44C571456C431C52BA9DD336B1A5F8753263FFBBF6005A7AC41B11814D8CCE8CA7C6B68C4F9A56845611FD6D46C35562176A9E14B357EE8DF2B3F76950986449C0AD69B0BFEF0641CFFEE6CA5112F71E1978592018BE903F66F340EDDDF09089FB1DA7C60F76B3D92527D470E11455137D94A80082FC1AB8DFA33F518E348D50068DC6BFA59015590904AE41CAE8E6A05F2A1296D97077A04DABEC3E27E25173C60F955161EA514178875427F4018AE8CE74578E79E80310F069A611AE281EA56517083EE94B5B37A1493E614AE495D28CC5D8E5A6EA4119FF599BC8DAC4167880FB7EC2FF09007E874ACBF9CAF516CBD6E305EA8492B3FEAF23BC6571A5B800489E07BDB1F2C800BAF3E7D35B4EC997B21A3C29960A9FAA177344E6F9B9C59489A67E782B630D9CB44FB0F82922839403A85C7AD53A9F32D163A64DC226EAA21E0994B218DB931E50BC31C0E1B5651CF2098EB00153DC510E086B1FEB74661932A95116E04BF13E9E302A4CD3783C572CF52249F5FDA51AEE054682E7D3E9BE99FA215853668F015F5F788BC6DE4261C7E53A2FB9B46FAAF6C821BC64ECE7AB00F059A65EA3EA9AC7C64971F504F26D97B48817B3DF9DC46B3C106C041D1A136B4731AA2922B97DEB83A3AD798A719BAA1CC2ADDE4A34D5EA63188A0CFBD3407F3930647C3993848154841EEEAEBCDC2149D942FB644A671D50A1B51ED937765C0C2AAB1B35FC6E4E6DE85E82B4D87727BF30085AD56A27A796F53CB4D3609F07BD7645F7B32EC8B72E51592714D78514941E217E6A8A393F91A907BBEBF9804CAF5925756BB3EB09D32E125469D4413DA437C8BB4CFF2F9C23C6ABA4B90395F55E94E0113E372FDFB37E7801F0AF52AACA367BF4BF90C58D093771AF0991244B91BE5C251F9380444AA86C221D06D0BC12BD1C2DB949E7DB4A5DF1EFA0A4BD339B8F1B937F2AF48072CF8F69E47BC2E20286D2524A59F271852286AF9B8BB57C5FED3E3010743E81629BD1C366D9350DC9329BC839F7B8AD5B7E570C85EF644413F0A6974DA2CE7FD7194C30A43780D5146942339CE2B186698B8CFA564998F0DA458E36F2B66CEDA779C9E9957D987676AD23A507730959ECC0016FF3A53167DB27B2F226A2B4B5EB7A409915DD46A882362462CB5BB7C3D2A75998AF280055E9105EF6A91BFDF40FC5FD0E6E97EDF27F96872351DD3E8C28F46AAC52365CF914A32E5C21626BE9E13BF80A1E7E616022639DB2A5ED92A119164A3FE6DFD83DBEFCE4CFEF2250893E21030934A382A288C69BF0FC7E9C92280906A4BA331C652BC4F904B9B54DCF3DB0651E43A6C83FB9843F85F0DBCA8D2E7F492200039906CF62A95D7B1830FDECAC0306B1A98B6F7B399E406A172202E29FA157E168F4B9C6979150F5AC2EF7769E4A729B6D59DD8F944E9A4A118FD06355D19B28ABDF256B4390DCD5C098DE989678AC25659763FC22E05FC4EB5860F4EFF891AF7D33883382B554819C5CBBA093B55E335D550DACD6AFF9DF70A2A92C1BA88F210224F8F1DFF0B420B6C2F673497B86A156F5F1C675D301F55D69E5D275BD43C850F39D321DBC76B0F153EF703DEF0FE7480D5C83EB1535F0FF92A37EB637DC3AB8D7C7965C8517131F5273B10A2B5E64C16C85791D41854E43BD503F0E52180E9C29499C45CE64BD97C0BA486377BFBE1C6EA2A84AE249C8AE40CF3E86989F0379B9D02694DA77F9E73560E0F38AFD05744E0A30FEC0D8DFF8A1CA3A0EC629144E96B590FD5F75D92F40E0FC0A1127486133218B844D932E038CD1B04DF12E1EC6CEC249345EAF4DACF0D38453A533E5193257BB55AA785666C64B91491B0A5DB93688FBE07D66D926759B669E18521210CAD05EF3F8972754DEA64BCA926D661B145AF5B8090D1A4E51D9CBF8818A4EBFC8FF1BD6CF2C76B914B8A7BEE0EB33F37ECA54E2DA3CBC29F1720DBF0A024C969D4B1E36326FB6F63C9195608C68A3D7C87AC394210D0F4CB7D858A88168FCC25B79E29197E2EA3B3D4A862B70A1D7F3251C75F02D476926DD863B778059B83198414E0672AA1F27898C8A6F035D26AA117F838EC83D453A0D5C49AA350B288F1FBCE59D86C8CCC99F14A221AA18A9F300DA266DCF084910890994ABCBD8185D28BAE4CCA4BD68D4D5790FEFBD7A6D56B8C78974F9A8675E6C410F6D5F7F6D254F1C7885F48F0391E1BEEAEC7437553D480FBA79F55DD5B19C596DC2089BCF9980959958F7FB7E6DB0358093379414F67BCE670BDDBC67BC8ACE419C2E48C5B57EC624C5693562B719C7E6B09F3A309D255D0B7A8B8430F7E9544A881EEB694C7282E20EA3E1ADEA50564B935D528C0372397F26B1497DFA3D0F117F7A6797C1626D1AACEC708302CB0C0E406BEF60B7F6578623EA59A005B804C009A38E0A615F1FEDABBCDA5269C9C48E148A143562E1A372C0DB9D8F249FB5A7ABE5928B4BBB17DBD747A57D9438774BAE2550A5B205FEA96912A2FFE3FBEF1D6DF372A31B1084F0715829C141B845551C086DCF8FB9BEFB43B417AF3426BAF6007DC2EFC3B4999D2A658B5A19CC61FCB3E2ED5EB14D1ADEF650C7254F5163A2FC01B987E3000517DCD878B3D9268E912CA3675000B10E53F5B8172477AF6FE3778CB0E5D279309245647970C216E2E608E25F1C4FAED708E98E1D88193FF5DE2D33B178BCD345DAAA3ADEB8B1B6D7C3E9C2468F943A4AF0596B0AA480A159BB882857360DD34CEB848F5CF3481A660F70E49916F9A952B001E60F11A31CEFB39D3F49BF76159FF3E8B3570BBF5D759F5626B1FACEDF4AD03E261A7E095044665CE61C3359BA5A046E44C8E5506E2BD7E5C5C61EC2EC722ACD680BA597A47ED44E937AA64C0E3523F1EA891BF01E2B92D54EE9A3684A122D33ACD2A6D14133A8DC35EBE37F49D59BB4BB5F24940C18E0B4B5F1349AB813E994AC43DD0420A52527147C9A0F4729F8BCFF0941B934253B98628403937D1E2DEA8BD23A2EDE0A7BCF3A2D66FFC7049C8D2D3D52B4F9479F6652462AC2D18DEBBA361721EF71168CC59501174444B5A2E58AF71E8DFC4E9F836156C1C844EE12FCA65ED97F8189FF34B8EED18C26508B5ABD7DC94DBFD37F18A514F66BEA2AB8F02DFBEF4D54850B589898EBBE0E68E9F864D4468C96BAA0BDF1C074AAF51CD47B20784CDD20DCFC3444802DF292D0B21D32A93F2DCF3154860EE0F469CF0E8BCB4BB474C2C0F6E2F97EE8C155EF5B270FAD06AEB3336087B314915E7CC95153698BC2E486441D1484052BBD641183C9F5495CE45B270E5D085F4DF45707C7615CC89197B2646196A2F382EFBB8436E3B0A09CB2384FA6D3D7E436D19DBCAF897D8A2B3B41D17163C52CCCCE010274A70B6B985545072CC776AA5DCD1D7D1F191AB56003FCCA1F90F9488AC0C010A6FBCF7CCC51AFC15BA2F9E678B9B2D2B44DE9B7C841C386126135E1871324C9C7D3648DCB8213473E4D006FBDD976D2854DBC257DC1C21E0199C10AA0FADFBFAEE03693930F970285460EAC6BCCDB873F2AE73A173F17CF6C07C26B3FEDC0E81E8EA4FF7D68CAACE34340EF1990F3BF44E23BF65CAC9F65B50E4AB2ED67F01DE310314B56B351691609FD835399C51AD9B35E4118BF3B26AD5DAA9A0609CE6A24C8D2A1244709F770A655DF9E80C0C7441917C8329446EB8FB371C506EADD1DFBF6646E0790637395A2C1429C60252D485BD99EB641F0FBCA951DF3698F69DA2B8E751BB02BA592AEA7DD21E7B961499C0238B93F6AC1FC73DD562C80D39493800D0A0A594F26D16FE54EE71B5AA5CCD70B5F1ABC79687AA87DD986F10FDE0002EF9D964E80940FFC39C5F2FDFB81C190A83B0AAB7BB176476712EDE00F6F97973B9FC6061EB404C24993B85BD7BDB4582903BE253ECC3C10C0B65232F5F681953B179E19D4246B0799477359E0496BE7925D46065E4AC4B5EACFA466A8DB0A62F1D1AD326063C89539BBD517FC53ED562D98D20D8A7CE4FC1404B3BCEC7D500F4573EF14C99BCD70F290E6F4206E9BF9E4052A8DF39BF57BAC1969CB4D85E43FEFC1907449AAD6475CD2A7B9F962C315ED6DCFE913A2FAE5E1A695C5BCBC0568797F5154AAC68A30E0EBB8D2F73E6975440421D001AE2076AD1C65F3ACA6C05144A65D535C89243D6F099CD26C54760517EDB1CE98AB4F9E0B6E3A06B3765D62E7812C38B23D6A92ADC6CAF95A256FB750DBAFAA6D3E937BCA9314331C3EC2BFB571E0D54D3A98D5D28522326681F2B91E5BCF4ED462CC90B4CC27225742E5C2286AD1FFADD8418B9B3FD71B3CAB178F34703FDB8ABDD8F5C1461F89446ADB1175E35428091CC0A3B5705C3BC66A1916D1424D631E588FCFA838C2BF8BFE2CA2F5F6648E79942E3DA4B064A22AD6A9BB05C15228E1D20D4A4E8D041BEF83790E9707A581DBB7689E032A083381899EEF508E4B2A897FFAB447F821C848EED8CA09616CE2EFD13966C479F17E1A29D5B6F18387D15E7AB024AAD60E6D68869726EC117084D8E0C42A3A96F5B92139A4B5768CDF2E35810BD1AB3BB40DCE3F38853783F6856552BF95A4A835590582BB7206044086C1CA3BD9B8ADFB09C40A838DEE80E1B3756F98073651454C1567EBB9BB8D9FEA16E9CB0F30FA5E7944CCFE2732FB90178A6F439EF2C83D0FD90FA196CBBECA9DE1DA63AB609F53BF11303F3AE2283195AD62587795E7CE13CCB19132890CE25B085F7AE282F8DE315DED51D9E7B4652285ECB3929B18FEE5FE427610B9311F4173A555CC3D534439D074BB8153F99EF5C62288F9CD393B0C257FDF1AFA64BB68F3DCE632BF81FDFCFBFF93A4CF99D8D50805B18EDAFD09D086D586BF8A5D6A2026084C7DBDDE343F74C964ED3011E29C8683300EFBD9E93C68EE571CD156D8FE815579D8E5AEDB483103BED689A4CEB7EA73CB8E19A6994A01838E173EFE68E816CA53CE578B87754CB34961D83A611466478E9325529D6D15C156B2E2E06E1F624139D230DD3A32A90AD2C7097F43119E10A2E788F15795548B5470728DDDB77CFD86A6C3C6669B9A2217BC37B15B8EA558D2B9E99EEB37E105700A324FD17A5A00803F41C5317FC2445C7216FE28DD0F15BEF50566BFED945796D4F3DBB97D53204D5BD64478A75484912749D9407C09D01CCDC391BEC54A4D43C9157D0A871195C731EB746F61A3F82D6F1A9807C2BD3B275553AA6CDAAE509A3A350DA3F119521A3DF789E011E59EE8138C17EDFA2AEA5C15841D25DF2E3A1FBEE40A3CD98C275AE4FCAD2708F31D7354E4059D43FC5625858721409E990F1DAE7D7FF6B3084897B817D88A99C149497599957A667750E1CF446F5D24409E3CD2AE7F13197FA6705BFAE8C1BF36AA626D524EC10CC50F77B359D718734797BA0154CBC3CCCD88030C97386483EFFACEBA41E5061B95BEF6324AC98FD576AA2A8D264D05596B20200496C54C58146883B62C9051E5F52224294C996EA6B44F84EE277D029766D66AEA021467747DB5CE0597E5D91D92903B74DEF2A7100BFF8201F70D009B0963454C25351D8D43AF77A3E70C95BA5FF34747F55049243C06C036984C5C303378D475F841749BCB2DDE91A25C105501EEF479F2B6C68A60EB8F1A308E74EDEEF93E1E34A50CB272AC278ED9263C0DAE162B7C1FD035421A2CDA9774ADAF21B292C252B94398DF63894C88C4B5529FC5AA5A18E788D74EB6126C7FDEBE4D650E2871B25F37DB9EA8AB64FD4806121F4509D4FF190439B7A8690A81275D9C03CF2B51832B32DE2967485BF84E915F7BCA7647E09863CA48B37131815DF9E5F5A88535186C40F177A06B657B4437728EFA50AA22C45E49026053B3C2A3C554F1B2613EBE50F27CEBD3BB03C8CA17B22EE76C4200A0E85A70B6DFF7F511FA2265BB7D858556213C48436D573F120D4222BB1A5C924B2EF1605B4A1ED717EFAF63AE53B070D7C62B2F8CFDFFBD18DECB0C405E7575C6AD8CAEF4789D6164039F963F807C3B978CEFE718A83A68378F9156BF52F6A3F76E411CFFD88448BFB452ECC10CE99AE5F5E303EB099B89765A377868B0B2B3A0D631264AEE47BDA8FF3A92483D27CC269B16390B3ACCE3350DAA649AB53B9C1CFF2872B6C1F9BA67D9D22C6FBE01424A7DC815F968C77BE937563456A273992579C8E6AD585A0B3D38AAE13ED13B81D58599A43E86C4B4AE7825B358C6FB94BAD7F552544790377714DFAC7F17B9B6B3BAF2E5D6E87AE0D0769A39A5580D5347C78067D7D7C375A91B066A61E124E754549CF27779D43109D8E167423F13D05093CD1D31B7E6B76A89C6BA817D852775ACA8B385138C6CC73639FDA3AB6FDC5F84CD46DA221B2D437A51B54D43D98E6D77E31B07FF420AA12FD6FA8892C4220AFE432664F946E738DFF89EEBBFC16CB168CE1721738B4A1174265AEB27FF3808A80D3BFB6CB893D1B6B33DC27239E96108C6D0D20C912BC1EBBE7E245056220BE957E7B9D49EEE6C4D341AD73932D304798F0A0F04F31D8F70DB5E06E3ED2DA627D47E0AF1C2E14E56054A87AC9810B617A52D0DB5145FE4C2BF6D0D4AFB0F9314FE15167A5AD0FBA0C1454FBAB0705FB6BBFE5F7E39824E59DA24CC67B3AAD9491E7A40906487BF895E90F63CFE6D7C0984F1D2747676B82D09DFCCD2A8F6DD158C917DB81FDBE6213FE43780DDE17ADB969B3D64CD6BA6EF1F9ECC7D6F6207280078B10DBEBAD7581A2E8C2F83E4AAE8A26F8D1DF0F8CB45C690615EA304E5CE30D2A96C55696C6B1D82D274E9D5765C3E5D2D7D05EC6A202BFD0211B534B7C9FC684C7A72C2D619E9DEC4175477792BB930EB5888FB37198A6E1DCEEE6651038F5C0A15DEDCE6D1833CDA5CE4EE61CC144E7C5202FE532E0B274F2CE4E90D91F2BAF7808D0656D5A106EE157491277F92A36239D1CA7D26150C118F9ABCEDD5470A2A0069AC1BA97ED1CA9885FDF2B6750157AA5B72DB5E7C1140E1FDF78DC7FA04773F4570F4544281C2E9627E5F59CA9740A38B452C9F3A930956187079B4EE4C91B3E3D9F0F502F8558A092630BBA965FD8900E738FD1498FAC10E6AFDF58F32DC0824B405C0E1D962CB213D4D834D7D26199B9172CCA1A36D7A76DA603FE07CE0EB070AFD90E7A30D937A32D26419A002A32AD9043B1735AD3D0696AEDA5F47046F8A3134B8D45C090C0A54C70AE992A0916A49AE7F3006165FBC71CBA5F0611FA5140FC304CF49DF3081CEB754E9E87E4FB637D7E701D930EE23B6E7A739274EC3AEB90736D91745A92DCDC5FAEF42918E63079E07316C2F9E59D8B79062F1D816C536E8323F501A20A11D6FAA241A5CB4A04F8384206C1D4BA5BD2DC0DF41A69CCD6390270FF0451211B36B489AC95476493D812ADE03FD8EA165053401587F7A18C2F3FBF4960C82B30E9C7C30EA830FE7D052DB5A191C0F8DB73833839F0D7AE822027E19C3A899EDBB02AD49EA87E1A2D55EA6B010BD984FC6C5B12289B41264F9F2F23B8761F262598692F57DE1277F48B3EBD06762F791DAC23F5A5846795B4C4806EE0909163CF27111BE948EE0CB673F0B744707BE8189B059F6D33E52AC33BEC99DB223FD42F64BE1C3E8D505592A78D5F7D3E465A5E34C1FC7D7ADD80752A83CA5CFBDD7AE15AFFE7BC0A4BF3722EEC05E54482A88287D9850672C2DCDE120E0C7AF377659E5A3313D0FEAD9B350A80F0A5A4A480346AF02414FAD52E5108B911B7A4B877215E400B3FCD4E8786E962704A50EC2B2D2D7256777111EA6646AE8A57C84B56C30D704C4B914EBFCA60FC07CEE5DB943630CB07C872596E0E48193D8B6513232AE14EC985E19B27E231B2EDA344957695939677A09ECB8C65C93C63C6B08FE5DA691AD51D463012565EAE07805134DE6FD09BA7B3659089DB2B16DAB68A89406E67D63B3F0BC70C271C7D0295293CF5E174FE0609D593810EFAD6CD648BDF6D3253E64DCD6D2FA70FCDCEAF24B7C96A3E3E4B078E1668E5F6CB9A598FA202F0AE1DAD0AFC54BB46BEE1105C69C535390CD630A2BE448CFD70112A56A74AFEDC4CB48BD579FEE9039DF705869A1623B1596F77D7420B59F32801106F6AD8A16DB40B1ACD82415BBEADE36585C3BB47F37BFA7162C255542E8284D8EF8CFF88DB68A47249DCD14C1D2E8E5C44E258E9BA867902ADCD588A5A382A60A580458C8C59BD5F182742CA1BD6A52F35FAC26893D74C3D74429401712918098CCC493BD226EA8A9F8C7700123924131913453EF8069237ABCC4B851B0A868015162AB8B7B63B3110906B267DCCE5659F4FCA5298C4073BAAF392C5649B429D5E378557D5CA03C9A52B6208936AE2CFF83D7E28A3274398CB3586BEE9694A14396FA1D67BFA90524574B7DCF0E8C7B86C86A69FC0C2263B437016842743E7E1743802C4542DAC8E6A23D03A158BEE47F010F71E5D9A7063E26FE8C40B208160936B5CD4D13ACD22F928352902BF25A8C8D294B493907F6794A4DCC0E7CE621FE45CC6E5F33199D798FC6E833F9EA4EA54FF6A465EACF2EAC6864D3CD0057429D789466CC60CD853B829679FCC639446CB0657C15B869BFDF27AFB572303E17FF826F8C4EE2C747AE330858830F70879FC8FD6F8D7CA2BA986E5D4DA1B613DF88CE09212B99BA77FB3E3AF7AEFD4FACB02B3E3172AD43BA87A4433CE38E45C1DA3ACE463315CF5A87B14CF4745D5282B17B613A033A9FBF52A40D8265B49A49DFFFC6C71377C20F4B3EB43FE7D89D829477619A7E5B2F7CC9FD0299C838419661773087C7BB3573568DB256F94E57423B1AC21C0662B60F526AF49629B7A8F7E833F858E5C7423437ED22E6E704EA66B26E79878EDCE376E8BB682EF83EB4B9600015217C1219224381665C140C78374B80F47511C48B5238937464F3B0A5612D2F1FDCC91B74CD861CE655CBCF22B68F657EB7D8806DDDB03B4F08E52089938121B0F6B3ECDD2D23003C889FD2F9A4F6D3D4358976641511DDF513181B1C86DE10522AC021B6A301249FB9E6DB19DF42C5BA6D53F1FBF9A7A2249C516513522F8702636F688145B52B1FB6172CA96F59B9F845760677D91996B38371DAAC111D6BC59BF28F19B4E00B5E312191087255D008FEE158A8E1619CC0674E12DCAB593EAF6C99C9CBE9C700B498697A725E2F30EA74365F3CD3318AA1D0D7C07DCA4F2F6C3AC8EFF0501F8F65A07363621059517EF1BA27310ED930A1A1B0D4DA322D5FD13EF522D21A3A7D623FC499AB8648C1AA0CE2EF94316B2965A246AD7C8869E9C489AF1FD2DA40E3D688531CF77F083F281E012ECF83C4ADC97B5AE47CC38FDB41C7ECBF402AD42716821AE404A1D224363958B9E71DD4B3E77A16FC80598A3065E8E00F36F2DF940F4E99902A1D62D73470FB4923D3A46EF07E65D02963E1B5308121675F1C1973C656549030DCE1BAE145C7712A4879E2F3E219B72B673243BD71442B699F3A4E366C7B88C1266330282D0D9357FBCEC2F95AE54D87A50C8581597B0C24C2F77763B326A55EE924C4A492307610526A864CCDDF6FFC64321D570589BBC5F9CFBCDD95D0C7AD62DEC853875BA2F3C5E3FC20CFF99FF86539F37EDC56643EF7D70D0025B395061B83A100E1BE1D6096D007DC42082D4E793CCFB79CC5A06242518998D835B32B7E579AA14806AEB8A4F19E554FD72D2899617541C6B86B63AC60BD7B6185A7A86BC7702CCB91069ADA68EB4F117E239BB7A9581A56CAD59A618449EE02E2089CE3A1B97B22AE34BBB421F2194B00B80F1841480577415436FCC20FD60731E6E28138A320C9237FF656A5366890E492A318EFDAB7F22CDF81AE5CE56539034A8790E942E58118A8F141B2FC6E4559A04B9EF8827BB7C11D5A4CDAC22E42660082AEE184078053860369D354552F1CB9D798F3FDF657648A7D5BE4F41E6141FBD80732B6D3AB57C0F60D38848FD33F7E468BF7600E16F25B9552688D3AAE33DA731DFA536059D24AAD21AE940CF31E18A40508DD1623FC89EC11BE4B852EEEFD56C002C1388DCD5C54E0524BB681A25E076CFFF94EA7B5E0A0B7DA1DED8DBE3F9770536FFD43BB48C9E55E33554E5C0411BB823FE16AE3CFE51DFC9177764955DB39B08C627F74A7B9A16DCDCAAB1CC31E37B0D3B90ABA2F1EC00FD2EF6E4FF3A15358C551BACB93EF59361567E0834E72383F4EA2E8F76F000EE38B179F7F0F9A3351C5BFF81B49E8A5119C6CB5CFCF49A6875B3A99CF14E6CBABAC0F4F38FC97CBADE13BB807CEADF726AD565D65334539E879575702D58462BB2A7C7F322A16F3F1C4FE116CEDBA6094EB4712D774B8207189B700C8B84FC7D0DB49B02F7AF17A6270BD75AA54F8A79E4A1A6D588FEDF94C0829EC1496988507C8C5BB87A70DFC3FF6C7F985ED38CF6C23E04FFC8001C2958B5E0920B284A4A3A55023D13D4FB99D392A0F61281E6DE6AD1F907788504F80477B8C21454E4FF16236E42DF95C85E20DEC39B2920ED49AA540BF504E74627B678097B4EC800A37698C32118BFF564BDE9BE0E4B16A3D91A9A83FBE991DD88E7341BA96976F7694323E523B76DFE3C52F28188C8D64DFB1341EAFC98C9A28CE446C4983AC52A1C38F9CC5D8CAAABA4E8BF9B7E45E3521567A46AE5166642E89F8503F892F522A447B2FCB1BCE2EF4EC86E22F48FA99555DC193F080D3F0096A47BE3C2597FE83A27E8132D28EB55AE87B36C93F31A9E371BEF51E405037DBED6CC4916E5A855116586F7C34F33B3EE626DF600644EC881246E32B5716E9580A1733ABCB22346C4414E5FF2C085E2CBFB45BC77168F4164B7CECC874DA5594F6E8D0B7B6B36EDEEDA1342672A4D6925CA2864B93BC7F63994F8449929C3206E086738FADF14B1872973A6093B5916E565DC3B354FC544A44202598AC2326C5EB9F305C448CF68323DE4C5BD28472B340E43DEDCA0DC290CAA47238A7A26713869C6B4237D40EE2743BFCE74E5CADFC183B14075FC8088943F3B2E93FD3A96ACA364B9292413B2B67B43C855A898F877683FFA238C05E6F789ACCCC40C434FFFA494F2710C3DFA213DA7B56D5A4C273603ECE648F3E9D6EF1CBC0EAD4BFBAD01E0651103DD17A534A2CCD00CA53C713F3045B2389B81651E8E2C2B6629D127505EAE2ABD26F2086E9D6BD48CA6FC3BF98F99604F221DC203BCE9D61B756A89BB0B418249889529F7E8F070F35D35E572EFA012DABB16A98D0AC8A99E596A91468A1AAC939629FE780A45D8406B60D04C8E2B31EB7E28294FB2595F4E7071CD906FDFEC3EC3CBB02B03E38AF71EBE9EBCAE3DFC9A37E6B54 +remain = 1099511627774 +max = 1099511627775 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-12_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-12_256.rsp new file mode 100644 index 0000000000..7a3f549c8b --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-12_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHAKE_60/12_256 + +pk = 000000187C9DBD8C9B8EA4E9F5B0D99E80ACDC712F597F327BFE800419A478530242532C04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 000000180000000000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A7C9DBD8C9B8EA4E9F5B0D99E80ACDC712F597F327BFE800419A478530242532C04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001521B6795E3B31C6F469147CDE5776D1FAF80EE268B570DD87C1895E195F358E50100000000000135050ED1EAD3E799B63D5EDC01FDE9B7E3E8036A429C0AB56C909CC2B6378D6F020000000000010D93E097DE2D5330AA792D234007668B3E7F9E699621D298D2AB7577E8518A0703000000000001F2616B47D5F8376AF6A5FC658A75A52D032F7A1710630905C152957F41FA24010400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE5900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011420B60C54314ED8291B4F251FF32674EE6A3C3609140380F6B20865B7AE643401000000000001DA6EC89DAF2B01E86C06ABE8043C9A6EA0562A18C49B4A9497D347FAF8EB910002000000000001A0A42481338E08706BAC35F7B5F5D93432D40144F47A0F6790DF4B68525ED740030000000000014A9507DA8B4941DFD3D5E9A02EA050B97F9887A65D93FD8723FDC30C7E2AA4E00400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164A3FE6DFD83DBEFCE4CFEF2250893E21030934A382A288C69BF0FC7E9C92280906A4BA331C652BC4F904B9B54DCF3DB0651E43A6C83FB9843F85F0DBCA8D2E7F492200039906CF62A95D7B1830FDECAC0306B1A98B6F7B399E406A172202E29FA157E168F4B9C6979150F5AC2EF7769E4A729B6D59DD8F944E9A4A118FD06355D19B28ABDF256B4390DCD5C098DE989678AC25659763FC22E05FC4EB5860F400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018BB8E296C7509BC115ABB151E123D4E0343D51087A3A7321FD6406381792A7DA01000000000001166966BACD855719FD325B6CB7EEE8DEC0ABA7479BEEC9A71F451BD9EC1886B002000000000001E480EE1888B362F2F00B536DC0FB57F3AA94097DD543F05D299341633DEFE5FB03000000000001522E3D23E82223C8085779A58B7ECF45EB835F4B8FF5294923C95EEC4FCA5034040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096F5B92139A4B5768CDF2E35810BD1AB3BB40DCE3F38853783F6856552BF95A4A835590582BB7206044086C1CA3BD9B8ADFB09C40A838DEE80E1B3756F98073651454C1567EBB9BB8D9FEA16E9CB0F30FA5E7944CCFE2732FB90178A6F439EF2C83D0FD90FA196CBBECA9DE1DA63AB609F53BF11303F3AE2283195AD62587795E7CE13CCB19132890CE25B085F7AE282F8DE315DED51D9E7B4652285ECB3929B0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D10E76AEEA90CDFF9F15085B0834F5C0339E4C86D2CB52C234F6B18B472E8A020100000000000195C0CD14484D08075EDA691EE42CD999A552CA1A62318D9765CADAB553C1C5B90200000000000157A8A577120F2AD134FBF0E0E061E38A768CF935F4D2AA9A541C7A3D033A991503000000000001A467DDA3824B40F0D0D861A12328735CB8C23D1726982BE71F4CF68EEB4925500400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B07C872596E0E48193D8B6513232AE14EC985E19B27E231B2EDA344957695939677A09ECB8C65C93C63C6B08FE5DA691AD51D463012565EAE07805134DE6FD09BA7B3659089DB2B16DAB68A89406E67D63B3F0BC70C271C7D0295293CF5E174FE0609D593810EFAD6CD648BDF6D3253E64DCD6D2FA70FCDCEAF24B7C96A3E3E4B078E1668E5F6CB9A598FA202F0AE1DAD0AFC54BB46BEE1105C69C535390CD63000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151D5FD68390EB99D8038558DDDF270C7B6F86FB6880610C1958EC697B28F07030100000000000110E17383D0E375BD799216DC0666186C133435744D4C0B5160341DE623FB326A02000000000001446011ADFF0A4CDC66D4AD0938159A880A250A728A209F32F3AFA46A2FE4644303000000000001656C05D7A6E564380A829747834E40FABF67FCA7B2388E9EA19CB553E670F39D0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F1CBC0EAD4BFBAD01E0651103DD17A534A2CCD00CA53C713F3045B2389B81651E8E2C2B6629D127505EAE2ABD26F2086E9D6BD48CA6FC3BF98F99604F221DC203BCE9D61B756A89BB0B418249889529F7E8F070F35D35E572EFA012DABB16A98D0AC8A99E596A91468A1AAC939629FE780A45D8406B60D04C8E2B31EB7E28294FB2595F4E7071CD906FDFEC3EC3CBB02B03E38AF71EBE9EBCAE3DFC9A37E6B540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001FC2D9E83F622B942A7AB522F9BBA979A17180C4905EC5D9373BA8CFB20522714010000000000016319A9C8C78226547F3DCA6A70375F911BE4AE9028FDCCA6D161C5E3698EF41C02000000000001B15AA0B323C0B86CC6F8D84E17A54A6198649F962EADC06CE71C2D0FCE0F3F57030000000000016849136962E7C523775EF2B7BFA1967E4C45FD1B5FA9927D5068CB7045F945F80400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B76671FE88C84A4357C76C316723D855FCC4372ADE20F8746B501EB76E62E66AE390961FD58752D4914C7CA53CD0B83E168C40777F8F136502A84B6C1A338D450ACFE885E77790E4EA399EA859A3F37A5FCB8AD3679063566F14B36FABB97B125F4BAB4B60EE9B26EAB4BA86E1C81E61C1A4103D9BB2D17389A93D792C203B005A361C41D2C620CDA46919CD9F7D30E547F62CFCF3BAFC540F5E6D9CC212792A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C9A1D016CBD15EAD633BACDD80FA9B396D41EB60B5C6C42A9376572A15B7630801000000000001340AE4E9FBEFBB05FAE40AC69DD5D9882AEC64ACEB5B791C23B5E38F7E0D8C86020000000000017BF4F1D53369BD8AE978EE67ACE5844E4677C930973856D35464FFB7DD2E380A030000000000010A5A6E217E8ABD673B1F169D13255F2B1EF225A6B17B4E8FDB3638EEE425A0FC04000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002FE6945E6FAB674CFDEE3C8446481D1144C9AD9F8CA0DC87D99E2FE038A09F0E9741814E09511540CEAE2C0E950551E10B4BED309E2F6E7CE10500BD8B00C5BE0B5D88B01A1AF25ADD068421C0F98CF345A597427D043CB53ED18DB764F4288B2B88AD917C4F0788488D1C56B7579C7695983135EF479D902A4360389A206CCD9652672552F9726782AAE9A57D0C64034E7F124FF75B1B55AF309F0E9B4597E20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001407FB5EC75AC3694AE740341B13D2FFBC2F6AE7343A54E37F6C6F2EEAB258CAB010000000000016C508B22C241B8C08D163FE5B1977B860137F0FA390970C779F27757D5462FA8020000000000012AF02BB715D65D2C0C4F7658BA084A5F34ABFE8EC98BB4A4C7729B0B1D5727F50300000000000163E339A7757812D58B835953C2F8542B9ECA45C566C6D40776D1E0F54E4BF3750400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D896E231EE5DE2FF695736AA9B93B48C13D6D0F9E4EBB68A1088B311D3E1696610E7DBA6023AD3BB4122BDC83FA28938AA6023D1BA84752D897BAC75911F9928A4585F3C071FD858EC3721BE2A9F5FFCD260A7A5413BA2F7BE17E59830A7DE2299D83F779D0C780EFCA74D6D71015D7F21F54DF0A5231A5577BC161BFEB7F6B2A41B5B9A3661FCCA56ABDCFE63F3B49CCEF00938CC038FD084477C91123FA1490000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001FF52E922221EAEF117F25F4BA35F0DF3BFD2E83DC3CE0F32221B397B0F58D3D301000000000001456A0108B1CB197506370C82469217CD46DA5260518EBE060F5041541526F0B20200000000000139283287215239886CF223FC451D7DA8F28DD9DF4A17E46E24B0A3CEF86ADB3003000000000001C1BA8932F5114BBF3321498FBAFE23E699D71BE06B2EA0CC423F79688CB3DCE60400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DF8DCC3B3A8B6659B70F64725133A9FD36DE92C29A485C582BB80B5C6609CC4C7D274BB7FAAF35EC4D80F5362F198D5B837132D84273B57B21103639CA52F910FDBD585155A2BD052051BC9E8E43C7AA006A41FE7864BBFBA510253161545DC3E660490763A929FD7A5FB32773FF52FDEA9FE7D35C141D13ABFEFA7A164D484F75B78484DACBE33271095DB0A74F25E78B1C0514641F50D62A173D20DF1B38600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001F29DF8D7B37FF45EFF2C758310D7A14228AF285986BD41E283E3197DB9A7F530010000000000016BF475A4431CFA7C1CF0BAEB757C97E64B03D109D598E620FF8641E5CD50710B02000000000001A870C6026E859248B7866BC1A623CDEC1A9E807C402550E33676E949C2B6DC8803000000000001D19E407B03C9F6EEA492ADDCB9DDE699227C8DC630DBD5134D93EC762844274F0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB939E6518A5122E37D4C257B0A0FD60CE0BA3BD55C9CBF369DD315A3C0609933D25DA403DF7E69FEB7EEE64DC3C13DC83217C2834B42876862CD48E99E69564B336506B85FDB493CF8FA87A7FE48DFE6778DDE8E8DD066FAA745C121480B5BF9D5F301B358D18FCCCBD24069E71836981F168FC49E6A4F27B00F6259B183B62CEAE0BF4AC0F53FCEBEB9052C0B48EB0666F361C5DA674B20B06AE2EA8783C2DD7EA74D98AC98C55748A368DF5B433C39538365EAE8DAE5E032A2008768FEB01F65D001AAC437781F742F536EFE2B3AE59EA12A6DC7F2712BA2D9D1C253D29B419A765985ACDB42BCCE5D64F6AF8368A5D122BB16B525A80C8BC5355A53917CC82262254378CFFDF1C7D6355F114E4FC013A5E4DD9AB373A0EFDC470854E20330BC00960ECBE882098D6D0D429A7AD19D3E5D4B78AC5E568C722A21877DA617190CB43123FB04333FAE5846953E33407080D04DF1417E740E7E7A14B0E3CA7D5B693F9615E1F7D417B9004F28D5002325B851C31F5EB31E1DAA80E6CFF22F11221E5180BB050888B6564A381E54401AF9409FE12A818B69BA34E1916092A0EBA24457EF994A1B0028649C9803045EC93CF416373F6A568856B771C3BB076AC265045ACE8E9BE3C3074D8806BEAA3B8B21F7E37F50B16221E14FE5503C615A13738CCDE39E2395E292119959CF686532CC3C9F9129E62ECFB43A091B06FD48ABE8C2CBE2D9691C8907881991CAB9D0D9CC7B2699F2261E5D799D26A7C8A4AEC40789B34CF5FE7BC8D24D6F0BBA7A5870E37F4D9B2605BB56ED9BAEB780CC74097DD8AA8741A97E22EC7B7434F81DE9D83CB9816A33C5A79D718C76A3442FE50C68FE1CE7AF728F2177F88E5168D4668518897AB050B57FF42AAC731E484B440D0D7B254383C74BE41C2AAEC02A8D8C7020355C4A1FAFAF4BBF56C74D78949D087259FE8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B179B32F9F94BBD8371B973B19E60C3CE2206A2061C7BCF159BC3A50163924774BB13C708A573472DA73B4C78DB30FEF310EA3643BC75D9155762D5B87809E2A727AC0428B746801D693074ED5245F29B8FF9FB782F2E57BDD89DD700EDBF12E8311946CAD9BCC98E3B1D581E678BEB1D0A6EFE15CF4052A1AECD328B2C4A8D5DDEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA36145D1653D108813E42654CB5350FFDB33BD2FDF4E416C6C0A61784E2327F42B2DA2AF040822C291D63645B0AC2377D0DE3FDBD99FF9CD9AAAE2B978C4DBEA95E330E90EAB0C4C34E88855C7C62C40B231AA1A9EB409D18CAA1C612A98F1B7BC25B18E3A89CAF96AA4BDF12F865EE7DB20273D7CA11970219BE997DD0EDE7A8ADFECFF1D90984694EF152346402207BD7D9166DC1B09F3C3520D109824442B8AB08869B0A4850BE3227E746998925CECCB422C4C05047D890E291B4E5478967A42BEEE34BA2765D86D183C71FB6A3CD86EAF457756FC000FAFDB24AF3C968E547A5223821BABF91B31B3F970D9F7C1FBFD16CC63D14243DB22CDBC266BFA4DE4B15D23B17D34C674649A695E80F84F6FEBAC0255BB155BD8B8D46FF7AFC532117E26985D99B0E23345F9A0247D834697804C6644501CA7D2726DA563C7F02371B5CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438DC67DF57A5B11025EDDC8915C57C8C72F6D6E71978496E206201184593506E39582DD2C803CE9204D2AC833C35BC683E0BD3CAD30BBCBF584AD38DAD30C9A400DE22F0CD6199FA6C622941E79F8C5C500389E9FBDEB8E1C926443B6FB0313DA9AABB163F5319C0164C1E58864827E38C18B7ECF6FB44274CCCB84B10F1A1BD76C8740F479777BDD7C557DBEFA9415B7FD50CA659E304EF4FA22680980D0FCEFC75E36231F740F38E9B4AC55BD8307F8AD9FE45B046B7BFF0F1B9FD5EEB82D474DC311A8418BB27CFE324426CD3311D65513B0A4D58515B94B8EE5ACC6815D6D1246527188E7B6C579CE42B28E1F273887FAFAA96D44FE6830E96081ED562FF4A08416DE4213A89CD666E2814FA290A5B1FA5AD6DB86B9E4DA85486E11BB36382C13607F50EDC83909F47A7D089CFEAF4680A6F2F10A2D9D9A679AE82D2DB387C5B7BCA11161E49E01C28D0FB7FEFE1C9A4BEDE994DEA4087F3B74906EA8E49153ABA49BE0F35C0572E9CE0C68B2267884C4BC4AD32BF28CE64DC7C825BDB2D8561C69161E075F48A40220159BFF1C4158187D4DE23C85979304DD4DBB98BAA57DBE6B7C55C271B134D61906F6ADBA4639BCAD3C1A70DA04A9409A4A35FEF1BC103D4F17BAFEC37C3F108B31327E0FB227E0E2C5B5410726ECC93B56D4D153572C2DB4EB4757F5B2232C475EB9802FEFB53EAC7BE6A090AAE98027AE13D2B338442FE6EF2DCF141C4D1AF00C7B3E973467FADDF6F1950ACF2BE908FED354EDFB147D6AC4B0740F87DE06E768293CC83AC995760FE0015CAC682036CCABA9C86B9B06924369E35688F7255F5D5422AB808D023B150D62D9A7DE4F7A5D28689EB038E9EF9D3366C3D777AB6D1C33878327018CC51EEDE65BB5FEEFDB1442B9006C76B10B6CE9EE1B6E43306DBB0D9030E3A191DA24634A80063F6A5269E77543525E11BCF02DF82E5921E3225EC97FC5F9174E0225E8C5D08B4C093EA28A19D03E908426578661E107E5E2C5371D79C31F11468112A6050703BB8FD9ACDEEF8D0BC31E82FB4F7DD0DFE8AE0216582E6C86FCBC1E7B3FFDD921F220702D827F145D79D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CE8D216DC6F19C3AC0A1017837C31D76ACDBD48F018A1CB14E98848B66A59F09AE557964888EBFCAD45C491A2A3C44B7085FCA7C983EA4AA22F62B99109F6E425CDFF5D87105EDC065810CA3E055F62FB80F5CAFEC57F7CB47A95B14A215714FB345FC73E57C1574E38657755CE991FCEEDC5ED84824E0E4AFD43205E126A3402910DCE16C59C8840FC7FC5ED9FE6379F9A388601D57B366FCF44FBD2D0C15A3D8A4A28D71ADE5965C137996748EFC7FB68ED165D2480FE34EF58A3169D03D0395D94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB08391412A812DBBE4FF09E10661B7DD604481AE6EB2F89A1FC04E393B3353F7547AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6222D7DC2F78B2E3FC4C8CEAE02E3FC9D7972CA803061F534D39E4F02809C7A18A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F9536829157F62BB003C2E45042DBEBA9622508F9AACA5FE89F665A5F35BA7C26D93A84F9DC744354C73885BC59EFB657317594D34B561FC2A789C919EE08D5D68185BFB2A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E1866ED93157270FB47C81CC3076E5B381E6B03127E7AE78C54F5F35B2474F18A2461297462FFAE651BDBF3D438E30420A3BA5686483DA2EACD874CC44102C09319C10FFE87AB2099A185DFD0FDDB6393B2F61490D65F93CE565C6575C877246044FD52ED475831AFE194BB163D0FE5A023BBC435497C3C16C8C7A85FF92426B59E588978E29EC0DAD032330035B797471B74BE366FA75D79D35228004D3231654D5F301D6597B83258DBE9284121A2BB21EF66F40C17FF135201D18092FA6A72B511A456786ECE1FCFC986A28C744DD4DEBCB552C638043B0602343CC796834B13660A86C5E3CCAAA1845C5165074AEFBA7C52190845A95DC59B1E8D6B052D253EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D1B478E24D9EDAC7EC8816FA54DFDAB0F181E9E1A8A6CD77A9EC29B3E35544898EAA311411BA22E8BA6418CF252675917A88572E0CE98CE03457996BA4FD86D07C4FA2D3487400E484F4CE0A83CF490C49588DB83ED1EE2A93B78101144586427FF43F434D3A40268920A4FA3C64C0F5F4600A8E52E01CD8210965C4B212DCC942C68D589D21FEF433904C26239698EA85C32423EF7AE1ADC90744996C956FD5D0683674010173EE4A110DA2642C8E1C4BF7B5DD3DE268A3AD0A261A30AFB6AD7D54210702C635C3E707CB1F17053D475A026EF57852DEC1FDA4252FDA2E69BA95C866BD432139CA8A4E367960F85B2FBC75420737CA4843B89F053192BB086BDC0D739B2753DBE42E1D45877097F3B97FCA6F43AC15DF883C3B42D9F472F910DE579301FF7F57D9857890651B64B6C1E8A7E2227ACAC7154D97252EACF8BC5FF430E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD637170756688D9AD3002B3148ACF0009CB1C0802EB04197FBD2FCE168B5FACDD052DD46F9F0B0A34295557CF741102E7592C24FA56DEDA63ECB7A2149E406C0943E5E554767D166EBC95FAF0E9B20C1E530633CF8BD7AB2A66CB105E108C1793B0D87ABBBBA9A4679A05C94BE6A698F4758B8BD38C51371C8043FC79E749D7E41C04DC6D815B0D32A779D0AC6E80C1D56B03C8EF30F6F6CB73A089B149F46BD4671D7C13B41A5B1BCAD94C0552C12CF23352200198CD876615EDDA7257E3CC94B732D75AF6D67A67929458E2639BA4A2967D05F76C4EAED429AC246CAB410B0FC8806B84EBFE1159C88D6E71EDDCC3B956F33739AD9FF6C43168B54FD592D845A54307AD16E42AAD4621D33A037D47D1002DE1AE0BCF2ADD9B01895EB0E63742FCBB5CFDA14EC9C63D94E3387E0FC22FB1B93D9065DF33D03AFA7D156BA719EB9DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF1DF5023719932492A5EE2B7A3B40B7C7F6814D179AEEFA584D317D536645921799727CED4C3D658D5A425D2D3EB1359C975FBE1A2FB2D11F37098B7234A19628624F07698EC3658799436DB5CCE6AC18702D4F27548F61BABC4807826E95D23889575EE119A88256D4326D4BBB48D0F589C6CB22E7F95D49F6607BE258753A6120CEFBC2E6C502138AEA689B4EDA13FDC39CC0759F392860168C2BA881FF70632D05E797A4F52453418035DFE9D072F0593E8029FFC25D75FC7DE13309B0AE4509D8A315C31F0FD0F480B598ADDB0D5A8F945FE6C28C2421DDB4A0DEB478478A49D5E628799ADC5E489FBDBC9DD38686EA7943969A5AC97497B2C380CAD367A8DF3DADD2E31F759AFA47A422D2A5F7C44CCB028AEC63EAA0727231A8BB4FAC096D19BA50AEC9522A00DDBEB86ED6DEB298AB433CDB7B4F15EA4AE08EB01782B70CD59C57D485848B16B9C55BCCECC876AA99071A9A7599868A9BB42F178BF3DD0FBB7EB52A796801D67E250148584C46F3E96898AA264BCC3826317B5BF7DFF55B6F3C3F3929FB552D79FFC1D014C52965F50B446DFC1CFB3302D8C7367A6F64C93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B787B24028E369C59743659E28980F3776146D88956F5E02B3E3116B8292C2E578C8708D4B518B95E8FCB7C7D5C3B16EF976B20FD0E53DCD6D92301061F2588F693A84052F8C776D033ED7A5EC71E928DD7CC7EED8DFC585AA94D8C9CF92D9694377C0268A53536DB64565FD9F5652B0A3634B381121BDA48C2D1FD9E189991D092178D79AEE8333BB0EC988417AD6CD9DD0DCBF6EFDB0E4E8D1B38E2A3DD01B3EAAD55E1CCB1291C87E2A835E86D2E0C0C3642166D2E9BC98CF354E28B6CD3F121606F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174BE4D5805F128D4A9B00266CB6CC792C45CA4E506C8B2504D13AC93044BF3FB332A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B275680E933FB83760E66AB8BBCD67108A95111001B9F8E85B6C96B4BBF952517D6330EB1C6AB68317C91468E90237214C46A5F496EE46E2E8069D65797581C01BA0B2DD1DFEE0F95C0AD7E426F877D0CD294CB0F3ECD1C65659D20594153630E46E4A32CA7D3B408B33227123C6449C4644192BAE44916FE60256703EAB9B2821973C8A37F2FC6B3B18FFE0E4C8036583B7E63E60A5EA8FE89401C8633BDC355FDDAD733A74922E73333FF9B2F9EAE2ABF957105197D92E7CAA56F91767E282E0910608FFA0E651B882398F8187E5203F8B56F788A4DE4130D211BAEDBE44B1DE0D729B926D5FBC98A1FA9EF01E415BE3795F085E28E1B32F86B0EC72DB22414EACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E947CA8092F4480FEC3CE1D8A6D8C4CBE3F7EB35919888B729C1CADAA559A42E1BBDA600C713EBB3487FAF3CCCC40CAFDEAE9B9C6EF40D5041B83973133A03156CE65E33173CC6EC41F0061D31797BF2D58C95B5B4E218AA783E09AAD39682072C6EAE7C52E3491E8B0345D3F6DD019D7DA6D9AE08FE40461B81D414B8D5BBE0672D892793121DDB345A2E5B1F8F3EECFFFEE5E425834717D59506DAC94BB9F31F00AC84767700A6FFBB6D93D4A9FC6F02C67F2710269A4162C284E0D9BF486ACFDB55A33CE915B41F167D533B268F96CE0C70A54377A5A76B1C8E992BD4908F6C9AE1B8A1129A6A94F2C1FA3EACE58297AB6E83568F0857FEBA399FAECFAC9FA94217BAD28BE66B04EF4EF7862DBFC7F9D86A69D63D84665C826910849A959626B2F95B16FBFAB29A97876BC2F43A43F841F6161648AA9D1689D67A4BEE2C859702320B726B0219DCC859A330C6C337AF2EFB0B9C8C689D2A7B92DC615BEF81F9488AC5E678E63D3E9C4CD4D2138F500D7967745773C58A8704107771E6AC93AA2307D387AF3CCF853E572E74624A7E40305FF4F57266A6BFBEEC78BC8CC981479D5A80F351588B5E378EC89F193C02A92E5BAB45E1C12BE0DBCAA00E85E73FF666690C4133023ACCD88989AD44530D63D54B090E115F6A25111B4F006B0EDBC73FFCA5B037240E88F9F4FDFF79F6874B6D6865B3B93037E272D66F1BB1EA9AD7952CE8F8F353C2910FBFC6F73626986970C6B1FA3F7D010A7DF2AD27ED28F727F9B6E10E08E9F23278C2C6ACA482528DFDD42021B690D777444DED9C912B2CD003DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D5023540D6CD04777ECAF4F4D58C64C158042656BCA7DFBBA61D7551154DC1535618FB3576C6A634E79E80BC56D4A77A32480711DCF387CC963BBC7A339C907928DBA6545BFEA6878A58236DC95D439F8F3061C099AEF80CB7128E0C1D3AC5841B65C0A738A16BA2EF4649CB510F512A819CD03BE1174182022DDBA30AE32DB5AB9ED29B2FCAF259886A4E479D5B5C118DFFA5529CF83978DBDC1B233C410279CC031E0EFD98F95DF6A32C1FB854F7DA54F12E0D0078F9287622542E551863DCB0B534DCA8EDE06545D0860957FF3A0C13495A47A669355FFF55DAC93C3357E5FC17274ACFCF9905705D6F32C7C6E6FCAE6086384B4939C70128CC73540E47ADC633EF01CD9E59A14EDC10AB0A9313ADC2123A4F3F3B4207CC9564D39F7CE86184505C432B568E4CCAEAA1BB93EFE4C696CA690F4B4EAC21A83E1860C5F26C6ACEE315F139E8C7543B2075D3FBF446058A1F0E0DC7893D9C78FB25914ACECE4664F58E03209D0EE1FCA892A9002B32FE67B0CD27E60F35706FC2BCE8A0F77E89FDD67DCAF4073DE5B72BFB56A87525875B0E27042175EAC158AB2D5A7B85C041FC13F81A9E78911686B33488DB258E31630B4D779F6F40E079F5094D31D70E74F2220ACCE407CB3491B80DCA95CF6126E9D2E955683F0B6BBA28885065E50309BD5E3429C626D547A87ED33769F9BFBB514F8792EB90F90C956F0148B9928189EE06BB40CE18932DB44AD96E226B6BB6A313DDC8CE4FB50C6C548BFA794FDD1EE7EAEA2F119CAA2E0DC7664B0136EE7F50B88FA4F4B1F0A665F36C56AAECC77D637637ABD7EE25BFC8B638430370B0F92FADBFE5C4F166A0B1FFDFDABA98EB3E5D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3C1578D7F6DFBFF09D46817D7C61EFDDFEC6AEB1A21EBD5AF1A0F399A2096C8E30821DCFD15298AB26911D40A97E78421AC35B6E8B47C483E1538E1C110540E6B23095AFAF8CCC9883C1BA2810AFDBC488849BF8E2BD2B63AA036BCE1BF9E6FE84C7C830C65CB9870A441512C55557F371276F3CA97910118271DC35F5A46454B02318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3FBF9F7DDEBC0995B90104C717FA2977F9559887204B56298813EAEFCE587F9D2DF49378B38F71833410D667351B1949CF406F18B0727666AA94DE7EA90B093CEEABA95EEE4D2DB043CFD3504F59CF36374C48E804535A76BB8BF67DFB39E03CE613D53D7515BBC8DF04062A185B7825FD3260B1B377B5D3CF470603B1900FC978329FE4F050A62A0440FA26E9B3D2CDA32E7F9FCFE6446B29FEC3639F068E56D446765B606D7B4FDA46826E8BB9E3FE9ADD93EBF3848B70C759922B63ADAFC8E71CA051A07FCDA3126BC8B4EAE41DB2031017A6794C6784FD8B93672BE6206ECC5F1396078719C45CEB31BDE4A3D503A56CD1BA60A875E2A5AC7CF340A79F261480A2A36EE4FE88106DD0976B8FD47010119D6D21982AF0E8E58AEF1BA68D4BF979DE633E719AAFC7A6C8AC6D127BDABFC3660711DAA2962D639D46747BC03BB269789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411923F9FC45FE90EEA617A4971AB81153088F58B488C507F5C230586CF967833C9A0DEA1CAD7FC139A9710382C46136E4F4007BBD729ACF06FBFEDFF5144533FBFE8186E4905539B32F01DF3F0FA65E08B09F4F16719DAE9A987DAC3A28B2B9E001FAAAD0F03810E525D26529CBA1829D42796B65515D55BCD2315DDDB342591BE8E217286002741AD99A1565D106690A5D6277539266747D8632686C5C9061D5119998BAF8B6C09E61D13B2D91426AB98DDECE3EBC2CCA03A8B6591E2A1712FE71F847F486D6E177932521D9196CF0F637314E2329A86F733D95CAA0C2F7F08FA45A993F52B44077712B70116CA4A7DB6587E24BFEB70AFBF3A6F1A33F469D98278A6603810F6664B9BDF27388FA8C69CDD4127B39AD97A6E2432E3C2B6E0087EEBCCC54DA43837F112E61409D225BF5E5222DC107D698C0E571EE8D532C99C6CA353C02F2BC7233F1636D14FAE126DD4433CCBB5DA1C5BD079804FC920E7A7906C9579B18D7B78824CB39614E28A2091D1194C26DFBE86462EE24FA1FE24ACA85F912404458AE8DDCC5B03A0E0402BB689ECE763D0825A8D566713A013923627115705098D63351D22772A01D57BD39566F1EF058044281C3275AAB8C44F905DEA89F9D1ACD8FC3C5E9F2DF429637D635359D0A3D91D765C71E5DA37C2BCF29F1EA9AEE40BCF69C70168BC10F1E9576CD541325A8A729566CAD7C0483ACC8E23DDCEBD1114559AAA8C6621F7A7AD11AD19D6312097C99841A84C35772FF6ACF5E1028BD5885C73C78A719FE0D63D52E9F55509B7AEB252865C6720285208786A2439382CD03CA0BFA2FF1A45B734943CA586AAD35DDCFB075538B0850551967EE7D7E1261DEDE7016BAC7E1B447BED75C565A09D3F173B5F9DF4CBD86780F35E9D7D62E54A2FEFFA0FCFC5CBAB99D2F5EF5784EC92C6A9C8DF06FD4491E197B153B084BB9A5F629E4E7923220EA7981AEDC10CCBE387725C16BCD5A4CFFB3566525CB00B5295DEFA64574065D1173DAC40340878BDAED7D71811FF8EB1B55C9E3C8BB8BEB2D011A9D6DBA1522C969314EA2A7FF20000EEFAC8F760CD24975B2CD9D37FFF352B4B13CEC723C68A595E301D02E0FD881D3286582D5472DB230F77C644E02E4FD2118592D323D93CD22E55EDAEC15693758CA10E3F215E6814BC13E2DACC05A226ACAF6DACA3B9EE91B0CD0740A5B50E6E10013407A7AC9A58F2C2D41A8CC0BD39BEB52BB643AA89A1194312A69D6245A1844A03D0EE0BD92C46B5D8EA77927C48D23107C3D498427E8DCEAEAA36E368A58EABA0E06B97532BD8D2B17A03933D6BB6E00C1AA62CFEF7C7834BB0705A50205C4EF8D3270C4A0716A59CAF17D13F6E01699B1ED376095D3F6850ED50053CB56D83A15DF12887CC06E7B45D143CF738881A322557FBAA2381B355638DEC332B690F7A2C91AD96C5102819AC027304301756A1B970378FC0C627135DB8D5F6B0B75316DCF93F0955E37193575DD0C14961D776379DAC58F5FC1150785BBBA92D1009E1B49D7E3362CFA468D539203E53FE2EDF38BA68448A3520CCF623D8427DE666CFB05E0BC25452E528FC4BAE4FCB020F4ED5EF4F2A71B9D225F7B7E6655E60877D7B7F3DCFFD8C4C77A3A3B36073A69EEE8B35F49BFA43AEC19ADE9CC7DFBB1F6A7AAFC69B3210DD8B9D2D54268336896CC79F76B441391662909A9261AE1A5D75C4F9C360AB0C19A94F3930B33ABF6EF6D5AD18ECADDB1B477C019334C76E553210D4C89E4C32DB11EC281F61A34DC4C3FA81C4C11ABA995BD4EBF44373AB98B000C9F53E39A9E09607A88AAC7AE6A1AB1E735E1D0F8F8D34253718687CFE01212B0B818030EC3F1C8F79574580A44C571456C431C52BA9DD336B1A5F8753263FFBBF6005A7AC41B11814D8CCE8CA7C6B68C4F9A56845611FD6D46C35562176A9E14B357EE8DF2B3F76950986449C0AD69B0BFEF0641CFFEE6CA5112F71E1978592018BE903F66F340EDDDF09089FB1DA7C60F76B3D92527D470E11455137D94A80082FC1AB8DFA33F518E348D50068DC6BFA59015590904AE41CAE8E6A05F2A1296D97077A04DABEC3E27E25173C60F955161EA514178875427F4018AE8CE74578E79E80310F069A611AE281EA56517083EE94B5B37A1493E614AE495D28CC5D8E5A6EA4119FF599BC8DAC4167880FB7EC2FF09007E874ACBF9CAF516CBD6E305EA8492B3FEAF23BC6571A5B800489E07BDB1F2C800BAF3E7D35B4EC997B21A3C29960A9FAA177344E6F9B9C59489A67E782B630D9CB44FB0F82922839403A85C7AD53A9F32D163A64DC226EAA21E0994B218DB931E50BC31C0E1B5651CF2098EB00153DC510E086B1FEB74661932A95116E04BF13E9E302A4CD3783C572CF52249F5FDA51AEE054682E7D3E9BE99FA215853668F015F5F788BC6DE4261C7E53A2FB9B46FAAF6C821BC64ECE7AB00F059A65EA3EA9AC7C64971F504F26D97B48817B3DF9DC46B3C106C041D1A136B4731AA2922B97DEB83A3AD798A719BAA1CC2ADDE4A34D5EA63188A0CFBD3407F3930647C3993848154841EEEAEBCDC2149D942FB644A671D50A1B51ED937765C0C2AAB1B35FC6E4E6DE85E82B4D87727BF30085AD56A27A796F53CB4D3609F07BD7645F7B32EC8B72E51592714D78514941E217E6A8A393F91A907BBEBF9804CAF5925756BB3EB09D32E125469D4413DA437C8BB4CFF2F9C23C6ABA4B90395F55E94E0113E372FDFB37E7801F0AF52AACA367BF4BF90C58D093771AF0991244B91BE5C251F9380444AA86C221D06D0BC12BD1C2DB949E7DB4A5DF1EFA0A4BD339B8F1B937F2AF48072CF8F69E47BC2E20286D2524A59F271852286AF9B8BB57C5FED3E3010743E81629BD1C366D9350DC9329BC839F7B8AD5B7E570C85EF644413F0A6974DA2CE7FD7194C30A43780D5146942339CE2B186698B8CFA564998F0DA458E36F2B66CEDA779C9E9957D987676AD23A507730959ECC0016FF3A53167DB27B2F226A2B4B5EB7A409915DD46A882362462CB5BB7C3D2A75998AF280055E9105EF6A91BFDF40FC5FD0E6E97EDF27F96872351DD3E8C28F46AAC52365CF914A32E5C21626BE9E13BF80A1E7E616022639DB2A5ED92A119EFF891AF7D33883382B554819C5CBBA093B55E335D550DACD6AFF9DF70A2A92C1BA88F210224F8F1DFF0B420B6C2F673497B86A156F5F1C675D301F55D69E5D275BD43C850F39D321DBC76B0F153EF703DEF0FE7480D5C83EB1535F0FF92A37EB637DC3AB8D7C7965C8517131F5273B10A2B5E64C16C85791D41854E43BD503F0E52180E9C29499C45CE64BD97C0BA486377BFBE1C6EA2A84AE249C8AE40CF3E86989F0379B9D02694DA77F9E73560E0F38AFD05744E0A30FEC0D8DFF8A1CA3A0EC629144E96B590FD5F75D92F40E0FC0A1127486133218B844D932E038CD1B04DF12E1EC6CEC249345EAF4DACF0D38453A533E5193257BB55AA785666C64B91491B0A5DB93688FBE07D66D926759B669E18521210CAD05EF3F8972754DEA64BCA926D661B145AF5B8090D1A4E51D9CBF8818A4EBFC8FF1BD6CF2C76B914B8A7BEE0EB33F37ECA54E2DA3CBC29F1720DBF0A024C969D4B1E36326FB6F63C9195608C68A3D7C87AC394210D0F4CB7D858A88168FCC25B79E29197E2EA3B3D4A862B70A1D7F3251C75F02D476926DD863B778059B83198414E0672AA1F27898C8A6F035D26AA117F838EC83D453A0D5C49AA350B288F1FBCE59D86C8CCC99F14A221AA18A9F300DA266DCF084910890994ABCBD8185D28BAE4CCA4BD68D4D5790FEFBD7A6D56B8C78974F9A8675E6C410F6D5F7F6D254F1C7885F48F0391E1BEEAEC7437553D480FBA79F55DD5B19C596DC2089BCF9980959958F7FB7E6DB0358093379414F67BCE670BDDBC67BC8ACE419C2E48C5B57EC624C5693562B719C7E6B09F3A309D255D0B7A8B8430F7E9544A881EEB694C7282E20EA3E1ADEA50564B935D528C0372397F26B1497DFA3D0F117F7A6797C1626D1AACEC708302CB0C0E406BEF60B7F6578623EA59A005B804C009A38E0A615F1FEDABBCDA5269C9C48E148A143562E1A372C0DB9D8F249FB5A7ABE5928B4BBB17DBD747A57D9438774BAE2550A5B205FEA96912A2FFE3FBEF1D6DF372A31B1084F0715829C141B845551C086DCF8FB9BEFB43B417AF3426BAF6007DC2EFC3B4999D2A658B5A19CC61FCB3E2ED5EB14D1ADEF650C7254F5163A2FC01B987E3000517DCD878B3D9268E912CA3675000B10E53F5B8172477AF6FE3778CB0E5D279309245647970C216E2E608E25F1C4FAED708E98E1D88193FF5DE2D33B178BCD345DAAA3ADEB8B1B6D7C3E9C2468F943A4AF0596B0AA480A159BB882857360DD34CEB848F5CF3481A660F70E49916F9A952B001E60F11A31CEFB39D3F49BF76159FF3E8B3570BBF5D759F5626B1FACEDF4AD03E261A7E095044665CE61C3359BA5A046E44C8E5506E2BD7E5C5C61EC2EC722ACD680BA597A47ED44E937AA64C0E3523F1EA891BF01E2B92D54EE9A3684A122D33ACD2A6D14133A8DC35EBE37F49D59BB4BB5F24940C18E0B4B5F1349AB813E994AC43DD0420A52527147C9A0F4729F8BCFF0941B934253B98628403937D1E2DEA8BD23A2EDE0A7BCF3A2D66FFC7049C8D2D3D52B4F9479F6652462AC2D18DEBBA361721EF71168CC59501174444B5A2E58AF71E8DFC4E9F836156C1C844EE12FCA65ED97F8189FF34B8EED18C26508B5ABD7DC94DBFD37F18A514F66BEA2AB8F02DFBEF4D54850B589898EBBE0E68E9F864D4468C96BAA0BDF1C074AAF51CD47B20784CDD20DCFC3444802DF292D0B21D32A93F2DCF3154860EE0F469CF0E8BCB4BB474C2C0F6E2F97EE8C155EF5B270FAD06AEB3336087B314915E7CC95153698BC2E486441D1484052BBD641183C9F5495CE45B270E5D085F4DF45707C7615CC89197B2646196A2F382EFBB8436E3B0A09CB2384FA6D3D7E436D19DBCAF897D8A2B3B41D17163C52CCCCE010274A70B6B985545072CC776AA5DCD1D7D1F191AB56003FCCA1F90F9488AC0C010A6FBCF7CCC51AFC15BA2F9E678B9B2D2B44DE9B7C841C386126135E1871324C9C7D3648DCB8213473E4D006FBDD976D2854DBC257DC1C21E0199C10AA0FADFBFAEE03693930F970285460EAC6BCCDB873F2AE73A173F17CF6C07C26B3FEDC0E81E8EA4FF7D68CAACE34340EF1990F3BF44E23BF65CAC9F65B50E4AB2ED67F01DE310314B56B351691609FD835399C51AD9B35E4118BF3B26AD5DAA9A0609CE6A24C8D2A1244709F770A655DF9E80C0C7441917C8329446EB8FB371C506EADD1DFBF6646E0790637395A2C1429C60252D485BD99EB641F0FBCA951DF3698F69DA2B8E751BB02BA592AEA7DD21E7B961499C0238B93F6AC1FC73DD562C80D39493800D0A0A594F26D16FE54EE71B5AA5CCD70B5F1ABC79687AA87DD986F10FDE0002EF9D964E80940FFC39C5F2FDFB81C190A83B0AAB7BB176476712EDE00F6F97973B9FC6061EB404C24993B85BD7BDB4582903BE253ECC3C10C0B65232F5F681953B179E19D4246B0799477359E0496BE7925D46065E4AC4B5EACFA466A8DB0A62F1D1AD326063C89539BBD517FC53ED562D98D20D8A7CE4FC1404B3BCEC7D500F4573EF14C99BCD70F290E6F4206E9BF9E4052A8DF39BF57BAC1969CB4D85E43FEFC1907449AAD6475CD2A7B9F962C315ED6DCFE913A2FAE5E1A695C5BCBC0568797F5154AAC68A30E0EBB8D2F73E6975440421D001AE2076AD1C65F3ACA6C05144A65D535C89243D6F099CD26C54760517EDB1CE98AB4F9E0B6E3A06B3765D62E7812C38B23D6A92ADC6CAF95A256FB750DBAFAA6D3E937BCA9314331C3EC2BFB571E0D54D3A98D5D28522326681F2B91E5BCF4ED462CC90B4CC27225742E5C2286AD1FFADD8418B9B3FD71B3CAB178F34703FDB8ABDD8F5C1461F89446ADB1175E35428091CC0A3B5705C3BC66A1916D1424D631E588FCFA838C2BF8BFE2CA2F5F6648E79942E3DA4B064A22AD6A9BB05C15228E1D20D4A4E8D041BEF83790E9707A581DBB7689E032A083381899EEF508E4B2A897FFAB447F821C848EED8CA09616CE2EFD13966C479F17E1A29D5B6F18387D15E7AB024AAD60E6D68869726EC117084D8E0C42A3A18FEE5FE427610B9311F4173A555CC3D534439D074BB8153F99EF5C62288F9CD393B0C257FDF1AFA64BB68F3DCE632BF81FDFCFBFF93A4CF99D8D50805B18EDAFD09D086D586BF8A5D6A2026084C7DBDDE343F74C964ED3011E29C8683300EFBD9E93C68EE571CD156D8FE815579D8E5AEDB483103BED689A4CEB7EA73CB8E19A6994A01838E173EFE68E816CA53CE578B87754CB34961D83A611466478E9325529D6D15C156B2E2E06E1F624139D230DD3A32A90AD2C7097F43119E10A2E788F15795548B5470728DDDB77CFD86A6C3C6669B9A2217BC37B15B8EA558D2B9E99EEB37E105700A324FD17A5A00803F41C5317FC2445C7216FE28DD0F15BEF50566BFED945796D4F3DBB97D53204D5BD64478A75484912749D9407C09D01CCDC391BEC54A4D43C9157D0A871195C731EB746F61A3F82D6F1A9807C2BD3B275553AA6CDAAE509A3A350DA3F119521A3DF789E011E59EE8138C17EDFA2AEA5C15841D25DF2E3A1FBEE40A3CD98C275AE4FCAD2708F31D7354E4059D43FC5625858721409E990F1DAE7D7FF6B3084897B817D88A99C149497599957A667750E1CF446F5D24409E3CD2AE7F13197FA6705BFAE8C1BF36AA626D524EC10CC50F77B359D718734797BA0154CBC3CCCD88030C97386483EFFACEBA41E5061B95BEF6324AC98FD576AA2A8D264D05596B20200496C54C58146883B62C9051E5F52224294C996EA6B44F84EE277D029766D66AEA021467747DB5CE0597E5D91D92903B74DEF2A7100BFF8201F70D009B0963454C25351D8D43AF77A3E70C95BA5FF34747F55049243C06C036984C5C303378D475F841749BCB2DDE91A25C105501EEF479F2B6C68A60EB8F1A308E74EDEEF93E1E34A50CB272AC278ED9263C0DAE162B7C1FD035421A2CDA9774ADAF21B292C252B94398DF63894C88C4B5529FC5AA5A18E788D74EB6126C7FDEBE4D650E2871B25F37DB9EA8AB64FD4806121F4509D4FF190439B7A8690A81275D9C03CF2B51832B32DE2967485BF84E915F7BCA7647E09863CA48B37131815DF9E5F5A88535186C40F177A06B657B4437728EFA50AA22C45E49026053B3C2A3C554F1B2613EBE50F27CEBD3BB03C8CA17B22EE76C4200A0E85A70B6DFF7F511FA2265BB7D858556213C48436D573F120D4222BB1A5C924B2EF1605B4A1ED717EFAF63AE53B070D7C62B2F8CFDFFBD18DECB0C405E7575C6AD8CAEF4789D6164039F963F807C3B978CEFE718A83A68378F9156BF52F6A3F76E411CFFD88448BFB452ECC10CE99AE5F5E303EB099B89765A377868B0B2B3A0D631264AEE47BDA8FF3A92483D27CC269B16390B3ACCE3350DAA649AB53B9C1CFF2872B6C1F9BA67D9D22C6FBE01424A7DC815F968C77BE937563456A273992579C8E6AD585A0B3D38AAE13ED13B81D58599A43E86C4B4AE7825B358C6FB94BAD7F552544790377714DFAC7F17B9B6B3BAF2E5D6E87AE0D0769A39A5580D5347C78067D7D7C375A91B066A61E124E754549CF27779D43109D8E167423F13D05093CD1D31B7E6B76A89C6BA817D852775ACA8B385138C6CC73639FDA3AB6FDC5F84CD46DA221B2D437A51B54D43D98E6D77E31B07FF420AA12FD6FA8892C4220AFE432664F946E738DFF89EEBBFC16CB168CE1721738B4A1174265AEB27FF3808A80D3BFB6CB893D1B6B33DC27239E96108C6D0D20C912BC1EBBE7E245056220BE957E7B9D49EEE6C4D341AD73932D304798F0A0F04F31D8F70DB5E06E3ED2DA627D47E0AF1C2E14E56054A87AC9810B617A52D0DB5145FE4C2BF6D0D4AFB0F9314FE15167A5AD0FBA0C1454FBAB0705FB6BBFE5F7E39824E59DA24CC67B3AAD9491E7A40906487BF895E90F63CFE6D7C0984F1D2747676B82D09DFCCD2A8F6DD158C917DB81FDBE6213FE43780DDE17ADB969B3D64CD6BA6EF1F9ECC7D6F6207280078B10DBEBAD7581A2E8C2F83E4AAE8A26F8D1DF0F8CB45C690615EA304E5CE30D2A96C55696C6B1D82D274E9D5765C3E5D2D7D05EC6A202BFD0211B534B7C9FC684C7A72C2D619E9DEC4175477792BB930EB5888FB37198A6E1DCEEE6651038F5C0A15DEDCE6D1833CDA5CE4EE61CC144E7C5202FE532E0B274F2CE4E90D91F2BAF7808D0656D5A106EE157491277F92A36239D1CA7D26150C118F9ABCEDD5470A2A0069AC1BA97ED1CA9885FDF2B6750157AA5B72DB5E7C1140E1FDF78DC7FA04773F4570F4544281C2E9627E5F59CA9740A38B452C9F3A930956187079B4EE4C91B3E3D9F0F502F8558A092630BBA965FD8900E738FD1498FAC10E6AFDF58F32DC0824B405C0E1D962CB213D4D834D7D26199B9172CCA1A36D7A76DA603FE07CE0EB070AFD90E7A30D937A32D26419A002A32AD9043B1735AD3D0696AEDA5F47046F8A3134B8D45C090C0A54C70AE992A0916A49AE7F3006165FBC71CBA5F0611FA5140FC304CF49DF3081CEB754E9E87E4FB637D7E701D930EE23B6E7A739274EC3AEB90736D91745A92DCDC5FAEF42918E63079E07316C2F9E59D8B79062F1D816C536E8323F501A20A11D6FAA241A5CB4A04F8384206C1D4BA5BD2DC0DF41A69CCD6390270FF0451211B36B489AC95476493D812ADE03FD8EA165053401587F7A18C2F3FBF4960C82B30E9C7C30EA830FE7D052DB5A191C0F8DB73833839F0D7AE822027E19C3A899EDBB02AD49EA87E1A2D55EA6B010BD984FC6C5B12289B41264F9F2F23B8761F262598692F57DE1277F48B3EBD06762F791DAC23F5A5846795B4C4806EE0909163CF27111BE948EE0CB673F0B744707BE8189B059F6D33E52AC33BEC99DB223FD42F64BE1C3E8D505592A78D5F7D3E465A5E34C1FC7D7ADD80752A83CA5CFBDD7AE15AFFE7BC0A4BF3722EEC05E54482A88287D9850672C2DCDE120E0C7AF377659E5A3313D0FEAD9B350A80F0A5A4A480346AF02414FAD52E5108B911B7A4B877215E400B3FCD4E8786E962704A50EC2B2D2D7256777111EA6646AE8A57C84B56C30D704C4B914EBFCA60FC07CEE5DB943630C0A2BE448CFD70112A56A74AFEDC4CB48BD579FEE9039DF705869A1623B1596F77D7420B59F32801106F6AD8A16DB40B1ACD82415BBEADE36585C3BB47F37BFA7162C255542E8284D8EF8CFF88DB68A47249DCD14C1D2E8E5C44E258E9BA867902ADCD588A5A382A60A580458C8C59BD5F182742CA1BD6A52F35FAC26893D74C3D74429401712918098CCC493BD226EA8A9F8C7700123924131913453EF8069237ABCC4B851B0A868015162AB8B7B63B3110906B267DCCE5659F4FCA5298C4073BAAF392C5649B429D5E378557D5CA03C9A52B6208936AE2CFF83D7E28A3274398CB3586BEE9694A14396FA1D67BFA90524574B7DCF0E8C7B86C86A69FC0C2263B437016842743E7E1743802C4542DAC8E6A23D03A158BEE47F010F71E5D9A7063E26FE8C40B208160936B5CD4D13ACD22F928352902BF25A8C8D294B493907F6794A4DCC0E7CE621FE45CC6E5F33199D798FC6E833F9EA4EA54FF6A465EACF2EAC6864D3CD0057429D789466CC60CD853B829679FCC639446CB0657C15B869BFDF27AFB572303E17FF826F8C4EE2C747AE330858830F70879FC8FD6F8D7CA2BA986E5D4DA1B613DF88CE09212B99BA77FB3E3AF7AEFD4FACB02B3E3172AD43BA87A4433CE38E45C1DA3ACE463315CF5A87B14CF4745D5282B17B613A033A9FBF52A40D8265B49A49DFFFC6C71377C20F4B3EB43FE7D89D829477619A7E5B2F7CC9FD0299C838419661773087C7BB3573568DB256F94E57423B1AC21C0662B60F526AF49629B7A8F7E833F858E5C7423437ED22E6E704EA66B26E79878EDCE376E8BB682EF83EB4B9600015217C1219224381665C140C78374B80F47511C48B5238937464F3B0A5612D2F1FDCC91B74CD861CE655CBCF22B68F657EB7D8806DDDB03B4F08E52089938121B0F6B3ECDD2D23003C889FD2F9A4F6D3D4358976641511DDF513181B1C86DE10522AC021B6A301249FB9E6DB19DF42C5BA6D53F1FBF9A7A2249C516513522F8702636F688145B52B1FB6172CA96F59B9F845760677D91996B38371DAAC111D6BC59BF28F19B4E00B5E312191087255D008FEE158A8E1619CC0674E12DCAB593EAF6C99C9CBE9C700B498697A725E2F30EA74365F3CD3318AA1D0D7C07DCA4F2F6C3AC8EFF0501F8F65A07363621059517EF1BA27310ED930A1A1B0D4DA322D5FD13EF522D21A3A7D623FC499AB8648C1AA0CE2EF94316B2965A246AD7C8869E9C489AF1FD2DA40E3D688531CF77F083F281E012ECF83C4ADC97B5AE47CC38FDB41C7ECBF402AD42716821AE404A1D224363958B9E71DD4B3E77A16FC80598A3065E8E00F36F2DF940F4E99902A1D62D73470FB4923D3A46EF07E65D02963E1B5308121675F1C1973C656549030DCE1BAE145C7712A4879E2F3E219B72B673243BD71442B699F3A4E366C7B88C1266330282D0D9357FBCEC2F95AE54D87A50C8581597B0C24C2F77763B326A55EE924C4A492307610526A864CCDDF6FFC64321D570589BBC5F9CFBCDD95D0C7AD62DEC853875BA2F3C5E3FC20CFF99FF86539F37EDC56643EF7D70D0025B395061B83A100E1BE1D6096D007DC42082D4E793CCFB79CC5A06242518998D835B32B7E579AA14806AEB8A4F19E554FD72D2899617541C6B86B63AC60BD7B6185A7A86BC7702CCB91069ADA68EB4F117E239BB7A9581A56CAD59A618449EE02E2089CE3A1B97B22AE34BBB421F2194B00B80F1841480577415436FCC20FD60731E6E28138A320C9237FF656A5366890E492A318EFDAB7F22CDF81AE5CE56539034A8790E942E58118A8F141B2FC6E4559A04B9EF8827BB7C11D5A4CDAC22E42660082AEE184078053860369D354552F1CB9D798F3FDF657648A7D5BE4F41E6141FBD80732B6D3AB57C0F60D38848FD33F7E468BF7600E16F25B9552688D3AAE33DA731DFA536059D24AAD21AE940CF31E18A40508DD1623FC89EC11BE4B852EEEFD56C002C1388DCD5C54E0524BB681A25E076CFFF94EA7B5E0A0B7DA1DED8DBE3F9770536FFD43BB48C9E55E33554E5C0411BB823FE16AE3CFE51DFC9177764955DB39B08C627F74A7B9A16DCDCAAB1CC31E37B0D3B90ABA2F1EC00FD2EF6E4FF3A15358C551BACB93EF59361567E0834E72383F4EA2E8F76F000EE38B179F7F0F9A3351C5BFF81B49E8A5119C6CB5CFCF49A6875B3A99CF14E6CBABAC0F4F38FC97CBADE13BB807CEADF726AD565D65334539E879575702D58462BB2A7C7F322A16F3F1C4FE116CEDBA6094EB4712D774B8207189B700C8B84FC7D0DB49B02F7AF17A6270BD75AA54F8A79E4A1A6D588FEDF94C0829EC1496988507C8C5BB87A70DFC3FF6C7F985ED38CF6C23E04FFC8001C2958B5E0920B284A4A3A55023D13D4FB99D392A0F61281E6DE6AD1F907788504F80477B8C21454E4FF16236E42DF95C85E20DEC39B2920ED49AA540BF504E74627B678097B4EC800A37698C32118BFF564BDE9BE0E4B16A3D91A9A83FBE991DD88E7341BA96976F7694323E523B76DFE3C52F28188C8D64DFB1341EAFC98C9A28CE446C4983AC52A1C38F9CC5D8CAAABA4E8BF9B7E45E3521567A46AE5166642E89F8503F892F522A447B2FCB1BCE2EF4EC86E22F48FA99555DC193F080D3F0096A47BE3C2597FE83A27E8132D28EB55AE87B36C93F31A9E371BEF51E405037DBED6CC4916E5A855116586F7C34F33B3EE626DF600644EC881246E32B5716E9580A1733ABCB22346C4414E5FF2C085E2CBFB45BC77168F4164B7CECC874DA5594F6E8D0B7B6B36EDEEDA1342672A4D6925CA2864B93BC7F63994F8449929C3206E086738FADF14B1872973A6093B5916E565DC3B354FC544A44202598AC2326C5EB9F305C448CF68323DE4C5BD28472B340E43DEDCA0DC290CAA47238A7A26713869C6B4237D40EE2743BFCE74E5CADFC183B14075FC8088943F3B2E93FD3A96ACA364B9292413B2B67B43C855A898F877683FFA238C05E6F789ACCCC40C434FFFA494F2710C3DFA213DA7B56D5A4C273603ECE648F3E9D6E5DDC034C1B684A22B4C43569169D30694DA2D259C846541CD1FC1D4F3553DDDEB5650C0207248DED91C549B76BE830383E8E158E188D78CD90E7B03AB56FEAB895A3B82C1709F9FDE140EF89B847CF556D8D40BA06511E6B003080C2A9FA8E9B43888C41965DA5B6B2225206AA998AD1BB76E38DAA65F1759EBE6F4E301AB3B59D217FCD6C08C626143FE4B176E51D1B66839600593F01E40F7DEF55A9405B5F3E816E59039E3528A724CF0116508D784866E2FC9864778D5BD5F25DBF3C8023DB6AE937B028A471165990FED36BD793D165DA1A4A836FCC7B9039CE4375344659432BEB0820FFE1CE1DDF984FDAD61284FB7BF551CFFA91FDD3237950DBB9523C478C56AC1D0B5E7DC0BD88548A1946CB98BE05BAC55BFB535391558FA57EFAD67AAA9456D0F9AF82567AE1FBF375F69ED9B30324350C6FB4FAE7FEA4E7BF7012F515076835FA348D9ED6207D9A21A471AE1D5E036801694BCBF5268776EFBC9020F5101055D97EE9EB04C5CBFB4D9132855E2B0DB7C4F4C26B97A7B8DB1C2433BC12085E0E624896179924685837CF20258DD9D5F698BF4D1E5203F6CFFAACE82379CA26B15603786CE45AC18C296B05919A834CA0EBA4855F63CEE3BCA8FA2AD24C07D3B7B9F73ECFECABD9306C647F575D7ACC30ECD72329D51B7AAAFB919C0511DA596C23A520D9705BB6C5A4969346C30AF6D53D5A9032E04D1F960B87E0BE110FC1468A4E657BD55A832476E82A839B9B44199B12D51D3642F50774A9490BA404470C54A9249E772BCBB344597CCC73FA0919C4C67971C5195449D812F7A6979279C23B020C6801DCE5472B66B4457F56B7B0CE5C9AADB0955180917A72E93B10F4EDE8691ACA70109399FE9ECAEE4FDE5B687836315E7F16FABDD3FDBC2004D9ED41008D0AC77CE46DB9E402C14C08DE7C0AF9EBC927D40DA2D7C7DF9CDFB5DDAE39743E9A15C53A7999B3B35FD329FE1002975F668A2307221020F884388C0649E8A6EA76027BC254C948426CA44628071076E4E5C77C7F155AB517C5026032052792533A29E6FE7CE81A20C68786F9315C73A430429E2F2BDA55C4E3C09FA73081E19166F7F0359FA6B078F1B4EB95103698F9DF7610E30B3E801AF5BEC6D262A2B8F1D1EB0D00FA8B041F6AB95888643EE9B00F3E925455A0ADB35267FFA9E8354BC69AC46E67106979EE5B75705D80550D7173CC407A4201127FCCA7A162F00796F46DEB7CBB36311A900248FEA298EFF33A3D645E28FD183B230841F4D848A1FB51A7319D5C1474A05694C06741CD15B251FF33E95F18DC944DA035532E1F27C654C302FE8BFC7D8CB5541008B01AE4D5E7C2A09E4E5D5C5B314B67DE4A03BEF268203ACF15A4F9A148E4072710AD9C94F78A55784558C32F3A2E513E84E9B1299FBE18E607FF547B1619AAD1D63A1C761DEC8A262CBF89714EFFA189ECAFA723C81D00ADC10B09B4F678A6710BB3C64569F731E7F1BA28371905460C7E1C877F398422C48D8232DD5204089DEC49108CBA8DD493418DB492BBA225FE73C1CAA7D91D6638A2662F114A40CAC9D1D6AA16E67E0DD281EFAC4D883A25ADE30D9CD44FB2E2D24054CAB5C527301CA96B020EB0ECBDC803B9C1FF07BC50CF6921CBBBC757A2EBA28D307F9B67C752443A9859A35E14B25EF675243ACCC36641991D00E03234079C0B53E8AC99033B52967861C85D548D25DF927EC74C8AAFA5F78884B5443D8F43591451494BC12F7CA33BC42C629EF0AC93F11B942F4C8250C4A4411A6B14774EE772BC485E2C676746083A0DE3EC7D0894281E09686D13A7E628A4EEC1DEA1F847698086CCEB661AA10F54755E8E7553502F5F0431D91DD4D66B963B213D615A0DCECF5CA6195EC9610B92C3FBE750E3912180D33E3F04B29842F61CD1454CB4D0302F2BE905BE49F82F470380492429A349CE86B0EAA2E305326985321D35B1AAED5FD3324D12EE14CB3FA5BB739696228F645A1E9A9063DFCE147C2065BE5E2E7741B20B29A037974174FD42F0796CA07764153278AF8707320DD6A820EF2A72EB981A82EACE9FF55179554DFFB3F8E1796973E86BAB1C22848968823EF74DA3977108CBA1FD67EBA4170539D24F12087F5954E6FC086D915A2037E7BFCE97A394F987EA1D6FB7DAE67765939991E7F2163C33DD20950E0F00A4EF163CA7A903C0AAE22A6516C172D54A73D4EB181DEC2B1BD62671562D60192F32844EC777DB3EB698A8575787EE699402A80F6E2AD283A6EF387C23A4102463C14E2EBC5A0FACCDCBF0E359263792DAE6DCF0E2EC202ADFFA1480357A3B722DBCFBFEB8D341FB67CE96AE936A36D42113F298E3125289FD8617DC69536B2E52BC81E903A7E72CDF15A0FE289C51C35F5A04237B797D1E3E71E09FEEFEEEBA7F14A9BEE50D4ABA48BB2F39B0E6702AADC8A93BBBF9496A15C7F35AF67415973BB58626E9315042019E1D35F768D377035870264A1806AE7A142ED4FC9A3EB4A9F54185E990889BA19EA36961EAFD483802AE4AA6E7FB34B1F7A6AE378C229FE154FCC476AAB6C23C524877DA7BD994F8859B7B9DE9F841EA055A56469962133E231EFE161886085944D70F07819D4896F6E63F5A20F4EDA06DD45EBCAFEF5D5B384E7F0B2DD10809D9B84885385C12C5345DBE856A4E2513277E576581BFBC6D73F085314E0AF1D2A3364532D4EBEF4F8F960201DC635731765B4FEFB8D13C18626D5D4A955B1FAF6E5D65B87CEFA18B021B72187365C45D6FAB5B2A4AE7060C5479124B5F5CD2E6D6496E52BDECB9900686BC6DBC0848C8E71FC9D7740405ED290C5AAA70A3126A4040C5966DFFFA6CA4D20BDE82441C973D7E639F774C806964B00221ADFD7C60836F032E794DC6B814B9E36EAAF0AC330407ACA11305731003502A578C9DD2556400086DE1A137176E752AD2A0BA318FC09DC51977725ADEC2F5CC4D71BB2AAA373DA9EB4A01F5E7DA252F75FE7B94A3F80E9EAD1863D1A478E5E6D63702D7730843AD460B0522D28F9EE1F5E6AC01DBE3CDF91F291202C4FEDA136CA6899184C53A94B2A2B2F027760875ADAD89484F21305226C8AB81BAF359B9A9399C4E71E343043B41FB814656E62A49F75D72F8B70EDD2B3AFE68C0449920ACE28BC7B4117CAD1B78A0ABC4069B742CB4781B10664BE256B345925FC0E56EC16437374426D7330716AE3F4FAAD02FD5B5F7C01CE23E9304914C8305B39309B9A7AC172E0C8FA63812A11F4A4EB5338CBFC2287AA1490D8166BD1866CE08654BDE8069D65EDCED448117EEE3B3C69549CFEE04B802B06567FB33D41BA1FE380CAD9B3D3F732A6D065F84B401C78DA3684BAF9A559A548807ECD23CD0B75EB36AA7350E23756FBC96BDF49334FBF1ABE26E165804C5627A08B11AB1DE840350BBF7FE153011BB1BE7489EB5A211FC23BA240F5ED74AA2C3E84443939F4728AD938391C6C1CC808BF9EE734E81711868D986A1616E3CD56F1A61E1B339A057688C74A3FFA6BFF6EF62022D21CD6D7729746463A520065B66CCDBDD296771F9B5C002491191EAA0A72609EEDAB634DD69D328665D6109E9DE6284018DBD25F77234C556A474968445D85011E09E31A17FEE95798508E7762221BAEC3D6A4956DF1262A3B13B967154E369B26A70C16838260C63979DC56A02BB1E3953DEE601E69F5467F7CE20C1DC799902C391D27635BADFCD73242DB995F7B6CBC331BE00FF871DF5DB0F2A497B9B06DEE8C77ABAB0B27F2AA4FE1383668A8C3DBBDB9FC21F053171ED76E797F08043204E2FDFF63760C15373A120A95F9989194AD1D5126B4C224F0722AEB2327AFC908A6635BE840BE589401F1E97858FBF94B2295930A490117755D298A5D3E417ABBE3EAAFC8585E76C08CF7B563B2DED16B40538FA4267CDD3B3455783035CBF9258B5503F4F072D7FBF60DCACA6DA5AE3482A3CBAB760F774720BA86DCDB03E38B75F27D6DE9C06BE33B8B68983DDCF453802BEF21332B1F221BF653F58331116E31F8939F51D8FC63531DD0BADB161C8ADAB525E6DFA1F8C84C6A2AA557330DF4DAC68DFDB1D29344869792FC6E4AFA247A3DF68EC505CC8770F7B4805F2A8AF534629BC61C92A1B1C02D55656D7A19115C48616F6C813248C20901FBEF34EC0DE8C429174040458C3B431A62D2C57CE4BA13CA80063DE7BD6668384FF7CB02629C967538617C4F58E4CE1B2E26F09DC7F51E9C3548D9A99016438D9F98E2C7FE468BB5E4CDE479EC24936BE7CF353E185385BC82E7ED9A11C3193C00B923587E98DCD268AC6035FCDF802B733497FF41CEDE795BE3434A5BEB065297A701A24EAA026A4A95B5DA980020C77714A463521794DE232AE1A538FFFEBDAB46C8A6A660A338F932184DBFFC9ECE13B8A8D5808FF2ABB614C39444AE701828BDDDB7B91446894E323C9270763AB3DF7D0A4028EA99EB3823D64625AFF2E01E381ADCB40F1B7B833296CA35F17EFF716232FCA154ADC289A1C9ED14AC0E527E8243BC3540357EB5ADBA8800921611B48A81EC2482CAC88FD4693256F4755700FA47DE0807D29C71264F848D907F9C5FFBFE2581503A591C0ED2711EC0EEB80AD335F0E6435DB9AD543E6A1F881C52F867F51E5280CAAE4BF63BB222DD7AFFC0B1C5C63DCFB19E3F17AB415BADAF3A8396F15C20AD2B5A6C8603CA70742FED3128D6F9C52F3A8CC7B8473643FE4C54FE696885AEC9C1A02CBA04C5C81A4844E927DDF668ABE9A083B84FCFC15D2C747BEC2526CA293E8363F1B495CDA2573DE1BE95D2F5882C89CCF61998EEA4CF5002C3674807C9800D652AAE2A0210DD9C206B5D351C5320DAA89A79D025A365396BBAB9EF785BD4485B5D59E9A10559F3C6F7D541119DEFA26CEEBF7ADF3A0CCB0F1EF2ED7367F2EC87B335994041923C1924798925EF572912EB5C3A344B0F9724632BE4011EBAB92F9423514B19DCABA93A4A7C8F51C0EBEFBD86E50DC6820DD61C166A52DCEC9BEB5230ED209E9BC839F6F16C7F0BDCAD1BB429C8FB4403AE3A72304F178FACFEA00DA6ABA89ADFF21CAD65BD1ACDFF2F8F5AE0D89C25FBA430BC54F8B4C79A159E22750395CBF2A8296C49A74D1AAF4AF55E6A52445044C948F43E9E49CB730267A2AC636AFA84F96F935E8BC021A68CA506272C4332EA472F5A8DEBD98A002CC8E4332B542194C34BE4F493572C563AB7C44E93BCE4AE67DFFD6FED96C3F3CE2470AFB2DD4A0FF01AD6FD485649B1F262CF8C86E51D41686A9E71CDA534E02ABA6C832E92E3B664F5205509B774211D8634843245D3553D8912EAB493A8825DE21810ED60C61C3C51E702207308509BA05E78E6DFA755EB4660944FBDC0DC8AC53DAD237DB0C9531FEC555425F4B1198A2C97F75C588E490ED7806FE0EEC48450D1EFFF90512343BCF48BAF528E30F3AC1A3BF72EBC51D872CB8990435B35189DEC662F45F327CB14DFA069624F20DA2346B2C556C9AD4F692A739829F4B967054AC1222F351E7B81454AA5D594304361BA49810FD0C6DC469BC9137AFFF98D0AE0CC13BACA774394A1575CF01339CEB8085DC985DCEA36BADDE80E50FB8BE1F6165A5B6976391A6468815FC70C6A5976109930414FCBCB070F469446F0B71DA220F64D800695A0CCFAAE22E876BB0B283C3DBCE83638D571102E894F9DA43C9B4C359063DDA0B86FC9C7D45DA126C7F06E2C9ED770B17E57E860B03C64AC7E9FDD8ED8CE95E2DBC2F51122FA2B6730151B144CB6C82E3FBA42C55A5405AC1E023840771F8EED666662AF35431A463BB569839A4871AA21C4817A0144A79720F530F32A682743B9C01AEDB95FED48C38C9793F59C2098E60779293D0F8E20284C2267F03C085303AE010171256C4787EE88FEAB7B31E269142887D2CCC30B8737772DED1A9F671556BFE43A7C381D764B6318A82DD7FFFD190222B5A33F79232EFB1E767E6764A9FEFAA5165B7645FD10D7E30C735EBB49038D582E2DCA81BC47EFE21514B20795DDFE04F114C7AFB4F91881B8C03FD368F3AC30437269B521FFDB8DE0D978CA78D28C716086F58B2767A2323D46172274BAB8DB92814987D9AE26BC0140361E4528877C2C66668F2F7A127F63F5A43C2964894036C46F90A673040FB198DC50D9866BB956364FDE3B9BB6F2E9274D4A6E05AB919609FA3DA339C75A542083E1D6CFC6AE7D40C1EBE4D9AD9358AD16D392E78C086A682FC2CA00E386764073A121157F98A15C7FADFB9525D581A7DE84DF9B0293BC1B7961BEA4A894FC598CD76D6BE49CA389D3C6D06A4E79CB682BFD8D2246D1BBDE5E9754AD3B3F5F6A8DDAB708CAFF40909EA4DF53753D1DDE1C8C959F939DE10DE4CB937C21111973B890AEC27B06C8DADFCEADA3A211FAADE3411FD5F376CD1752B91019C3D9AB949209A344D24C5F4432B6354AE4B2631811990F49E16DF01DB78577132348B7D5A4157E60D7DF14798C8B606A6240AE45D6F1448314AB98AFD0D703266671192FDBCCA33B67A469D1F600F51C4A75BAADA71838D74272B41DBEF720DF137D57F208C195144527958F7EF69D6AE9631E899DF15B8EB560E372A5618FE7319296204A68C97DE9BCAB00296957F7A1955C8EEF4484EF2617E73E5783F8A3DD61BCB40A2F2C560CD6C8EFA96A9C58B73E0D654A5C016E6C776BA3D9D13D78CD7C5B640BEAEDAC87B16D12DE8BF4BBDF77F04A917D70046C285D6CDD3AF7284C2DDB5AA9016DA50207D2C28F52CC0B924D2515271BD986DCE5659D337FD9F2D939E192E310BF0D3A00CE794F0DB51D912630E4F35A04D94E7D9A2DB86FECFE8D799AAD2059D7410D1F2FA0DDBFAA343946A16CBE0D334C8DF591C890B3EB764E29AFB3077EE99525EF898C7B3D460CDB6B8B6F42D1A62813AA0F5179B95AA5291E36345059CE4066F9A2E8AA9411A70FA0D9E51BE77C21A5D7150411086CA188254437C9F5857927E6551D4D551A930D2FF7C8FBC0E5D9C03F584AECB8EB5565279F63AC74A1E9DB16EA8A0F4B6D0845372BB842A2B08A96F1D9A16BEA070CA72101CABEE6A2B17D5E33FE91C134D0DC7CF8A2F019937101D7C02EE727A56587E440AF7D82D036D5A124C1268BD6E32D73F896A9EEAE3B67517889E2EE99BDF8960A857B4D494BAFFD01E098B1C7F95B4A8A205644212A171EC485DD2CAE014962F15B1557ECFA9205DAEC5C5DB83D9B5642C817CBD6CA12E5B56650990FE46842C425FFE5C0C18D4669CEF27800A7A7FD3F34944B63BBE4EB0A41FBD6D0FCA12CFA457C72B122EE5CFD43429E9FBE78A38FDFEDF58724519E0550EEAB0481485453FB22FCA1C0A4FB3993B48166CB0B7F88A1609FBD833A866728747DF88B798DCB7BAFF64458567EF3419C9A659EC81B8329920496E82FAC7634BB7936AA6A467FD8971C061908A0F63F52E847E9D7667FF8C7995F457C4E0DEA5E9E8ECB60E8EE3BBE3CF55321A6E2E33C6FFE922AB56E6C494445451A1A0A9F144A0FA330AFDB58D3BD0A1D0166D6CA7AF21B86F0CE184F0BE6F1CF84609AA79E8D59D5BDFD7BC69A997E3D8B51B4C9F95165D9A451DE1342A736053BD21D538F9B1A43C9CA3621526D031344B51D5DEAF78F85BDB8BAB5CF11D6AD7B1F99DD4E90CC6B4B2F524ABB33B50BDE01D046AC09CEEDDE4D32225EAC2FF4D5E6E1B4D391C3A9D20D542214D03DC25462B60E8F5D80EC469FAAB57E4AA15BA50F94AD559DB5FD02FD5E334D5988C82EFA9B94E0A347757B81ADDF735753119350C0F3E8F3657BE5F58D4EB1E51583560B0775CDADE003C320FA6650D69674B3224318E8F51A17B4F3C9A5F9B3D9C1C3F6AC472D56EB9CCFA6FF592E8397BB30F558F12E290EA0333A6A0ED58A2EB1BA457FFE88888B610C9015A7DB11850D49011898A40E01C98A129DA9BDA8C64827879842D3966619A0388ABD88CA787005B7B69FE56066A0AAB8BD9D28ACE6AADC728E3EB30E16E4ED6C0F93670891CCCF18CE0CC7822E9CEB6D9E6B2B4F0F2DCA5382887A81F7CE2AEB122F0B7429C0E0D5BB32E53DAC5094481A2385D9F65B2FD2922F84D03AEDC4CA79C4F81F0A73386FFA7E5FE5B41D1571C426D88B18861FFC16311D61DF54F123A65DDCC2A6A5380F396C5B532A657BB0A97CCCE2F7D8C46096D0883CB16EAA8C57087678D9AE57D502E9C693DD899435DFC44F274B5F7F67A09F9C62AE0C08DC225B65983E3FBBC014000B51E3AC1B6290F135DE1FD32C6B6C049314DD7546E10A1EFA5A5A715D197B27408FC04AD61ED93A1FA08A764D2932060EF61ACDBEBCA8D6A16BB146FF0F6720BE6716292D2351B3F396B25015701B1827A8805204678ADF18AC38DDE4E2B27C6B1514BD197248FA9E88655E7DD20EDF4C9060653CE3C49D3B722514C421D0DAAB0CE802C7DE6A85C247B9DAF3EE936FE2823E13632FA91B9217B749DECECC7B4CC5A30168E0661CC142B8C62D5D056FEFA683EA4B06C74AAFA0170685D3F60E68CB0CE4F343B5F2900FA928557312A390F6744D47DB83D2B1917EB736B68383A90A14011A3C5EF48C7779E5BB6413824DFFB0B584420FCA86F7B798C33F790535EE0090E7CF6A0BBC0FDCA5D8A157748B4FE5B1CC64D9F1FEC367AC4D967712B7193F05058A35D7D286686AB611F1C4807B8F6B95BC021BCACD7EE59156710476C0BC628C387C1ED619BFF0FB68593502CAEC6996845C28489039AAD9BF5F0BD92776804ADBCE3BCBFE5F9F4FAA49DB29E53F6D047427A874AAE9B37A2FF7E753B7C712BAB4B128D88420CB0B8AB746491FBD4EBB70CE6AB653DCBE5A175E92D94DDACFB6F13094DC4205EAC3F85AC3EDED83C86DDEE0A9EF785DD42BEFD4299B5F044EF271571E5DB7D5349E47F14CEB297866621578F976DDD07F01698F8312117532CA2F68F57420F77CB85A8E0F1408ADAFB96D6BA04A0E6269B9F5D9121959617885F4F75E052D09DCC32C91F56A3E86832F6764038B61CF1DF5E6D588CB1028FACC7F99AE4082E5A604A5BAAA180845045993EACC930B64AEE680A9ADAFFE21A271721A3771EE60B12B85987CF25265D0ACF2C6FB55E762E877ED8E44266941C47F410A5698102D7E263F8530FB0EE9A26E0E5603A189CCEEAF7141CAA1467A523948869C47F4E2905E7B48A468FE615643E66BBDC55356E395381FC0C747ADF495233356FAEA046F2C18F2DCA0A7CE744C110D0E0B2DD861BB5080570DB0A2674C5F177E902E171C6A96BADB979A5DB94CA8F73BD8AE70B43C3F8E2B618097D2C796F7F92DC56092A6B0D863A04E2F4645C4817E42AFA9CDFBACF1597341DA1BCDF29F38B37B8BB135A937EC8D16BFDF3B5E1CB4C335FCCDF7F71522E7BF2004EEF77F9B73B5B69216C4EFA4DBDC170132F2E0B897A8D5DF9866CA80F54342B024ADF78B550DEAD9E1642483205723024A15DC37AAC36EA593E152A6F7F8AD2A985AABBE3F1171E738FAF2594370A0C330CCE5D06E23EB942EBCB8F68FA465FB98F8FF1604A4AC4A286629AD3AD552032A49FA27774734B8C8F0DB2DD6A28C2D4DCF2E07BF1969AC4A9F218939EC685DAD80D848A8F6E803DF90A4BD133EE88F1013942FB74E19333B4AE530EE5E7752EDB8603D0D9D962A9CDB3D2188A610CE5C6D71D6A508446BE79DAF26B866DB6EEF1ACF5A995C9EFA9B33256A9582DBB4773BBAC9DEEAC03175BC18D283E76A8815EDF736F4C3217E810807BECE4442A002B71F87F6BDED77E5780FADC3AADB2FC146788D4E7F6EFCAF95213CF7F954C210754A3E79164E2373306C87F9814A07F155BE50F9EC2968F5E9D1A620240DAD2FCBD7521D8A875F8C50E6F86DEFB1BBC6ED7E8A9E434BAD73AC655B507A7F306A1554E73683BC5626D9EBA5C68CA9017AF81F74DB79CB2C594ECE50A73C8AA927554A30444D147DB937D5664D480D85FD560225E6DF2CCC33FF2C4EFC13A9E1116A373EB9CE1A064D10DF412A0C989FDCFCE6453AF69131D21DBC2B0D2EA5690DD4C76ACE68101E8C62487E06B303B41538A6FA71F264156E58E3BB29726E527F8C2E0E8285A9600FECE97E8FEC1C23F3FAFC6BD9D87067888B619328E25178198ED8CF2EA8D064A7B4B3B23FCC20734472B21D1E953024A3EF48B6379D632663607D22B81D3733E5E0A91F2A923BCBD91869BC51392625D0AB03676E6F2493327BC2F3E22C372BD1B6F9B33979FBB4F0EAA539E0510348F54C08C8F15AD4164AE7C8AF54F1C350AB9199BCBDDB54F4A346345F8F3D2418CEC1ACAC26E0AA592417D341A561BBD234FD5592E98308464AC5075B12EC1CBBDCF6D755C1B7214DAD0D68B2E031001216D0F0E8C458ED8446C81C6A689E776128C8327153E8908A38DB062520C4674773AFAEEE925B3C147F2573BAF628B90451CD169A7CE7CD110E54FF4AADDF92D0BFA853BFA03DC7C4E56A0A9807F3D17461E018C0CFB45968788D8242B3F6BC497052C272A1D1F9AD87DF0AE450BC9CFD342C10B6D1B644607C7CE3A26E8502C3C511B4958AC2064F9341036687A2F60C1415484D044B9C1B311EC5DFC5CE73D419FA7F2FDA6A69DEE46B8B53304FFB8C6B54C28524C3F85AE319DD339EEA6EC82DB6F0E71A52ED1032A01E00E9197843D5D6CC394CD826938E3791CAB36CD64C1B96B9139B761FA05B7CE05B548AD6AF898EACC9F41EEC6F4913B0493C22354CF3FD33D7CDB1A77823945EEFF0FF14FE286D8C6C94D681870457EA2B17EB50F15F3A4FCC15D3FEE02C1755B1311C8AD40A953FEB72429989F20465C0614826D863F0F2B8B6F79506D1F4696049B87DEE0DD4F9572EC64E7DFA4E2762012D5D7501399407BBD1377A99D38BE5523D286BFE047F15A35470262B8AEF766EC1F1044BE8E8091E28337F2E6AC3CE60230CEBA94D7263F17631E7BD5AC570E4F8E9DB1295C47523F55AC69BCB6E700C96275D622DAAD8FA5EB8AC2D8596C66D9A36921AC8876DD857DF0CCCD9E995B42B9B4A35E2173167FFAD52C3EDF245E1F309A39463EE1AACB6CE436ADEEEADD3F23CB7A046AC04B1975643D26D8947B99BA98C8115AEFBFC68AE16161045F4AFB151FCB9A8B99B48DA52A16DA615960743BFC8D37DB87BC5267432EB1F3B2B7CD6BDCE900D18C7DEBEA76E74FFAE48AFB2B2F0D93BD7550EED69704645586760AB0D7A4E1EFEAD9E32C11FA3D2941403A4928F52608E56DA5841B23F9ECD188588D1E06595C8096BD8BFEC4C8026D733E6958366140C45E074A1FDDBE5E660287157668246664C17701CA69FA30AC21E2C66EB6FC2133ECBFDA9053013002A2985376E8C64E3DF2E5A1ED150A2A77DA3E48749C2FEDA06F1E4F2E13344348FCF64587B3DD571FEDEF9435C00D6B9905EC78C3CF2E2275B1CE57CD54281CD7B2653618793966DCBD52213C1DE648E00866BFF9879685D91367FEE3A0C860C40BEE995D1F83E3DD8A18826B2BB1394A3DC5ACC8D32ABD88AC3883736F1A87F1207ADC1DC24314AFA573CEC977E9CB9A872F42228CD3A3A1F2CDE0F5B48AAB9F8E57AA4DB21CD76CD4F6818DBFA5A6EEA2045FC4A5FC94232700411BBEBF3CFA3A1EA79DBD80B06A1756910DFDA987316433548788243EE97A2CA95E48FE04EC9B94409088D1A174F0C72EB9CD40C68F01185090D53C8314CD4A1E3EA7ADE58B834634D9684A9B7597FFD0F94C63E4ABCE55F0DBDF098BB25E91DC34E12B87FE7990E7F42AE93D3786BBB04EF4557645971CBE15361C9CA0334F7BC24060E7719B302BD30B03DF4F6FE0E4704171622F698F49A12A2F275B54F189D3CCBCC985E3484D6CF116B48838B7285FF2BA096B1D5922F3CE587E8E01E2D52D810E8F4A043E8E52961423CB4D5598DB0956D5571701CFAD3D7D82F6880C5DACC062B38B132B860E67D872C6C13B3A058DFB5EB2514D20349A672D4CBEA53A0992E4DB48DF060ECDEB36AE029F911F2D09C56C26659A3AB6B062FB87DAB85703921BEE6AB6753189ED1E66A6D114E98B09413F8D07C8056F393431A3CEDB33E90B8C599D41D1E62E95F4BFF1B95D16F29DA210E290E623331E35D0C751D82C935CD554F17D936A690435447DA2C31DFF0CA9A5FC732E9A9F2045AE04594F36DAE29EB90ADE939D701491E2F5EF7B3425161EBA828083733742B7D9CD69C6C51E9A574C2130C92C + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 27688 +sm = 00000000000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6936812CC6477E4A34C890D220F2C0ADF50811BF03F0A198DD1EFCE9B1BD475ADB107005759C1AD991FBACA5F12BE25CCF5A487CDCB35D2FA0415A48AED18AECF13077F648B8C7435CE755907418C55379857F06E2F7A61A232B67C86AC1352B9C6DFFEB95D5F828ACA606136DCA17F08C38DE5AEBF9CAC54646BF3B7809882E94D6C58C88F8FD5C2C018CB53B7BBDA343D9B0F76F9057BA0C56DE12931A556205430682E22AC918051D97466B12D2FC559413DEFAAFC677C8351565ACC58D4813CDA3DE3DAA746040AF1B2C23D07DE37701C19D709600831D7D504B9EE5726175C867B0E080333CE315D72777219B6350D39E366D591FE3ED9EE9EF63A3291ED55C6DD4C888FD4C8BDEF806EB73B632B3C27697F2410935EBD0B4EB7D4FE85D9C2BDAB9A5E9A5FDF318AAE6D462D982DA995A71471994CC82E5A293A2228BD645083110E6EA40E37B74D165AB9F394E7E8C66143A319C832923A83D13133CC09F74706B5F89A6A5C36351181638BB36F11309C672B7B4D234CD7E4537489406FAAC07D59B03A06086E043466BACB5E4DDAB7AC7F43409219F27561CA6168DD17988266C9B2D49652CB8CDEC30866F81F41B8F6EB6C6F5DDAE07C5E405A42EC217E50AA87CD6E7083FB9309F7536D7CEEB80FE10ED59DE83E6CBCF832280B1CE403B410AF91DED3E66AA5A849B0E9006B97005A133E7BE66BC295473961DF6C5935EA50DC699D5233C7C07E22FA98EACB905820F49CB77A44374C0219D53B7570BDECDC6DB095544CECE9268232729556E6339B9B8A2F22FEEA16F32E6FBA55778D3E7D9E51D6E5B2E8BCAF0DC0AC338EE1AC30758672A27DC09A9BE38957BAAE5F97ECD8B86028FF8FEE10503ECAD7AA2C80431D97F2F60C7E0AF24FE782584921BE921E1C2CC0ECBA29139E304A0BDF7123670D3FF614F1F0E22C7C8E161E91A68117C321B617B039B9E959026ABAA73BDB8BCB6E852AC7E661E2C316BB3BD479B46A3C3D7F58A693491E85A75DC3F8DD5BC0124C3C811236F16D02FC5A46E77215A1A303D5064C11C7DDEE11810F33E05292A78CDD6F8A34709B56414A4CB3247AA9757EF13771EA5BB3CAEE6D93AFA18665B2B6621EDD3C961C151179A97B4CC73FDA4B0851CE702E085953B9D195E13981E55CCDBA1620CB5DA2D599570A30BD9FC3023FD9559D895E07980FC00563233B57946EC04F8FC996E63DFD602DC132C6C621E713C34F333AE17767867E6E866D96C29B3DD48C7DC7C519070C9059B394DE8D15BFECE1FCE1884860BE12411A625BAD6A8CD7A99C157C62AC36B3A2F7D8C162BA7F7F4601025685E59E261826B1D9E9A9AC5B4AA1DD947CDAE896AE82981B2430CF17DF5F99AEC8A7B6D51DA7367CAA8BEA46AAEE4571D657D290FEA3545B757A7FA09AAB8ED0C941B5F91EA0A89DFE54737A37267760AFD2CC84A9F6A9548A58E119830C4A1C28BDAFB0F94E7539D5F73E2043018B8FCEB218AD24D0B5AF139DE4BF0968A70B206EDA0FF3324096BDCB13A3DA1C550639C0606508C1FA5D4D8C57C4450C792469FC166C18EF0134760323FF8BEF4E9E16C1C48BB565F6F3F7774A9CE75488FBA6FF0205FD45334A09906A3774718DDF36BB668C0E6EA958198FD4DBFA834119583E248955DAD739F078DD240FB8B5A3642BF5506B1E2CC30E6E7DC45BFDA37C100EB88E44069492CECC82E9E4EC8C7C2C9F85B00EC8AD191BF0B1D8C6D027A7C176BCE1CA7CBBA0C336D80411D9A61A5E4D093FE138ABA2002AE12DD317205ABE4FA332FDDFB4AAE669A71A0A6A402D3E8DB7E401A3F8FD69EC9C4AD644FC10F73E8D4EAA8D202E38A3609D1034E9A9460341D702019E62520710B50C76A82229A1075E52F918DB230C481D0350A33EA0E6C8A2D8670C1C475BCEFC9106350D0DFCCD2D1E46187432CB18B46F12AE9BABA851D30304EE94F6647F707A3583CDB82837D280DC501FE49B9D27AE13D5796BC047F5482AD8837D9292111D56E88AC70930176D14EE75E771DAF91316664D9F6F84B4509B13FB00DF87ED2BFDEA30928486A9363A6559C08A4ED761F5FC89A488B81BAAFA27919CE38E7D5550819CBD0F02A02420FC3F10D62E2E1436804B7F12E6B451A6AFBD1EF6E49CE8FD350DE872090DE73F0C124AE014920F104EC5BC7EA0FCEBE08F20F05310687E973E17F1B39B9436F1C1BD5CB39C7641828A7CE9326E53AFF9DD828FC436A9C04183ECC25BFC1E19A6B2C5CB182239761D25ABCF71FE3C2D1BB52A35052545FA899B73D5DA8D6340B3C2794D4A24A4FD388C8581C384407EA9429D048B67D56B413B9002434DEFA4F2F025658778DFCF9BF148E70A2A7084AB49FC4849D497AAEC8FA2A8C8DB244001F4348AE47425932E61A64C79846C2BCE8E0D611E1C6993589B529400771332F16F123352198A4D6872CF63F4401ADA24D8BAA8DD8A433AE2F58F188C064465DF6ADF6E57E982A8D5234D0F19650FF52D3F474B9AFB3DDB2C7606402D32BDFD91415832B3C3D22FF68DFF183D81F0811A8EC2C94C40AB226519C8D324F3069F4ADC08211A716C181B1D47ADFB07120B152898366FC0906F835ED4B9FE9A776EC249F3B7A73C8ADD42D2B17B5893635D1C1F7665FC12087A0DB4851503264508C31852B8741903D43BE0EFD469F89F28A87041F739E13504103A1A8324392800C0F640D6A7D75DCE2D69607864529BFC4219BC6D76EEEF5E7B592DBE80AB3D19CC9500A8ACF148F75009E4EEF81EDA55DA30A254D0B3C2EF633F5E04CDB10A20311D2846AB24749D78FAB6EC47F89E4A338CE9B8073DAE5D30A9571B807D43788E72A7A499DA5589B7C5BF91173A9A573A7CB1C938876CA58C9DEE64B7EDCB6BACA85C9E20AFAD6B68054B862DDFCEB991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EA6B7E3BC14749E7C7FA2F28480EFC0784B9C5FEEE217946EF2D55F5FD2902B6E01B40AFF393D6177502756D15DB5232BCD58ABDB633EFEA7390FF8BEA443BFB32F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D265894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB939E6518A5122E37D4C257B0A0FD60CE0BA3BD55C9CBF369DD315A3C0609933D25DA403DF7E69FEB7EEE64DC3C13DC83217C2834B42876862CD48E99E69564B336506B85FDB493CF8FA87A7FE48DFE6778DDE8E8DD066FAA745C121480B5BF9D5F301B358D18FCCCBD24069E71836981F168FC49E6A4F27B00F6259B183B62CEAE0BF4AC0F53FCEBEB9052C0B48EB0666F361C5DA674B20B06AE2EA8783C2DD7EA74D98AC98C55748A368DF5B433C39538365EAE8DAE5E032A2008768FEB01F65D001AAC437781F742F536EFE2B3AE59EA12A6DC7F2712BA2D9D1C253D29B419A765985ACDB42BCCE5D64F6AF8368A5D122BB16B525A80C8BC5355A53917CC82262254378CFFDF1C7D6355F114E4FC013A5E4DD9AB373A0EFDC470854E20330BC00960ECBE882098D6D0D429A7AD19D3E5D4B78AC5E568C722A21877DA617190CB43123FB04333FAE5846953E33407080D04DF1417E740E7E7A14B0E3CA7D5B693F9615E1F7D417B9004F28D5002325B851C31F5EB31E1DAA80E6CFF22F11221E5180BB050888B6564A381E54401AF9409FE12A818B69BA34E1916092A0EBA24457EF994A1B0028649C9803045EC93CF416373F6A568856B771C3BB076AC265045ACE8E9BE3C3074D8806BEAA3B8B21F7E37F50B16221E14FE5503C615A13738CCDE39E2395E292119959CF686532CC3C9F9129E62ECFB43A091B06FD48ABE8C2CBE2D9691C8907881991CAB9D0D9CC7B2699F2261E5D799D26A7C8A4AEC40789B34CF5FE7BC8D24D6F0BBA7A5870E37F4D9B2605BB56ED9BAEB780CC74097DD8AA8741A97E22EC7B7434F81DE9D83CB9816A33C5A79D718C76A3442FE50C68FE1CE7AF728F2177F88E5168D4668518897AB050B57FF42AAC731E484B440D0D7B254383C74BE41C2AAEC02A8D8C7020355C4A1FAFAF4BBF56C74D78949D087259FE8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B179B32F9F94BBD8371B973B19E60C3CE2206A2061C7BCF159BC3A50163924774BB13C708A573472DA73B4C78DB30FEF310EA3643BC75D9155762D5B87809E2A727AC0428B746801D693074ED5245F29B8FF9FB782F2E57BDD89DD700EDBF12E8311946CAD9BCC98E3B1D581E678BEB1D0A6EFE15CF4052A1AECD328B2C4A8D5DDEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA36145D1653D108813E42654CB5350FFDB33BD2FDF4E416C6C0A61784E2327F42B2DA2AF040822C291D63645B0AC2377D0DE3FDBD99FF9CD9AAAE2B978C4DBEA95E330E90EAB0C4C34E88855C7C62C40B231AA1A9EB409D18CAA1C612A98F1B7BC25B18E3A89CAF96AA4BDF12F865EE7DB20273D7CA11970219BE997DD0EDE7A8ADFECFF1D90984694EF152346402207BD7D9166DC1B09F3C3520D109824442B8AB08869B0A4850BE3227E746998925CECCB422C4C05047D890E291B4E5478967A42BEEE34BA2765D86D183C71FB6A3CD86EAF457756FC000FAFDB24AF3C968E547A5223821BABF91B31B3F970D9F7C1FBFD16CC63D14243DB22CDBC266BFA4DE4B15D23B17D34C674649A695E80F84F6FEBAC0255BB155BD8B8D46FF7AFC532117E26985D99B0E23345F9A0247D834697804C6644501CA7D2726DA563C7F02371B5CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438DC67DF57A5B11025EDDC8915C57C8C72F6D6E71978496E206201184593506E39582DD2C803CE9204D2AC833C35BC683E0BD3CAD30BBCBF584AD38DAD30C9A400DE22F0CD6199FA6C622941E79F8C5C500389E9FBDEB8E1C926443B6FB0313DA9AABB163F5319C0164C1E58864827E38C18B7ECF6FB44274CCCB84B10F1A1BD76C8740F479777BDD7C557DBEFA9415B7FD50CA659E304EF4FA22680980D0FCEFC75E36231F740F38E9B4AC55BD8307F8AD9FE45B046B7BFF0F1B9FD5EEB82D474DC311A8418BB27CFE324426CD3311D65513B0A4D58515B94B8EE5ACC6815D6D1246527188E7B6C579CE42B28E1F273887FAFAA96D44FE6830E96081ED562FF4A08416DE4213A89CD666E2814FA290A5B1FA5AD6DB86B9E4DA85486E11BB36382C13607F50EDC83909F47A7D089CFEAF4680A6F2F10A2D9D9A679AE82D2DB387C5B7BCA11161E49E01C28D0FB7FEFE1C9A4BEDE994DEA4087F3B74906EA8E49153ABA49BE0F35C0572E9CE0C68B2267884C4BC4AD32BF28CE64DC7C825BDB2D8561C69161E075F48A40220159BFF1C4158187D4DE23C85979304DD4DBB98BAA57DBE6B7C55C271B134D61906F6ADBA4639BCAD3C1A70DA04A9409A4A35FEF1BC103D4F17BAFEC37C3F108B31327E0FB227E0E2C5B5410726ECC93B56D4D153572C2DB4EB4757F5B2232C475EB9802FEFB53EAC7BE6A090AAE98027AE13D2B338442FE6EF2DCF141C4D1AF00C7B3E973467FADDF6F1950ACF2BE908FED354EDFB147D6AC4B0740F87DE06E768293CC83AC995760FE0015CAC682036CCABA9C86B9B06924369E35688F7255F5D5422AB808D023B150D62D9A7DE4F7A5D28689EB038E9EF9D3366C3D777AB6D1C33878327018CC51EEDE65BB5FEEFDB1442B9006C76B10B6CE9EE1B6E43306DBB0D9030E3A191DA24634A80063F6A5269E77543525E11BCF02DF82E5921E3225EC97FC5F9174E0225E8C5D08B4C093EA28A19D03E908426578661E107E5E2C5371D79C31F11468112A6050703BB8FD9ACDEEF8D0BC31E82FB4F7DD0DFE8AE0216582E6C86FCBC1E7B3FFDD921F220702D827F145D79D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CE8D216DC6F19C3AC0A1017837C31D76ACDBD48F018A1CB14E98848B66A59F09AE22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB96557964888EBFCAD45C491A2A3C44B7085FCA7C983EA4AA22F62B99109F6E425CDFF5D87105EDC065810CA3E055F62FB80F5CAFEC57F7CB47A95B14A215714FB345FC73E57C1574E38657755CE991FCEEDC5ED84824E0E4AFD43205E126A3402910DCE16C59C8840FC7FC5ED9FE6379F9A388601D57B366FCF44FBD2D0C15A3D8A4A28D71ADE5965C137996748EFC7FB68ED165D2480FE34EF58A3169D03D0395D94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB08391412A812DBBE4FF09E10661B7DD604481AE6EB2F89A1FC04E393B3353F7547AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6222D7DC2F78B2E3FC4C8CEAE02E3FC9D7972CA803061F534D39E4F02809C7A18A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F9536829157F62BB003C2E45042DBEBA9622508F9AACA5FE89F665A5F35BA7C26D93A84F9DC744354C73885BC59EFB657317594D34B561FC2A789C919EE08D5D68185BFB2A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E1866ED93157270FB47C81CC3076E5B381E6B03127E7AE78C54F5F35B2474F18A2461297462FFAE651BDBF3D438E30420A3BA5686483DA2EACD874CC44102C09319C10FFE87AB2099A185DFD0FDDB6393B2F61490D65F93CE565C6575C877246044FD52ED475831AFE194BB163D0FE5A023BBC435497C3C16C8C7A85FF92426B59E588978E29EC0DAD032330035B797471B74BE366FA75D79D35228004D3231654D5F301D6597B83258DBE9284121A2BB21EF66F40C17FF135201D18092FA6A72B511A456786ECE1FCFC986A28C744DD4DEBCB552C638043B0602343CC796834B13660A86C5E3CCAAA1845C5165074AEFBA7C52190845A95DC59B1E8D6B052D253EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D1B478E24D9EDAC7EC8816FA54DFDAB0F181E9E1A8A6CD77A9EC29B3E35544898EAA311411BA22E8BA6418CF252675917A88572E0CE98CE03457996BA4FD86D07C4FA2D3487400E484F4CE0A83CF490C49588DB83ED1EE2A93B78101144586427FF43F434D3A40268920A4FA3C64C0F5F4600A8E52E01CD8210965C4B212DCC942C68D589D21FEF433904C26239698EA85C32423EF7AE1ADC90744996C956FD5D0683674010173EE4A110DA2642C8E1C4BF7B5DD3DE268A3AD0A261A30AFB6AD7D54210702C635C3E707CB1F17053D475A026EF57852DEC1FDA4252FDA2E69BA95C866BD432139CA8A4E367960F85B2FBC75420737CA4843B89F053192BB086BDC0D739B2753DBE42E1D45877097F3B97FCA6F43AC15DF883C3B42D9F472F910DE579301FF7F57D9857890651B64B6C1E8A7E2227ACAC7154D97252EACF8BC5FF430E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD637170756688D9AD3002B3148ACF0009CB1C0802EB04197FBD2FCE168B5FACDD052DD46F9F0B0A34295557CF741102E7592C24FA56DEDA63ECB7A2149E406C0943E5E554767D166EBC95FAF0E9B20C1E530633CF8BD7AB2A66CB105E108C1793B0D87ABBBBA9A4679A05C94BE6A698F4758B8BD38C51371C8043FC79E749D7E41C04DC6D815B0D32A779D0AC6E80C1D56B03C8EF30F6F6CB73A089B149F46BD4671D7C13B41A5B1BCAD94C0552C12CF23352200198CD876615EDDA7257E3CC94B732D75AF6D67A67929458E2639BA4A2967D05F76C4EAED429AC246CAB410B0FC8806B84EBFE1159C88D6E71EDDCC3B956F33739AD9FF6C43168B54FD592D845A54307AD16E42AAD4621D33A037D47D1002DE1AE0BCF2ADD9B01895EB0E63742FCBB5CFDA14EC9C63D94E3387E0FC22FB1B93D9065DF33D03AFA7D156BA719EB9DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF1DF5023719932492A5EE2B7A3B40B7C7F6814D179AEEFA584D317D536645921799727CED4C3D658D5A425D2D3EB1359C975FBE1A2FB2D11F37098B7234A19628624F07698EC3658799436DB5CCE6AC18702D4F27548F61BABC4807826E95D23889575EE119A88256D4326D4BBB48D0F589C6CB22E7F95D49F6607BE258753A6120CEFBC2E6C502138AEA689B4EDA13FDC39CC0759F392860168C2BA881FF70632D05E797A4F52453418035DFE9D072F0593E8029FFC25D75FC7DE13309B0AE4509D8A315C31F0FD0F480B598ADDB0D5A8F945FE6C28C2421DDB4A0DEB478478A49D5E628799ADC5E489FBDBC9DD38686EA7943969A5AC97497B2C380CAD367A8DF3DADD2E31F759AFA47A422D2A5F7C44CCB028AEC63EAA0727231A8BB4FAC096D19BA50AEC9522A00DDBEB86ED6DEB298AB433CDB7B4F15EA4AE08EB01782B70CD59C57D485848B16B9C55BCCECC876AA99071A9A7599868A9BB42F178BF3DD0FBB7EB52A796801D67E250148584C46F3E96898AA264BCC3826317B5BF7DFF55B6F3C3F3929FB552D79FFC1D014C52965F50B446DFC1CFB3302D8C7367A6F64C93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B787B24028E369C59743659E28980F3776146D88956F5E02B3E3116B8292C2E578C8708D4B518B95E8FCB7C7D5C3B16EF976B20FD0E53DCD6D92301061F2588F693A84052F8C776D033ED7A5EC71E928DD7CC7EED8DFC585AA94D8C9CF92D9694377C0268A53536DB64565FD9F5652B0A3634B381121BDA48C2D1FD9E189991D092178D79AEE8333BB0EC988417AD6CD9DD0DCBF6EFDB0E4E8D1B38E2A3DD01B3EAAD55E1CCB1291C87E2A835E86D2E0C0C3642166D2E9BC98CF354E28B6CD3F121606F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174BE4D5805F128D4A9B00266CB6CC792C45CA4E506C8B2504D13AC93044BF3FB3357F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B82A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B275680E933FB83760E66AB8BBCD67108A95111001B9F8E85B6C96B4BBF952517D6330EB1C6AB68317C91468E90237214C46A5F496EE46E2E8069D65797581C01BA0B2DD1DFEE0F95C0AD7E426F877D0CD294CB0F3ECD1C65659D20594153630E46E4A32CA7D3B408B33227123C6449C4644192BAE44916FE60256703EAB9B2821973C8A37F2FC6B3B18FFE0E4C8036583B7E63E60A5EA8FE89401C8633BDC355FDDAD733A74922E73333FF9B2F9EAE2ABF957105197D92E7CAA56F91767E282E0910608FFA0E651B882398F8187E5203F8B56F788A4DE4130D211BAEDBE44B1DE0D729B926D5FBC98A1FA9EF01E415BE3795F085E28E1B32F86B0EC72DB22414EACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E947CA8092F4480FEC3CE1D8A6D8C4CBE3F7EB35919888B729C1CADAA559A42E1BBDA600C713EBB3487FAF3CCCC40CAFDEAE9B9C6EF40D5041B83973133A03156CE65E33173CC6EC41F0061D31797BF2D58C95B5B4E218AA783E09AAD39682072C6EAE7C52E3491E8B0345D3F6DD019D7DA6D9AE08FE40461B81D414B8D5BBE0672D892793121DDB345A2E5B1F8F3EECFFFEE5E425834717D59506DAC94BB9F31F00AC84767700A6FFBB6D93D4A9FC6F02C67F2710269A4162C284E0D9BF486ACFDB55A33CE915B41F167D533B268F96CE0C70A54377A5A76B1C8E992BD4908F6C9AE1B8A1129A6A94F2C1FA3EACE58297AB6E83568F0857FEBA399FAECFAC9FA94217BAD28BE66B04EF4EF7862DBFC7F9D86A69D63D84665C826910849A959626B2F95B16FBFAB29A97876BC2F43A43F841F6161648AA9D1689D67A4BEE2C859702320B726B0219DCC859A330C6C337AF2EFB0B9C8C689D2A7B92DC615BEF81F9488AC5E678E63D3E9C4CD4D2138F500D7967745773C58A8704107771E6AC93AA2307D387AF3CCF853E572E74624A7E40305FF4F57266A6BFBEEC78BC8CC981479D5A80F351588B5E378EC89F193C02A92E5BAB45E1C12BE0DBCAA00E85E73FF666690C4133023ACCD88989AD44530D63D54B090E115F6A25111B4F006B0EDBC73FFCA5B037240E88F9F4FDFF79F6874B6D6865B3B93037E272D66F1BB1EA9AD7952CE8F8F353C2910FBFC6F73626986970C6B1FA3F7D010A7DF2AD27ED28F727F9B6E10E08E9F23278C2C6ACA482528DFDD42021B690D777444DED9C912B2CD003DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D5023540D6CD04777ECAF4F4D58C64C158042656BCA7DFBBA61D7551154DC1535618FB3576C6A634E79E80BC56D4A77A32480711DCF387CC963BBC7A339C907928DBA6545BFEA6878A58236DC95D439F8F3061C099AEF80CB7128E0C1D3AC5841B65C0A738A16BA2EF4649CB510F512A819CD03BE1174182022DDBA30AE32DB5AB9ED29B2FCAF259886A4E479D5B5C118DFFA5529CF83978DBDC1B233C410279CC031E0EFD98F95DF6A32C1FB854F7DA54F12E0D0078F9287622542E551863DCB0B534DCA8EDE06545D0860957FF3A0C13495A47A669355FFF55DAC93C3357E5FC17274ACFCF9905705D6F32C7C6E6FCAE6086384B4939C70128CC73540E47ADC633EF01CD9E59A14EDC10AB0A9313ADC2123A4F3F3B4207CC9564D39F7CE86184505C432B568E4CCAEAA1BB93EFE4C696CA690F4B4EAC21A83E1860C5F26C6ACEE315F139E8C7543B2075D3FBF446058A1F0E0DC7893D9C78FB25914ACECE4664F58E03209D0EE1FCA892A9002B32FE67B0CD27E60F35706FC2BCE8A0F77E89FDD67DCAF4073DE5B72BFB56A87525875B0E27042175EAC158AB2D5A7B85C041FC13F81A9E78911686B33488DB258E31630B4D779F6F40E079F5094D31D70E74F2220ACCE407CB3491B80DCA95CF6126E9D2E955683F0B6BBA28885065E50309BD5E3429C626D547A87ED33769F9BFBB514F8792EB90F90C956F0148B9928189EE06BB40CE18932DB44AD96E226B6BB6A313DDC8CE4FB50C6C548BFA794FDD1EE7EAEA2F119CAA2E0DC7664B0136EE7F50B88FA4F4B1F0A665F36C56AAECC77D637637ABD7EE25BFC8B638430370B0F92FADBFE5C4F166A0B1FFDFDABA98EB3E5D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3C1578D7F6DFBFF09D46817D7C61EFDDFEC6AEB1A21EBD5AF1A0F399A2096C8E30821DCFD15298AB26911D40A97E78421AC35B6E8B47C483E1538E1C110540E6B23095AFAF8CCC9883C1BA2810AFDBC488849BF8E2BD2B63AA036BCE1BF9E6FE84C7C830C65CB9870A441512C55557F371276F3CA97910118271DC35F5A46454B02318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3FBF9F7DDEBC0995B90104C717FA2977F9559887204B56298813EAEFCE587F9D2DF49378B38F71833410D667351B1949CF406F18B0727666AA94DE7EA90B093CEEABA95EEE4D2DB043CFD3504F59CF36374C48E804535A76BB8BF67DFB39E03CE613D53D7515BBC8DF04062A185B7825FD3260B1B377B5D3CF470603B1900FC978329FE4F050A62A0440FA26E9B3D2CDA32E7F9FCFE6446B29FEC3639F068E56D446765B606D7B4FDA46826E8BB9E3FE9ADD93EBF3848B70C759922B63ADAFC8E71CA051A07FCDA3126BC8B4EAE41DB2031017A6794C6784FD8B93672BE6206ECC5F1396078719C45CEB31BDE4A3D503A56CD1BA60A875E2A5AC7CF340A79F261480A2A36EE4FE88106DD0976B8FD47010119D6D21982AF0E8E58AEF1BA68D4BF979DE633E719AAFC7A6C8AC6D127BDABFC3660711DAA2962D639D46747BC03BB269789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411923F9FC45FE90EEA617A4971AB81153088F58B488C507F5C230586CF967833C9A0DEA1CAD7FC139A9710382C46136E4F4007BBD729ACF06FBFEDFF5144533FBFED92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE598186E4905539B32F01DF3F0FA65E08B09F4F16719DAE9A987DAC3A28B2B9E001FAAAD0F03810E525D26529CBA1829D42796B65515D55BCD2315DDDB342591BE8E217286002741AD99A1565D106690A5D6277539266747D8632686C5C9061D5119998BAF8B6C09E61D13B2D91426AB98DDECE3EBC2CCA03A8B6591E2A1712FE71F847F486D6E177932521D9196CF0F637314E2329A86F733D95CAA0C2F7F08FA45A993F52B44077712B70116CA4A7DB6587E24BFEB70AFBF3A6F1A33F469D98278A6603810F6664B9BDF27388FA8C69CDD4127B39AD97A6E2432E3C2B6E0087EEBCCC54DA43837F112E61409D225BF5E5222DC107D698C0E571EE8D532C99C6CA353C02F2BC7233F1636D14FAE126DD4433CCBB5DA1C5BD079804FC920E7A7906C9579B18D7B78824CB39614E28A2091D1194C26DFBE86462EE24FA1FE24ACA85F912404458AE8DDCC5B03A0E0402BB689ECE763D0825A8D566713A013923627115705098D63351D22772A01D57BD39566F1EF058044281C3275AAB8C44F905DEA89F9D1ACD8FC3C5E9F2DF429637D635359D0A3D91D765C71E5DA37C2BCF29F1EA9AEE40BCF69C70168BC10F1E9576CD541325A8A729566CAD7C0483ACC8E23DDCEBD1114559AAA8C6621F7A7AD11AD19D6312097C99841A84C35772FF6ACF5E1028BD5885C73C78A719FE0D63D52E9F55509B7AEB252865C6720285208786A2439382CD03CA0BFA2FF1A45B734943CA586AAD35DDCFB075538B0850551967EE7D7E1261DEDE7016BAC7E1B447BED75C565A09D3F173B5F9DF4CBD86780F35E9D7D62E54A2FEFFA0FCFC5CBAB99D2F5EF5784EC92C6A9C8DF06FD4491E197B153B084BB9A5F629E4E7923220EA7981AEDC10CCBE387725C16BCD5A4CFFB3566525CB00B5295DEFA64574065D1173DAC40340878BDAED7D71811FF8EB1B55C9E3C8BB8BEB2D011A9D6DBA1522C969314EA2A7FF20000EEFAC8F760CD24975B2CD9D37FFF352B4B13CEC723C68A595E301D02E0FD881D3286582D5472DB230F77C644E02E4FD2118592D323D93CD22E55EDAEC15693758CA10E3F215E6814BC13E2DACC05A226ACAF6DACA3B9EE91B0CD0740A5B50E6E10013407A7AC9A58F2C2D41A8CC0BD39BEB52BB643AA89A1194312A69D6245A1844A03D0EE0BD92C46B5D8EA77927C48D23107C3D498427E8DCEAEAA36E368A58EABA0E06B97532BD8D2B17A03933D6BB6E00C1AA62CFEF7C7834BB0705A50205C4EF8D3270C4A0716A59CAF17D13F6E01699B1ED376095D3F6850ED50053CB56D83A15DF12887CC06E7B45D143CF738881A322557FBAA2381B355638DEC332B690F7A2C91AD96C5102819AC027304301756A1B970378FC0C627135DB8D5F6B0B75316DCF93F0955E37193575DD0C14961D776379DAC58F5FC1150785BBBA92D1009E1B49D7E3362CFA468D539203E53FE2EDF38BA68448A3520CCF623D8427DE666CFB05E0BC25452E528FC4BAE4FCB020F4ED5EF4F2A71B9D225F7B7E6655E60877D7B7F3DCFFD8C4C77A3A3B36073A69EEE8B35F49BFA43AEC19ADE9CC7DFBB1F6A7AAFC69B3210DD8B9D2D54268336896CC79F76B441391662909A9261AE1A5D75C4F9C360AB0C19A94F3930B33ABF6EF6D5AD18ECADDB1B477C019334C76E553210D4C89E4C32DB11EC281F61A34DC4C3FA81C4C11ABA995BD4EBF44373AB98B000C9F53E39A9E09607A88AAC7AE6A1AB1E735E1D0F8F8D34253718687CFE01212B0B818030EC3F1C8F79574580A44C571456C431C52BA9DD336B1A5F8753263FFBBF6005A7AC41B11814D8CCE8CA7C6B68C4F9A56845611FD6D46C35562176A9E14B357EE8DF2B3F76950986449C0AD69B0BFEF0641CFFEE6CA5112F71E1978592018BE903F66F340EDDDF09089FB1DA7C60F76B3D92527D470E11455137D94A80082FC1AB8DFA33F518E348D50068DC6BFA59015590904AE41CAE8E6A05F2A1296D97077A04DABEC3E27E25173C60F955161EA514178875427F4018AE8CE74578E79E80310F069A611AE281EA56517083EE94B5B37A1493E614AE495D28CC5D8E5A6EA4119FF599BC8DAC4167880FB7EC2FF09007E874ACBF9CAF516CBD6E305EA8492B3FEAF23BC6571A5B800489E07BDB1F2C800BAF3E7D35B4EC997B21A3C29960A9FAA177344E6F9B9C59489A67E782B630D9CB44FB0F82922839403A85C7AD53A9F32D163A64DC226EAA21E0994B218DB931E50BC31C0E1B5651CF2098EB00153DC510E086B1FEB74661932A95116E04BF13E9E302A4CD3783C572CF52249F5FDA51AEE054682E7D3E9BE99FA215853668F015F5F788BC6DE4261C7E53A2FB9B46FAAF6C821BC64ECE7AB00F059A65EA3EA9AC7C64971F504F26D97B48817B3DF9DC46B3C106C041D1A136B4731AA2922B97DEB83A3AD798A719BAA1CC2ADDE4A34D5EA63188A0CFBD3407F3930647C3993848154841EEEAEBCDC2149D942FB644A671D50A1B51ED937765C0C2AAB1B35FC6E4E6DE85E82B4D87727BF30085AD56A27A796F53CB4D3609F07BD7645F7B32EC8B72E51592714D78514941E217E6A8A393F91A907BBEBF9804CAF5925756BB3EB09D32E125469D4413DA437C8BB4CFF2F9C23C6ABA4B90395F55E94E0113E372FDFB37E7801F0AF52AACA367BF4BF90C58D093771AF0991244B91BE5C251F9380444AA86C221D06D0BC12BD1C2DB949E7DB4A5DF1EFA0A4BD339B8F1B937F2AF48072CF8F69E47BC2E20286D2524A59F271852286AF9B8BB57C5FED3E3010743E81629BD1C366D9350DC9329BC839F7B8AD5B7E570C85EF644413F0A6974DA2CE7FD7194C30A43780D5146942339CE2B186698B8CFA564998F0DA458E36F2B66CEDA779C9E9957D987676AD23A507730959ECC0016FF3A53167DB27B2F226A2B4B5EB7A409915DD46A882362462CB5BB7C3D2A75998AF280055E9105EF6A91BFDF40FC5FD0E6E97EDF27F96872351DD3E8C28F46AAC52365CF914A32E5C21626BE9E13BF80A1E7E616022639DB2A5ED92A119164A3FE6DFD83DBEFCE4CFEF2250893E21030934A382A288C69BF0FC7E9C92280906A4BA331C652BC4F904B9B54DCF3DB0651E43A6C83FB9843F85F0DBCA8D2E7F492200039906CF62A95D7B1830FDECAC0306B1A98B6F7B399E406A172202E29FA157E168F4B9C6979150F5AC2EF7769E4A729B6D59DD8F944E9A4A118FD06355D19B28ABDF256B4390DCD5C098DE989678AC25659763FC22E05FC4EB5860F4EFF891AF7D33883382B554819C5CBBA093B55E335D550DACD6AFF9DF70A2A92C1BA88F210224F8F1DFF0B420B6C2F673497B86A156F5F1C675D301F55D69E5D275BD43C850F39D321DBC76B0F153EF703DEF0FE7480D5C83EB1535F0FF92A37EB637DC3AB8D7C7965C8517131F5273B10A2B5E64C16C85791D41854E43BD503F0E52180E9C29499C45CE64BD97C0BA486377BFBE1C6EA2A84AE249C8AE40CF3E86989F0379B9D02694DA77F9E73560E0F38AFD05744E0A30FEC0D8DFF8A1CA3A0EC629144E96B590FD5F75D92F40E0FC0A1127486133218B844D932E038CD1B04DF12E1EC6CEC249345EAF4DACF0D38453A533E5193257BB55AA785666C64B91491B0A5DB93688FBE07D66D926759B669E18521210CAD05EF3F8972754DEA64BCA926D661B145AF5B8090D1A4E51D9CBF8818A4EBFC8FF1BD6CF2C76B914B8A7BEE0EB33F37ECA54E2DA3CBC29F1720DBF0A024C969D4B1E36326FB6F63C9195608C68A3D7C87AC394210D0F4CB7D858A88168FCC25B79E29197E2EA3B3D4A862B70A1D7F3251C75F02D476926DD863B778059B83198414E0672AA1F27898C8A6F035D26AA117F838EC83D453A0D5C49AA350B288F1FBCE59D86C8CCC99F14A221AA18A9F300DA266DCF084910890994ABCBD8185D28BAE4CCA4BD68D4D5790FEFBD7A6D56B8C78974F9A8675E6C410F6D5F7F6D254F1C7885F48F0391E1BEEAEC7437553D480FBA79F55DD5B19C596DC2089BCF9980959958F7FB7E6DB0358093379414F67BCE670BDDBC67BC8ACE419C2E48C5B57EC624C5693562B719C7E6B09F3A309D255D0B7A8B8430F7E9544A881EEB694C7282E20EA3E1ADEA50564B935D528C0372397F26B1497DFA3D0F117F7A6797C1626D1AACEC708302CB0C0E406BEF60B7F6578623EA59A005B804C009A38E0A615F1FEDABBCDA5269C9C48E148A143562E1A372C0DB9D8F249FB5A7ABE5928B4BBB17DBD747A57D9438774BAE2550A5B205FEA96912A2FFE3FBEF1D6DF372A31B1084F0715829C141B845551C086DCF8FB9BEFB43B417AF3426BAF6007DC2EFC3B4999D2A658B5A19CC61FCB3E2ED5EB14D1ADEF650C7254F5163A2FC01B987E3000517DCD878B3D9268E912CA3675000B10E53F5B8172477AF6FE3778CB0E5D279309245647970C216E2E608E25F1C4FAED708E98E1D88193FF5DE2D33B178BCD345DAAA3ADEB8B1B6D7C3E9C2468F943A4AF0596B0AA480A159BB882857360DD34CEB848F5CF3481A660F70E49916F9A952B001E60F11A31CEFB39D3F49BF76159FF3E8B3570BBF5D759F5626B1FACEDF4AD03E261A7E095044665CE61C3359BA5A046E44C8E5506E2BD7E5C5C61EC2EC722ACD680BA597A47ED44E937AA64C0E3523F1EA891BF01E2B92D54EE9A3684A122D33ACD2A6D14133A8DC35EBE37F49D59BB4BB5F24940C18E0B4B5F1349AB813E994AC43DD0420A52527147C9A0F4729F8BCFF0941B934253B98628403937D1E2DEA8BD23A2EDE0A7BCF3A2D66FFC7049C8D2D3D52B4F9479F6652462AC2D18DEBBA361721EF71168CC59501174444B5A2E58AF71E8DFC4E9F836156C1C844EE12FCA65ED97F8189FF34B8EED18C26508B5ABD7DC94DBFD37F18A514F66BEA2AB8F02DFBEF4D54850B589898EBBE0E68E9F864D4468C96BAA0BDF1C074AAF51CD47B20784CDD20DCFC3444802DF292D0B21D32A93F2DCF3154860EE0F469CF0E8BCB4BB474C2C0F6E2F97EE8C155EF5B270FAD06AEB3336087B314915E7CC95153698BC2E486441D1484052BBD641183C9F5495CE45B270E5D085F4DF45707C7615CC89197B2646196A2F382EFBB8436E3B0A09CB2384FA6D3D7E436D19DBCAF897D8A2B3B41D17163C52CCCCE010274A70B6B985545072CC776AA5DCD1D7D1F191AB56003FCCA1F90F9488AC0C010A6FBCF7CCC51AFC15BA2F9E678B9B2D2B44DE9B7C841C386126135E1871324C9C7D3648DCB8213473E4D006FBDD976D2854DBC257DC1C21E0199C10AA0FADFBFAEE03693930F970285460EAC6BCCDB873F2AE73A173F17CF6C07C26B3FEDC0E81E8EA4FF7D68CAACE34340EF1990F3BF44E23BF65CAC9F65B50E4AB2ED67F01DE310314B56B351691609FD835399C51AD9B35E4118BF3B26AD5DAA9A0609CE6A24C8D2A1244709F770A655DF9E80C0C7441917C8329446EB8FB371C506EADD1DFBF6646E0790637395A2C1429C60252D485BD99EB641F0FBCA951DF3698F69DA2B8E751BB02BA592AEA7DD21E7B961499C0238B93F6AC1FC73DD562C80D39493800D0A0A594F26D16FE54EE71B5AA5CCD70B5F1ABC79687AA87DD986F10FDE0002EF9D964E80940FFC39C5F2FDFB81C190A83B0AAB7BB176476712EDE00F6F97973B9FC6061EB404C24993B85BD7BDB4582903BE253ECC3C10C0B65232F5F681953B179E19D4246B0799477359E0496BE7925D46065E4AC4B5EACFA466A8DB0A62F1D1AD326063C89539BBD517FC53ED562D98D20D8A7CE4FC1404B3BCEC7D500F4573EF14C99BCD70F290E6F4206E9BF9E4052A8DF39BF57BAC1969CB4D85E43FEFC1907449AAD6475CD2A7B9F962C315ED6DCFE913A2FAE5E1A695C5BCBC0568797F5154AAC68A30E0EBB8D2F73E6975440421D001AE2076AD1C65F3ACA6C05144A65D535C89243D6F099CD26C54760517EDB1CE98AB4F9E0B6E3A06B3765D62E7812C38B23D6A92ADC6CAF95A256FB750DBAFAA6D3E937BCA9314331C3EC2BFB571E0D54D3A98D5D28522326681F2B91E5BCF4ED462CC90B4CC27225742E5C2286AD1FFADD8418B9B3FD71B3CAB178F34703FDB8ABDD8F5C1461F89446ADB1175E35428091CC0A3B5705C3BC66A1916D1424D631E588FCFA838C2BF8BFE2CA2F5F6648E79942E3DA4B064A22AD6A9BB05C15228E1D20D4A4E8D041BEF83790E9707A581DBB7689E032A083381899EEF508E4B2A897FFAB447F821C848EED8CA09616CE2EFD13966C479F17E1A29D5B6F18387D15E7AB024AAD60E6D68869726EC117084D8E0C42A3A96F5B92139A4B5768CDF2E35810BD1AB3BB40DCE3F38853783F6856552BF95A4A835590582BB7206044086C1CA3BD9B8ADFB09C40A838DEE80E1B3756F98073651454C1567EBB9BB8D9FEA16E9CB0F30FA5E7944CCFE2732FB90178A6F439EF2C83D0FD90FA196CBBECA9DE1DA63AB609F53BF11303F3AE2283195AD62587795E7CE13CCB19132890CE25B085F7AE282F8DE315DED51D9E7B4652285ECB3929B18FEE5FE427610B9311F4173A555CC3D534439D074BB8153F99EF5C62288F9CD393B0C257FDF1AFA64BB68F3DCE632BF81FDFCFBFF93A4CF99D8D50805B18EDAFD09D086D586BF8A5D6A2026084C7DBDDE343F74C964ED3011E29C8683300EFBD9E93C68EE571CD156D8FE815579D8E5AEDB483103BED689A4CEB7EA73CB8E19A6994A01838E173EFE68E816CA53CE578B87754CB34961D83A611466478E9325529D6D15C156B2E2E06E1F624139D230DD3A32A90AD2C7097F43119E10A2E788F15795548B5470728DDDB77CFD86A6C3C6669B9A2217BC37B15B8EA558D2B9E99EEB37E105700A324FD17A5A00803F41C5317FC2445C7216FE28DD0F15BEF50566BFED945796D4F3DBB97D53204D5BD64478A75484912749D9407C09D01CCDC391BEC54A4D43C9157D0A871195C731EB746F61A3F82D6F1A9807C2BD3B275553AA6CDAAE509A3A350DA3F119521A3DF789E011E59EE8138C17EDFA2AEA5C15841D25DF2E3A1FBEE40A3CD98C275AE4FCAD2708F31D7354E4059D43FC5625858721409E990F1DAE7D7FF6B3084897B817D88A99C149497599957A667750E1CF446F5D24409E3CD2AE7F13197FA6705BFAE8C1BF36AA626D524EC10CC50F77B359D718734797BA0154CBC3CCCD88030C97386483EFFACEBA41E5061B95BEF6324AC98FD576AA2A8D264D05596B20200496C54C58146883B62C9051E5F52224294C996EA6B44F84EE277D029766D66AEA021467747DB5CE0597E5D91D92903B74DEF2A7100BFF8201F70D009B0963454C25351D8D43AF77A3E70C95BA5FF34747F55049243C06C036984C5C303378D475F841749BCB2DDE91A25C105501EEF479F2B6C68A60EB8F1A308E74EDEEF93E1E34A50CB272AC278ED9263C0DAE162B7C1FD035421A2CDA9774ADAF21B292C252B94398DF63894C88C4B5529FC5AA5A18E788D74EB6126C7FDEBE4D650E2871B25F37DB9EA8AB64FD4806121F4509D4FF190439B7A8690A81275D9C03CF2B51832B32DE2967485BF84E915F7BCA7647E09863CA48B37131815DF9E5F5A88535186C40F177A06B657B4437728EFA50AA22C45E49026053B3C2A3C554F1B2613EBE50F27CEBD3BB03C8CA17B22EE76C4200A0E85A70B6DFF7F511FA2265BB7D858556213C48436D573F120D4222BB1A5C924B2EF1605B4A1ED717EFAF63AE53B070D7C62B2F8CFDFFBD18DECB0C405E7575C6AD8CAEF4789D6164039F963F807C3B978CEFE718A83A68378F9156BF52F6A3F76E411CFFD88448BFB452ECC10CE99AE5F5E303EB099B89765A377868B0B2B3A0D631264AEE47BDA8FF3A92483D27CC269B16390B3ACCE3350DAA649AB53B9C1CFF2872B6C1F9BA67D9D22C6FBE01424A7DC815F968C77BE937563456A273992579C8E6AD585A0B3D38AAE13ED13B81D58599A43E86C4B4AE7825B358C6FB94BAD7F552544790377714DFAC7F17B9B6B3BAF2E5D6E87AE0D0769A39A5580D5347C78067D7D7C375A91B066A61E124E754549CF27779D43109D8E167423F13D05093CD1D31B7E6B76A89C6BA817D852775ACA8B385138C6CC73639FDA3AB6FDC5F84CD46DA221B2D437A51B54D43D98E6D77E31B07FF420AA12FD6FA8892C4220AFE432664F946E738DFF89EEBBFC16CB168CE1721738B4A1174265AEB27FF3808A80D3BFB6CB893D1B6B33DC27239E96108C6D0D20C912BC1EBBE7E245056220BE957E7B9D49EEE6C4D341AD73932D304798F0A0F04F31D8F70DB5E06E3ED2DA627D47E0AF1C2E14E56054A87AC9810B617A52D0DB5145FE4C2BF6D0D4AFB0F9314FE15167A5AD0FBA0C1454FBAB0705FB6BBFE5F7E39824E59DA24CC67B3AAD9491E7A40906487BF895E90F63CFE6D7C0984F1D2747676B82D09DFCCD2A8F6DD158C917DB81FDBE6213FE43780DDE17ADB969B3D64CD6BA6EF1F9ECC7D6F6207280078B10DBEBAD7581A2E8C2F83E4AAE8A26F8D1DF0F8CB45C690615EA304E5CE30D2A96C55696C6B1D82D274E9D5765C3E5D2D7D05EC6A202BFD0211B534B7C9FC684C7A72C2D619E9DEC4175477792BB930EB5888FB37198A6E1DCEEE6651038F5C0A15DEDCE6D1833CDA5CE4EE61CC144E7C5202FE532E0B274F2CE4E90D91F2BAF7808D0656D5A106EE157491277F92A36239D1CA7D26150C118F9ABCEDD5470A2A0069AC1BA97ED1CA9885FDF2B6750157AA5B72DB5E7C1140E1FDF78DC7FA04773F4570F4544281C2E9627E5F59CA9740A38B452C9F3A930956187079B4EE4C91B3E3D9F0F502F8558A092630BBA965FD8900E738FD1498FAC10E6AFDF58F32DC0824B405C0E1D962CB213D4D834D7D26199B9172CCA1A36D7A76DA603FE07CE0EB070AFD90E7A30D937A32D26419A002A32AD9043B1735AD3D0696AEDA5F47046F8A3134B8D45C090C0A54C70AE992A0916A49AE7F3006165FBC71CBA5F0611FA5140FC304CF49DF3081CEB754E9E87E4FB637D7E701D930EE23B6E7A739274EC3AEB90736D91745A92DCDC5FAEF42918E63079E07316C2F9E59D8B79062F1D816C536E8323F501A20A11D6FAA241A5CB4A04F8384206C1D4BA5BD2DC0DF41A69CCD6390270FF0451211B36B489AC95476493D812ADE03FD8EA165053401587F7A18C2F3FBF4960C82B30E9C7C30EA830FE7D052DB5A191C0F8DB73833839F0D7AE822027E19C3A899EDBB02AD49EA87E1A2D55EA6B010BD984FC6C5B12289B41264F9F2F23B8761F262598692F57DE1277F48B3EBD06762F791DAC23F5A5846795B4C4806EE0909163CF27111BE948EE0CB673F0B744707BE8189B059F6D33E52AC33BEC99DB223FD42F64BE1C3E8D505592A78D5F7D3E465A5E34C1FC7D7ADD80752A83CA5CFBDD7AE15AFFE7BC0A4BF3722EEC05E54482A88287D9850672C2DCDE120E0C7AF377659E5A3313D0FEAD9B350A80F0A5A4A480346AF02414FAD52E5108B911B7A4B877215E400B3FCD4E8786E962704A50EC2B2D2D7256777111EA6646AE8A57C84B56C30D704C4B914EBFCA60FC07CEE5DB943630CB07C872596E0E48193D8B6513232AE14EC985E19B27E231B2EDA344957695939677A09ECB8C65C93C63C6B08FE5DA691AD51D463012565EAE07805134DE6FD09BA7B3659089DB2B16DAB68A89406E67D63B3F0BC70C271C7D0295293CF5E174FE0609D593810EFAD6CD648BDF6D3253E64DCD6D2FA70FCDCEAF24B7C96A3E3E4B078E1668E5F6CB9A598FA202F0AE1DAD0AFC54BB46BEE1105C69C535390CD630A2BE448CFD70112A56A74AFEDC4CB48BD579FEE9039DF705869A1623B1596F77D7420B59F32801106F6AD8A16DB40B1ACD82415BBEADE36585C3BB47F37BFA7162C255542E8284D8EF8CFF88DB68A47249DCD14C1D2E8E5C44E258E9BA867902ADCD588A5A382A60A580458C8C59BD5F182742CA1BD6A52F35FAC26893D74C3D74429401712918098CCC493BD226EA8A9F8C7700123924131913453EF8069237ABCC4B851B0A868015162AB8B7B63B3110906B267DCCE5659F4FCA5298C4073BAAF392C5649B429D5E378557D5CA03C9A52B6208936AE2CFF83D7E28A3274398CB3586BEE9694A14396FA1D67BFA90524574B7DCF0E8C7B86C86A69FC0C2263B437016842743E7E1743802C4542DAC8E6A23D03A158BEE47F010F71E5D9A7063E26FE8C40B208160936B5CD4D13ACD22F928352902BF25A8C8D294B493907F6794A4DCC0E7CE621FE45CC6E5F33199D798FC6E833F9EA4EA54FF6A465EACF2EAC6864D3CD0057429D789466CC60CD853B829679FCC639446CB0657C15B869BFDF27AFB572303E17FF826F8C4EE2C747AE330858830F70879FC8FD6F8D7CA2BA986E5D4DA1B613DF88CE09212B99BA77FB3E3AF7AEFD4FACB02B3E3172AD43BA87A4433CE38E45C1DA3ACE463315CF5A87B14CF4745D5282B17B613A033A9FBF52A40D8265B49A49DFFFC6C71377C20F4B3EB43FE7D89D829477619A7E5B2F7CC9FD0299C838419661773087C7BB3573568DB256F94E57423B1AC21C0662B60F526AF49629B7A8F7E833F858E5C7423437ED22E6E704EA66B26E79878EDCE376E8BB682EF83EB4B9600015217C1219224381665C140C78374B80F47511C48B5238937464F3B0A5612D2F1FDCC91B74CD861CE655CBCF22B68F657EB7D8806DDDB03B4F08E52089938121B0F6B3ECDD2D23003C889FD2F9A4F6D3D4358976641511DDF513181B1C86DE10522AC021B6A301249FB9E6DB19DF42C5BA6D53F1FBF9A7A2249C516513522F8702636F688145B52B1FB6172CA96F59B9F845760677D91996B38371DAAC111D6BC59BF28F19B4E00B5E312191087255D008FEE158A8E1619CC0674E12DCAB593EAF6C99C9CBE9C700B498697A725E2F30EA74365F3CD3318AA1D0D7C07DCA4F2F6C3AC8EFF0501F8F65A07363621059517EF1BA27310ED930A1A1B0D4DA322D5FD13EF522D21A3A7D623FC499AB8648C1AA0CE2EF94316B2965A246AD7C8869E9C489AF1FD2DA40E3D688531CF77F083F281E012ECF83C4ADC97B5AE47CC38FDB41C7ECBF402AD42716821AE404A1D224363958B9E71DD4B3E77A16FC80598A3065E8E00F36F2DF940F4E99902A1D62D73470FB4923D3A46EF07E65D02963E1B5308121675F1C1973C656549030DCE1BAE145C7712A4879E2F3E219B72B673243BD71442B699F3A4E366C7B88C1266330282D0D9357FBCEC2F95AE54D87A50C8581597B0C24C2F77763B326A55EE924C4A492307610526A864CCDDF6FFC64321D570589BBC5F9CFBCDD95D0C7AD62DEC853875BA2F3C5E3FC20CFF99FF86539F37EDC56643EF7D70D0025B395061B83A100E1BE1D6096D007DC42082D4E793CCFB79CC5A06242518998D835B32B7E579AA14806AEB8A4F19E554FD72D2899617541C6B86B63AC60BD7B6185A7A86BC7702CCB91069ADA68EB4F117E239BB7A9581A56CAD59A618449EE02E2089CE3A1B97B22AE34BBB421F2194B00B80F1841480577415436FCC20FD60731E6E28138A320C9237FF656A5366890E492A318EFDAB7F22CDF81AE5CE56539034A8790E942E58118A8F141B2FC6E4559A04B9EF8827BB7C11D5A4CDAC22E42660082AEE184078053860369D354552F1CB9D798F3FDF657648A7D5BE4F41E6141FBD80732B6D3AB57C0F60D38848FD33F7E468BF7600E16F25B9552688D3AAE33DA731DFA536059D24AAD21AE940CF31E18A40508DD1623FC89EC11BE4B852EEEFD56C002C1388DCD5C54E0524BB681A25E076CFFF94EA7B5E0A0B7DA1DED8DBE3F9770536FFD43BB48C9E55E33554E5C0411BB823FE16AE3CFE51DFC9177764955DB39B08C627F74A7B9A16DCDCAAB1CC31E37B0D3B90ABA2F1EC00FD2EF6E4FF3A15358C551BACB93EF59361567E0834E72383F4EA2E8F76F000EE38B179F7F0F9A3351C5BFF81B49E8A5119C6CB5CFCF49A6875B3A99CF14E6CBABAC0F4F38FC97CBADE13BB807CEADF726AD565D65334539E879575702D58462BB2A7C7F322A16F3F1C4FE116CEDBA6094EB4712D774B8207189B700C8B84FC7D0DB49B02F7AF17A6270BD75AA54F8A79E4A1A6D588FEDF94C0829EC1496988507C8C5BB87A70DFC3FF6C7F985ED38CF6C23E04FFC8001C2958B5E0920B284A4A3A55023D13D4FB99D392A0F61281E6DE6AD1F907788504F80477B8C21454E4FF16236E42DF95C85E20DEC39B2920ED49AA540BF504E74627B678097B4EC800A37698C32118BFF564BDE9BE0E4B16A3D91A9A83FBE991DD88E7341BA96976F7694323E523B76DFE3C52F28188C8D64DFB1341EAFC98C9A28CE446C4983AC52A1C38F9CC5D8CAAABA4E8BF9B7E45E3521567A46AE5166642E89F8503F892F522A447B2FCB1BCE2EF4EC86E22F48FA99555DC193F080D3F0096A47BE3C2597FE83A27E8132D28EB55AE87B36C93F31A9E371BEF51E405037DBED6CC4916E5A855116586F7C34F33B3EE626DF600644EC881246E32B5716E9580A1733ABCB22346C4414E5FF2C085E2CBFB45BC77168F4164B7CECC874DA5594F6E8D0B7B6B36EDEEDA1342672A4D6925CA2864B93BC7F63994F8449929C3206E086738FADF14B1872973A6093B5916E565DC3B354FC544A44202598AC2326C5EB9F305C448CF68323DE4C5BD28472B340E43DEDCA0DC290CAA47238A7A26713869C6B4237D40EE2743BFCE74E5CADFC183B14075FC8088943F3B2E93FD3A96ACA364B9292413B2B67B43C855A898F877683FFA238C05E6F789ACCCC40C434FFFA494F2710C3DFA213DA7B56D5A4C273603ECE648F3E9D6EF1CBC0EAD4BFBAD01E0651103DD17A534A2CCD00CA53C713F3045B2389B81651E8E2C2B6629D127505EAE2ABD26F2086E9D6BD48CA6FC3BF98F99604F221DC203BCE9D61B756A89BB0B418249889529F7E8F070F35D35E572EFA012DABB16A98D0AC8A99E596A91468A1AAC939629FE780A45D8406B60D04C8E2B31EB7E28294FB2595F4E7071CD906FDFEC3EC3CBB02B03E38AF71EBE9EBCAE3DFC9A37E6B545DDC034C1B684A22B4C43569169D30694DA2D259C846541CD1FC1D4F3553DDDEB5650C0207248DED91C549B76BE830383E8E158E188D78CD90E7B03AB56FEAB895A3B82C1709F9FDE140EF89B847CF556D8D40BA06511E6B003080C2A9FA8E9B43888C41965DA5B6B2225206AA998AD1BB76E38DAA65F1759EBE6F4E301AB3B59D217FCD6C08C626143FE4B176E51D1B66839600593F01E40F7DEF55A9405B5F3E816E59039E3528A724CF0116508D784866E2FC9864778D5BD5F25DBF3C8023DB6AE937B028A471165990FED36BD793D165DA1A4A836FCC7B9039CE4375344659432BEB0820FFE1CE1DDF984FDAD61284FB7BF551CFFA91FDD3237950DBB9523C478C56AC1D0B5E7DC0BD88548A1946CB98BE05BAC55BFB535391558FA57EFAD67AAA9456D0F9AF82567AE1FBF375F69ED9B30324350C6FB4FAE7FEA4E7BF7012F515076835FA348D9ED6207D9A21A471AE1D5E036801694BCBF5268776EFBC9020F5101055D97EE9EB04C5CBFB4D9132855E2B0DB7C4F4C26B97A7B8DB1C2433BC12085E0E624896179924685837CF20258DD9D5F698BF4D1E5203F6CFFAACE82379CA26B15603786CE45AC18C296B05919A834CA0EBA4855F63CEE3BCA8FA2AD24C07D3B7B9F73ECFECABD9306C647F575D7ACC30ECD72329D51B7AAAFB919C0511DA596C23A520D9705BB6C5A4969346C30AF6D53D5A9032E04D1F960B87E0BE110FC1468A4E657BD55A832476E82A839B9B44199B12D51D3642F50774A9490BA404470C54A9249E772BCBB344597CCC73FA0919C4C67971C5195449D812F7A6979279C23B020C6801DCE5472B66B4457F56B7B0CE5C9AADB0955180917A72E93B10F4EDE8691ACA70109399FE9ECAEE4FDE5B687836315E7F16FABDD3FDBC2004D9ED41008D0AC77CE46DB9E402C14C08DE7C0AF9EBC927D40DA2D7C7DF9CDFB5DDAE39743E9A15C53A7999B3B35FD329FE1002975F668A2307221020F884388C0649E8A6EA76027BC254C948426CA44628071076E4E5C77C7F155AB517C5026032052792533A29E6FE7CE81A20C68786F9315C73A430429E2F2BDA55C4E3C09FA73081E19166F7F0359FA6B078F1B4EB95103698F9DF7610E30B3E801AF5BEC6D262A2B8F1D1EB0D00FA8B041F6AB95888643EE9B00F3E925455A0ADB35267FFA9E8354BC69AC46E67106979EE5B75705D80550D7173CC407A4201127FCCA7A162F00796F46DEB7CBB36311A900248FEA298EFF33A3D645E28FD183B230841F4D848A1FB51A7319D5C1474A05694C06741CD15B251FF33E95F18DC944DA035532E1F27C654C302FE8BFC7D8CB5541008B01AE4D5E7C2A09E4E5D5C5B314B67DE4A03BEF268203ACF15A4F9A148E4072710AD9C94F78A55784558C32F3A2E513E84E9B1299FBE18E607FF547B1619AAD1D63A1C761DEC8A262CBF89714EFFA189ECAFA723C81D00ADC10B09B4F678A6710BB3C64569F731E7F1BA28371905460C7E1C877F398422C48D8232DD5204089DEC49108CBA8DD493418DB492BBA225FE73C1CAA7D91D6638A2662F114A40CAC9D1D6AA16E67E0DD281EFAC4D883A25ADE30D9CD44FB2E2D24054CAB5C527301CA96B020EB0ECBDC803B9C1FF07BC50CF6921CBBBC757A2EBA28D307F9B67C752443A9859A35E14B25EF675243ACCC36641991D00E03234079C0B53E8AC99033B52967861C85D548D25DF927EC74C8AAFA5F78884B5443D8F43591451494BC12F7CA33BC42C629EF0AC93F11B942F4C8250C4A4411A6B14774EE772BC485E2C676746083A0DE3EC7D0894281E09686D13A7E628A4EEC1DEA1F847698086CCEB661AA10F54755E8E7553502F5F0431D91DD4D66B963B213D615A0DCECF5CA6195EC9610B92C3FBE750E3912180D33E3F04B29842F61CD1454CB4D0302F2BE905BE49F82F470380492429A349CE86B0EAA2E305326985321D35B1AAED5FD3324D12EE14CB3FA5BB739696228F645A1E9A9063DFCE147C2065BE5E2E7741B20B29A037974174FD42F0796CA07764153278AF8707320DD6A820EF2A72EB981A82EACE9FF55179554DFFB3F8E1796973E86BAB1C22848968823EF74DA3977108CBA1FD67EBA4170539D24F12087F5954E6FC086D915A2037E7BFCE97A394F987EA1D6FB7DAE67765939991E7F2163C33DD20950E0F00A4EF163CA7A903C0AAE22A6516C172D54A73D4EB181DEC2B1BD62671562D60192F32844EC777DB3EB698A8575787EE699402A80F6E2AD283A6EF387C23A4102463C14E2EBC5A0FACCDCBF0E359263792DAE6DCF0E2EC202ADFFA1480357A3B722DBCFBFEB8D341FB67CE96AE936A36D42113F298E3125289FD8617DC69536B2E52BC81E903A7E72CDF15A0FE289C51C35F5A04237B797D1E3E71E09FEEFEEEBA7F14A9BEE50D4ABA48BB2F39B0E6702AADC8A93BBBF9496A15C7F35AF67415973BB58626E9315042019E1D35F768D377035870264A1806AE7A142ED4FC9A3EB4A9F54185E990889BA19EA36961EAFD483802AE4AA6E7FB34B1F7A6AE378C229FE154FCC476AAB6C23C524877DA7BD994F8859B7B9DE9F841EA055A56469962133E231EFE161886085944D70F07819D4896F6E63F5A20F4EDA06DD45EBCAFEF5D5B384E7F0B2DD10809D9B84885385C12C5345DBE856A4E2513277E576581BFBC6D73F085314E0AF1D2A3364532D4EBEF4F8F960201DC635731765B4FEFB8D13C18626D5D4A955B1FAF6E5D65B87CEFA18B021B72187365C45D6FAB5B2A4AE7060C5479124B5F5CD2E6D6496E52BDECB9900686BC6DBC0848C8E71FC9D7740405ED290C5AAA70A3126A4040C5966DFFFA6CA4D20BDE82441C973D7E639F774C806964B00221ADFD7C60836F032E794DC6B814B9E36EAAF0AC330407ACA11305731003502A578C9DD2556400086DE1A137176E752AD2A0BA318FC09DC51977725ADEC2F5CC4D71BB2AAA373DA9EB4A01F5E7DA252F75FE7B94A3F80E9EAD1863D1A478E5E6D63702D7730843AD460B0522D28F9EE1F5E6AC01DBE3B76671FE88C84A4357C76C316723D855FCC4372ADE20F8746B501EB76E62E66AE390961FD58752D4914C7CA53CD0B83E168C40777F8F136502A84B6C1A338D450ACFE885E77790E4EA399EA859A3F37A5FCB8AD3679063566F14B36FABB97B125F4BAB4B60EE9B26EAB4BA86E1C81E61C1A4103D9BB2D17389A93D792C203B005A361C41D2C620CDA46919CD9F7D30E547F62CFCF3BAFC540F5E6D9CC212792ACDF91F291202C4FEDA136CA6899184C53A94B2A2B2F027760875ADAD89484F21305226C8AB81BAF359B9A9399C4E71E343043B41FB814656E62A49F75D72F8B70EDD2B3AFE68C0449920ACE28BC7B4117CAD1B78A0ABC4069B742CB4781B10664BE256B345925FC0E56EC16437374426D7330716AE3F4FAAD02FD5B5F7C01CE23E9304914C8305B39309B9A7AC172E0C8FA63812A11F4A4EB5338CBFC2287AA1490D8166BD1866CE08654BDE8069D65EDCED448117EEE3B3C69549CFEE04B802B06567FB33D41BA1FE380CAD9B3D3F732A6D065F84B401C78DA3684BAF9A559A548807ECD23CD0B75EB36AA7350E23756FBC96BDF49334FBF1ABE26E165804C5627A08B11AB1DE840350BBF7FE153011BB1BE7489EB5A211FC23BA240F5ED74AA2C3E84443939F4728AD938391C6C1CC808BF9EE734E81711868D986A1616E3CD56F1A61E1B339A057688C74A3FFA6BFF6EF62022D21CD6D7729746463A520065B66CCDBDD296771F9B5C002491191EAA0A72609EEDAB634DD69D328665D6109E9DE6284018DBD25F77234C556A474968445D85011E09E31A17FEE95798508E7762221BAEC3D6A4956DF1262A3B13B967154E369B26A70C16838260C63979DC56A02BB1E3953DEE601E69F5467F7CE20C1DC799902C391D27635BADFCD73242DB995F7B6CBC331BE00FF871DF5DB0F2A497B9B06DEE8C77ABAB0B27F2AA4FE1383668A8C3DBBDB9FC21F053171ED76E797F08043204E2FDFF63760C15373A120A95F9989194AD1D5126B4C224F0722AEB2327AFC908A6635BE840BE589401F1E97858FBF94B2295930A490117755D298A5D3E417ABBE3EAAFC8585E76C08CF7B563B2DED16B40538FA4267CDD3B3455783035CBF9258B5503F4F072D7FBF60DCACA6DA5AE3482A3CBAB760F774720BA86DCDB03E38B75F27D6DE9C06BE33B8B68983DDCF453802BEF21332B1F221BF653F58331116E31F8939F51D8FC63531DD0BADB161C8ADAB525E6DFA1F8C84C6A2AA557330DF4DAC68DFDB1D29344869792FC6E4AFA247A3DF68EC505CC8770F7B4805F2A8AF534629BC61C92A1B1C02D55656D7A19115C48616F6C813248C20901FBEF34EC0DE8C429174040458C3B431A62D2C57CE4BA13CA80063DE7BD6668384FF7CB02629C967538617C4F58E4CE1B2E26F09DC7F51E9C3548D9A99016438D9F98E2C7FE468BB5E4CDE479EC24936BE7CF353E185385BC82E7ED9A11C3193C00B923587E98DCD268AC6035FCDF802B733497FF41CEDE795BE3434A5BEB065297A701A24EAA026A4A95B5DA980020C77714A463521794DE232AE1A538FFFEBDAB46C8A6A660A338F932184DBFFC9ECE13B8A8D5808FF2ABB614C39444AE701828BDDDB7B91446894E323C9270763AB3DF7D0A4028EA99EB3823D64625AFF2E01E381ADCB40F1B7B833296CA35F17EFF716232FCA154ADC289A1C9ED14AC0E527E8243BC3540357EB5ADBA8800921611B48A81EC2482CAC88FD4693256F4755700FA47DE0807D29C71264F848D907F9C5FFBFE2581503A591C0ED2711EC0EEB80AD335F0E6435DB9AD543E6A1F881C52F867F51E5280CAAE4BF63BB222DD7AFFC0B1C5C63DCFB19E3F17AB415BADAF3A8396F15C20AD2B5A6C8603CA70742FED3128D6F9C52F3A8CC7B8473643FE4C54FE696885AEC9C1A02CBA04C5C81A4844E927DDF668ABE9A083B84FCFC15D2C747BEC2526CA293E8363F1B495CDA2573DE1BE95D2F5882C89CCF61998EEA4CF5002C3674807C9800D652AAE2A0210DD9C206B5D351C5320DAA89A79D025A365396BBAB9EF785BD4485B5D59E9A10559F3C6F7D541119DEFA26CEEBF7ADF3A0CCB0F1EF2ED7367F2EC87B335994041923C1924798925EF572912EB5C3A344B0F9724632BE4011EBAB92F9423514B19DCABA93A4A7C8F51C0EBEFBD86E50DC6820DD61C166A52DCEC9BEB5230ED209E9BC839F6F16C7F0BDCAD1BB429C8FB4403AE3A72304F178FACFEA00DA6ABA89ADFF21CAD65BD1ACDFF2F8F5AE0D89C25FBA430BC54F8B4C79A159E22750395CBF2A8296C49A74D1AAF4AF55E6A52445044C948F43E9E49CB730267A2AC636AFA84F96F935E8BC021A68CA506272C4332EA472F5A8DEBD98A002CC8E4332B542194C34BE4F493572C563AB7C44E93BCE4AE67DFFD6FED96C3F3CE2470AFB2DD4A0FF01AD6FD485649B1F262CF8C86E51D41686A9E71CDA534E02ABA6C832E92E3B664F5205509B774211D8634843245D3553D8912EAB493A8825DE21810ED60C61C3C51E702207308509BA05E78E6DFA755EB4660944FBDC0DC8AC53DAD237DB0C9531FEC555425F4B1198A2C97F75C588E490ED7806FE0EEC48450D1EFFF90512343BCF48BAF528E30F3AC1A3BF72EBC51D872CB8990435B35189DEC662F45F327CB14DFA069624F20DA2346B2C556C9AD4F692A739829F4B967054AC1222F351E7B81454AA5D594304361BA49810FD0C6DC469BC9137AFFF98D0AE0CC13BACA774394A1575CF01339CEB8085DC985DCEA36BADDE80E50FB8BE1F6165A5B6976391A6468815FC70C6A5976109930414FCBCB070F469446F0B71DA220F64D800695A0CCFAAE22E876BB0B283C3DBCE83638D571102E894F9DA43C9B4C359063DDA0B86FC9C7D45DA126C7F06E2C9ED770B17E57E860B03C64AC7E9FDD8ED8CE95E2DBC2F51122FA2B6730151B144CB6C82E3FBA42C55A5405AC1E023840771F8EED666662AF35431A463BB569839A4871AA21C4817A0144A79720F530F32A682743B9C01AEDB95FED48C38C9793F59C2098E60779293D0F8E20284C2267F03C085303AE010171256C4787EE88FEAB7B31E269142887D2CCC30B8737772DED1A9F671556BFE43A7C381D764B6318A82DD7FFFD190222B5A33F79232EFB1E767E6764A9FEFAA5165B7645FD10D7E30C735EBB49038D582E2DCA81BC47EFE21514B20795DDFE04F114C7AFB4F91881B8C03FD368F3AC30437269B521FFDB8DE0D978CA78D28C716086F58B2767A2323D46172272FE6945E6FAB674CFDEE3C8446481D1144C9AD9F8CA0DC87D99E2FE038A09F0E9741814E09511540CEAE2C0E950551E10B4BED309E2F6E7CE10500BD8B00C5BE0B5D88B01A1AF25ADD068421C0F98CF345A597427D043CB53ED18DB764F4288B2B88AD917C4F0788488D1C56B7579C7695983135EF479D902A4360389A206CCD9652672552F9726782AAE9A57D0C64034E7F124FF75B1B55AF309F0E9B4597E24BAB8DB92814987D9AE26BC0140361E4528877C2C66668F2F7A127F63F5A43C2964894036C46F90A673040FB198DC50D9866BB956364FDE3B9BB6F2E9274D4A6E05AB919609FA3DA339C75A542083E1D6CFC6AE7D40C1EBE4D9AD9358AD16D392E78C086A682FC2CA00E386764073A121157F98A15C7FADFB9525D581A7DE84DF9B0293BC1B7961BEA4A894FC598CD76D6BE49CA389D3C6D06A4E79CB682BFD8D2246D1BBDE5E9754AD3B3F5F6A8DDAB708CAFF40909EA4DF53753D1DDE1C8C959F939DE10DE4CB937C21111973B890AEC27B06C8DADFCEADA3A211FAADE3411FD5F376CD1752B91019C3D9AB949209A344D24C5F4432B6354AE4B2631811990F49E16DF01DB78577132348B7D5A4157E60D7DF14798C8B606A6240AE45D6F1448314AB98AFD0D703266671192FDBCCA33B67A469D1F600F51C4A75BAADA71838D74272B41DBEF720DF137D57F208C195144527958F7EF69D6AE9631E899DF15B8EB560E372A5618FE7319296204A68C97DE9BCAB00296957F7A1955C8EEF4484EF2617E73E5783F8A3DD61BCB40A2F2C560CD6C8EFA96A9C58B73E0D654A5C016E6C776BA3D9D13D78CD7C5B640BEAEDAC87B16D12DE8BF4BBDF77F04A917D70046C285D6CDD3AF7284C2DDB5AA9016DA50207D2C28F52CC0B924D2515271BD986DCE5659D337FD9F2D939E192E310BF0D3A00CE794F0DB51D912630E4F35A04D94E7D9A2DB86FECFE8D799AAD2059D7410D1F2FA0DDBFAA343946A16CBE0D334C8DF591C890B3EB764E29AFB3077EE99525EF898C7B3D460CDB6B8B6F42D1A62813AA0F5179B95AA5291E36345059CE4066F9A2E8AA9411A70FA0D9E51BE77C21A5D7150411086CA188254437C9F5857927E6551D4D551A930D2FF7C8FBC0E5D9C03F584AECB8EB5565279F63AC74A1E9DB16EA8A0F4B6D0845372BB842A2B08A96F1D9A16BEA070CA72101CABEE6A2B17D5E33FE91C134D0DC7CF8A2F019937101D7C02EE727A56587E440AF7D82D036D5A124C1268BD6E32D73F896A9EEAE3B67517889E2EE99BDF8960A857B4D494BAFFD01E098B1C7F95B4A8A205644212A171EC485DD2CAE014962F15B1557ECFA9205DAEC5C5DB83D9B5642C817CBD6CA12E5B56650990FE46842C425FFE5C0C18D4669CEF27800A7A7FD3F34944B63BBE4EB0A41FBD6D0FCA12CFA457C72B122EE5CFD43429E9FBE78A38FDFEDF58724519E0550EEAB0481485453FB22FCA1C0A4FB3993B48166CB0B7F88A1609FBD833A866728747DF88B798DCB7BAFF64458567EF3419C9A659EC81B8329920496E82FAC7634BB7936AA6A467FD8971C061908A0F63F52E847E9D7667FF8C7995F457C4E0DEA5E9E8ECB60E8EE3BBE3CF55321A6E2E33C6FFE922AB56E6C494445451A1A0A9F144A0FA330AFDB58D3BD0A1D0166D6CA7AF21B86F0CE184F0BE6F1CF84609AA79E8D59D5BDFD7BC69A997E3D8B51B4C9F95165D9A451DE1342A736053BD21D538F9B1A43C9CA3621526D031344B51D5DEAF78F85BDB8BAB5CF11D6AD7B1F99DD4E90CC6B4B2F524ABB33B50BDE01D046AC09CEEDDE4D32225EAC2FF4D5E6E1B4D391C3A9D20D542214D03DC25462B60E8F5D80EC469FAAB57E4AA15BA50F94AD559DB5FD02FD5E334D5988C82EFA9B94E0A347757B81ADDF735753119350C0F3E8F3657BE5F58D4EB1E51583560B0775CDADE003C320FA6650D69674B3224318E8F51A17B4F3C9A5F9B3D9C1C3F6AC472D56EB9CCFA6FF592E8397BB30F558F12E290EA0333A6A0ED58A2EB1BA457FFE88888B610C9015A7DB11850D49011898A40E01C98A129DA9BDA8C64827879842D3966619A0388ABD88CA787005B7B69FE56066A0AAB8BD9D28ACE6AADC728E3EB30E16E4ED6C0F93670891CCCF18CE0CC7822E9CEB6D9E6B2B4F0F2DCA5382887A81F7CE2AEB122F0B7429C0E0D5BB32E53DAC5094481A2385D9F65B2FD2922F84D03AEDC4CA79C4F81F0A73386FFA7E5FE5B41D1571C426D88B18861FFC16311D61DF54F123A65DDCC2A6A5380F396C5B532A657BB0A97CCCE2F7D8C46096D0883CB16EAA8C57087678D9AE57D502E9C693DD899435DFC44F274B5F7F67A09F9C62AE0C08DC225B65983E3FBBC014000B51E3AC1B6290F135DE1FD32C6B6C049314DD7546E10A1EFA5A5A715D197B27408FC04AD61ED93A1FA08A764D2932060EF61ACDBEBCA8D6A16BB146FF0F6720BE6716292D2351B3F396B25015701B1827A8805204678ADF18AC38DDE4E2B27C6B1514BD197248FA9E88655E7DD20EDF4C9060653CE3C49D3B722514C421D0DAAB0CE802C7DE6A85C247B9DAF3EE936FE2823E13632FA91B9217B749DECECC7B4CC5A30168E0661CC142B8C62D5D056FEFA683EA4B06C74AAFA0170685D3F60E68CB0CE4F343B5F2900FA928557312A390F6744D47DB83D2B1917EB736B68383A90A14011A3C5EF48C7779E5BB6413824DFFB0B584420FCA86F7B798C33F790535EE0090E7CF6A0BBC0FDCA5D8A157748B4FE5B1CC64D9F1FEC367AC4D967712B7193F05058A35D7D286686AB611F1C4807B8F6B95BC021BCACD7EE59156710476C0BC628C387C1ED619BFF0FB68593502CAEC6996845C28489039AAD9BF5F0BD92776804ADBCE3BCBFE5F9F4FAA49DB29E53F6D047427A874AAE9B37A2FF7E753B7C712BAB4B128D88420CB0B8AB746491FBD4EBB70CE6AB653DCBE5A175E92D94DDACFB6F13094DC4205EAC3F85AC3EDED83C86DDEE0A9EF785DD42BEFD4299B5F044EF271571E5DB7D5349E47F14CEB297866621578F976DDD07F01698F8312117532CA2F68F57420F77CB85A8E0F1408ADAFB96D6BA04A0E6269B9F5D9121959617885F4F75E052D09DCC32C91F56A3E86832F6764038B61CF1DF5E6D588CB1028FACC7F99AE4082E5A604A5BAAA180845045993EACC930B64AEE680A9ADAFFE21A271721A3771EE60B12B85987CF25265D0ACF2C6FB55E762E877ED8E44266941C47F410A5698102D7E263F8530FB0EE9A26E0E5603A189CD896E231EE5DE2FF695736AA9B93B48C13D6D0F9E4EBB68A1088B311D3E1696610E7DBA6023AD3BB4122BDC83FA28938AA6023D1BA84752D897BAC75911F9928A4585F3C071FD858EC3721BE2A9F5FFCD260A7A5413BA2F7BE17E59830A7DE2299D83F779D0C780EFCA74D6D71015D7F21F54DF0A5231A5577BC161BFEB7F6B2A41B5B9A3661FCCA56ABDCFE63F3B49CCEF00938CC038FD084477C91123FA149CEEAF7141CAA1467A523948869C47F4E2905E7B48A468FE615643E66BBDC55356E395381FC0C747ADF495233356FAEA046F2C18F2DCA0A7CE744C110D0E0B2DD861BB5080570DB0A2674C5F177E902E171C6A96BADB979A5DB94CA8F73BD8AE70B43C3F8E2B618097D2C796F7F92DC56092A6B0D863A04E2F4645C4817E42AFA9CDFBACF1597341DA1BCDF29F38B37B8BB135A937EC8D16BFDF3B5E1CB4C335FCCDF7F71522E7BF2004EEF77F9B73B5B69216C4EFA4DBDC170132F2E0B897A8D5DF9866CA80F54342B024ADF78B550DEAD9E1642483205723024A15DC37AAC36EA593E152A6F7F8AD2A985AABBE3F1171E738FAF2594370A0C330CCE5D06E23EB942EBCB8F68FA465FB98F8FF1604A4AC4A286629AD3AD552032A49FA27774734B8C8F0DB2DD6A28C2D4DCF2E07BF1969AC4A9F218939EC685DAD80D848A8F6E803DF90A4BD133EE88F1013942FB74E19333B4AE530EE5E7752EDB8603D0D9D962A9CDB3D2188A610CE5C6D71D6A508446BE79DAF26B866DB6EEF1ACF5A995C9EFA9B33256A9582DBB4773BBAC9DEEAC03175BC18D283E76A8815EDF736F4C3217E810807BECE4442A002B71F87F6BDED77E5780FADC3AADB2FC146788D4E7F6EFCAF95213CF7F954C210754A3E79164E2373306C87F9814A07F155BE50F9EC2968F5E9D1A620240DAD2FCBD7521D8A875F8C50E6F86DEFB1BBC6ED7E8A9E434BAD73AC655B507A7F306A1554E73683BC5626D9EBA5C68CA9017AF81F74DB79CB2C594ECE50A73C8AA927554A30444D147DB937D5664D480D85FD560225E6DF2CCC33FF2C4EFC13A9E1116A373EB9CE1A064D10DF412A0C989FDCFCE6453AF69131D21DBC2B0D2EA5690DD4C76ACE68101E8C62487E06B303B41538A6FA71F264156E58E3BB29726E527F8C2E0E8285A9600FECE97E8FEC1C23F3FAFC6BD9D87067888B619328E25178198ED8CF2EA8D064A7B4B3B23FCC20734472B21D1E953024A3EF48B6379D632663607D22B81D3733E5E0A91F2A923BCBD91869BC51392625D0AB03676E6F2493327BC2F3E22C372BD1B6F9B33979FBB4F0EAA539E0510348F54C08C8F15AD4164AE7C8AF54F1C350AB9199BCBDDB54F4A346345F8F3D2418CEC1ACAC26E0AA592417D341A561BBD234FD5592E98308464AC5075B12EC1CBBDCF6D755C1B7214DAD0D68B2E031001216D0F0E8C458ED8446C81C6A689E776128C8327153E8908A38DB062520C4674773AFAEEE925B3C147F2573BAF628B90451CD169A7CE7CD110E54FF4AADDF92D0BFA853BFA03DC7C4E56A0A9807F3D17461E018C0CFB45968788D8242B3F6BC497052C272A1D1F9AD87DF0AE450BC9CFD342C10B6D1B644607C7CE3A26E8502C3C511B4958AC2064F9341036687A2F60C1415484D044B9C1B311EC5DFC5CE73D419FA7F2FDA6A69DEE46B8B53304FFB8C6B54C28524C3F85AE319DD339EEA6EC82DB6F0E71A52ED1032A01E00E9197843D5D6CC394CD826938E3791CAB36CD64C1B96B9139B761FA05B7CE05B548AD6AF898EACC9F41EEC6F4913B0493C22354CF3FD33D7CDB1A77823945EEFF0FF14FE286D8C6C94D681870457EA2B17EB50F15F3A4FCC15D3FEE02C1755B1311C8AD40A953FEB72429989F20465C0614826D863F0F2B8B6F79506D1F4696049B87DEE0DD4F9572EC64E7DFA4E2762012D5D7501399407BBD1377A99D38BE5523D286BFE047F15A35470262B8AEF766EC1F1044BE8E8091E28337F2E6AC3CE60230CEBA94D7263F17631E7BD5AC570E4F8E9DB1295C47523F55AC69BCB6E700C96275D622DAAD8FA5EB8AC2D8596C66D9A36921AC8876DD857DF0CCCD9E995B42B9B4A35E2173167FFAD52C3EDF245E1F309A39463EE1AACB6CE436ADEEEADD3F23CB7A046AC04B1975643D26D8947B99BA98C8115AEFBFC68AE16161045F4AFB151FCB9A8B99B48DA52A16DA615960743BFC8D37DB87BC5267432EB1F3B2B7CD6BDCE900D18C7DEBEA76E74FFAE48AFB2B2F0D93BD7550EED69704645586760AB0D7A4E1EFEAD9E32C11FA3D2941403A4928F52608E56DA5841B23F9ECD188588D1E06595C8096BD8BFEC4C8026D733E6958366140C45E074A1FDDBE5E660287157668246664C17701CA69FA30AC21E2C66EB6FC2133ECBFDA9053013002A2985376E8C64E3DF2E5A1ED150A2A77DA3E48749C2FEDA06F1E4F2E13344348FCF64587B3DD571FEDEF9435C00D6B9905EC78C3CF2E2275B1CE57CD54281CD7B2653618793966DCBD52213C1DE648E00866BFF9879685D91367FEE3A0C860C40BEE995D1F83E3DD8A18826B2BB1394A3DC5ACC8D32ABD88AC3883736F1A87F1207ADC1DC24314AFA573CEC977E9CB9A872F42228CD3A3A1F2CDE0F5B48AAB9F8E57AA4DB21CD76CD4F6818DBFA5A6EEA2045FC4A5FC94232700411BBEBF3CFA3A1EA79DBD80B06A1756910DFDA987316433548788243EE97A2CA95E48FE04EC9B94409088D1A174F0C72EB9CD40C68F01185090D53C8314CD4A1E3EA7ADE58B834634D9684A9B7597FFD0F94C63E4ABCE55F0DBDF098BB25E91DC34E12B87FE7990E7F42AE93D3786BBB04EF4557645971CBE15361C9CA0334F7BC24060E7719B302BD30B03DF4F6FE0E4704171622F698F49A12A2F275B54F189D3CCBCC985E3484D6CF116B48838B7285FF2BA096B1D5922F3CE587E8E01E2D52D810E8F4A043E8E52961423CB4D5598DB0956D5571701CFAD3D7D82F6880C5DACC062B38B132B860E67D872C6C13B3A058DFB5EB2514D20349A672D4CBEA53A0992E4DB48DF060ECDEB36AE029F911F2D09C56C26659A3AB6B062FB87DAB85703921BEE6AB6753189ED1E66A6D114E98B09413F8D07C8056F393431A3CEDB33E90B8C599D41D1E62E95F4BFF1B95D16F29DA210E290E623331E35D0C751D82C935CD554F17D936A690435447DA2C31DFF0CA9A5FC732E9A9F2045AE04594F36DAE29EB90ADE939D701491E2F5EF7B3425161EBA828083733742B7D9CD69C6C51E9A574C2130C92CDF8DCC3B3A8B6659B70F64725133A9FD36DE92C29A485C582BB80B5C6609CC4C7D274BB7FAAF35EC4D80F5362F198D5B837132D84273B57B21103639CA52F910FDBD585155A2BD052051BC9E8E43C7AA006A41FE7864BBFBA510253161545DC3E660490763A929FD7A5FB32773FF52FDEA9FE7D35C141D13ABFEFA7A164D484F75B78484DACBE33271095DB0A74F25E78B1C0514641F50D62A173D20DF1B3860 +remain = 1152921504606846974 +max = 1152921504606846975 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-3_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-3_256.rsp new file mode 100644 index 0000000000..ab3935d58d --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-3_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHAKE_60/3_256 + +pk = 00000016BBA15DFC230A90773653F36EDD994F661301535E235D0034A34B25B25C58531B04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 000000160000000000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94ABBA15DFC230A90773653F36EDD994F661301535E235D0034A34B25B25C58531B04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C7D176B37A7DC26214FBBF555DDEF8D970B6AA840AFCEE7B674EE05845118A6FB277ABEB1A792B61CA4D24646DBBFD623564F93B74C1277C1AE4CB326411850F0371D6A848ED0BBFB8B0BC3254398F513E630D075CDD277E0AE10D8D13EBDD0CC60AB0FFC61631C5D17989AD9DDF25BADAF0BB87FD0E32975EB673434812D58CC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D9330900000000000121C29A3D4E6C5DAA979424FCA26B0EBE6D3FEA8F078FA9A98B0F55503C2541CE0A0000000000015EB6FB8267689B81BC8E2C8950E5F59F4B43194AB167C4A60EC9BCDA7572E5980B000000000001F02838F27F104405AA4D9E111D3A0B1849F6725926BA5B3A6412DEF900E7259A0C000000000001BA1EE79A04487C5639BA096A60E3E17F7A0E9C0238FA049EA7AFF52FAF5890980D000000000001B63504B794C356EB44A98DE32960830E6B275526432F232A7729ADA72571E8D90E0000000000014DA82230B909123D34E30FE0722BDD93EB6D56243518275547CBA7C473744E6F0F0000000000017AD15652FFFF1B8B9E752AD4A07EA737B8D79DE25D7F194E19ACF003E62C48F610000000000001D6819E585CEA52B14299092F01E66E9A6E7AFC9613A69B89ADE061890A230145110000000000017FB1A159FFBC19461AD72D4E385722A08E9A942BDBC3CF8352CAECD938737D89120000000000017B2C7FC20B3305327D2F0FC3C4854B0053D00E56EE4E005E43CBE807A619BEA8130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A86CB037675575D46C48D89A7B644810666979BFDDE595E1A2362B9961A71D9F75A4A72ABF56BBE2C07844E774123A5DEED0116677B286BB3F8BCAF92D501A5FF375487D2694B089FAF47D8632DA9E213A9C914689D9FD8B0DA5320F6A89787E198248FA523B9B2E910FE55F6127ABFE1FF1EDFBAFF132A06AB9FF0F2E368AEFC6AFAAE9F61068AEEFCAF427D37CD93FC0B0D226CDCF6A7C1F007BE2E59568970AB644D475E62D7B8E7E5F7BBCEA4D007BDDAAFCF6B84E09BCBC5553F516E2E5DFFFEB66C9F5EF34559251705C736FF66A96AD2CA2C40A368602DF65045808D87B7E24CE23C67906BF64C90CF0E0F8621537D08A09290E431737F9C493DBADF98C9E250E094C6F0F7E850F5EF65E71967F69159ADD14974C1AF501C74F01D1C36AEBE604A32DC02B676BBD7CE4BC3967FA8899F3B1F654E7F3E425ADB5ACF59B6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000018F224E19E61C8A7076585BF7780AD32D73D04D66A52F0B4CB6D35D9496906BFB05000000000001C0F7248E24BEA5635FD0F3F3411F1A20316CD29E2BDE6DCCBDEF8AFD463CADB306000000000001BFE2E0B4F4BD9B2B955C3CE73D4D0E703C44BE5168224D99756D865D86689E1607000000000001EB5D1F16948BBDEB3335E0F93C3DAC5C3FF7DCB33B16BB28D3826194192729F80800000000000194BC268989E8C957203F60EFD29089692A7FA0980912BCCB1FF3D6921B9805610900000000000182B44F3F72EC96002984E059C46042E3085A35BBBA6A0CA79700D29DB34DF2FA0A000000000001174A1DED5F222EB3573B2A6CC27870F2FAB30A64FFB9601B5B8167314CD3C4AC0B000000000001CEC1E018C94D354F99802059603298AAB121FB0D1CE89A6C90B945D90A6233560C00000000000184D0355AC86A5E83CCA4300AD4EF13DCF7D6185ADD1B29F22FF24B446B6A184C0D000000000001EF0BF8DB8426844A322EACD3C79500078561868864057744206E70294F1B4FBF0E000000000001EA649E4FFD3B7A864E5C9177F8B14D91BE4CFDB050B6EBC86571996AFC1AF62C0F000000000001F80F14346EB4A8387798C08955A0CAF061B367B1F969D28F833140663D9A4B24100000000000010990AE38170C318A1CB81B1C8C6D980077F153C1C0403EC9645459C3C222225011000000000001DDF5AD2829966C243C523B4B91800973741F27929353122DFD2F0F9DE717F31D12000000000001254C2BE70DF73E405F76FFAA6BF442F41018C0C2D3823AC64CC175A601ECE527130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B832C73668D17AF4C29F2A72A1E8DC0D74C9F2446DE7A42F50A5DCA2F12EE84A91F75004E452A4E5FC799176A42B4D0A0A0CDAD9B44CC246872114650941B08315BA68E4B39A713B08A66F1715FE9300E5AAC533E37AE289B74341BC1DC7C75725C9838412E48A4CE312DEBC345B16A3A1F6388F350997448653448F6C7C91B7BE24118C3A0F4E431E88766E5A6C6113C8A2D1D2646B5EA5821C90CBE2CCB6CCA072F8AC327FD013B98A44146A45192D07A49B3FE150DB78658E659EB8546072823C7AFABE43959B08C3E239FAD4B3F0E87E872FF749B1DB73E5E9337731596C9DCE65AC0A8965DCD720A4B978015DE82E08B56B7C9D2D895861C15B766F9AB3C97E87206A7B951DA427DECC0653B7008BEE0B34E5B8A9D486832469079EECE91552F6208FDCFFD2E81B9E968F16C7A6E718FD43A6699A0E4D2F4692F3F56C2E31C33C937720276C8362A6839A6A055BDB5737525429AF0ACC1C8345BE9A2E9F269938969EE47C53A6E06BF3D9896DD79382F4210266C3BBB9F17386003F120AE41CF9F513B70D94E5A0DF54A0D52D5632495C7D6C843BBA812723C1BA75A6CD8B8FDA61F39B5EE34DABF596608877296A59158883CA4FB0402E22AEF63B5E1658DA5CD6F3BD2AD8D2846B76F86A831EF9F8E2F2EC334ADF81B976512F8FE7D2B9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001521B6795E3B31C6F469147CDE5776D1FAF80EE268B570DD87C1895E195F358E50100000000000135050ED1EAD3E799B63D5EDC01FDE9B7E3E8036A429C0AB56C909CC2B6378D6F020000000000010D93E097DE2D5330AA792D234007668B3E7F9E699621D298D2AB7577E8518A0703000000000001F2616B47D5F8376AF6A5FC658A75A52D032F7A1710630905C152957F41FA240104000000000001806EBD8412403D61AFCBD000376F11695F17BD253F82340C13342F750D09B2D205000000000001207581737977FDD59550FE1E0E62692061E1E37C554529C52E427434D2BC50AD060000000000012C3C45D74BE1C78902947B902756864EFD771DAF34009F91281FBAD0636A74EE070000000000014DC0E1A0DD7194009DC2FC5355C4D62179DA0010E19737654D7DC0E4C9761DFD0800000000000112F03C455D30919DCE22D2F8A0D4B5491A8188A32F17059A6AF994ADE911EF7509000000000001D61AF779A884D53CC99CB056977E564D49F3190CB260462D33ED4C7F0C47AEA80A00000000000174597C0DE43986083F16D33DB5D530E1771AB7CD8D0FBD09BD72854FED1D42C70B0000000000013CBB61C52DC21D115B9BBB0BA69F63D69C35C4047DE852373D70E445D4EB8F710C00000000000149B8C0E29BD2C1508E64FCE039EA36B491D678210DA046FDA6F7216B6276B64E0D0000000000016452B2D12F811FCC1544588490B05FEE831CC4B55263A2425F4AFDB7C804F5710E000000000001862BEC10334F6E0D0E998675C7F4E33F5DA105D68125FB2A8CAA0864D82B1AFF0F000000000001892D8275D3DF4A2354CA013048D86DCCD42EC388A2C20763E351DDA579550C131000000000000124BE91AFEB60D60AB3FAC980149680E6292FD0D89B416DB25C3F354084EDCC911100000000000135E8282E4B19327B8509A8F740D4C94CECB06BB8857844D40E6B38A061E75FB412000000000001B78706158F9720D3B08696410F42566DA7B34846E1D8A586FC003234F885B75A1300000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000665137D5D47667E1CA8F1B70A9029441013DB1E00D4FB39DE01E275ADE1AF6E6483B18C34D78AD814C71F370A0AF1E681C1041FFFACF9685BABB03923BDB41701F927F3316ED4DA8420A373F5471BE4A7215CFE5683EF16855C748D8FBD21DD9A6C36EBDA9BC5497F5C0C93DDBD40A717DCE151B87E8D5CCEFE5E8A0A66B3F92739B24915DA4B87BC7E555AE0554A8FC1D2514A7979DCC78E92D79C6908005648F90E5E4AB32CBDE27EF1BDE91C49C5184A3CE134D7AD33A1AC03F4A09CC245DAB6033C99636D9F6E9A723429F5EDFE118C045EDA721EB21387225EE2764A00D99625EB4FDDDAE398DBB4D8CD926310601CB34D38B7BA4BF60C66925B2E66B838C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A3692F3176BEC212C8CDDA63B223901AFF8E3CA0612978B7D97E8F2E1C000B0D2FB992BE80BE6906A967BE9949853BED6333CB070A1384B5A26ADF28D3BC5ED2236C6699909AC8EF3CE18997A672EFA2087DC9C0C38BB416613F206E136D3135C4E39F98C7C1F50DBBD69337069248EC64C3E5C6EE0EB7618396BFBC2BA26667426721DC84D3A53129AF465CAB586A54924BD35CA4BB250865AE0EFE67BDF060D8F947141B55502BD264BE2F24B40DA59C45FA59620F207E10FE94013B6A9F94182CFDA5694E19B1ADA22B18F183D7DF0A51AE2876A5D6B79D911B0B8A0D3EA283DDE8F0FC0DA1D77498ADC4DE901F89F11DE2753E8EF674622BF03110CB519AE4F6CD0ADC41A43D1929CBE5047D9B09FE60D9075C85CEAE9C825EA53585D180FB610BBA83BBA2E590AC5257DF858E7F11B8298C848F2F79D78C37F00474AEF9B5E9AEDBA4C81ABA062F24531171F8137F7FCF50FE09A38F60404B03CD1BAA934D6DB5CFCB1DC552BF873C6AA9B5FE76FAE92D4C3674E20DCA7BBF430C865F6E5FB5D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF710D288F760D8E6A64D9E2E53F680C21D30AC1439A4A90469D0C6271AB6EFBB90A4F4DBFF7D5F3875C6507DB321D81C3510D7E7F48B297881DB6FA0AFCE41645FC93A37FF04FCBA7FC19B9089BEABCF9BDF44E2C4614A73FEC80C1234162B41BDF1313F6E13AE2C48A6C4CABEF5EDE59AD461384DEFAF1935E23F5CAB3829A81E2DFFBBCF2FFB141D975EABF78FB4BD484F75E08318C08B2104A468E670786397EEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA360AB78FD9219EA890695CE44CC785A3A4DD39CB8F3C82FA5C6A3167055CF3309EB06EB90826159619E65C5E29D46D35E61C961AEC002F87B44A2B7D5C0E2111D17268FC3B147434264112A2E95AADA6ED860C50359372609ADB174741CC3AAAAD1FB50A42A560BB18D12C228F10D2776DED26752930890259A5C0F64C7D30C49383F92F1EAC6B1E8D6BA05423368AD3A8BD145D397389720E80F6EE11965E467D4D5864E164E51437277F698BEDA846AEB66DA3DEF39CA3288D30C001D3B0BCA113AFE8AD333A08D801A9E4C52DF0DDD4C63D8DF7EA938014336BDCDFA10E960DDDB4B5471263D096A49E3C83A188C46AD4EA8D2AEAAD3B1BA78CF6F116D0818BD2F38DB39D74D340546233ABC52278B381B7DEDC3A3B5DAADC8A4E7519AC9F3572A35C016CC7A8E0FABC029801012DD7454D7475E5D8B492A119AC583F4043D25CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438D81219D292421651600D48C2BD291766ABA14ADDC9186764DD212446D27C3738D2F606A9654BB310288F37CF0ECD5D38590E4D887D9D5C523527007F6501ACBE7CF36803727022D98CB15BCC0A88A509DF3B9A84E99B41843283FF2E10FBDA3C14CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D446D278BBC90D6A56B71D6DA6FCA49F332776F402F58D180482B2EBA5132D8ED67144DA06AAF952EF5B9BEBBF0CC8101E93F3BE05E58EB75D55B3CE72B9C8A07725C61C24C34DEB9A7349E51256EECB7DB61510D8BF55798B060EEDF9F9551AA615F1661F544B0779B2974A54BE8BBA388D6D7FB8E2C0956DCB23F834025CAE4BF26B798CBD5938A517C4C3B8FD3B8FE920558256C391433854481944BE487AFBD226853E385D942014B393488D554FBC143B44F7E9F348FB79920D4AB758CAEC55ED8CD388DCE4B4381D5C3A9FF36ACF9948993CF2B2E03030646852CB4193585AC6C56947193F96292D813FCF3671D46B9DF2D99D43E0AB4F1994B81235A50D5D977FA3560CA3D46CF60945C8D3E1103B6B1D13CCFAE43741BE65EAFFB9DCAB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832D381248D668B0A5ADC623F2529B02CCE42442E86382E03BA3FAF21F86FDE1C633C9A17426EF1F4923824A1E394BBAF5058C00950968357FEA01AFA8303DAA21BAE4617293B3B19A50C88C8F7D8A677A3314640452734E7FE4BA483C8AF87356E6822D943C23705352F458ED80B8375DA6F1F0DD7688CBC6101727F2AE7FE500C98A185F29DC71EE3506F8425B8D7EA94BE228679F42ACED5C9162D6A0E9AF148E5903C0ACC117C2BAAF1EC4A73A0BF73CDC646D1559EB1FA607044B5C7CA60FBDD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C6F2AE696330DD7C816130134AC101764D6B4FAFA1E71A404CEBA3406E1996391AC35A28F18E05DA188AA8FB52712696C986C25F70A31DA73957B238FAE89EE0BE4F77ED34ADFF62BB5C0838F9B645F6851BCA9241ACBCD3038BC40F40F076D1CCD8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CEC2A8424E383ACE82322B3629ADA77D454B677A60A2932B49F844A9389E73FCCB04A4A962E7382E5125E529A0E244ACA7F30287FD74C8938A6CFD5FF3857622A676F9528968A73DCB3458A2ACACFED4EE0F6C6B3EFA7207E8F13B15A8F7DF45A3024EA2D0C6179540EF44A8DD43F70222075D9A11B4C32BB0822113EABC09D37D0925C5D27FF4B27EF82812B5609734A615CDB54529EB30EF57F70B1F177F56776E9AF34A592C707753819140669172E2BA4657977CFA700911BD68BDCA9392759431A2E164C7F420B10982E4AE55E77E15C2499B4F0685AA0FFF4C5830F1CF18E0C22B855FAAEFAA6FAC5D79BB0E504D666EBE0D8F8BE770CAA37FD9A4C254357AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6861E7E10F9C70FFC41ACFDF5DF7C525935C838DFF06C5468E647D8F85F945009A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F953682934476EDB8FE887C37129998A21E92F020460D3AF85356DAA577666F5DC0BCC59CCB9D20278F8B155728F4234D7F11EA25B128E7283D09BCB5F54A03163FCEE112A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E10F0D0BD64F607F4E22EC40D80D95808240F1E89E3F856E32304B1B30486468E5A416E66F1A2A85269A95FB827C5AAB7C55061CD2F8FD8B1B467C274A878E290B66B89AC0D71ECF1800F4DB2701176854E40F42D44AEA68CFA350E5FC1EAB4DA784E1DC80443371C10A5CB7E68EC999451FD9017D85C1413F7E13F521B8F62A2BD56DA107015044432ADDA5485CAC00CE0F17A54A9577EC30221D873FE86D21AB50B0422EA1955082CDDAFC53B4A608CE7BD87264C3B1E44D4DA3EA036C17A0C2CCE310F020942DB86B6974C0A2BC2CEBA92880041135754702C769DFA1F62499203A406C768EC14796AD5DBC55FFC30BAD441FC03BF7EAFAC09D8787C4B5F2A8EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D15998001DA4935E216F14DEB2F74D9EB3BC833378A789B550B985FE0A09EE8D8ABF84E861978642C8AF755604D8C0A0821DC1A47E813464E374F09680E752871421599B4BBD0AD2C7ABCA4223B5223616BF5FF927A2BE4997EC8D7E2C75E6C4761AD4C6F40E96BA127BFB08BC1212F7E4FBCBD839B558C5984116355EF45744AD99D74D29C3880C7C7D839C34061BE1CC4CA1FFF12AE81E5A4DFDC1A2D90039E964261BA2D0266E5193CF81859B3C8D464D8B0A7AEB3C822783C4BF41C71A04D4ADA9EC6FA901CCEDAAF06EAA15D89FA7541347EBD19D6D75DEB384B32C275685DA7B596BF37CF982D238B813055E3B929EB119B2A54E6ADB3B8D315A997B721F589100BDFCC72415407617C203AADBDE0A26C50CFB5DF1BBFCB7D484C2103D54BAE53F5401E80CEEC135F9717D3A82E7F919CD1710B254C91BC2688C8DC1D114B3B1BF9EE40897C9692586285A1553057D54A5AA1D794911CF6F4493E7C4A56B39E8C88BB5E4FEC69BA1F9A3FE964D40DD0AE57A8EF70D2C7ED2C954BE542DA5B856C01988E33CE1160823EA49E5E4D6AD4EFD2BD6EB0A5DA925C0159C4EE9714B7B154E1D715C8FEB898A1DA31D5A8ABAB9CDBAB991459E62BE9F0E0A69791265ACD8F7AEDAF736FB944D3CEA82A1B3F23ED9AC0025760D260009668580A7FE2EFDA06FBD6C189BF2DC49AF474F0198F7A896DFA96C21479389CD1B85C660AB4409EFB415FFD9571BBCCFDA01333286A5A934E32D7C6D7EF3A20DD86ED5391AE3F0AE016E52696CB81A00C5186FDF5B3169C51128537427E443FAB85BB58EE6D9F0B43F56996ECCFF99689272C1CA1E12AA1197E29A23D0AB616D1DA9DDA0BB85E150F12E5F7A773411120EEEF802E49440D774E85754826DA02D1309E1050550F24550D49609811B6662B4E1FAA554A4B0DA3B6D79762A0AED8EFF1E0A78FCE68DBD11046CD8555D83FC03E04D766C89732A1F14D56BBE8724BDEDC4D3BC5712FAC4A5141DB75ADDFA2313FD11CFB56C0847DED068A7134B38B66338B3DDE3EEA0C1A11B95F4AD251AFA121C53B39AECB4F804F003D4B202EEF58BBEB16E8ECC1A373ED33FE945991DAC70B8C1DBB499B8F43EDE0EF546FB88837D8042E03AB9E5ADB3F6B9D7B1B95C9FD7233772FDE5DB57B2C533127B0A566BE3C386339DD406F37450F0E477859629CE2B957F3415CC4E2CDB795EB766193DB9CC1E5D3455ED18876287061E39313146C9975417905C247964637492577D9D6F33F4CB1E79426A67B00522DB7DC0D3942F9848287C6F1ECC38A0C93D0E666CAD000AB73B23019D08FC342C9941B31E8BABB65862DAC87CF204EEFC17B6D204F607F60F62A60CD3A02B6E121E1CE591185608500C11AAAEB039497472C12F766386647573387AFEBEB8DD850B853D7C548CC8ACF1E3CEA95E9F2710A6CEEEBBF4A3C6B5A69785106B54205049A9D3C611AE5B4C793058B64536750007BDD97662E2D4C0466738B53D22288F3116F88C5BD5670FA08278385F22510070BB44827D0268FA12DFF0AEF482A87AE152C9A588C6DBB41E4B0B325FF957E45A7F6E7234A8DD609AFC3E2D553CC25C9324591794E60FDE66E2F268FCAA01768FECD57AC90DDCCC988A37AE97A46F7ED29F3D2D34A83AA3CBF17F7C34651BC1278DA9646B228247E0BE29AEA13601305C9F130DD40BAB49A9D9DEC13337A24AA2181E57014F6DAB71CA701C1DBB33A28DEBB815B034952CC68E38E566CBD1B23C1AB6DF52384591A92F8C039F240D39B2F363E8621EBECEBADA3DA938E783A72AB8B5D0D287157649EA39E6D7DCC178F2F979A1931CA6692B746A851CBE2FB336307160CFA574F4EC5319F339F2C79B060A8D875507227D8010A9D74F4E2CE9C92F14466121252B8706F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174CC1FEA72203D681B212B1890DDB2D48CA6197C5B9ABDC377723EF0884703BE27 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 8392 +sm = 00000000000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6E5E19338E14E4588FDAD9A348A2B69BB3DB947C41E74B1C49E267A77A94FE9B2438442FE81428E5791B24619D5C18E17066E74EBB881E828DE7442F7EC0F03CCBCEFD889D3361070C554580F55CDC11D8572F0E0F241E24FF7A7AC9E3BFD197FD962E4E6007A684AF87B096B9034966949F56D02660E2B7279214CEB93E6207366A0D5672F44DBB9632CE082C47A1191092030F878A87D3007016131038259D35C2EBF786119150D628A09E9E1C58F8508716FA31DCE1C2CCF7854910D291C83498AC8202BBB4017F727A5E938725AB65B75087A25A952B3F2A54A07C27A654FCEB150A192915844DBD22D5956CF2334FB69351F62036F9C7BF591274153FCF4DCFFA47AB17563DEFAC3A51C0C7E96367FD2A5BDB6420DB2F8E1FA8A1E04E02BD2F72D66DE7B1926B078E7789AF0FF371935A7E432EDF91FF02B2F55E3D348544E86EFC3CBB41204EAD55A3B933F6F3CAA2C4BE36D24A290DB58852434D7C45EBBA724670050F31569813630709AB6A4E35D66684AB154CF647FD64DA3B2E5530B4ECA5ABD9666549F8079173D267642D94F9660C76FF6D5378E015B792B13BB6A3AA55210070C4A413B056C20B2C53135921000948C58FA834135A5C0B3B2849A586CB2FF84925B00E791AD53B58AC6E577BF03A33D008112242388D1464B4616413EFF6A8317C1BA5D42DB01AE12DF2DF062E71777C618CBE7B220A76E5CBF2C0CCE36561758781EB57877CDA69BA5118EBF885452A682B2F650FB9C650884F655867F45720C67D422D5D284328E5439C2BE923E7F9C5307F30E5091A88A02B818B7E31A574796497C2AD22C79CDFF65DE6D4E12F165710A69D1474BC7FB5E4DF07EFD4A4BBDD190878F81047F477A4FF9B89DBA8ACA2B5058528061CC13CC41C207AE1E556CD36E764A42276078F723FA45F7DDE9B045FA1B2B87D528A0C4CB0B5D16C7813F05F9578CECC287D621864B54E54836F3315642DAF8E0F3A61CF1AB866C0EC37A66D86CED0DCAA7DAD8A4E71E08A856A7E8809F918430DD06389BF995302B29441CCE5279FC490F0C8016647BF4125C4E75F168CEC378A488F66EDAF3A6A71C48FA89786E1A76FE326B90AF058B1627040851A517242451CFC34CC73FDA4B0851CE702E085953B9D195E13981E55CCDBA1620CB5DA2D599570A28E55818BC0221E11D899EA733D34DF501FA99A2446DA2F93074804B56E3A7C859E35F94A4492867F7A94B9CBA5348F7071C5732563F8C1C008AD8C1767EC2D20F68C863733E6CA47A29B5851D58F687B256965482434A3643877BD2C0EEC4FF5F8CC13A89E775AB6123C3A1D8301FBA857F30B65D1961FCCDF1C0A1E541092064590954449C3DA834F44EF0A3DA76A90F5FE8EFBFEDBC1BAAE5256E6A1599B45EF51D9A6F477F108EFC9DCC7F139617993D5362ED390A73955749EF1FF0825D5728E4A8CA6264070A7F1F09CD093CAD71FE3263B0E60C73F5F8641AFAF0767651D6534AE73B220CA73A13917887367D055D38A65273890D1FB7A3AD50A7BEC3E7B693C41F717FEC260DC06486D04822DCD3BA1CEB89F12DFFE3534B51B107E7B565F6F3F7774A9CE75488FBA6FF0205FD45334A09906A3774718DDF36BB668C3739D139D5E629140BE6778F0C912343373F637A516E029047FCCECD7C99A5966B1E2CC30E6E7DC45BFDA37C100EB88E44069492CECC82E9E4EC8C7C2C9F85B06F2846EB553C0C49BBD6342D26380F215F7E213C61335DE8F2FE877D38BC2BF84DBDCE94CF1B52C96E524E7179C8ACBBCFCAB586CE6CDAC4FD71787904D4D19A3C95963CC8A0B0F4073965CD5FEBC875F971ECD647F269A6365491CFB0E6F090CEDD43D7F85EB9C9B771CB8EEA797E79F369BCE45087374A20BDC6FEB45871AF23ED0DEA058A8286493883F63B6E25C9BED28B91EC3E6DA1574ECB713557BD2FDC3BCE635C4C98CD3ABDA6B585B5B449422C4CA053D1BD0F83D42696307351BF6C2BC2E38B5392D75F260AB7393D4EC5143E08DE25ABA6FA90C13F1C3CB010C4509B13FB00DF87ED2BFDEA30928486A9363A6559C08A4ED761F5FC89A488B81BD6EB146BA166B7B203A84170E9548C89FD3F34D1B8A288200E2D803B6E5B0A46A45A8CE5E4DA1B56AF04BE0A2D9C1329842C497877D9A5E8FEEA8BD056653836DC0C5363795788CEFC6210B502DB88C434099C46316476FB3FB07E701E29075A820C8D25218B7AB81957686E1BB2C02A72AD3B067589E7E454232E6D4AED6D53228C7A86656CF2453006F1E5F826B247F52F4E7571D886BCEF76579C5A1079EB84454856FC5CBB7A94FE1E8BD05D1597E645C90A90D55196BE811AD44683DC922867C4C6EA4699B17DEA5264D74F30E6C28321576BE93430D75ECBD4D8A99DA5DA96673D115C6382653416DFFD0674E93337AD105F1C5ACDEDF7520B819C2C6669480FCD587D115B1D7951C75225493628CB4963EEF967CF17C509540AD2B7655DD0CA93368A62B937DB491F571A2CBFF957ACC7EDC2201410DB78EFDD783B77B822CD2D5C228338C8F636B590C8B4A083F22185374FB311A8C28990CB91D89E58448E57618F066065AD0653A7135CE175D55D84E19D45932534D0045CE8827E6C485A679499AC15C89843802B844E9E5A280057C9A5DCE4D75B14DCB8CF4475FB01A405403F4ADDD2097729FDE708EB369DB19FAFC35528A11EFF706445E69FF3D16410BA04D24CB605E507D60D552FAA2EC3B70B4AED58517804EC52A746859329225E1BCB7F680B66729BEAAB9C5AC5A2120C8D427E349F364F595BC1D728DAEA01CE9C99BAC79F55E0CCB1C03AF2EF2C56D45E06D33F9D3ABBC6CB4BE097379B461E10794BF16A80B825E59B4645E849AD89E8F7D867355ACE237317FFECE24D982E067547936FBB57F2C25218A230EFB1A665F3D948CDEAA9F8659900F10C43437C01BF081D2664641DB6FD5B0CBE2004A96DD26D999937817B3A8DFF74E2CB3E61134E6B4CF5811150F4276945BA08D0779468902DB915F36620A54536F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C7D176B37A7DC26214FBBF555DDEF8D970B6AA840AFCEE7B674EE05845118A6FB277ABEB1A792B61CA4D24646DBBFD623564F93B74C1277C1AE4CB326411850F0371D6A848ED0BBFB8B0BC3254398F513E630D075CDD277E0AE10D8D13EBDD0CC60AB0FFC61631C5D17989AD9DDF25BADAF0BB87FD0E32975EB673434812D58CC665137D5D47667E1CA8F1B70A9029441013DB1E00D4FB39DE01E275ADE1AF6E6483B18C34D78AD814C71F370A0AF1E681C1041FFFACF9685BABB03923BDB41701F927F3316ED4DA8420A373F5471BE4A7215CFE5683EF16855C748D8FBD21DD9A6C36EBDA9BC5497F5C0C93DDBD40A717DCE151B87E8D5CCEFE5E8A0A66B3F92739B24915DA4B87BC7E555AE0554A8FC1D2514A7979DCC78E92D79C6908005648F90E5E4AB32CBDE27EF1BDE91C49C5184A3CE134D7AD33A1AC03F4A09CC245DAB6033C99636D9F6E9A723429F5EDFE118C045EDA721EB21387225EE2764A00D99625EB4FDDDAE398DBB4D8CD926310601CB34D38B7BA4BF60C66925B2E66B838C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A3692F3176BEC212C8CDDA63B223901AFF8E3CA0612978B7D97E8F2E1C000B0D2FB992BE80BE6906A967BE9949853BED6333CB070A1384B5A26ADF28D3BC5ED2236C6699909AC8EF3CE18997A672EFA2087DC9C0C38BB416613F206E136D3135C4E39F98C7C1F50DBBD69337069248EC64C3E5C6EE0EB7618396BFBC2BA26667426721DC84D3A53129AF465CAB586A54924BD35CA4BB250865AE0EFE67BDF060D8F947141B55502BD264BE2F24B40DA59C45FA59620F207E10FE94013B6A9F94182CFDA5694E19B1ADA22B18F183D7DF0A51AE2876A5D6B79D911B0B8A0D3EA283DDE8F0FC0DA1D77498ADC4DE901F89F11DE2753E8EF674622BF03110CB519AE4F6CD0ADC41A43D1929CBE5047D9B09FE60D9075C85CEAE9C825EA53585D180FB610BBA83BBA2E590AC5257DF858E7F11B8298C848F2F79D78C37F00474AEF9B5E9AEDBA4C81ABA062F24531171F8137F7FCF50FE09A38F60404B03CD1BAA934D6DB5CFCB1DC552BF873C6AA9B5FE76FAE92D4C3674E20DCA7BBF430C865F6E5FB5D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF710D288F760D8E6A64D9E2E53F680C21D30AC1439A4A90469D0C6271AB6EFBB90A4F4DBFF7D5F3875C6507DB321D81C3510D7E7F48B297881DB6FA0AFCE41645FC93A37FF04FCBA7FC19B9089BEABCF9BDF44E2C4614A73FEC80C1234162B41BDF1313F6E13AE2C48A6C4CABEF5EDE59AD461384DEFAF1935E23F5CAB3829A81E2DFFBBCF2FFB141D975EABF78FB4BD484F75E08318C08B2104A468E670786397EEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA360AB78FD9219EA890695CE44CC785A3A4DD39CB8F3C82FA5C6A3167055CF3309EB06EB90826159619E65C5E29D46D35E61C961AEC002F87B44A2B7D5C0E2111D17268FC3B147434264112A2E95AADA6ED860C50359372609ADB174741CC3AAAAD1FB50A42A560BB18D12C228F10D2776DED26752930890259A5C0F64C7D30C49383F92F1EAC6B1E8D6BA05423368AD3A8BD145D397389720E80F6EE11965E467D4D5864E164E51437277F698BEDA846AEB66DA3DEF39CA3288D30C001D3B0BCA113AFE8AD333A08D801A9E4C52DF0DDD4C63D8DF7EA938014336BDCDFA10E960DDDB4B5471263D096A49E3C83A188C46AD4EA8D2AEAAD3B1BA78CF6F116D0818BD2F38DB39D74D340546233ABC52278B381B7DEDC3A3B5DAADC8A4E7519AC9F3572A35C016CC7A8E0FABC029801012DD7454D7475E5D8B492A119AC583F4043D25CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438D81219D292421651600D48C2BD291766ABA14ADDC9186764DD212446D27C3738D2F606A9654BB310288F37CF0ECD5D38590E4D887D9D5C523527007F6501ACBE7CF36803727022D98CB15BCC0A88A509DF3B9A84E99B41843283FF2E10FBDA3C14CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D446D278BBC90D6A56B71D6DA6FCA49F332776F402F58D180482B2EBA5132D8ED67144DA06AAF952EF5B9BEBBF0CC8101E93F3BE05E58EB75D55B3CE72B9C8A07725C61C24C34DEB9A7349E51256EECB7DB61510D8BF55798B060EEDF9F9551AA615F1661F544B0779B2974A54BE8BBA388D6D7FB8E2C0956DCB23F834025CAE4BF26B798CBD5938A517C4C3B8FD3B8FE920558256C391433854481944BE487AFBD226853E385D942014B393488D554FBC143B44F7E9F348FB79920D4AB758CAEC55ED8CD388DCE4B4381D5C3A9FF36ACF9948993CF2B2E03030646852CB4193585AC6C56947193F96292D813FCF3671D46B9DF2D99D43E0AB4F1994B81235A50D5D977FA3560CA3D46CF60945C8D3E1103B6B1D13CCFAE43741BE65EAFFB9DCAB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832D381248D668B0A5ADC623F2529B02CCE42442E86382E03BA3FAF21F86FDE1C633C9A17426EF1F4923824A1E394BBAF5058C00950968357FEA01AFA8303DAA21BAE4617293B3B19A50C88C8F7D8A677A3314640452734E7FE4BA483C8AF87356E6822D943C23705352F458ED80B8375DA6F1F0DD7688CBC6101727F2AE7FE500C98A185F29DC71EE3506F8425B8D7EA94BE228679F42ACED5C9162D6A0E9AF148E5903C0ACC117C2BAAF1EC4A73A0BF73CDC646D1559EB1FA607044B5C7CA60FBDD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C6F2AE696330DD7C816130134AC101764D6B4FAFA1E71A404CEBA3406E1996391AC35A28F18E05DA188AA8FB52712696C986C25F70A31DA73957B238FAE89EE0BE4F77ED34ADFF62BB5C0838F9B645F6851BCA9241ACBCD3038BC40F40F076D1CCD8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CEC2A8424E383ACE82322B3629ADA77D454B677A60A2932B49F844A9389E73FCCB22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A86CB037675575D46C48D89A7B644810666979BFDDE595E1A2362B9961A71D9F75A4A72ABF56BBE2C07844E774123A5DEED0116677B286BB3F8BCAF92D501A5FF375487D2694B089FAF47D8632DA9E213A9C914689D9FD8B0DA5320F6A89787E198248FA523B9B2E910FE55F6127ABFE1FF1EDFBAFF132A06AB9FF0F2E368AEFC6AFAAE9F61068AEEFCAF427D37CD93FC0B0D226CDCF6A7C1F007BE2E59568970AB644D475E62D7B8E7E5F7BBCEA4D007BDDAAFCF6B84E09BCBC5553F516E2E5DFFFEB66C9F5EF34559251705C736FF66A96AD2CA2C40A368602DF65045808D87B7E24CE23C67906BF64C90CF0E0F8621537D08A09290E431737F9C493DBADF98C9E250E094C6F0F7E850F5EF65E71967F69159ADD14974C1AF501C74F01D1C36AEBE604A32DC02B676BBD7CE4BC3967FA8899F3B1F654E7F3E425ADB5ACF59B604A4A962E7382E5125E529A0E244ACA7F30287FD74C8938A6CFD5FF3857622A676F9528968A73DCB3458A2ACACFED4EE0F6C6B3EFA7207E8F13B15A8F7DF45A3024EA2D0C6179540EF44A8DD43F70222075D9A11B4C32BB0822113EABC09D37D0925C5D27FF4B27EF82812B5609734A615CDB54529EB30EF57F70B1F177F56776E9AF34A592C707753819140669172E2BA4657977CFA700911BD68BDCA9392759431A2E164C7F420B10982E4AE55E77E15C2499B4F0685AA0FFF4C5830F1CF18E0C22B855FAAEFAA6FAC5D79BB0E504D666EBE0D8F8BE770CAA37FD9A4C254357AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6861E7E10F9C70FFC41ACFDF5DF7C525935C838DFF06C5468E647D8F85F945009A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F953682934476EDB8FE887C37129998A21E92F020460D3AF85356DAA577666F5DC0BCC59CCB9D20278F8B155728F4234D7F11EA25B128E7283D09BCB5F54A03163FCEE112A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E10F0D0BD64F607F4E22EC40D80D95808240F1E89E3F856E32304B1B30486468E5A416E66F1A2A85269A95FB827C5AAB7C55061CD2F8FD8B1B467C274A878E290B66B89AC0D71ECF1800F4DB2701176854E40F42D44AEA68CFA350E5FC1EAB4DA784E1DC80443371C10A5CB7E68EC999451FD9017D85C1413F7E13F521B8F62A2BD56DA107015044432ADDA5485CAC00CE0F17A54A9577EC30221D873FE86D21AB50B0422EA1955082CDDAFC53B4A608CE7BD87264C3B1E44D4DA3EA036C17A0C2CCE310F020942DB86B6974C0A2BC2CEBA92880041135754702C769DFA1F62499203A406C768EC14796AD5DBC55FFC30BAD441FC03BF7EAFAC09D8787C4B5F2A8EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D15998001DA4935E216F14DEB2F74D9EB3BC833378A789B550B985FE0A09EE8D8ABF84E861978642C8AF755604D8C0A0821DC1A47E813464E374F09680E752871421599B4BBD0AD2C7ABCA4223B5223616BF5FF927A2BE4997EC8D7E2C75E6C4761AD4C6F40E96BA127BFB08BC1212F7E4FBCBD839B558C5984116355EF45744AD99D74D29C3880C7C7D839C34061BE1CC4CA1FFF12AE81E5A4DFDC1A2D90039E964261BA2D0266E5193CF81859B3C8D464D8B0A7AEB3C822783C4BF41C71A04D4ADA9EC6FA901CCEDAAF06EAA15D89FA7541347EBD19D6D75DEB384B32C275685DA7B596BF37CF982D238B813055E3B929EB119B2A54E6ADB3B8D315A997B721F589100BDFCC72415407617C203AADBDE0A26C50CFB5DF1BBFCB7D484C2103D54BAE53F5401E80CEEC135F9717D3A82E7F919CD1710B254C91BC2688C8DC1D114B3B1BF9EE40897C9692586285A1553057D54A5AA1D794911CF6F4493E7C4A56B39E8C88BB5E4FEC69BA1F9A3FE964D40DD0AE57A8EF70D2C7ED2C954BE542DA5B856C01988E33CE1160823EA49E5E4D6AD4EFD2BD6EB0A5DA925C0159C4EE9714B7B154E1D715C8FEB898A1DA31D5A8ABAB9CDBAB991459E62BE9F0E0A69791265ACD8F7AEDAF736FB944D3CEA82A1B3F23ED9AC0025760D260009668580A7FE2EFDA06FBD6C189BF2DC49AF474F0198F7A896DFA96C21479389CD1B85C660AB4409EFB415FFD9571BBCCFDA01333286A5A934E32D7C6D7EF3A20DD86ED5391AE3F0AE016E52696CB81A00C5186FDF5B3169C51128537427E443FAB85BB58EE6D9F0B43F56996ECCFF99689272C1CA1E12AA1197E29A23D0AB616D1DA9DDA0BB85E150F12E5F7A773411120EEEF802E49440D774E85754826DA02D1309E1050550F24550D49609811B6662B4E1FAA554A4B0DA3B6D79762A0AED8EFF1E0A78FCE68DBD11046CD8555D83FC03E04D766C89732A1F14D56BBE8724BDEDC4D3BC5712FAC4A5141DB75ADDFA2313FD11CFB56C0847DED068A7134B38B66338B3DDE3EEA0C1A11B95F4AD251AFA121C53B39AECB4F804F003D4B202EEF58BBEB16E8ECC1A373ED33FE945991DAC70B8C1DBB499B8F43EDE0EF546FB88837D8042E03AB9E5ADB3F6B9D7B1B95C9FD7233772FDE5DB57B2C533127B0A566BE3C386339DD406F37450F0E477859629CE2B957F3415CC4E2CDB795EB766193DB9CC1E5D3455ED18876287061E39313146C9975417905C247964637492577D9D6F33F4CB1E79426A67B00522DB7DC0D3942F9848287C6F1ECC38A0C93D0E666CAD000AB73B23019D08FC342C9941B31E8BABB65862DAC87CF204EEFC17B6D204F607F60F62A60CD3A02B6E121E1CE591185608500C11AAAEB039497472C12F766386647573387AFEBEB8DD850B853D7C548CC8ACF1E3CEA95E9F2710A6CEEEBBF4A3C6B5A69785106B54205049A9D3C611AE5B4C793058B64536750007BDD97662E2D4C0466738B53D22288F3116F88C5BD5670FA08278385F22510070BB44827D0268FA12DFF0AEF482A87AE152C9A588C6DBB41E4B0B325FF957E45A7F6E7234A8DD609AFC3E2D553CC25C9324591794E60FDE66E2F268FCAA01768FECD57AC90DDCCC988A37AE97A46F7ED29F3D2D34A83AA3CBF17F7C34651BC1278DA9646B228247E0BE29AEA13601305C9F130DD40BAB49A9D9DEC13337A24AA2181E57014F6DAB71CA701C1DBB33A28DEBB815B034952CC68E38E566CBD1B23C1AB6DF52384591A92F8C039F240D39B2F363E8621EBECEBADA3DA938E783A72AB8B5D0D287157649EA39E6D7DCC178F2F979A1931CA6692B746A851CBE2FB336307160CFA574F4EC5319F339F2C79B060A8D875507227D8010A9D74F4E2CE9C92F14466121252B8706F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174CC1FEA72203D681B212B1890DDB2D48CA6197C5B9ABDC377723EF0884703BE2757F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B832C73668D17AF4C29F2A72A1E8DC0D74C9F2446DE7A42F50A5DCA2F12EE84A91F75004E452A4E5FC799176A42B4D0A0A0CDAD9B44CC246872114650941B08315BA68E4B39A713B08A66F1715FE9300E5AAC533E37AE289B74341BC1DC7C75725C9838412E48A4CE312DEBC345B16A3A1F6388F350997448653448F6C7C91B7BE24118C3A0F4E431E88766E5A6C6113C8A2D1D2646B5EA5821C90CBE2CCB6CCA072F8AC327FD013B98A44146A45192D07A49B3FE150DB78658E659EB8546072823C7AFABE43959B08C3E239FAD4B3F0E87E872FF749B1DB73E5E9337731596C9DCE65AC0A8965DCD720A4B978015DE82E08B56B7C9D2D895861C15B766F9AB3C97E87206A7B951DA427DECC0653B7008BEE0B34E5B8A9D486832469079EECE91552F6208FDCFFD2E81B9E968F16C7A6E718FD43A6699A0E4D2F4692F3F56C2E31C33C937720276C8362A6839A6A055BDB5737525429AF0ACC1C8345BE9A2E9F269938969EE47C53A6E06BF3D9896DD79382F4210266C3BBB9F17386003F120AE41CF9F513B70D94E5A0DF54A0D52D5632495C7D6C843BBA812723C1BA75A6CD8B8FDA61F39B5EE34DABF596608877296A59158883CA4FB0402E22AEF63B5E1658DA5CD6F3BD2AD8D2846B76F86A831EF9F8E2F2EC334ADF81B976512F8FE7D2B9 +remain = 1152921504606846974 +max = 1152921504606846975 \ No newline at end of file diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-6_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-6_256.rsp new file mode 100644 index 0000000000..bf11e7de76 --- /dev/null +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-6_256.rsp @@ -0,0 +1,14 @@ +# XMSSMT-SHAKE_60/6_256 + +pk = 000000171657949C495B0A1FD294C1E4123901C1A43FE62FEBC70C30CB6088378ADDBAAA04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 +sk = 000000170000000000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A1657949C495B0A1FD294C1E4123901C1A43FE62FEBC70C30CB6088378ADDBAAA04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D933090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000018F224E19E61C8A7076585BF7780AD32D73D04D66A52F0B4CB6D35D9496906BFB05000000000001C0F7248E24BEA5635FD0F3F3411F1A20316CD29E2BDE6DCCBDEF8AFD463CADB306000000000001BFE2E0B4F4BD9B2B955C3CE73D4D0E703C44BE5168224D99756D865D86689E1607000000000001EB5D1F16948BBDEB3335E0F93C3DAC5C3FF7DCB33B16BB28D3826194192729F80800000000000194BC268989E8C957203F60EFD29089692A7FA0980912BCCB1FF3D6921B980561090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B832C73668D17AF4C29F2A72A1E8DC0D74C9F2446DE7A42F50A5DCA2F12EE84A91F75004E452A4E5FC799176A42B4D0A0A0CDAD9B44CC246872114650941B08315BA68E4B39A713B08A66F1715FE9300E5AAC533E37AE289B74341BC1DC7C75725C9838412E48A4CE312DEBC345B16A3A1F6388F350997448653448F6C7C91B7BE24118C3A0F4E431E88766E5A6C6113C8A2D1D2646B5EA5821C90CBE2CCB6CCA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001521B6795E3B31C6F469147CDE5776D1FAF80EE268B570DD87C1895E195F358E50100000000000135050ED1EAD3E799B63D5EDC01FDE9B7E3E8036A429C0AB56C909CC2B6378D6F020000000000010D93E097DE2D5330AA792D234007668B3E7F9E699621D298D2AB7577E8518A0703000000000001F2616B47D5F8376AF6A5FC658A75A52D032F7A1710630905C152957F41FA240104000000000001806EBD8412403D61AFCBD000376F11695F17BD253F82340C13342F750D09B2D205000000000001207581737977FDD59550FE1E0E62692061E1E37C554529C52E427434D2BC50AD060000000000012C3C45D74BE1C78902947B902756864EFD771DAF34009F91281FBAD0636A74EE070000000000014DC0E1A0DD7194009DC2FC5355C4D62179DA0010E19737654D7DC0E4C9761DFD0800000000000112F03C455D30919DCE22D2F8A0D4B5491A8188A32F17059A6AF994ADE911EF750900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE59F8968E30E844A031BC745FED8550EE78B1266A91694B967E66785403F9FDE097DBFF047A171318C43FB2472127512463FA79877B475C7F810D28AE0BA7C5966102673F9F55653D9E546E378D2BB17CD35FAD2F50C5372DF7871B1F1DE78A72FC84F2AD1BACFB45712FB13E3773B3565B021D30A31602528EF16FE6D83795A1A8620E06BE25AAB07A8F3F1EE979687840B7C863D0D8A547A5F7197FB72024DA7F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011420B60C54314ED8291B4F251FF32674EE6A3C3609140380F6B20865B7AE643401000000000001DA6EC89DAF2B01E86C06ABE8043C9A6EA0562A18C49B4A9497D347FAF8EB910002000000000001A0A42481338E08706BAC35F7B5F5D93432D40144F47A0F6790DF4B68525ED740030000000000014A9507DA8B4941DFD3D5E9A02EA050B97F9887A65D93FD8723FDC30C7E2AA4E004000000000001BDEA75F9BF80695B677BD7E643AAB0D6DEE791B64A29E66D796C51176B9F718C050000000000014F174AE6AE0AD2D1C856FD802C756287A8496B907E56C4BE48E85864F71DE7160600000000000131702A4AC2D7BD2722AD083379A254918CF9EE0656A5DAD6B07C11A74BBEC85207000000000001C2F54B401EC9CFC51F249ED76CF09A24665D8603D3747E67778075CC7817C4D708000000000001A1D56697DB12706AEF7EF31B1584DFB73FC269AEDE8C438FE9B6FE17C7A659860900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164A3FE6DFD83DBEFCE4CFEF2250893E21030934A382A288C69BF0FC7E9C92280906A4BA331C652BC4F904B9B54DCF3DB0651E43A6C83FB9843F85F0DBCA8D2E7F492200039906CF62A95D7B1830FDECAC0306B1A98B6F7B399E406A172202E29FA157E168F4B9C6979150F5AC2EF7769E4A729B6D59DD8F944E9A4A118FD06355D19B28ABDF256B4390DCD5C098DE989678AC25659763FC22E05FC4EB5860F4532E1EFCBAA0ACFCB91F30D21D2C90F8DBB5B419D8771AF1FA14AED614FA2B5DAB9F6F85016293B0716170A972790FEA6B0967F1FF1848CD29934182A9DDEA9BB49DE7B0A8EE13DA1F0A46E2376820EE34C1CA84E4524F21B5AA5FF74310EA831A3D3D08BCE359B830828E376B3C3999A9AC6168ABC74DDA8FFF0B35D6CD022BEC9BF0527A743822DFB79CBC96A90B6CF80B4E244E8F4386B653AF3D322BCF1E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018BB8E296C7509BC115ABB151E123D4E0343D51087A3A7321FD6406381792A7DA01000000000001166966BACD855719FD325B6CB7EEE8DEC0ABA7479BEEC9A71F451BD9EC1886B002000000000001E480EE1888B362F2F00B536DC0FB57F3AA94097DD543F05D299341633DEFE5FB03000000000001522E3D23E82223C8085779A58B7ECF45EB835F4B8FF5294923C95EEC4FCA50340400000000000175597A079FE64BFEAEDAB8F7995E5E9F7C88741A0DD3F273361C01971985AC6305000000000001DF8A269F13EC6CFE6713B0E94D2C3B25A880F3BF1B34A76946666837A1A3FABF060000000000011EC3BD5D59B96FC03D21CF2A93978E5397521400E05C4BB2F66B8C53C5322DCB07000000000001462C4051C5F8F1C53FB2A73D731FA41C1CD97C3BE99C1ADE2751A405C95B683F08000000000001428C6A22C98B1969BB9E66F698DDADF342C585C26289E42FEA210E34A4C279A4090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096F5B92139A4B5768CDF2E35810BD1AB3BB40DCE3F38853783F6856552BF95A4A835590582BB7206044086C1CA3BD9B8ADFB09C40A838DEE80E1B3756F98073651454C1567EBB9BB8D9FEA16E9CB0F30FA5E7944CCFE2732FB90178A6F439EF2C83D0FD90FA196CBBECA9DE1DA63AB609F53BF11303F3AE2283195AD62587795E7CE13CCB19132890CE25B085F7AE282F8DE315DED51D9E7B4652285ECB3929B9D6F51E82EA4BB5AAB4110925E014691A62121C27B5D929D24069ECDD6148B64213FCD94FB9EB6CA08C3D942DCB7FADCE9FB3917E40A455701CA8028A1456EDECC5EE3A3A27DE819CC28084BA0BA992CBA7D3DEDB39B4FBF247D2845FF9D4B455F5D29E81C17C5FFDEFFF7CA2153F968A130EED46293DACE1777C0173B089DD2DC63CA91C994E506ECC920E8A96608FB6E4F970A59145E77CBB83D1A5C22F9170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D10E76AEEA90CDFF9F15085B0834F5C0339E4C86D2CB52C234F6B18B472E8A020100000000000195C0CD14484D08075EDA691EE42CD999A552CA1A62318D9765CADAB553C1C5B90200000000000157A8A577120F2AD134FBF0E0E061E38A768CF935F4D2AA9A541C7A3D033A991503000000000001A467DDA3824B40F0D0D861A12328735CB8C23D1726982BE71F4CF68EEB492550040000000000016C6BC09F7073D85882AF0A9B60C224629A2B9BA3C0F3CBCBAD527E4DA7B9C003050000000000018ACD5F94CF14BD16B576FB1BA005CBD50AC4B03D5E54BAE131D723BC35FCD1AA06000000000001366FD19DE6022FE26A5E139A7E119C7045423D56D1C83861F263D7127DE85E9007000000000001BCCB39DEACD797170E9D863E6DD42F7C8C9B5B10CBB9130E84561B98073B1A57080000000000017937AF716807E93101BC400344D3698048E787D2FC6DD01EC7629B28F9D3F51609000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB931516966BA24D9585F1C0B04D660E629B3A2A3F31AEB6AC3EE8DF4DB67DABB5C332B61CC10887A0A207201703DFC4C27B774468F2CD9C6EFC711426E248C33EF946923D4C1AFA7B608F9F080410AE8F9F08CB38D5C0F6664EA0F630D34DFC55462334F617F3E4AE640E6C2D27597D4967E08EDC91704B9E3EE49EC4F0506994C3DD1027F8BE7FC46589CC21F9BEAF4F4130BC7D8325FD638235372E12CBB84FC424BAFF7D301855839698FE2E38B63BE461E681B43A02F99E466319E808084BDEFF59DC9DA0BC5F523A21D4525D81501A83F357BAB3633C061D403C7ADD90CBF38C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A36918612009A7CF4A981971AB37B767BC120AA994494DA75CABF22D1FE63F1464E981A0FF2BA93D3AAF2CEEADAFCB80FB7D012A588D4E409051A44F7287EB74B23A7F9A4302D2E7EA81F9FFD74D72807123DC3529B24DA2AF50619784A32B75985FE5AF8191B1CCF65322E266C37555CC3A971BF53E46DFDBC336CE5DAB6A84AC0F17F219C1DB9BD42A4F9662C74AF602347DE8A4EF176A34EAA287C9615F90FC02ABB78D80A6327768932976729CC4BC564E870C58EE9889C877CE31BA913EA7E454C0868D80335CC063C57D0BC1FB3C5E09B3A20F8166F8BDC41B01A8EEB62127C5BF88686BB8D0350F7BE6B56E0CE6E66B0998140C6F839A1AB13D68EF718809E2973CBB24BF5D927E83DD6C16C292D94B6EFE4A1BC9E050E8D6992BFD1C6F906C0A7B81474293A86ED095FD785C5BBA70F51BA7D49E9A5FFCE8193DD10914F642178026F159AE536FC1FABC7B78A3C2DF55D0C8E1EF23883C6FDBC053B447825E75F945D8157A967B58B0574C6E0615387CE1652DC027B72C45A8E9A4287219D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF71E8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B1A8277D00D5F8C835AB2820DFCFC4C8AFB2CB247B6DACFCDFB3765002D7D6EBA358848E7C7C63DA066252A81CC95E38A556ACD239ACB010A8169696B347EE86AE99CC7386155ECC56277B39192742ED8C959F142209943A017FBCE130FBDC3A491E7F650C98DAA0497D6C9CCABFD02921ABE4CFF254FB1521C702FB19F3DBBA1B691F7E44003C618C1B0C1B68A840B9763D43295E0CB779A59EEF7ED63AA1020069B2EF88BBCAB1D03693FE34C4C497F7936878D4DAB7B75BFF0FD8A0509D9A3B0CF209C9B7D09732CA0914617778AD289AC2110692D502C8DC75316530280FC926A62D46620A91EB4C89377C47ACC72884CAE39545022290B0D0EFA74045E4FFE5B7950E421091808852738371BAF20E81ADEE43642303C0F979B8EDAF4B47ADFB135B60A3E4F0BD2340A03D9F774ED36135C7C7241A89B2E9C71979E6BAA1E4D272BEA996623E399F2DA2AAAF6D0CE10191BA0853C08743DF8F9C98575E4F398BC3F19CFCBDB00B6C71E6B2B86A0E3BB72811DA873A3A318F6F334B64992648C9DA43BE0DB9CBA43FB1191DB64EA575DB1FA7F5E345ED532AEFC9F878894723ACC25CFEA3765FD8B4445453AB184E6C5A33FE8C136C8B401ED890A840BCC8C13CE2560D86119D74B6258D4381A4813572B6AEE5DB91BFA38F1E36EFF3DE17E255F8302A3A8161AD44F095659EEBB8E99100B7A19BCB8842ED58C474D1FFC28FD87A032D583050C09C64D4AE5F937743FC5E4705D9EADC758DF2CE55F240A40267311278E9198452030917F0ADB64226D6D413BCCB02C9A5C830AE5F2DBF73BCD8161132CCF43553B8FBA8E5283C953AEE50DDCE4EB59D29E4A2E5DA0530B922286F3588848CAFE9182175706266C466D65F41C3C18B000789C74952E3E2FEE44CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D58C6E04B24FDA2C3239210393254B41DA390EE357C7C175EA1DFD32FE5AADE666337542E508FAD05AA818E37539322BE1320FB587B83E86AA18434C47CA39E9850984F7339BD164FD46557BE86FB71B18CCAB5C34449AA65150D6F47A8117453D706F30DEDEB127BBA56F23193113CCBEB626F61BC4EA2D5053B489414A7F9731010D4333E72690C936D00367C343DA301A455B4CA7DCFC4215B0EE5185F1DFEAD2F09542D42C8CC1BA6ACFA452C6237454C5D115C0F5E04479131F9F1ACCA098EF0ACDFEF6FA39E4AEE14B0823E911EF2DAE145E261AE05A117E5A52E9DEDAC73742F90B4EAA8AA944F14679B0F72AADF6B56B31F3A2AA0AFA243C3DCCF6FFD2799FFA1F9861A5C04B0A8F68CC1BC8C90703AB05FBE50C15F06B04570370DEBB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832121C0C078E6BA4A80F1A20BD16BA90FCD04D43A0927C164582A796C12545CBD0BE45745F9E0090A47F31AB9B11E1496EED876912B13A841C06B6A5E812B11EC912A83D6B8663FBA403442AB4C70D3CCB76BE6686CD55D831E8DCCD05594F47FD58A835E3132D95EF4B4E8EBC275280999BF68305531A7F9F5EF2E8ED77C42227D0ED07B337CEB70317037ADA07819791A04BBF73646CC89806912EB3E2BABA0C80C7EB7BBAB7CE68583B609A5152A39457D51EE0A3CB4E897EB6363CB767057ADD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C63F474F26E2917A9A1B025C28BAC7D53E4E150E981E0D5BA4129911F99588369CD97444E871D47141AA795560B9576AF7870E3F62BC6F010869F6CA393E48A0BF5BE7ED218D65D942EC0F815F2258A47F7A509B6BB999C17B28D46B7D3CA59061D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C09FB9C3782471D5185D98077B9CD560F0F2D8109B8F2DFA711892BAF0A4A828E506417EECDAD332975E49F3E9019CE173E2ED3985D7C241AB4F7AE082E8EF49FD6E7D8241F8BAB4D68DE3288296539D0DDF68497D7634A964B76E82AF13767129B7FE5BF4C85685F9C1649B8A52FCBAA9B2AF0C0C2BE1904DEB98ADA34507734E7937BE5E686F6DDD4E57D5EEF9FDC2164D60CD06AB5C9D11B840625837703C3CEB44B6542B684CFC5EB9B3297D946E7F698FD75C5A824EEA9328EDBA65225623ECF3B1F560C0D9DD03CA404DDEB74F901FA06FF4D2B0972C31F94450036B01DDD94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB0AC0CF31A27014816177F79DBE703195F44C47205EC4A5CBE62146B5246AFD86660BB52A30FCC16AC9D773E97F581C7518D007FE0489C09FDFA334F49313FAC2B579C7AF47F9946A85247DC902ACD5E0B22949F45945DDD51DF6AB0FBC225603D7377F93D29F2DF9500194E614F93DEFECBCA3AFB03D22F8FD7661D9D41D62D3F34476EDB8FE887C37129998A21E92F020460D3AF85356DAA577666F5DC0BCC5986DAAF87F5A9E602BA73B7392923FDC5B81A6BAE67BDABA7F7D2E9410D160455BE2CC6A833BA1B0F8FE54852A576BCECECF9BDAEF1C9B426B3DBCA32353CEF2D782F9FF8C8DB114C65E259BD077E800BBF0AF92AE1083501FBCB6D736C848AFA2C836F2E20EAC0336B58D10000EE1E6FE4AF2C87B2DB73F0F695508E653A3755D0CF17516575A25E8960FFDB7B1A00FBED460A8BC7EDC370A52E214885B7DD496596F52B1697C11D5127906C27EEA91E5D3E948E752D54EDC1A8284B9330F1BAF79C2B31C41136602FB4D1A7418EE586E7386677F90D185CF9D61FD7178055651AAB6AFAF6B955469C05B619297155F922B97B7FD28FDA0C0FF3BF34081177EC83DC0433EFB8A1417D60691D76E15384DADDFE66566032B722D99F959653F5C68D4FACDEB4DB5F9CA52CAB9D78109D66D75ECA67FE82A790ADABA4C8F8EDC5663FE77361E78A43189D2B89D1F26535B1E860C9F18E7A3BC6892A68C68AF96C1F4730192CE3BF69D4E7048912FFAA309913C054E041306B4B0079D606F9EF3E08020379FC3A11CE22436F7C8BE6C5F5EE2C1C1778320456C18A68F306AD1B55954389F635A502169454E7C432BADF0A68F529903CA29C2B836DFF01B67CB745A77A9E7813A52B92C810B51BC3E71D7AAA9A9F31EE4542965AA0F6F9907D1595A31E720D4A7098FB2D72F01F8B83BF3A93D05157307E2B595F0609BF2C8B94EF6A5D60E53F20C1559A9476CD2391127B12D77357269359C424A769021D139860DCA4136B718B65880234089C1138705945AB76C815ECB06C01C73C60312FE6DE218F09C1607F528CEDD2898E077008FF6E47C4FB6B2C103BA92C399A24CC38B373B3D7F00D63E6A42412F710C62528106482F703ABC7CD198A24723A6BE730E6DC971D468EA20D76800F938E651FAFD425643ECCDE70BB4DC1D6FE4E9B3D3624C330E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD6847C7DCD156F805A9A513F17CFB60F16925F4C587744E4AD35C7127757AAD37B73E5277D6614F0C315BB9E3BE48F654AD2D343B3967FCCF5387EE8297F2F74214B7B154E1D715C8FEB898A1DA31D5A8ABAB9CDBAB991459E62BE9F0E0A69791265ACD8F7AEDAF736FB944D3CEA82A1B3F23ED9AC0025760D260009668580A7FED8B073D52EB9D1847445D2064669D9E03116C2D999F3274876F37552E2D8A04E4409EFB415FFD9571BBCCFDA01333286A5A934E32D7C6D7EF3A20DD86ED5391AF91188FC2BBA388067FA443275DF1C06B23BEBEB418CCF1A7CA0E4BAD57780AD7D5528BD18362F273F0D97C081E502F32EFE1508B343268F1D2EB3F12914313283E40F4EC9F02AA17AA8A310FF50DF2712F49896FE31BA07A188488E45EB59D6BD6B858D527BBC0892580637EE631FDE8EAC14EDEB1E73EC75C8C241294EA628DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF47606C4D632B57BF57812D2B2CB85C631F239710C05C7743C2F4515F6C64CBBC8109E7FFA421A5A637256FFE7F44413BBDE5787EB92060591282ED69794E9D64356A585D5E293E705EFC493596D08F3E68CA984532F71A20D81C4BE0CA989A19C2FC268CACE37F8F2D5B481F2A4F387043A4715FE805C6FE2D4AB89DEBE10CAFD406F37450F0E477859629CE2B957F3415CC4E2CDB795EB766193DB9CC1E5D34B022FF9C01B7ABAB66A08EA5A0983E6E85954C92A6D3B2AB9D45BA49B21D45A3468B53440BB45283D3251613D162A9CE508A5766740BC16F13842C2F89F2396E3363A1934E3AF2E7221957FDBC5F2BAA72B6E62BAEB9E6D33B248A5102714178A60CD3A02B6E121E1CE591185608500C11AAAEB039497472C12F766386647573D2974687D3B63D655D412B1DC0D3084791DC9CF5BC4A42D6D3787A187D4765E5C65894BA159FCFEE27FB3B36A54A9FA312C81EA09C6762770B9649872A738FA0111D745A1F9A0BC53FA819D6E7220FB07293058C8EE51270F86D956780BB52984745B68DA948F7F936345F770F38661F35198D5BED466C3E1C7A23DD56D543CFC93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B7871339ACAC858B546C9139F4B917CDA356F04B779BBF803351C1B452BD9EDD0E2DA226A5F930C3C97F43D4633BF11B8BCEBF646B8608685E36F0ECDE7C7FB5F977E4D61038C745DE151D832D47C979224CADCFDB0C82650055F1519B94680A840FA14B55B2190C71AC1F7A7AEED989BE8C8AC61149A0C809449B677AC353867D0185EB15322792A3A7E328FEE3DF2230E4B70551FD7F9BD57BBEAF02E40124C58F019EEB66602B9EA10094839EFA9070F5C2DA3AAB6CDE6EB58246A59AFFA0352106F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C013843CFEF1EDA266283A5CE4A6ACD7597519FBD097E9E460D9B071D34EDC61672D14E6D9D4F9A033B5B473A1B13476C3C447E884455A5D168DA793F9E2F09612A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B2BD0A2D4978F82258687586F9E6EE6AA21877D8A2C7AE37332573C420DB9C8754CC20EB937A8B94056D96EF571162B0106AEBFC344B5F28D52B8CD02F6168F45B321639DDDFBB333C5B872E80370F408EFFB5CC7394767F8CEC0CDCD7C9189E1B24FD29C7FBA4B14F30B8F5996155855C08A749B6AAED58C55271223A53D1E8714549EEA65B9A9245D9F5AD2EEBAE82637B9E3C78A24B5262873759CAE9AF9054C3230F88509E71CAE2238AA2DA1C25F0DCBFDE9BCC7B234BF1EA6697DD4E8B020B099CD92492855F1B528BA0B359BDEC1E77245432B7B1B2A5A7B969947A2FCFEAB2E94762E2F3F524E88E6FEFC4DBECED7EA550E6BCEDFF229E69D9C7C7803FACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E9847ED6D3A7874015F0AE87EE37FB6C478F7330A07D4C59E314847065E2F1F5F7F6DAE557F85B03FE6BB31B28A40263B64218FAD4572BC5FF2FD4E3F8F9A8894795658466BFB5DAFFCD99A69D532713CE072D81A42045933CDD30DD257F6C9848577D9F8B09B5D7BF71CF202AC4CF296E05C6A7ADF77D8FC670B88DAD02DE5A80D4168F7F72A7252B0E421F9734012AC8A8188677647D35ED6199EB300A6B71111D7CC77F04AF5E559A0D34CE1E1490576716A861E79902678C1241CB6F614176147ED88C82A99CCF2BBF62AE65572300CD4FB12DED4B6B0901D5F6BD02F036BF66B095215AAA76BAA4A07E2C0CAD2B2D76BEB56956C26ACDC11FDEFE9D42C6A698C09F0ECAC502F2F7E00233329DCA9595A191DF6C87B728E8F9B59105B9074992A62F2DFB38852C7F4BA5BF782395E906AF48136AB2DEAB4BBE7F0F79867696DDAA4176F14C9DC7A301B0DACA30332F73CA3356A62A4832A12DCCC3D696505F59E73148ED6401A34F6986428CB1CF18FD61DF1455A042455FBD97A76A404E65CD0BF41E26465281A0BA11EAA39CB48B99F2354BF5407629727B52DBA14B29C65083AE8B8891AECA5500BD15DE9E66E7D5C0104891C17A108B79D8D96D35F12170E2C930F8F16068AE3CA8511016203A1A4726CFEC7B6AAC959B67F3FF1E4AAEAD667487299703D38472B5085FC55B9BB775574AAA118BC81076CD53A4AA7E927482B1D617C09C6C24DEB07DD41C2C42B6A0BE168493CA5A40266AF5B992B9B2C65CFA82A2EFC515948A5FC521A7F49DC4BBAD296BB6FD4AA6FE1B7A7726229C03DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D973867CC37DAFE8FC39332DFD321B1ACA45587EB6D4727F5AFEC4178CDD8AF03FA0629DA84844B5131CC2AA07E2FBB8F80D3320AF5C1734031AEB68DB8B6C7358F775E8538C260FE6A79DDAE2BC7D40222B2942A2D8ADD3F295A135B5FBBA319FA3636F56D1BC8CBFA175EA61C1F53980664282E56291B4ECE5B5FF33C2141F04A3FF83EFC062CF6C635497FD03D6E56E405C43C4A31DDE872C4E277AA190D1D8350A298F16BE75BE305891F9D1084146199960A881C34318CFCF1366E82A487CEE95D5EC9F9756FFFC9DF3A1058E367160B321753C937D587130F9AAC766C19F033CCB2D886AB532683F50D360D10DF559AA16DA2C0E3203337B46EA1FCC1407675C5057052EDEFFF36BB2A6331522DC5CBC871C52CC35E95DF677771084A6E3E10A56111E6B9F7DAEB1FAA11B9CE5EA450A7D75F2B7266193CEA51A9532D8A32A2D4C275ECE75C3A59C3F02E3F9F40968642D6387F752C801A761F121A3EEF4F6B0AB83B7E815E5BB9D67EF85BF9DBF72E5E6DAEF4A6F7519130BD4F826A82D23332BC291A3D320CBFBE4BF1A143B78FAF7C1BF61F30801BCF715A05F2F7429F0D1A3B9F90D191754FE3D761A77CEA46082D3D2CA5BF26EF05257DBC8B72D156920EBCB1E064FBEC3CA43AF31CB2A53B246BA02E3F8AD4E07DE794CC1D8E3814DE61807A116F768CFFB159D16CB7214EAF1F52452B768380F4E16E2BCC10E82A027148477F2C717844DBB1677D6F2559AACA58E4759D40C7D62610399D6EDBC6DD4DA7904D2C53E4D9E07928FE181D503C5D45D6DE07E767025D9B0386F8C123C38CAEF00BE2223E8B1F46370B1D20FF0DBF78CB6A016D0F72F07820238885D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3A1E6EADFE7066FC6A5781AF310597B333977E34D01483A860E7D986357107DADB4F5D040550E524D9D1AA456CAED45FB5F6475160AB01C8AEC46EEA735384E4FBF205BB117F68C03F6D301E5C469033B05360DA23CF49DA36E050D627B2067B30983B2B426DCE0B78C0500BD15B3D2572537DC9B5F0BC0E1A12F533F58B2E21102318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3F5C33BF53D2A951EA7BE7FE2D487362EEC1DCB93920B266C5AD39FFA0FC6D4B335B1355A6D8AD3CFE51E9F69C8961A82831BD27F727C9030A816E817783DF89B519D6EC14C9CD88B73FD6152250E229BC6CD8C952777CC5D670051B18F5AFC99860FF7387C5880564703541C2883BC93C5C0EEFA57AF9E9D9D04EAB3BA87782807C37D299789C60C63CC2E86B5610ECA54D3949E17070B1978781F705E32042AFF28FA979979A511C5D14ADD08AFF7DDAE858415D7B0CBA138BF6D1C72C99A9564FE6CB5C9ED554B98D21CB796FC053CAFB4B3E8214F44643C99D9C92EA847A1B6DF3BC21FBF810F9D04B26771BC6DBAD0BDE30265D402E62EEE8ADC84CE8AF0FECBE8F68D13501515B8C28F68AD45D9D1A454904DE944A90C7500049FB74979AE952EBDCBA09DE543283CCA44D3F00EABF99DD714B8FDE3755D30105AC8CBC4569789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411935E2773E3B03C5E4959D9A2F7D55B05B8574768DF40B5EBF76FCAA69F463E0FAFC9F02B01C7B89C1AFB661B43AED07A9D54A6669DCD9022A4EA628CA69577EB10D3E331C300BBA084A239D762A49141F81E46C97BCB157E81FFD88A34862C07F224E2ABEEEDB7E701AEF0A2FBC73A73CCF9B88E0606784D0BF4E99D41EA993B5401881439CBF17699A62F3D426EBD3681942C7F6F7B40835A7C996B400565E8BC9E636698FE0B197B96767C304CC366E2279F19A9E76B8B549DB73200EA7B3F788CCA15EC4A56D86CFBA4058C3C514F3154854CA6939229C3FAD386BF62626211CDAA71529B5410E08604348A4FA025A71894B946DF27454F27BC01996F23C8677C11780437BBE7131493B77D15C667AB0012BAD1CED0DE088C3D83795C30A3E34C878413680940B88C4693DD69B53E014174D8DB87EA6138C8CA99800F4F93981189912022DDCA5B6D5AA4DD2E04C394191204492E8CD5BD3B1599292F066E4E9D5917ADC3CF954851323255BB47D6FB2B0B6E93D9C2E39E23F7F02915149F9234FB2F13E6BDE58B24DD23CAD19056B0F92E3C1449421FEB5A740C7BDD04C76D8C2AA84F1BD9CCB562B9AC66C54ACC986BCCC869025339B9EE0CD9B8C0D7025B3662F8BDAFF77D6C77324F336C1A5276F7734EB3399FEC4A5902AA5971A933EEA9AEE40BCF69C70168BC10F1E9576CD541325A8A729566CAD7C0483ACC8E23D17DB2E495CA46032D9EAB61DFB6703C7C06BA4FD0513B55B05512CECC642CBB9D75AE94922FA66546C306BB281A106EB0D25D4156DD04911DB499F9A77B8F8487EB0287D9D564EDA31C37DD33E57A8D5A33C3088F4269E28E87145AC781DC38A75D575DDDEF448BAA06A60E54E4F6EBF94B095C14E36CDFD29B45BE3455F1930F39F77150E595CF127D1FB7E8226CA954C355D7098E783D32A41E702A611115154F3DB1A8484E4C6A81D13632998E75BC4B868F7E6178F035BF1BEA7510E3A823DBF976A0741138D1D5C9B2B434076228B7C3DAEB0576CD1194E82E62A8F902F9C84A1040262E83913A179EC88A1973DA20CD50D9676DBA1B8C036B97AF2C2005F1F556D1C462DAAF0E1E720B728AE3A7187F576F6B19177F83CB2953F058E0573D795A69B4C72365CE904C9690FAD0ACBC12108D950BE728E935FB7FE0779C54C8C0CDED49F111DE5777AA6131EE9084796DDEE52FDD7567A66ACFC8BAFFE19F46D0BC02258E9CD605176480A7E11B2B7283334B1398342061098099C06B1DB47A027B6577055A67649E98A0AE2E890FAE3186EBDBC6962257DCADBD50352BF17A03933D6BB6E00C1AA62CFEF7C7834BB0705A50205C4EF8D3270C4A0716A593858D31D1B989FA57C694A39CF877024ADFBC5FA2386FD36B07BE137723172C0E08CDDD0185E2510CAA4E4845ECA6C9750F4501FEA182D7748CE3BC2C902DF532BFAA83B530C214A5C649102309116DEFCCD338D8AB9CBEC500C26095E4BE1521964AD4694546C8D1F3774776C0595E0ADD0203F0FE1489B43ABF5FFA96C25138D539203E53FE2EDF38BA68448A3520CCF623D8427DE666CFB05E0BC25452E526C7FFB8D1DC496F047277FB03444CB5ED7342FFA18EEE7B1730925FDB23A34CEE84A5DB13C4AC46BE0B0FBF36759DA3E7B8C3289628F7E8254BDE347A1267A888D7FB18D021FC09668E7DDCC0FE714DFCBCD73AEE1395991E44B423F05043F6094F3930B33ABF6EF6D5AD18ECADDB1B477C019334C76E553210D4C89E4C32DB105FFEA84396B80DCE49EC772FC586D65A0C6FA012888B314FCA5FE7D56304AEC2B6EBCA87240731E19F8A237E3080A5B4FB92BC823AEA37AE3886609B5E4335559AB13257E92D2EE60938B3FA1A8B15958F8340A6062A0045C098A08D6A78F0C8806789322017F576BE2590AF4AFE35C2C1DD17A4EFBCE7F65B7FCED0A56A91C2D5724455D0A7A4BE1A543451792BE01E9A9614C6026623E730A21A5AA1B22EA38E983F1CB3C6AFCEE94FD813CE143F84FA32A70A97CEB20BA50BEA097D13CAB9F0E7032D052D9D9903A39F07E56690711D67081510427FE7D665D64BDD70EFD0215C6EF994CF6FD7444DBFB51DF33FD88A9B2D54BADC321512B7B57AE2AEF89959050169E710CC7D38B011611B655BA781A5B3391868F48AE12EA4F0D539BADFF7D81270E6847C387DD76569E539687B1FFF23F0226CE24125D85D229804869826671E44CD3B5942738E53432EB5267B1DFD7C80DA709A3E6ED28B83E10721F4D08519A3474C951803C0172025BE77A6CD8F5F9B9E09ED8CEB187F381D57F893F96E78A10C1AE29A306BE20246579F74C2AEDA46D2FB03A5A08C152BD736C93C7450149AFF1C0505E34E48C193F046647C61565FA6BC99044E7FCD0488716774CC0371D9ABC47CC69C415AF45B35FD240661DA201D3906863E1E0236A8A0307E854DBF000462D7217090E77A43FCA84061F881F71DC197BCE1D6B518FFC25A3E4926F64229AFFA4098F5198DCD8BBD2F99F95453723D6BD04DC5F2C732970D2AE4A9165E3AC8C8A767F0BA93BCE6F76F1E4A96D167E9EDFBA17A78E7EB3015E158630058EFDA8FFFD9D1B074C8ABE07300265DBCF6CFD550047FECFDFE05721DB0EC4FC21D4C675B7387B6D524DF052BAB92912B6DFF155F00462AF058203F94021F6388249475132A803A31E55E366AD3935EA2D7BF1FB0DD9AAB9D494ECCB3B7D0B7663374228438E11FFA2918324BAEFE443FB17B1A1950B0989D5B3379A13D82AAC83687BCCA2358DE7DA30541EB84E75DEA2D27409E7C02131C1FEFC1E02CA55584FFFA7CD7E8B6E2E2B7B685BB96710B6BD0B672334E8902CF6D49F47CA682E4343EB5DD588B7E61FD37D1972BACBC77C27CF06218B51E82E000185CB9BD13F89E6C3AF38596F181FC8A31B68C8C21DC711EC8BABA1CD7E812B4D6C939B449251718439129B95119BC9BE22C5E237B0B083582093D9DFF114C0F632A0C0016FF3A53167DB27B2F226A2B4B5EB7A409915DD46A882362462CB5BB7C3D2FA7DFAE5EF6969F34FF7E1B0958C4297CECDF374312B3231354D04E61AB4B668921E65D7ED31AB5AA46E5DE9EA4F5243CBBDDF261FCE1BCD26DE90FB46AF94530DA62C28D019C7BB1B7D245E3B773871F0871B12ADB9306D31135B241A8E49D6EC6743C95469C24DAB5CE75E670357F3D22481C2E01E30215A0538DB0448CB9340D58FC633C9CA5141CFD79109D30F5943DD8A69F47F49C25E89EF486180AE64497FF2197EE4D518994942F6FA35BAB9D747CB356907B409CB427788C3D7708D77B706D9F90FAC25E492EB60F2DFAD94821D05D8F5721D46560CDC2E43963F70B64C7EC230170F2221693D7FC10B0F27CC4B154EDA86B74CF82CB44EB097E3703FE0B938346856014A50A106F64B236B17DBFEBF2B455FBB9C999CC1F9E7CC7D4DF12E1EC6CEC249345EAF4DACF0D38453A533E5193257BB55AA785666C64B91491B0A5DB93688FBE07D66D926759B669E18521210CAD05EF3F8972754DEA64BC0846516FEB472ACFF5EE2D7E29F7633E32E1A91E5DD713A56AABD6ED1EB967F371FE4D1A7EDF2432FC050A47F34300DC4B69F8553FA4A23509A45977E62736EC9653A51FA687A30FC0787CBD6824BCE36088AACAE7F55D877F773255A13B3A006CE4D2B2ACED5C03764B81B9DE5D9E0EBF9230164C5F75F05C4353F64A182FA15948C9BD8D89E5C6364B84ABFBEE413D0EC4D3B553A46B63FF0699542A2A7ED568B6E8A9C2C772B4F7F7FA17726174968E216636B4FC547AE59D73DD40F320D6B3329C868728B97CC704859F851149108B705C39AF3DD97EFAEBD39ACCFAAC8EE1FAAEABB32E689063B11483C47510DA0DA16B02EE4E397B146B6F777B1F2C393379414F67BCE670BDDBC67BC8ACE419C2E48C5B57EC624C5693562B719C7E696E1C83076E0EDE8540DE3D7AA00AC5A50E481F7BAA41C43A1C2EF09100EBFFE5EED9FCC095945F525F66ACD9A814582D6609DE9FDC132974B98454B501DEAB673C6D33AD29686E1D43912840DF6398F2468C0788D1D3B597004E6BDB7A89B57DCD4249EB51489F4DDA36B0A3B90C4EA616135B089C4D4B8DA02E695EB8657B2E12FB5554D2D833353A3FBF3FEA441A755FC4F0A49C243C3682A20B04AAB0EC430C9BFA134C383E4B6FD45DFB613E362B171F0C2B2473B38E92A21C72C100505B3E2ED5EB14D1ADEF650C7254F5163A2FC01B987E3000517DCD878B3D9268E912CA3675000B10E53F5B8172477AF6FE3778CB0E5D279309245647970C216E2E626D2148795132C2479B65FEEFD8B38395AE4A34ACD06B005F311974D6197A0FB415D7FA5E64502FC8C878B14462F0C6458E04BE6DA9308697467937AE52099382FCDC35FD7D2734B1150C214107CA53F6EAC9D584AFF8FBC6C2AF2B711F45BCC5626B1FACEDF4AD03E261A7E095044665CE61C3359BA5A046E44C8E5506E2BD7D4F6F08B57C7303472AD0369BD7B5199525024D34A0143DE46F8F3316F4A8B93DC5AE6B02A0F362EC7F9EEEF5303E3C0E13246E0F214FC2843F6116A7986920BAFDBC483B7D8F84ACCA690C6FBAF794BAEB0B687249A360CFE9E1C0A2817F2D93A166ACD35C00A1BDC4B1AC6BAEE6588B0958D5C2A0D63E6DADD81AE2ED7B8ACAA19040E7E30E454D629944FD10E1AC8ADC8C0CBCDD9868B973299A4DC927C49E944C7C00705669F96557477EE62F0E6140D613B110B9FBECAF70983B17EC4A470FFA4BFB8AEDB435FC607B957898278FC2D33E66F68E1F630D4A06B6413ED8C2B7BCD931DD4271D12B29336E47FBB378D48A956DDB447ED3A2B93E3C3A5559DB3B18505CFD0AE9377C5F87964A89B20952F5804125EACFF6CD0C256CB30288ED1BA4324F9F7850AB4A14F5107A91C3DFF05B82D1C4E3BBE38B7C6380AD2D1C41621187066598C2A314A84E55E8260D78D6220923EDF59C8CB7BB6E5B6AEB96BD7E436D19DBCAF897D8A2B3B41D17163C52CCCCE010274A70B6B985545072CC765A499A3E4FA7388E44F9A1F9F0D45694EAF817A3A7D068D3FF6F054145C716DD7CE747D3889E49DB2121A81EB40E2E2D08750F1CCF791EC924ED46F3C5C741E57C9CA75D7EF3C821A3A2EDACA966CDA766A3CE6EC0DEA096870022496856890CAEE492ACBDB949FE0BD8CE0C3E72468318B0322F894C64EED64AFDE22A7A1C2B22B348830444DD5B99050B4D3976A70DED872E92593215ECA63D2EF78B901B89230D2C18BFB4D50EBC5949A090DA9D27C7B9B3ADA9C787913ECD0D8E578DB0D646965DDF5C5DD3395906A9C02E7F33194DA5A6583C198A7D41CE382A6BA5B8F9E52701B31E1987E7AFE0109391E187223DBEC2E516F103BE65BF0FF2141194836BC3DA9C1031A5D51676AE1914885D9CE838DB07F72B047AC46EBB3E1FC79AE2BA473FAC3EAD512D9F1D3AC2536093EA580F0384B36F8B798C8313207EA12A1E244F0B2AE1B64664D23C8C2D7CD5EFC95C18F4EB7B196F368F29D39578DD3F53E050D351AE6D93A40AD4915927D82925BAEB09E8A877AB1C6B704775C0EE210025CEDD475823479761DB3C8CFBDD9739754C743307E5B9E81036C748B79AB78D0C56DABCB9893147A5BF4E3655329E433A0521B08DE2BDE442CBE9A2721EAA94B4F9C0DFAEC4D500FCC073568B0421444AB51CE94C9489818D4C598C1E219AB50C7F7D914FD59BC96542C72BB3636746A9C08A4A416E7E581255FEF48340CF1D9D6C5E9832B004C0F646FECA43FBF0E016BBCCDE92C1CC9AF6C92BB735640733DC1C031BD10D554E51BE3DBE3306D64CFA148779EDCAD8AEB21F5FDF085FB1DA0BE2DDEDCD1B094810903D80BE04D1FBFA7E59E17069DDBB49EEC76320B74F31C4428BDE620DE149EE74DD9BF22FE0047FF71486E339072F2B603B8055D7BA43FD71B3CAB178F34703FDB8ABDD8F5C1461F89446ADB1175E35428091CC0A3B58DD435FB4D9B5D62FDB9FA0A34224FAED03B10B5FE70EA67AE1A3005D3DC4AFBB064A22AD6A9BB05C15228E1D20D4A4E8D041BEF83790E9707A581DBB7689E032A083381899EEF508E4B2A897FFAB447F821C848EED8CA09616CE2EFD13966C494E919BD76A7C971A7731B13C4601F7B659429C2F7F7592F4B17894BC1391235 + + +count = 0 +seed = 1840C60AD9F35C900372EF38D08671A74353C965C3C5DE0668C9C3E5CF3926304322530FD9681CF3A9C71FD633D60C66 +mlen = 33 +msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE +smlen = 14824 +sm = 00000000000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6CE81C6363BA48FE2B0D71D79936241991202D5104DF670AF8FD02AB7A23DE82E836BC369F2D8F1CF51071C04B6F9E53D566244F07B484199D4371F1B44303CCE8AC6CBDDD4679835304CA9F74433A62DF5524FC44D637BBAB3520CE625826DAA944B9F2B22F2D9419B5B5DB6301DDEA449F184552E9EF0F4B80893CE0D38184D844AC73D3DF74710D87286288BFC59EFDA5B93828D6EE2785EEE07487B1B36165852D62225D7554249CC1FE71B8CA3B01240808B769DC4154DB886DB5C1EF5B55644534E0F86ADE3417BE364CACDF76C0C906F64BD58A7B363C52870995A9DDE573341348D3D99C6759EE3444AC8A7C1801E45A8981573519B8C4AE4954C0AD861B94240759D2668D905F569E62A80D2FE7A221D6637D43DD890EE5DDA19C64B97C8C184673F470042729CFC1417C7D363B9EFD028AF65E4A1C95F2E6286AE6217745BD9E9B7B1FDC64E5A30640EF813AE0A4B46D5EE89A7A674E2D96BCE130D78727144332A7276950BC3A0548E270CBD4FC31004AF248BEA3BF61558946A2DDAED185C777160E9B20E4A823B470CBD2D890348594F4502BB34E2CD86B1E5C393B0896752FCAE3699AF03C2E8C8725BE6073251317D1EEFB497336A32C511CAE0FF66E62A9501705B04495C7B1052E59C094A12D534DA283FFA112C6C4F0F84481FFACD6E480671C8705E234CB846BE6A2323B69DE001457284D03FB6709B9A09BA06825E1A32451CA92D7B58785E22C755B2083EEEEBEB7071E62A3AC45C099B5A7F8E341A8CBF33A1D8338EE6696C485C3447024EAC99D174BADC9F88763968223ED5CE3170858485437C132229DB3823CF7D727E8DDC6B6BF00983947D021F22B71F638350358266320296B2E22A7495A708E30B7835A169D303A94A318A3D8AC4BADAAF808051A63BF66C7426CDFAD57168794CF4B50D8FBE4439B6416CC20ED1097E1670E2B93FA14EB1BA35D7B2C047E6BE110205B80B6F169695CDD44B935E0ACFE1323451349968E0E7B71DFAC15FC53E1FEB7E987BBCE964CF61EC44881F2AC9A8E607CB63D640D64C4433EE80CBFDFBCB0B822F192A053C5120DEA4E6B4D0E8F6B2040D9CCF85DA7C9522BD571EFF09D5B1561225886FFCD6B78810F452317BE7048D2C1679145C0E4F36E34D3A45169F8127BE584FEC80129C3DE3F2D9487FC2287870964D9F328563E36677622B3E074A980DAB585FF96FD09B7A843E4B2BA51E42D964AF28BDFA113E2853EE1051EF044C34EE020DBC7172C159B394DE8D15BFECE1FCE1884860BE12411A625BAD6A8CD7A99C157C62AC36B3DBF8805CDDF0CAB4272FFA12C062DF8602E4E53CCCA89F5A821904F2CF333CC9C4D5288AAB31781CB01B5D4A9AA378AB2DDE7F865F0933515DBA6527FA1C44C381B553342B5840124030F6004BF0D0C29A67C7601C0FEA9192B1434C362D81C65728E4A8CA6264070A7F1F09CD093CAD71FE3263B0E60C73F5F8641AFAF07676799DCF127420486671BA5E757D09573B0C09130A7C90B6D8CCDF578765B4FB0BA839339BB9AB60CB5B1F922D6C430FDF84A3A8A81B7FC0282C404FAD61A9AEC079B54A100E0E44DB333BCEC50007F239B57FAF01D826F08313BEB59A591A4BA0C6D26F71CA01814F9DB4CF438E89C2E99E26EB47DEF45EA8A595A177DA49A888B84DB5B399E45FEB575E3A4131D0DD98AE8482529815DC0CF2717E7B9EBC26524503881BFAD12C8887BD0D9C2019ED15FC5DABFEFFFBC6117388688BCD4ABFEC0610C27800BA6EF3954933656348BDE0A3D47C80581305B672BCCA2A235F654F01A3F8FD69EC9C4AD644FC10F73E8D4EAA8D202E38A3609D1034E9A9460341D78347A384EFBE009EE5ACD512C88DC34BB54340BC9B1C0CCA389E8BDE6AF14B3DB250101F04D29BDC7D2094146125ADA6A3063A0098EC13C0BE830901807F99B5155C4BB0727EF06F5BA2D821170E457D290444C80475A6DEAA1E9EB7B334F93253913A2A372B5CEC76D57348A81842EC2A2BA6D8D23C976F3CB9F3D349A8448C5FDAC524981F6F2094DC9F5FDE8F50B7F07061ECA5CF27E01B529BE1948522206C8051F01577D24C318FEBC2762DEE56090A69FA567D0C5C78126420F1A05ADA51A6AFBD1EF6E49CE8FD350DE872090DE73F0C124AE014920F104EC5BC7EA0FCEBE08F20F05310687E973E17F1B39B9436F1C1BD5CB39C7641828A7CE9326E53A330165405C68139B17268176ECDB8152C820EFE4B2A27F111680129D3CDD01F47DE9C9D7E9E73AB798649D6E629B2BA94CEAA58172565F34A2DC536D64EB4C81041F74F76D99E4FF70A47B904C80118090DA4220AC717C36C588FD89EFC4730049FA8AAD5AF60BDAFAC1B2FCCA3ECB67A59F97E752BDC33C5CFF2E1ED929D6F4214ED25F04D7E07E38C51FF1B1B3BCF0D8D38B31CD3B8A69210C1C3E5A92FB8FF9E494DD38DDE356F73A78AFA9F052468928384DE9E28DBC174230EEF55BEFCAB87909D9D5B21508BBD0D5D3876F754FE9285CA3208CA501606F0EB6B7FA672FA34C4701D464A9F05DCD14482A95871046B385D87F0CE6BE103A45B7E8F10E458448E57618F066065AD0653A7135CE175D55D84E19D45932534D0045CE8827EA5B7096A5B0960BC218F36C8BE436AF40B6FC2A6B7D8884F55DB87AB811FF571FB01A405403F4ADDD2097729FDE708EB369DB19FAFC35528A11EFF706445E69F463A8321FB76FDF380A71B9412AC6DFE1FB190D60A05F8E5FA34E90E9F735BB155DA30A254D0B3C2EF633F5E04CDB10A20311D2846AB24749D78FAB6EC47F89EDAEA01CE9C99BAC79F55E0CCB1C03AF2EF2C56D45E06D33F9D3ABBC6CB4BE09793A386048112071548CF0A71C9991DBB3A11D93483E3716D9A8BAAF62BC5BB58E24D982E067547936FBB57F2C25218A230EFB1A665F3D948CDEAA9F8659900F10C43437C01BF081D2664641DB6FD5B0CBE2004A96DD26D999937817B3A8DFF7404AC0D7D1CDB6AB21EDBB8D7AFA8D1DA69E5878F2D83BF8B926E29C2EFEB16A4F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD5894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB931516966BA24D9585F1C0B04D660E629B3A2A3F31AEB6AC3EE8DF4DB67DABB5C332B61CC10887A0A207201703DFC4C27B774468F2CD9C6EFC711426E248C33EF946923D4C1AFA7B608F9F080410AE8F9F08CB38D5C0F6664EA0F630D34DFC55462334F617F3E4AE640E6C2D27597D4967E08EDC91704B9E3EE49EC4F0506994C3DD1027F8BE7FC46589CC21F9BEAF4F4130BC7D8325FD638235372E12CBB84FC424BAFF7D301855839698FE2E38B63BE461E681B43A02F99E466319E808084BDEFF59DC9DA0BC5F523A21D4525D81501A83F357BAB3633C061D403C7ADD90CBF38C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A36918612009A7CF4A981971AB37B767BC120AA994494DA75CABF22D1FE63F1464E981A0FF2BA93D3AAF2CEEADAFCB80FB7D012A588D4E409051A44F7287EB74B23A7F9A4302D2E7EA81F9FFD74D72807123DC3529B24DA2AF50619784A32B75985FE5AF8191B1CCF65322E266C37555CC3A971BF53E46DFDBC336CE5DAB6A84AC0F17F219C1DB9BD42A4F9662C74AF602347DE8A4EF176A34EAA287C9615F90FC02ABB78D80A6327768932976729CC4BC564E870C58EE9889C877CE31BA913EA7E454C0868D80335CC063C57D0BC1FB3C5E09B3A20F8166F8BDC41B01A8EEB62127C5BF88686BB8D0350F7BE6B56E0CE6E66B0998140C6F839A1AB13D68EF718809E2973CBB24BF5D927E83DD6C16C292D94B6EFE4A1BC9E050E8D6992BFD1C6F906C0A7B81474293A86ED095FD785C5BBA70F51BA7D49E9A5FFCE8193DD10914F642178026F159AE536FC1FABC7B78A3C2DF55D0C8E1EF23883C6FDBC053B447825E75F945D8157A967B58B0574C6E0615387CE1652DC027B72C45A8E9A4287219D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF71E8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B1A8277D00D5F8C835AB2820DFCFC4C8AFB2CB247B6DACFCDFB3765002D7D6EBA358848E7C7C63DA066252A81CC95E38A556ACD239ACB010A8169696B347EE86AE99CC7386155ECC56277B39192742ED8C959F142209943A017FBCE130FBDC3A491E7F650C98DAA0497D6C9CCABFD02921ABE4CFF254FB1521C702FB19F3DBBA1B691F7E44003C618C1B0C1B68A840B9763D43295E0CB779A59EEF7ED63AA1020069B2EF88BBCAB1D03693FE34C4C497F7936878D4DAB7B75BFF0FD8A0509D9A3B0CF209C9B7D09732CA0914617778AD289AC2110692D502C8DC75316530280FC926A62D46620A91EB4C89377C47ACC72884CAE39545022290B0D0EFA74045E4FFE5B7950E421091808852738371BAF20E81ADEE43642303C0F979B8EDAF4B47ADFB135B60A3E4F0BD2340A03D9F774ED36135C7C7241A89B2E9C71979E6BAA1E4D272BEA996623E399F2DA2AAAF6D0CE10191BA0853C08743DF8F9C98575E4F398BC3F19CFCBDB00B6C71E6B2B86A0E3BB72811DA873A3A318F6F334B64992648C9DA43BE0DB9CBA43FB1191DB64EA575DB1FA7F5E345ED532AEFC9F878894723ACC25CFEA3765FD8B4445453AB184E6C5A33FE8C136C8B401ED890A840BCC8C13CE2560D86119D74B6258D4381A4813572B6AEE5DB91BFA38F1E36EFF3DE17E255F8302A3A8161AD44F095659EEBB8E99100B7A19BCB8842ED58C474D1FFC28FD87A032D583050C09C64D4AE5F937743FC5E4705D9EADC758DF2CE55F240A40267311278E9198452030917F0ADB64226D6D413BCCB02C9A5C830AE5F2DBF73BCD8161132CCF43553B8FBA8E5283C953AEE50DDCE4EB59D29E4A2E5DA0530B922286F3588848CAFE9182175706266C466D65F41C3C18B000789C74952E3E2FEE44CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D58C6E04B24FDA2C3239210393254B41DA390EE357C7C175EA1DFD32FE5AADE666337542E508FAD05AA818E37539322BE1320FB587B83E86AA18434C47CA39E9850984F7339BD164FD46557BE86FB71B18CCAB5C34449AA65150D6F47A8117453D706F30DEDEB127BBA56F23193113CCBEB626F61BC4EA2D5053B489414A7F9731010D4333E72690C936D00367C343DA301A455B4CA7DCFC4215B0EE5185F1DFEAD2F09542D42C8CC1BA6ACFA452C6237454C5D115C0F5E04479131F9F1ACCA098EF0ACDFEF6FA39E4AEE14B0823E911EF2DAE145E261AE05A117E5A52E9DEDAC73742F90B4EAA8AA944F14679B0F72AADF6B56B31F3A2AA0AFA243C3DCCF6FFD2799FFA1F9861A5C04B0A8F68CC1BC8C90703AB05FBE50C15F06B04570370DEBB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832121C0C078E6BA4A80F1A20BD16BA90FCD04D43A0927C164582A796C12545CBD0BE45745F9E0090A47F31AB9B11E1496EED876912B13A841C06B6A5E812B11EC912A83D6B8663FBA403442AB4C70D3CCB76BE6686CD55D831E8DCCD05594F47FD58A835E3132D95EF4B4E8EBC275280999BF68305531A7F9F5EF2E8ED77C42227D0ED07B337CEB70317037ADA07819791A04BBF73646CC89806912EB3E2BABA0C80C7EB7BBAB7CE68583B609A5152A39457D51EE0A3CB4E897EB6363CB767057ADD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C63F474F26E2917A9A1B025C28BAC7D53E4E150E981E0D5BA4129911F99588369CD97444E871D47141AA795560B9576AF7870E3F62BC6F010869F6CA393E48A0BF5BE7ED218D65D942EC0F815F2258A47F7A509B6BB999C17B28D46B7D3CA59061D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C09FB9C3782471D5185D98077B9CD560F0F2D8109B8F2DFA711892BAF0A4A828E506417EECDAD332975E49F3E9019CE173E2ED3985D7C241AB4F7AE082E8EF49FD22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A6E7D8241F8BAB4D68DE3288296539D0DDF68497D7634A964B76E82AF13767129B7FE5BF4C85685F9C1649B8A52FCBAA9B2AF0C0C2BE1904DEB98ADA34507734E7937BE5E686F6DDD4E57D5EEF9FDC2164D60CD06AB5C9D11B840625837703C3CEB44B6542B684CFC5EB9B3297D946E7F698FD75C5A824EEA9328EDBA65225623ECF3B1F560C0D9DD03CA404DDEB74F901FA06FF4D2B0972C31F94450036B01DDD94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB0AC0CF31A27014816177F79DBE703195F44C47205EC4A5CBE62146B5246AFD86660BB52A30FCC16AC9D773E97F581C7518D007FE0489C09FDFA334F49313FAC2B579C7AF47F9946A85247DC902ACD5E0B22949F45945DDD51DF6AB0FBC225603D7377F93D29F2DF9500194E614F93DEFECBCA3AFB03D22F8FD7661D9D41D62D3F34476EDB8FE887C37129998A21E92F020460D3AF85356DAA577666F5DC0BCC5986DAAF87F5A9E602BA73B7392923FDC5B81A6BAE67BDABA7F7D2E9410D160455BE2CC6A833BA1B0F8FE54852A576BCECECF9BDAEF1C9B426B3DBCA32353CEF2D782F9FF8C8DB114C65E259BD077E800BBF0AF92AE1083501FBCB6D736C848AFA2C836F2E20EAC0336B58D10000EE1E6FE4AF2C87B2DB73F0F695508E653A3755D0CF17516575A25E8960FFDB7B1A00FBED460A8BC7EDC370A52E214885B7DD496596F52B1697C11D5127906C27EEA91E5D3E948E752D54EDC1A8284B9330F1BAF79C2B31C41136602FB4D1A7418EE586E7386677F90D185CF9D61FD7178055651AAB6AFAF6B955469C05B619297155F922B97B7FD28FDA0C0FF3BF34081177EC83DC0433EFB8A1417D60691D76E15384DADDFE66566032B722D99F959653F5C68D4FACDEB4DB5F9CA52CAB9D78109D66D75ECA67FE82A790ADABA4C8F8EDC5663FE77361E78A43189D2B89D1F26535B1E860C9F18E7A3BC6892A68C68AF96C1F4730192CE3BF69D4E7048912FFAA309913C054E041306B4B0079D606F9EF3E08020379FC3A11CE22436F7C8BE6C5F5EE2C1C1778320456C18A68F306AD1B55954389F635A502169454E7C432BADF0A68F529903CA29C2B836DFF01B67CB745A77A9E7813A52B92C810B51BC3E71D7AAA9A9F31EE4542965AA0F6F9907D1595A31E720D4A7098FB2D72F01F8B83BF3A93D05157307E2B595F0609BF2C8B94EF6A5D60E53F20C1559A9476CD2391127B12D77357269359C424A769021D139860DCA4136B718B65880234089C1138705945AB76C815ECB06C01C73C60312FE6DE218F09C1607F528CEDD2898E077008FF6E47C4FB6B2C103BA92C399A24CC38B373B3D7F00D63E6A42412F710C62528106482F703ABC7CD198A24723A6BE730E6DC971D468EA20D76800F938E651FAFD425643ECCDE70BB4DC1D6FE4E9B3D3624C330E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD6847C7DCD156F805A9A513F17CFB60F16925F4C587744E4AD35C7127757AAD37B73E5277D6614F0C315BB9E3BE48F654AD2D343B3967FCCF5387EE8297F2F74214B7B154E1D715C8FEB898A1DA31D5A8ABAB9CDBAB991459E62BE9F0E0A69791265ACD8F7AEDAF736FB944D3CEA82A1B3F23ED9AC0025760D260009668580A7FED8B073D52EB9D1847445D2064669D9E03116C2D999F3274876F37552E2D8A04E4409EFB415FFD9571BBCCFDA01333286A5A934E32D7C6D7EF3A20DD86ED5391AF91188FC2BBA388067FA443275DF1C06B23BEBEB418CCF1A7CA0E4BAD57780AD7D5528BD18362F273F0D97C081E502F32EFE1508B343268F1D2EB3F12914313283E40F4EC9F02AA17AA8A310FF50DF2712F49896FE31BA07A188488E45EB59D6BD6B858D527BBC0892580637EE631FDE8EAC14EDEB1E73EC75C8C241294EA628DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF47606C4D632B57BF57812D2B2CB85C631F239710C05C7743C2F4515F6C64CBBC8109E7FFA421A5A637256FFE7F44413BBDE5787EB92060591282ED69794E9D64356A585D5E293E705EFC493596D08F3E68CA984532F71A20D81C4BE0CA989A19C2FC268CACE37F8F2D5B481F2A4F387043A4715FE805C6FE2D4AB89DEBE10CAFD406F37450F0E477859629CE2B957F3415CC4E2CDB795EB766193DB9CC1E5D34B022FF9C01B7ABAB66A08EA5A0983E6E85954C92A6D3B2AB9D45BA49B21D45A3468B53440BB45283D3251613D162A9CE508A5766740BC16F13842C2F89F2396E3363A1934E3AF2E7221957FDBC5F2BAA72B6E62BAEB9E6D33B248A5102714178A60CD3A02B6E121E1CE591185608500C11AAAEB039497472C12F766386647573D2974687D3B63D655D412B1DC0D3084791DC9CF5BC4A42D6D3787A187D4765E5C65894BA159FCFEE27FB3B36A54A9FA312C81EA09C6762770B9649872A738FA0111D745A1F9A0BC53FA819D6E7220FB07293058C8EE51270F86D956780BB52984745B68DA948F7F936345F770F38661F35198D5BED466C3E1C7A23DD56D543CFC93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B7871339ACAC858B546C9139F4B917CDA356F04B779BBF803351C1B452BD9EDD0E2DA226A5F930C3C97F43D4633BF11B8BCEBF646B8608685E36F0ECDE7C7FB5F977E4D61038C745DE151D832D47C979224CADCFDB0C82650055F1519B94680A840FA14B55B2190C71AC1F7A7AEED989BE8C8AC61149A0C809449B677AC353867D0185EB15322792A3A7E328FEE3DF2230E4B70551FD7F9BD57BBEAF02E40124C58F019EEB66602B9EA10094839EFA9070F5C2DA3AAB6CDE6EB58246A59AFFA0352106F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C013843CFEF1EDA266283A5CE4A6ACD7597519FBD097E9E460D9B071D34EDC61672D14E6D9D4F9A033B5B473A1B13476C3C447E884455A5D168DA793F9E2F096157F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B832C73668D17AF4C29F2A72A1E8DC0D74C9F2446DE7A42F50A5DCA2F12EE84A91F75004E452A4E5FC799176A42B4D0A0A0CDAD9B44CC246872114650941B08315BA68E4B39A713B08A66F1715FE9300E5AAC533E37AE289B74341BC1DC7C75725C9838412E48A4CE312DEBC345B16A3A1F6388F350997448653448F6C7C91B7BE24118C3A0F4E431E88766E5A6C6113C8A2D1D2646B5EA5821C90CBE2CCB6CCA02A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B2BD0A2D4978F82258687586F9E6EE6AA21877D8A2C7AE37332573C420DB9C8754CC20EB937A8B94056D96EF571162B0106AEBFC344B5F28D52B8CD02F6168F45B321639DDDFBB333C5B872E80370F408EFFB5CC7394767F8CEC0CDCD7C9189E1B24FD29C7FBA4B14F30B8F5996155855C08A749B6AAED58C55271223A53D1E8714549EEA65B9A9245D9F5AD2EEBAE82637B9E3C78A24B5262873759CAE9AF9054C3230F88509E71CAE2238AA2DA1C25F0DCBFDE9BCC7B234BF1EA6697DD4E8B020B099CD92492855F1B528BA0B359BDEC1E77245432B7B1B2A5A7B969947A2FCFEAB2E94762E2F3F524E88E6FEFC4DBECED7EA550E6BCEDFF229E69D9C7C7803FACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E9847ED6D3A7874015F0AE87EE37FB6C478F7330A07D4C59E314847065E2F1F5F7F6DAE557F85B03FE6BB31B28A40263B64218FAD4572BC5FF2FD4E3F8F9A8894795658466BFB5DAFFCD99A69D532713CE072D81A42045933CDD30DD257F6C9848577D9F8B09B5D7BF71CF202AC4CF296E05C6A7ADF77D8FC670B88DAD02DE5A80D4168F7F72A7252B0E421F9734012AC8A8188677647D35ED6199EB300A6B71111D7CC77F04AF5E559A0D34CE1E1490576716A861E79902678C1241CB6F614176147ED88C82A99CCF2BBF62AE65572300CD4FB12DED4B6B0901D5F6BD02F036BF66B095215AAA76BAA4A07E2C0CAD2B2D76BEB56956C26ACDC11FDEFE9D42C6A698C09F0ECAC502F2F7E00233329DCA9595A191DF6C87B728E8F9B59105B9074992A62F2DFB38852C7F4BA5BF782395E906AF48136AB2DEAB4BBE7F0F79867696DDAA4176F14C9DC7A301B0DACA30332F73CA3356A62A4832A12DCCC3D696505F59E73148ED6401A34F6986428CB1CF18FD61DF1455A042455FBD97A76A404E65CD0BF41E26465281A0BA11EAA39CB48B99F2354BF5407629727B52DBA14B29C65083AE8B8891AECA5500BD15DE9E66E7D5C0104891C17A108B79D8D96D35F12170E2C930F8F16068AE3CA8511016203A1A4726CFEC7B6AAC959B67F3FF1E4AAEAD667487299703D38472B5085FC55B9BB775574AAA118BC81076CD53A4AA7E927482B1D617C09C6C24DEB07DD41C2C42B6A0BE168493CA5A40266AF5B992B9B2C65CFA82A2EFC515948A5FC521A7F49DC4BBAD296BB6FD4AA6FE1B7A7726229C03DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D973867CC37DAFE8FC39332DFD321B1ACA45587EB6D4727F5AFEC4178CDD8AF03FA0629DA84844B5131CC2AA07E2FBB8F80D3320AF5C1734031AEB68DB8B6C7358F775E8538C260FE6A79DDAE2BC7D40222B2942A2D8ADD3F295A135B5FBBA319FA3636F56D1BC8CBFA175EA61C1F53980664282E56291B4ECE5B5FF33C2141F04A3FF83EFC062CF6C635497FD03D6E56E405C43C4A31DDE872C4E277AA190D1D8350A298F16BE75BE305891F9D1084146199960A881C34318CFCF1366E82A487CEE95D5EC9F9756FFFC9DF3A1058E367160B321753C937D587130F9AAC766C19F033CCB2D886AB532683F50D360D10DF559AA16DA2C0E3203337B46EA1FCC1407675C5057052EDEFFF36BB2A6331522DC5CBC871C52CC35E95DF677771084A6E3E10A56111E6B9F7DAEB1FAA11B9CE5EA450A7D75F2B7266193CEA51A9532D8A32A2D4C275ECE75C3A59C3F02E3F9F40968642D6387F752C801A761F121A3EEF4F6B0AB83B7E815E5BB9D67EF85BF9DBF72E5E6DAEF4A6F7519130BD4F826A82D23332BC291A3D320CBFBE4BF1A143B78FAF7C1BF61F30801BCF715A05F2F7429F0D1A3B9F90D191754FE3D761A77CEA46082D3D2CA5BF26EF05257DBC8B72D156920EBCB1E064FBEC3CA43AF31CB2A53B246BA02E3F8AD4E07DE794CC1D8E3814DE61807A116F768CFFB159D16CB7214EAF1F52452B768380F4E16E2BCC10E82A027148477F2C717844DBB1677D6F2559AACA58E4759D40C7D62610399D6EDBC6DD4DA7904D2C53E4D9E07928FE181D503C5D45D6DE07E767025D9B0386F8C123C38CAEF00BE2223E8B1F46370B1D20FF0DBF78CB6A016D0F72F07820238885D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3A1E6EADFE7066FC6A5781AF310597B333977E34D01483A860E7D986357107DADB4F5D040550E524D9D1AA456CAED45FB5F6475160AB01C8AEC46EEA735384E4FBF205BB117F68C03F6D301E5C469033B05360DA23CF49DA36E050D627B2067B30983B2B426DCE0B78C0500BD15B3D2572537DC9B5F0BC0E1A12F533F58B2E21102318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3F5C33BF53D2A951EA7BE7FE2D487362EEC1DCB93920B266C5AD39FFA0FC6D4B335B1355A6D8AD3CFE51E9F69C8961A82831BD27F727C9030A816E817783DF89B519D6EC14C9CD88B73FD6152250E229BC6CD8C952777CC5D670051B18F5AFC99860FF7387C5880564703541C2883BC93C5C0EEFA57AF9E9D9D04EAB3BA87782807C37D299789C60C63CC2E86B5610ECA54D3949E17070B1978781F705E32042AFF28FA979979A511C5D14ADD08AFF7DDAE858415D7B0CBA138BF6D1C72C99A9564FE6CB5C9ED554B98D21CB796FC053CAFB4B3E8214F44643C99D9C92EA847A1B6DF3BC21FBF810F9D04B26771BC6DBAD0BDE30265D402E62EEE8ADC84CE8AF0FECBE8F68D13501515B8C28F68AD45D9D1A454904DE944A90C7500049FB74979AE952EBDCBA09DE543283CCA44D3F00EABF99DD714B8FDE3755D30105AC8CBC4569789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411935E2773E3B03C5E4959D9A2F7D55B05B8574768DF40B5EBF76FCAA69F463E0FAFC9F02B01C7B89C1AFB661B43AED07A9D54A6669DCD9022A4EA628CA69577EB1D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE59F8968E30E844A031BC745FED8550EE78B1266A91694B967E66785403F9FDE097DBFF047A171318C43FB2472127512463FA79877B475C7F810D28AE0BA7C5966102673F9F55653D9E546E378D2BB17CD35FAD2F50C5372DF7871B1F1DE78A72FC84F2AD1BACFB45712FB13E3773B3565B021D30A31602528EF16FE6D83795A1A8620E06BE25AAB07A8F3F1EE979687840B7C863D0D8A547A5F7197FB72024DA7F0D3E331C300BBA084A239D762A49141F81E46C97BCB157E81FFD88A34862C07F224E2ABEEEDB7E701AEF0A2FBC73A73CCF9B88E0606784D0BF4E99D41EA993B5401881439CBF17699A62F3D426EBD3681942C7F6F7B40835A7C996B400565E8BC9E636698FE0B197B96767C304CC366E2279F19A9E76B8B549DB73200EA7B3F788CCA15EC4A56D86CFBA4058C3C514F3154854CA6939229C3FAD386BF62626211CDAA71529B5410E08604348A4FA025A71894B946DF27454F27BC01996F23C8677C11780437BBE7131493B77D15C667AB0012BAD1CED0DE088C3D83795C30A3E34C878413680940B88C4693DD69B53E014174D8DB87EA6138C8CA99800F4F93981189912022DDCA5B6D5AA4DD2E04C394191204492E8CD5BD3B1599292F066E4E9D5917ADC3CF954851323255BB47D6FB2B0B6E93D9C2E39E23F7F02915149F9234FB2F13E6BDE58B24DD23CAD19056B0F92E3C1449421FEB5A740C7BDD04C76D8C2AA84F1BD9CCB562B9AC66C54ACC986BCCC869025339B9EE0CD9B8C0D7025B3662F8BDAFF77D6C77324F336C1A5276F7734EB3399FEC4A5902AA5971A933EEA9AEE40BCF69C70168BC10F1E9576CD541325A8A729566CAD7C0483ACC8E23D17DB2E495CA46032D9EAB61DFB6703C7C06BA4FD0513B55B05512CECC642CBB9D75AE94922FA66546C306BB281A106EB0D25D4156DD04911DB499F9A77B8F8487EB0287D9D564EDA31C37DD33E57A8D5A33C3088F4269E28E87145AC781DC38A75D575DDDEF448BAA06A60E54E4F6EBF94B095C14E36CDFD29B45BE3455F1930F39F77150E595CF127D1FB7E8226CA954C355D7098E783D32A41E702A611115154F3DB1A8484E4C6A81D13632998E75BC4B868F7E6178F035BF1BEA7510E3A823DBF976A0741138D1D5C9B2B434076228B7C3DAEB0576CD1194E82E62A8F902F9C84A1040262E83913A179EC88A1973DA20CD50D9676DBA1B8C036B97AF2C2005F1F556D1C462DAAF0E1E720B728AE3A7187F576F6B19177F83CB2953F058E0573D795A69B4C72365CE904C9690FAD0ACBC12108D950BE728E935FB7FE0779C54C8C0CDED49F111DE5777AA6131EE9084796DDEE52FDD7567A66ACFC8BAFFE19F46D0BC02258E9CD605176480A7E11B2B7283334B1398342061098099C06B1DB47A027B6577055A67649E98A0AE2E890FAE3186EBDBC6962257DCADBD50352BF17A03933D6BB6E00C1AA62CFEF7C7834BB0705A50205C4EF8D3270C4A0716A593858D31D1B989FA57C694A39CF877024ADFBC5FA2386FD36B07BE137723172C0E08CDDD0185E2510CAA4E4845ECA6C9750F4501FEA182D7748CE3BC2C902DF532BFAA83B530C214A5C649102309116DEFCCD338D8AB9CBEC500C26095E4BE1521964AD4694546C8D1F3774776C0595E0ADD0203F0FE1489B43ABF5FFA96C25138D539203E53FE2EDF38BA68448A3520CCF623D8427DE666CFB05E0BC25452E526C7FFB8D1DC496F047277FB03444CB5ED7342FFA18EEE7B1730925FDB23A34CEE84A5DB13C4AC46BE0B0FBF36759DA3E7B8C3289628F7E8254BDE347A1267A888D7FB18D021FC09668E7DDCC0FE714DFCBCD73AEE1395991E44B423F05043F6094F3930B33ABF6EF6D5AD18ECADDB1B477C019334C76E553210D4C89E4C32DB105FFEA84396B80DCE49EC772FC586D65A0C6FA012888B314FCA5FE7D56304AEC2B6EBCA87240731E19F8A237E3080A5B4FB92BC823AEA37AE3886609B5E4335559AB13257E92D2EE60938B3FA1A8B15958F8340A6062A0045C098A08D6A78F0C8806789322017F576BE2590AF4AFE35C2C1DD17A4EFBCE7F65B7FCED0A56A91C2D5724455D0A7A4BE1A543451792BE01E9A9614C6026623E730A21A5AA1B22EA38E983F1CB3C6AFCEE94FD813CE143F84FA32A70A97CEB20BA50BEA097D13CAB9F0E7032D052D9D9903A39F07E56690711D67081510427FE7D665D64BDD70EFD0215C6EF994CF6FD7444DBFB51DF33FD88A9B2D54BADC321512B7B57AE2AEF89959050169E710CC7D38B011611B655BA781A5B3391868F48AE12EA4F0D539BADFF7D81270E6847C387DD76569E539687B1FFF23F0226CE24125D85D229804869826671E44CD3B5942738E53432EB5267B1DFD7C80DA709A3E6ED28B83E10721F4D08519A3474C951803C0172025BE77A6CD8F5F9B9E09ED8CEB187F381D57F893F96E78A10C1AE29A306BE20246579F74C2AEDA46D2FB03A5A08C152BD736C93C7450149AFF1C0505E34E48C193F046647C61565FA6BC99044E7FCD0488716774CC0371D9ABC47CC69C415AF45B35FD240661DA201D3906863E1E0236A8A0307E854DBF000462D7217090E77A43FCA84061F881F71DC197BCE1D6B518FFC25A3E4926F64229AFFA4098F5198DCD8BBD2F99F95453723D6BD04DC5F2C732970D2AE4A9165E3AC8C8A767F0BA93BCE6F76F1E4A96D167E9EDFBA17A78E7EB3015E158630058EFDA8FFFD9D1B074C8ABE07300265DBCF6CFD550047FECFDFE05721DB0EC4FC21D4C675B7387B6D524DF052BAB92912B6DFF155F00462AF058203F94021F6388249475132A803A31E55E366AD3935EA2D7BF1FB0DD9AAB9D494ECCB3B7D0B7663374228438E11FFA2918324BAEFE443FB17B1A1950B0989D5B3379A13D82AAC83687BCCA2358DE7DA30541EB84E75DEA2D27409E7C02131C1FEFC1E02CA55584FFFA7CD7E8B6E2E2B7B685BB96710B6BD0B672334E8902CF6D49F47CA682E4343EB5DD588B7E61FD37D1972BACBC77C27CF06218B51E82E000185CB9BD13F89E6C3AF38596F181FC8A31B68C8C21DC711EC8BABA1CD7E812B4D6C939B449251718439129B95119BC9BE22C5E237B0B083582093D9DFF114C0F632A0C0016FF3A53167DB27B2F226A2B4B5EB7A409915DD46A882362462CB5BB7C3D2FA7DFAE5EF6969F34FF7E1B0958C4297CECDF374312B3231354D04E61AB4B668921E65D7ED31AB5AA46E5DE9EA4F5243CBBDDF261FCE1BCD26DE90FB46AF9453164A3FE6DFD83DBEFCE4CFEF2250893E21030934A382A288C69BF0FC7E9C92280906A4BA331C652BC4F904B9B54DCF3DB0651E43A6C83FB9843F85F0DBCA8D2E7F492200039906CF62A95D7B1830FDECAC0306B1A98B6F7B399E406A172202E29FA157E168F4B9C6979150F5AC2EF7769E4A729B6D59DD8F944E9A4A118FD06355D19B28ABDF256B4390DCD5C098DE989678AC25659763FC22E05FC4EB5860F4532E1EFCBAA0ACFCB91F30D21D2C90F8DBB5B419D8771AF1FA14AED614FA2B5DAB9F6F85016293B0716170A972790FEA6B0967F1FF1848CD29934182A9DDEA9BB49DE7B0A8EE13DA1F0A46E2376820EE34C1CA84E4524F21B5AA5FF74310EA831A3D3D08BCE359B830828E376B3C3999A9AC6168ABC74DDA8FFF0B35D6CD022BEC9BF0527A743822DFB79CBC96A90B6CF80B4E244E8F4386B653AF3D322BCF1E0DA62C28D019C7BB1B7D245E3B773871F0871B12ADB9306D31135B241A8E49D6EC6743C95469C24DAB5CE75E670357F3D22481C2E01E30215A0538DB0448CB9340D58FC633C9CA5141CFD79109D30F5943DD8A69F47F49C25E89EF486180AE64497FF2197EE4D518994942F6FA35BAB9D747CB356907B409CB427788C3D7708D77B706D9F90FAC25E492EB60F2DFAD94821D05D8F5721D46560CDC2E43963F70B64C7EC230170F2221693D7FC10B0F27CC4B154EDA86B74CF82CB44EB097E3703FE0B938346856014A50A106F64B236B17DBFEBF2B455FBB9C999CC1F9E7CC7D4DF12E1EC6CEC249345EAF4DACF0D38453A533E5193257BB55AA785666C64B91491B0A5DB93688FBE07D66D926759B669E18521210CAD05EF3F8972754DEA64BC0846516FEB472ACFF5EE2D7E29F7633E32E1A91E5DD713A56AABD6ED1EB967F371FE4D1A7EDF2432FC050A47F34300DC4B69F8553FA4A23509A45977E62736EC9653A51FA687A30FC0787CBD6824BCE36088AACAE7F55D877F773255A13B3A006CE4D2B2ACED5C03764B81B9DE5D9E0EBF9230164C5F75F05C4353F64A182FA15948C9BD8D89E5C6364B84ABFBEE413D0EC4D3B553A46B63FF0699542A2A7ED568B6E8A9C2C772B4F7F7FA17726174968E216636B4FC547AE59D73DD40F320D6B3329C868728B97CC704859F851149108B705C39AF3DD97EFAEBD39ACCFAAC8EE1FAAEABB32E689063B11483C47510DA0DA16B02EE4E397B146B6F777B1F2C393379414F67BCE670BDDBC67BC8ACE419C2E48C5B57EC624C5693562B719C7E696E1C83076E0EDE8540DE3D7AA00AC5A50E481F7BAA41C43A1C2EF09100EBFFE5EED9FCC095945F525F66ACD9A814582D6609DE9FDC132974B98454B501DEAB673C6D33AD29686E1D43912840DF6398F2468C0788D1D3B597004E6BDB7A89B57DCD4249EB51489F4DDA36B0A3B90C4EA616135B089C4D4B8DA02E695EB8657B2E12FB5554D2D833353A3FBF3FEA441A755FC4F0A49C243C3682A20B04AAB0EC430C9BFA134C383E4B6FD45DFB613E362B171F0C2B2473B38E92A21C72C100505B3E2ED5EB14D1ADEF650C7254F5163A2FC01B987E3000517DCD878B3D9268E912CA3675000B10E53F5B8172477AF6FE3778CB0E5D279309245647970C216E2E626D2148795132C2479B65FEEFD8B38395AE4A34ACD06B005F311974D6197A0FB415D7FA5E64502FC8C878B14462F0C6458E04BE6DA9308697467937AE52099382FCDC35FD7D2734B1150C214107CA53F6EAC9D584AFF8FBC6C2AF2B711F45BCC5626B1FACEDF4AD03E261A7E095044665CE61C3359BA5A046E44C8E5506E2BD7D4F6F08B57C7303472AD0369BD7B5199525024D34A0143DE46F8F3316F4A8B93DC5AE6B02A0F362EC7F9EEEF5303E3C0E13246E0F214FC2843F6116A7986920BAFDBC483B7D8F84ACCA690C6FBAF794BAEB0B687249A360CFE9E1C0A2817F2D93A166ACD35C00A1BDC4B1AC6BAEE6588B0958D5C2A0D63E6DADD81AE2ED7B8ACAA19040E7E30E454D629944FD10E1AC8ADC8C0CBCDD9868B973299A4DC927C49E944C7C00705669F96557477EE62F0E6140D613B110B9FBECAF70983B17EC4A470FFA4BFB8AEDB435FC607B957898278FC2D33E66F68E1F630D4A06B6413ED8C2B7BCD931DD4271D12B29336E47FBB378D48A956DDB447ED3A2B93E3C3A5559DB3B18505CFD0AE9377C5F87964A89B20952F5804125EACFF6CD0C256CB30288ED1BA4324F9F7850AB4A14F5107A91C3DFF05B82D1C4E3BBE38B7C6380AD2D1C41621187066598C2A314A84E55E8260D78D6220923EDF59C8CB7BB6E5B6AEB96BD7E436D19DBCAF897D8A2B3B41D17163C52CCCCE010274A70B6B985545072CC765A499A3E4FA7388E44F9A1F9F0D45694EAF817A3A7D068D3FF6F054145C716DD7CE747D3889E49DB2121A81EB40E2E2D08750F1CCF791EC924ED46F3C5C741E57C9CA75D7EF3C821A3A2EDACA966CDA766A3CE6EC0DEA096870022496856890CAEE492ACBDB949FE0BD8CE0C3E72468318B0322F894C64EED64AFDE22A7A1C2B22B348830444DD5B99050B4D3976A70DED872E92593215ECA63D2EF78B901B89230D2C18BFB4D50EBC5949A090DA9D27C7B9B3ADA9C787913ECD0D8E578DB0D646965DDF5C5DD3395906A9C02E7F33194DA5A6583C198A7D41CE382A6BA5B8F9E52701B31E1987E7AFE0109391E187223DBEC2E516F103BE65BF0FF2141194836BC3DA9C1031A5D51676AE1914885D9CE838DB07F72B047AC46EBB3E1FC79AE2BA473FAC3EAD512D9F1D3AC2536093EA580F0384B36F8B798C8313207EA12A1E244F0B2AE1B64664D23C8C2D7CD5EFC95C18F4EB7B196F368F29D39578DD3F53E050D351AE6D93A40AD4915927D82925BAEB09E8A877AB1C6B704775C0EE210025CEDD475823479761DB3C8CFBDD9739754C743307E5B9E81036C748B79AB78D0C56DABCB9893147A5BF4E3655329E433A0521B08DE2BDE442CBE9A2721EAA94B4F9C0DFAEC4D500FCC073568B0421444AB51CE94C9489818D4C598C1E219AB50C7F7D914FD59BC96542C72BB3636746A9C08A4A416E7E581255FEF48340CF1D9D6C5E9832B004C0F646FECA43FBF0E016BBCCDE92C1CC9AF6C92BB735640733DC1C031BD10D554E51BE3DBE3306D64CFA148779EDCAD8AEB21F5FDF085FB1DA0BE2DDEDCD1B094810903D80BE04D1FBFA7E59E17069DDBB49EEC76320B74F31C4428BDE620DE149EE74DD9BF22FE0047FF71486E339072F2B603B8055D7BA43FD71B3CAB178F34703FDB8ABDD8F5C1461F89446ADB1175E35428091CC0A3B58DD435FB4D9B5D62FDB9FA0A34224FAED03B10B5FE70EA67AE1A3005D3DC4AFBB064A22AD6A9BB05C15228E1D20D4A4E8D041BEF83790E9707A581DBB7689E032A083381899EEF508E4B2A897FFAB447F821C848EED8CA09616CE2EFD13966C494E919BD76A7C971A7731B13C4601F7B659429C2F7F7592F4B17894BC139123596F5B92139A4B5768CDF2E35810BD1AB3BB40DCE3F38853783F6856552BF95A4A835590582BB7206044086C1CA3BD9B8ADFB09C40A838DEE80E1B3756F98073651454C1567EBB9BB8D9FEA16E9CB0F30FA5E7944CCFE2732FB90178A6F439EF2C83D0FD90FA196CBBECA9DE1DA63AB609F53BF11303F3AE2283195AD62587795E7CE13CCB19132890CE25B085F7AE282F8DE315DED51D9E7B4652285ECB3929B9D6F51E82EA4BB5AAB4110925E014691A62121C27B5D929D24069ECDD6148B64213FCD94FB9EB6CA08C3D942DCB7FADCE9FB3917E40A455701CA8028A1456EDECC5EE3A3A27DE819CC28084BA0BA992CBA7D3DEDB39B4FBF247D2845FF9D4B455F5D29E81C17C5FFDEFFF7CA2153F968A130EED46293DACE1777C0173B089DD2DC63CA91C994E506ECC920E8A96608FB6E4F970A59145E77CBB83D1A5C22F917 +remain = 1152921504606846974 +max = 1152921504606846975 \ No newline at end of file diff --git a/tests/helpers.py b/tests/helpers.py index f050f83366..781df5e45a 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -204,7 +204,9 @@ def get_katfile(t: str, sig_stfl_name: str) -> str: algo_dir = 'xmss' if not algo_dir: return '' - kat_filename = f"{sig_stfl_name}.rsp" + # Replace the "/" to "-" in XMSSMT parameters + clean_sig_stfl_name = sig_stfl_name.replace("/", "-", 1) + kat_filename = f"{clean_sig_stfl_name}.rsp" katfile = os.path.join('tests', 'KATs', t, algo_dir, kat_filename) return katfile diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index 9685265902..8e56bac5b8 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -2,7 +2,6 @@ // This KAT test only generates a subset of the NIST KAT files. // To extract the subset from a submission file, use the command: -// cat PQCsignKAT_XMSS-SHA2_10_256.rsp | head -n 16 | tail -n 14 #include #include @@ -19,42 +18,41 @@ #include "system_info.c" -#define MAX_MARKER_LEN 50 +#define MAX_MARKER_LEN 50 // // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) // -int -FindMarker(FILE *infile, const char *marker) { - char line[MAX_MARKER_LEN]; - int i, len; +int FindMarker(FILE *infile, const char *marker) { + char line[MAX_MARKER_LEN]; + unsigned long i, len; int curr_line; - len = (int)strlen(marker); - if ( len > MAX_MARKER_LEN - 1 ) { + len = strlen(marker); + if (len > MAX_MARKER_LEN - 1) { len = MAX_MARKER_LEN - 1; } - for ( i = 0; i < len; i++ ) { + for (i = 0; i < len; i++) { curr_line = fgetc(infile); - line[i] = curr_line; - if (curr_line == EOF ) { + line[i] = (char)curr_line; + if (curr_line == EOF) { return 0; } } line[len] = '\0'; - while ( 1 ) { - if ( !strncmp(line, marker, len) ) { + while (1) { + if (!strncmp(line, marker, len)) { return 1; } - for ( i = 0; i < len - 1; i++ ) { + for (i = 0; i < len - 1; i++) { line[i] = line[i + 1]; } curr_line = fgetc(infile); - line[len - 1] = curr_line; - if (curr_line == EOF ) { + line[len - 1] = (char)curr_line; + if (curr_line == EOF) { return 0; } line[len] = '\0'; @@ -67,22 +65,21 @@ FindMarker(FILE *infile, const char *marker) { // // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) // -int -ReadHex(FILE *infile, unsigned char *a, int Length, char *str) { - int i, ch, started; - unsigned char ich; +int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, char *str) { + int i, ch, started; + unsigned char ich; - if ( Length == 0 ) { + if (Length == 0) { a[0] = 0x00; return 1; } memset(a, 0x00, Length); started = 0; - if ( FindMarker(infile, str) ) - while ( (ch = fgetc(infile)) != EOF ) { - if ( !isxdigit(ch) ) { - if ( !started ) { - if ( ch == '\n' ) { + if (FindMarker(infile, str)) + while ((ch = fgetc(infile)) != EOF) { + if (!isxdigit(ch)) { + if (!started) { + if (ch == '\n') { break; } else { continue; @@ -92,20 +89,21 @@ ReadHex(FILE *infile, unsigned char *a, int Length, char *str) { } } started = 1; - if ( (ch >= '0') && (ch <= '9') ) { - ich = ch - '0'; - } else if ( (ch >= 'A') && (ch <= 'F') ) { - ich = ch - 'A' + 10; - } else if ( (ch >= 'a') && (ch <= 'f') ) { - ich = ch - 'a' + 10; - } else { // shouldn't ever get here + if ((ch >= '0') && (ch <= '9')) { + ich = (unsigned char)ch - '0'; + } else if ((ch >= 'A') && (ch <= 'F')) { + ich = (unsigned char)ch - 'A' + 10; + } else if ((ch >= 'a') && (ch <= 'f')) { + ich = (unsigned char)ch - 'a' + 10; + } else { + // shouldn't ever get here ich = 0; } - for ( i = 0; i < Length - 1; i++ ) { - a[i] = (a[i] << 4) | (a[i + 1] >> 4); + for (i = 0; i < Length - 1; i++) { + a[i] = (unsigned char) (a[i] << 4) | (unsigned char) (a[i + 1] >> 4); } - a[Length - 1] = (a[Length - 1] << 4) | ich; + a[Length - 1] = (unsigned char) (a[Length - 1] << 4) | (unsigned char) ich; } else { return 0; } @@ -130,16 +128,16 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { FILE *fh = NULL; FILE *fp_rsp = NULL; OQS_SIG_STFL *sig = NULL; - uint8_t *msg = NULL; + uint8_t *msg = NULL, *msg_rand = NULL; size_t msg_len = 0; uint8_t *public_key = NULL; uint8_t *secret_key = NULL; - uint8_t *signature = NULL; + uint8_t *signature = NULL, *signature_kat = NULL; uint8_t *signed_msg = NULL; size_t signature_len = 0; size_t signed_msg_len = 0; - size_t sigs_remain = 0; - size_t sigs_maximum = 0; + unsigned long long sigs_remain = 0; + unsigned long long sigs_maximum = 0; OQS_STATUS rc, ret = OQS_ERROR; OQS_KAT_PRNG *prng = NULL; @@ -150,19 +148,20 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { sig = OQS_SIG_STFL_new(method_name); if (sig == NULL) { - printf("[sig_stfl_kat] %s was not enabled at compile-time.\n", method_name); + fprintf(stderr, "[sig_stfl_kat] %s was not enabled at compile-time.\n", method_name); goto algo_not_enabled; } - if ( (fp_rsp = fopen(katfile, "r")) == NULL ) { - printf("Couldn't open <%s> for read\n", katfile); + if ((fp_rsp = fopen(katfile, "r")) == NULL) { + fprintf(stderr, "Couldn't open <%s> for read\n", katfile); return OQS_ERROR; } // Grab the pk and sk from KAT file public_key = malloc(sig->length_public_key); secret_key = calloc(sig->length_secret_key, sizeof(uint8_t)); - signature = malloc(sig->length_signature); + signature = calloc(sig->length_signature, sizeof(uint8_t)); + signature_kat = calloc(sig->length_signature, sizeof(uint8_t)); if ((public_key == NULL) || (secret_key == NULL) || (signature == NULL)) { fprintf(stderr, "[kat_stfl_sig] %s ERROR: malloc failed!\n", method_name); @@ -170,12 +169,12 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { } if (!ReadHex(fp_rsp, public_key, sig->length_public_key, "pk = ")) { - printf("ERROR: unable to read 'pk' from <%s>\n", katfile); + fprintf(stderr, "ERROR: unable to read 'pk' from <%s>\n", katfile); goto err; } if (!ReadHex(fp_rsp, secret_key, sig->length_secret_key, "sk = ")) { - printf("ERROR: unable to read 'sk' from <%s>\n", katfile); + fprintf(stderr, "ERROR: unable to read 'sk' from <%s>\n", katfile); goto err; } @@ -187,8 +186,8 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { fprintf(fh, "\n\n"); fprintf(fh, "count = 0\n"); - if ( !ReadHex(fp_rsp, seed, 48, "seed = ") ) { - printf("ERROR: unable to read 'seed' from <%s>\n", katfile); + if (!ReadHex(fp_rsp, seed, 48, "seed = ")) { + fprintf(stderr, "ERROR: unable to read 'seed' from <%s>\n", katfile); goto err; } @@ -197,9 +196,23 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { msg_len = 33 * (0 + 1); fprintf(fh, "mlen = %zu\n", msg_len); - msg = malloc(msg_len); - OQS_randombytes(msg, msg_len); + msg_rand = malloc(msg_len); + + if (!ReadHex(fp_rsp, msg, msg_len, "msg = ")) { + fprintf(stderr, "ERROR: unable to read 'msg' from <%s>\n", katfile); + goto err; + } + + OQS_randombytes(msg_rand, msg_len); + + if (memcmp(msg_rand, msg, msg_len)) { + fprintf(stderr, "randombytes data unaligned\n"); + OQS_fprintBstr(fh, "m = ", msg, msg_len); + OQS_fprintBstr(fh, "m_rand = ", msg_rand, msg_len); + goto err; + } + OQS_fprintBstr(fh, "msg = ", msg, msg_len); rc = OQS_SIG_STFL_sign(sig, signature, &signature_len, msg, msg_len, secret_key); @@ -207,33 +220,44 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sign failed!\n", method_name); goto err; } - fprintf(fh, "smlen = %zu\n", signature_len); OQS_fprintBstr(fh, "sm = ", signature, signature_len); + if (signature_len != sig->length_signature) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sign incorrect length of signature!\n", method_name); + goto err; + } + + if (!ReadHex(fp_rsp, signature_kat, signature_len, "sm = ")) { + fprintf(stderr, "ERROR: unable to read 'msg' from <%s>\n", katfile); + goto err; + } + + if (memcmp(signature, signature_kat, signature_len)) { + OQS_fprintBstr(fh, "sm_kat = ", signature_kat, signature_len); + fprintf(stderr, "Incorrect signature output\n"); + goto err; + } + rc = OQS_SIG_STFL_verify(sig, msg, msg_len, signature, signature_len, public_key); if (rc != OQS_SUCCESS) { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_verify failed!\n", method_name); goto err; } - // print sklen and sk to check the updated secret key - fprintf(fh, "sklen = %zu\n", sig->length_secret_key); - OQS_fprintBstr(fh, "sk = ", secret_key, sig->length_secret_key); - rc = OQS_SIG_STFL_sigs_remaining(sig, &sigs_remain, secret_key); if (rc != OQS_SUCCESS) { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_remaining failed!\n", method_name); goto err; } - fprintf(fh, "remain = %zu\n", sigs_remain); + fprintf(fh, "remain = %llu\n", sigs_remain); rc = OQS_SIG_STFL_sigs_total(sig, &sigs_maximum, secret_key); if (rc != OQS_SUCCESS) { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_total failed!\n", method_name); goto err; } - fprintf(fh, "max = %zu\n", sigs_maximum); + fprintf(fh, "max = %llu", sigs_maximum); ret = OQS_SUCCESS; goto cleanup; @@ -252,9 +276,12 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { } OQS_MEM_insecure_free(public_key); OQS_MEM_insecure_free(signature); + OQS_MEM_insecure_free(signature_kat); OQS_MEM_insecure_free(msg); + OQS_MEM_insecure_free(msg_rand); OQS_SIG_STFL_free(sig); OQS_KAT_PRNG_free(prng); + fclose(fp_rsp); return ret; } diff --git a/tests/test_cmdline.py b/tests/test_cmdline.py index 66962cd98c..ca24bf92f9 100644 --- a/tests/test_cmdline.py +++ b/tests/test_cmdline.py @@ -32,9 +32,17 @@ def test_sig(sig_name): @pytest.mark.parametrize('sig_stfl_name', helpers.available_sig_stfls_by_name()) def test_sig_stfl(sig_stfl_name): if not(helpers.is_sig_stfl_enabled_by_name(sig_stfl_name)): pytest.skip('Not enabled') - helpers.run_subprocess( - [helpers.path_to_executable('test_sig_stfl'), sig_stfl_name], - ) + # Test with KATs apply for XMSS + if sig_stfl_name.startswith("XMSS"): + katfile = helpers.get_katfile("sig_stfl", sig_stfl_name) + if not katfile: pytest.skip("KATs file is missing") + helpers.run_subprocess( + [helpers.path_to_executable('test_sig_stfl'), sig_stfl_name, katfile], + ) + else: + helpers.run_subprocess( + [helpers.path_to_executable('test_sig_stfl'), sig_stfl_name], + ) if __name__ == "__main__": import sys diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 45f700608b..26385ab063 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -4,6 +4,7 @@ #pragma warning(disable : 4244 4293) #endif +#include #include #include #include @@ -25,11 +26,230 @@ #include "system_info.c" +/* + * For stateful signature, we skip key generation because it can takes hours to complete. + * So the ReadHex and and FindMarker serve the purpose of reading pre-generate keypair from KATs. + */ +#define MAX_MARKER_LEN 50 + +// +// ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) +// +int FindMarker(FILE *infile, const char *marker) { + char line[MAX_MARKER_LEN]; + unsigned long i, len; + int curr_line; + + len = strlen(marker); + if (len > MAX_MARKER_LEN - 1) { + len = MAX_MARKER_LEN - 1; + } + + for (i = 0; i < len; i++) { + curr_line = fgetc(infile); + line[i] = (char)curr_line; + if (curr_line == EOF) { + return 0; + } + } + line[len] = '\0'; + + while (1) { + if (!strncmp(line, marker, len)) { + return 1; + } + + for (i = 0; i < len - 1; i++) { + line[i] = line[i + 1]; + } + curr_line = fgetc(infile); + line[len - 1] = (char)curr_line; + if (curr_line == EOF) { + return 0; + } + line[len] = '\0'; + } + + // shouldn't get here + return 0; +} + +// +// ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) +// +int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, char *str) { + int i, ch, started; + unsigned char ich; + + if (Length == 0) { + a[0] = 0x00; + return 1; + } + memset(a, 0x00, Length); + started = 0; + if (FindMarker(infile, str)) + while ((ch = fgetc(infile)) != EOF) { + if (!isxdigit(ch)) { + if (!started) { + if (ch == '\n') { + break; + } else { + continue; + } + } else { + break; + } + } + started = 1; + if ((ch >= '0') && (ch <= '9')) { + ich = (unsigned char)ch - '0'; + } else if ((ch >= 'A') && (ch <= 'F')) { + ich = (unsigned char)ch - 'A' + 10; + } else if ((ch >= 'a') && (ch <= 'f')) { + ich = (unsigned char)ch - 'a' + 10; + } else { + // shouldn't ever get here + ich = 0; + } + + for (i = 0; i < Length - 1; i++) { + a[i] = (unsigned char) (a[i] << 4) | (unsigned char) (a[i + 1] >> 4); + } + a[Length - 1] = (unsigned char) (a[Length - 1] << 4) | (unsigned char) ich; + } else { + return 0; + } + + return 1; +} + +OQS_STATUS sig_stfl_keypair_from_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, uint8_t *secret_key) { + OQS_STATUS rc; + rc = OQS_SIG_STFL_keypair(sig, public_key, secret_key); + OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); + if (rc != OQS_SUCCESS) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_STATUS sig_stfl_keypair_from_KATs(OQS_SIG_STFL *sig, uint8_t *public_key, uint8_t *secret_key, const char *katfile) { + OQS_STATUS ret = OQS_ERROR; + FILE *fp_rsp = NULL; + + if ((fp_rsp = fopen(katfile, "r")) == NULL) { + fprintf(stderr, "Couldn't open <%s> for read\n", katfile); + goto err; + } + + // Grab the pk and sk from KAT file + if (!ReadHex(fp_rsp, public_key, sig->length_public_key, "pk = ")) { + fprintf(stderr, "ERROR: unable to read 'pk' from <%s>\n", katfile); + goto err; + } + + if (!ReadHex(fp_rsp, secret_key, sig->length_secret_key, "sk = ")) { + fprintf(stderr, "ERROR: unable to read 'sk' from <%s>\n", katfile); + goto err; + } + + // We are done reading, clean up and exit + ret = OQS_SUCCESS; + goto cleanup; + +err: + ret = OQS_ERROR; + +cleanup: + fclose(fp_rsp); + return ret; +} + +/* + * We read from KATs these parameters: + * XMSS-SHA2_16_256 + * XMSS-SHA2_20_256 + * XMSS-SHAKE_16_256 + * XMSS-SHAKE_20_256 + * XMSSMT-SHA2_40/2_256 + * XMSSMT-SHA2_60/3_256 + * XMSSMT-SHAKE_40/2_256 + * XMSSMT-SHAKE_60/3_256 + */ +OQS_STATUS sig_stfl_KATs_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, uint8_t *secret_key, const char *katfile) { + + printf("%s", sig->method_name); + if (0) { + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { + goto from_kats; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { + goto from_kats; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 + } else if (0 == strcasecmp(sig->method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { + goto from_kats; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 + } else if (0 == strcasecmp(sig->method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { + goto from_kats; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 + } else if (0 == strcasecmp(sig->method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { + goto from_kats; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 + } else if (0 == strcasecmp(sig->method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { + goto from_kats; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 + } else if (0 == strcasecmp(sig->method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { + goto from_kats; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 + } else if (0 == strcasecmp(sig->method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { + goto from_kats; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 + } else if (0 == strcasecmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { + goto from_kats; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 + } else if (0 == strcasecmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { + goto from_kats; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 + } else if (0 == strcasecmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { + goto from_kats; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 + } else if (0 == strcasecmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { + goto from_kats; +#endif + } else { + goto from_keygen; + } + +from_kats: + return sig_stfl_keypair_from_KATs(sig, public_key, secret_key, katfile); + +from_keygen: + return sig_stfl_keypair_from_keygen(sig, public_key, secret_key); +} + typedef struct magic_s { uint8_t val[31]; } magic_t; -static OQS_STATUS sig_stfl_test_correctness(const char *method_name) { +static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char *katfile) { OQS_SIG_STFL *sig = NULL; uint8_t *public_key = NULL; @@ -85,7 +305,10 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name) { OQS_randombytes(message, message_len); OQS_TEST_CT_DECLASSIFY(message, message_len); - rc = OQS_SIG_STFL_keypair(sig, public_key, secret_key); + /* + * Some keypair generation is fast, so we only read keypair from KATs for slow XMSS parameters + */ + rc = sig_stfl_KATs_keygen(sig, public_key, secret_key, katfile); OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); if (rc != OQS_SUCCESS) { fprintf(stderr, "ERROR: OQS_SIG_STFL_keypair failed\n"); @@ -205,14 +428,15 @@ static void TEST_SIG_STFL_randombytes(uint8_t *random_array, size_t bytes_to_rea #if OQS_USE_PTHREADS_IN_TESTS struct thread_data { - char *alg_name; + const char *alg_name; + const char *katfile; OQS_STATUS rc; OQS_STATUS rc1; }; void *test_wrapper(void *arg) { struct thread_data *td = arg; - td->rc = sig_stfl_test_correctness(td->alg_name); + td->rc = sig_stfl_test_correctness(td->alg_name, td->katfile); td->rc1 = sig_stfl_test_secret_key(td->alg_name); return NULL; } @@ -223,8 +447,8 @@ int main(int argc, char **argv) { printf("Testing stateful signature algorithms using liboqs version %s\n", OQS_version()); - if (argc != 2) { - fprintf(stderr, "Usage: test_sig_stfl algname\n"); + if (argc < 2) { + fprintf(stderr, "Usage: test_sig_stfl algname katfile\n"); fprintf(stderr, " algname: "); for (size_t i = 0; i < OQS_SIG_STFL_algs_length; i++) { if (i > 0) { @@ -239,7 +463,8 @@ int main(int argc, char **argv) { print_system_info(); - char *alg_name = argv[1]; + const char *alg_name = argv[1]; + const char *katfile = argv[2]; if (!OQS_SIG_STFL_alg_is_enabled(alg_name)) { printf("Stateful signature algorithm %s not enabled!\n", alg_name); OQS_destroy(); @@ -258,6 +483,7 @@ int main(int argc, char **argv) { pthread_t thread; struct thread_data td; td.alg_name = alg_name; + td.katfile = katfile; int trc = pthread_create(&thread, NULL, test_wrapper, &td); if (trc) { fprintf(stderr, "ERROR: Creating pthread\n"); @@ -268,7 +494,7 @@ int main(int argc, char **argv) { rc = td.rc; rc1 = td.rc1; #else - rc = sig_stfl_test_correctness(alg_name); + rc = sig_stfl_test_correctness(alg_name, katfile); rc1 = sig_stfl_test_secret_key(alg_name); #endif if ((rc != OQS_SUCCESS) || (rc1 != OQS_SUCCESS)) { From 55094c37f167ec4323411853ffc63da923741662 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Mon, 31 Jul 2023 12:53:22 -0400 Subject: [PATCH 09/68] LMS H5_W1 (#1513) * Support LMS H5_W1 * Fix style check * Rename CmakeLists.txt CMakeLists.txt * Add namespace * Address issues from scan results * Address SA issue * Fix formatting * Fix formatting * Commit Duc's SA fixes * Fix mem leak, and compiler warning. --- .CMake/alg_support.cmake | 2 + CMakeLists.txt | 3 + src/CMakeLists.txt | 5 + src/oqsconfig.h.cmake | 4 +- src/sig_stfl/lms/CMakeLists.txt | 45 +++ src/sig_stfl/lms/external/endian.h | 1 + src/sig_stfl/lms/external/hash.h | 1 + src/sig_stfl/lms/external/hss.h | 1 + src/sig_stfl/lms/external/hss_aux.h | 1 + src/sig_stfl/lms/external/hss_common.h | 1 + src/sig_stfl/lms/external/hss_derive.h | 1 + src/sig_stfl/lms/external/hss_internal.h | 1 + src/sig_stfl/lms/external/hss_keygen.c | 3 + src/sig_stfl/lms/external/hss_reserve.h | 1 + src/sig_stfl/lms/external/hss_sign_inc.h | 1 + src/sig_stfl/lms/external/hss_thread.h | 1 + src/sig_stfl/lms/external/hss_verify.h | 1 + src/sig_stfl/lms/external/hss_verify_inc.h | 1 + src/sig_stfl/lms/external/hss_zeroize.h | 1 + src/sig_stfl/lms/external/lm_common.h | 1 + src/sig_stfl/lms/external/lm_ots.h | 1 + src/sig_stfl/lms/external/lm_ots_common.h | 1 + src/sig_stfl/lms/external/lm_ots_verify.h | 1 + src/sig_stfl/lms/external/lm_verify.h | 1 + src/sig_stfl/lms/external/lms_namespace.h | 96 +++++++ src/sig_stfl/lms/external/sha256.h | 1 + src/sig_stfl/lms/sig_stfl_lms.c | 93 ++++++ src/sig_stfl/lms/sig_stfl_lms.h | 41 +++ src/sig_stfl/lms/sig_stfl_lms_functions.c | 266 ++++++++++++++++++ src/sig_stfl/lms/sig_stfl_lms_wrap.h | 62 ++++ src/sig_stfl/sig_stfl.c | 23 +- src/sig_stfl/sig_stfl.h | 21 +- src/sig_stfl/xmss/sig_stfl_xmss.h | 112 ++++---- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c | 17 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c | 12 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c | 12 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c | 12 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c | 12 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c | 12 +- .../xmss/sig_stfl_xmss_shake128_h10.c | 12 +- .../xmss/sig_stfl_xmss_shake128_h16.c | 12 +- .../xmss/sig_stfl_xmss_shake128_h20.c | 12 +- .../xmss/sig_stfl_xmss_shake256_h10.c | 12 +- .../xmss/sig_stfl_xmss_shake256_h16.c | 12 +- .../xmss/sig_stfl_xmss_shake256_h20.c | 12 +- .../xmss/sig_stfl_xmssmt_sha256_h20_2.c | 12 +- .../xmss/sig_stfl_xmssmt_sha256_h20_4.c | 12 +- .../xmss/sig_stfl_xmssmt_sha256_h40_2.c | 12 +- .../xmss/sig_stfl_xmssmt_sha256_h40_4.c | 12 +- .../xmss/sig_stfl_xmssmt_sha256_h40_8.c | 12 +- .../xmss/sig_stfl_xmssmt_sha256_h60_12.c | 12 +- .../xmss/sig_stfl_xmssmt_sha256_h60_3.c | 12 +- .../xmss/sig_stfl_xmssmt_sha256_h60_6.c | 12 +- .../xmss/sig_stfl_xmssmt_shake128_h20_2.c | 12 +- .../xmss/sig_stfl_xmssmt_shake128_h20_4.c | 12 +- .../xmss/sig_stfl_xmssmt_shake128_h40_2.c | 12 +- .../xmss/sig_stfl_xmssmt_shake128_h40_4.c | 12 +- .../xmss/sig_stfl_xmssmt_shake128_h40_8.c | 12 +- .../xmss/sig_stfl_xmssmt_shake128_h60_12.c | 12 +- .../xmss/sig_stfl_xmssmt_shake128_h60_3.c | 12 +- .../xmss/sig_stfl_xmssmt_shake128_h60_6.c | 12 +- tests/test_sig_stfl.c | 2 +- 62 files changed, 846 insertions(+), 292 deletions(-) create mode 100644 src/sig_stfl/lms/CMakeLists.txt create mode 100644 src/sig_stfl/lms/external/lms_namespace.h create mode 100644 src/sig_stfl/lms/sig_stfl_lms.c create mode 100644 src/sig_stfl/lms/sig_stfl_lms.h create mode 100644 src/sig_stfl/lms/sig_stfl_lms_functions.c create mode 100644 src/sig_stfl/lms/sig_stfl_lms_wrap.h diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index aaf8ea6fef..da79308dfd 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -528,6 +528,8 @@ cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6 "" ON "OQS_ENAB cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) +option(OQS_ENABLE_SIG_STFL_LMS "Enable LMS algorithm family" ON) + if((OQS_MINIMAL_BUILD STREQUAL "ON")) message(FATAL_ERROR "OQS_MINIMAL_BUILD option ${OQS_MINIMAL_BUILD} no longer supported") endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index f95809e9df..16b09a6400 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -199,6 +199,9 @@ endif() if(OQS_ENABLE_SIG_STFL_XMSS) set(PUBLIC_HEADERS ${PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/src/sig_stfl/xmss/sig_stfl_xmss.h) endif() +if(OQS_ENABLE_SIG_STFL_LMS) + set(PUBLIC_HEADERS ${PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/src/sig_stfl/lms/sig_stfl_lms.h) +endif() ##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_INCLUDE_HEADERS_END execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/include/oqs) execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${PUBLIC_HEADERS} ${PROJECT_BINARY_DIR}/include/oqs) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e6e6ce6f07..a5b64fd294 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -62,6 +62,11 @@ if(OQS_ENABLE_SIG_STFL_XMSS) set(SIG_STFL_OBJS ${SIG_STFL_OBJS} ${XMSS_OBJS}) endif() +if(OQS_ENABLE_SIG_STFL_LMS) + add_subdirectory(sig_stfl/lms) + set(SIG_STFL_OBJS ${SIG_STFL_OBJS} ${LMS_OBJS}) +endif() + add_library(oqs kem/kem.c ${KEM_OBJS} sig/sig.c diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index aef6c427aa..9626119e71 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -219,4 +219,6 @@ #cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_8 1 #cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 1 #cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6 1 -#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 1 \ No newline at end of file +#cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 1 + +#cmakedefine OQS_ENABLE_SIG_STFL_LMS 1 diff --git a/src/sig_stfl/lms/CMakeLists.txt b/src/sig_stfl/lms/CMakeLists.txt new file mode 100644 index 0000000000..93fa290084 --- /dev/null +++ b/src/sig_stfl/lms/CMakeLists.txt @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: MIT + +set(_LMS_OBJS "") + +set(SRCS + external/endian.c + external/hash.c + external/hss.c + external/hss_alloc.c + external/hss_aux.c + external/hss_common.c + external/hss_compute.c + external/hss_derive.c + external/hss_generate.c + external/hss_keygen.c + external/hss_param.c + external/hss_reserve.c + external/hss_sign.c + external/hss_sign_inc.c + external/hss_thread_single.c + external/hss_verify.c + external/hss_verify_inc.c + external/hss_zeroize.c + external/lm_common.c + external/lm_ots_common.c + external/lm_ots_sign.c + external/lm_ots_verify.c + external/lm_verify.c + external/sha256.c + sig_stfl_lms.c + sig_stfl_lms_functions.c + ) + +#if (OQS_ENABLE_SIG_STFL_lms) +# add_compile_definitions(OQS_ENABLE_SIG_STFL_lms) +# set (SRCS ${SRCS} sig_stfl_lms.c sig_stfl_lms_functions.c) +#endif() + + +add_library(lms OBJECT ${SRCS}) +set(_LMS_OBJS ${_LMS_OBJS} $) +set(LMS_OBJS ${_LMS_OBJS} PARENT_SCOPE) + + + diff --git a/src/sig_stfl/lms/external/endian.h b/src/sig_stfl/lms/external/endian.h index 9f8099d808..a94177ddeb 100644 --- a/src/sig_stfl/lms/external/endian.h +++ b/src/sig_stfl/lms/external/endian.h @@ -2,6 +2,7 @@ #define ENDIAN_H_ #include +#include "lms_namespace.h" void put_bigendian( void *target, unsigned long long value, size_t bytes ); unsigned long long get_bigendian( const void *target, size_t bytes ); diff --git a/src/sig_stfl/lms/external/hash.h b/src/sig_stfl/lms/external/hash.h index a61f9f5039..5e8fb3134d 100644 --- a/src/sig_stfl/lms/external/hash.h +++ b/src/sig_stfl/lms/external/hash.h @@ -3,6 +3,7 @@ #include "sha256.h" #include #include +#include "lms_namespace.h" /* * This defines the hash interface used within HSS. diff --git a/src/sig_stfl/lms/external/hss.h b/src/sig_stfl/lms/external/hss.h index b4e5e1698d..5ff8fc5c52 100644 --- a/src/sig_stfl/lms/external/hss.h +++ b/src/sig_stfl/lms/external/hss.h @@ -4,6 +4,7 @@ #include #include #include "common_defs.h" +#include "lms_namespace.h" /* * This is intended to be a usable (nontoy) implementation of the LMS diff --git a/src/sig_stfl/lms/external/hss_aux.h b/src/sig_stfl/lms/external/hss_aux.h index 634df88684..02e6677a38 100644 --- a/src/sig_stfl/lms/external/hss_aux.h +++ b/src/sig_stfl/lms/external/hss_aux.h @@ -9,6 +9,7 @@ #include "common_defs.h" #include #include +#include "lms_namespace.h" struct hss_working_key; diff --git a/src/sig_stfl/lms/external/hss_common.h b/src/sig_stfl/lms/external/hss_common.h index c455b9af5e..a5640d669e 100644 --- a/src/sig_stfl/lms/external/hss_common.h +++ b/src/sig_stfl/lms/external/hss_common.h @@ -3,6 +3,7 @@ #include #include "common_defs.h" +#include "lms_namespace.h" /* * This returns the length of the public key for the given parameter set diff --git a/src/sig_stfl/lms/external/hss_derive.h b/src/sig_stfl/lms/external/hss_derive.h index ee47eb6cfc..57ba4a1bc8 100644 --- a/src/sig_stfl/lms/external/hss_derive.h +++ b/src/sig_stfl/lms/external/hss_derive.h @@ -4,6 +4,7 @@ #include "common_defs.h" #include "config.h" +#include "lms_namespace.h" #if SECRET_MAX > 31 #error The code is not designed for a SECRET_MAX that high diff --git a/src/sig_stfl/lms/external/hss_internal.h b/src/sig_stfl/lms/external/hss_internal.h index c1541375fe..4e7c53675d 100644 --- a/src/sig_stfl/lms/external/hss_internal.h +++ b/src/sig_stfl/lms/external/hss_internal.h @@ -5,6 +5,7 @@ #include "common_defs.h" #include "hss.h" #include "config.h" +#include "lms_namespace.h" /* * This is the central internal include file for the functions that make up diff --git a/src/sig_stfl/lms/external/hss_keygen.c b/src/sig_stfl/lms/external/hss_keygen.c index ac471a952a..743604f170 100644 --- a/src/sig_stfl/lms/external/hss_keygen.c +++ b/src/sig_stfl/lms/external/hss_keygen.c @@ -345,6 +345,9 @@ bool hss_generate_private_key( public_key += I_LEN; len_public_key -= I_LEN; memcpy( public_key, root_hash, size_hash ); public_key += size_hash; len_public_key -= size_hash; + /* Address static analysis issue*/ + LMS_UNUSED(public_key); + LMS_UNUSED(len_public_key); /* Hey, what do you know -- it all worked! */ hss_zeroize( private_key, sizeof private_key ); /* Zeroize local copy of */ diff --git a/src/sig_stfl/lms/external/hss_reserve.h b/src/sig_stfl/lms/external/hss_reserve.h index 3b101c1130..14f4da3096 100644 --- a/src/sig_stfl/lms/external/hss_reserve.h +++ b/src/sig_stfl/lms/external/hss_reserve.h @@ -7,6 +7,7 @@ */ #include "common_defs.h" +#include "lms_namespace.h" struct hss_working_key; diff --git a/src/sig_stfl/lms/external/hss_sign_inc.h b/src/sig_stfl/lms/external/hss_sign_inc.h index 426d271abd..cf4f25aec6 100644 --- a/src/sig_stfl/lms/external/hss_sign_inc.h +++ b/src/sig_stfl/lms/external/hss_sign_inc.h @@ -4,6 +4,7 @@ #include #include "hash.h" #include "common_defs.h" +#include "lms_namespace.h" /* * These are the functions to sign a message incrementally. diff --git a/src/sig_stfl/lms/external/hss_thread.h b/src/sig_stfl/lms/external/hss_thread.h index fbf572ad4b..0fa48e958c 100644 --- a/src/sig_stfl/lms/external/hss_thread.h +++ b/src/sig_stfl/lms/external/hss_thread.h @@ -29,6 +29,7 @@ * by the time hss_thread_done returns */ #include +#include "lms_namespace.h" /* This is our abstract object that stands for a set of threads */ struct thread_collection; diff --git a/src/sig_stfl/lms/external/hss_verify.h b/src/sig_stfl/lms/external/hss_verify.h index 7a29deb275..6561ee2a3c 100644 --- a/src/sig_stfl/lms/external/hss_verify.h +++ b/src/sig_stfl/lms/external/hss_verify.h @@ -2,6 +2,7 @@ #define HSS_VERIFY_H_ #include +#include "lms_namespace.h" struct hss_extra_info; /* diff --git a/src/sig_stfl/lms/external/hss_verify_inc.h b/src/sig_stfl/lms/external/hss_verify_inc.h index 147308b23c..6c3ec74da1 100644 --- a/src/sig_stfl/lms/external/hss_verify_inc.h +++ b/src/sig_stfl/lms/external/hss_verify_inc.h @@ -5,6 +5,7 @@ #include "hash.h" #include "common_defs.h" #include "hss.h" +#include "lms_namespace.h" /* * These are the functions to validate a signature incrementally. diff --git a/src/sig_stfl/lms/external/hss_zeroize.h b/src/sig_stfl/lms/external/hss_zeroize.h index 702d91137b..bfe84db155 100644 --- a/src/sig_stfl/lms/external/hss_zeroize.h +++ b/src/sig_stfl/lms/external/hss_zeroize.h @@ -2,6 +2,7 @@ #define HSS_ZEROIZE_H_ #include +#include "lms_namespace.h" /* Zeroize an area, that is, scrub it from holding any potentially secret */ /* information */ diff --git a/src/sig_stfl/lms/external/lm_common.h b/src/sig_stfl/lms/external/lm_common.h index 027eda2214..b577c22462 100644 --- a/src/sig_stfl/lms/external/lm_common.h +++ b/src/sig_stfl/lms/external/lm_common.h @@ -3,6 +3,7 @@ #include #include "common_defs.h" +#include "lms_namespace.h" size_t lm_get_public_key_len(param_set_t lm_type); size_t lm_get_signature_len(param_set_t lm_type, diff --git a/src/sig_stfl/lms/external/lm_ots.h b/src/sig_stfl/lms/external/lm_ots.h index 4fcf690342..4e33d9e9fd 100644 --- a/src/sig_stfl/lms/external/lm_ots.h +++ b/src/sig_stfl/lms/external/lm_ots.h @@ -3,6 +3,7 @@ #include "common_defs.h" #include +#include "lms_namespace.h" /* * These are routines that implement the OTS signature scheme. These routines diff --git a/src/sig_stfl/lms/external/lm_ots_common.h b/src/sig_stfl/lms/external/lm_ots_common.h index 12530dd6dd..fe6faebe98 100644 --- a/src/sig_stfl/lms/external/lm_ots_common.h +++ b/src/sig_stfl/lms/external/lm_ots_common.h @@ -3,6 +3,7 @@ #include #include "common_defs.h" +#include "lms_namespace.h" bool lm_ots_look_up_parameter_set(param_set_t parameter_set, unsigned *h, unsigned *n, unsigned *w, unsigned *p, unsigned *ls); diff --git a/src/sig_stfl/lms/external/lm_ots_verify.h b/src/sig_stfl/lms/external/lm_ots_verify.h index 439f0f94a6..dcf6551b0f 100644 --- a/src/sig_stfl/lms/external/lm_ots_verify.h +++ b/src/sig_stfl/lms/external/lm_ots_verify.h @@ -3,6 +3,7 @@ #include #include "common_defs.h" +#include "lms_namespace.h" /* * This validates an OTS signature, but instead of producing a SUCCESS/FAILURE diff --git a/src/sig_stfl/lms/external/lm_verify.h b/src/sig_stfl/lms/external/lm_verify.h index 7f48767fcb..b7b6b0736d 100644 --- a/src/sig_stfl/lms/external/lm_verify.h +++ b/src/sig_stfl/lms/external/lm_verify.h @@ -3,6 +3,7 @@ #include #include +#include "lms_namespace.h" bool lm_validate_signature( const unsigned char *public_key, diff --git a/src/sig_stfl/lms/external/lms_namespace.h b/src/sig_stfl/lms/external/lms_namespace.h new file mode 100644 index 0000000000..56898589ee --- /dev/null +++ b/src/sig_stfl/lms/external/lms_namespace.h @@ -0,0 +1,96 @@ +#ifndef _LMS_NAMESPACE_H +#define _LMS_NAMESPACE_H + +#define LMS_NAMESPACE(s) OQS_LMS_NAMESPACE_##s + +#define get_bigendian LMS_NAMESPACE(get_bigendian) +#define put_bigendian LMS_NAMESPACE(put_bigendian) +#define hss_finalize_hash_context LMS_NAMESPACE(hss_finalize_hash_context) +#define hss_hash LMS_NAMESPACE(hss_hash) +#define hss_hash_blocksize LMS_NAMESPACE(hss_hash_blocksize) +#define hss_hash_ctx LMS_NAMESPACE(hss_hash_ctx) +#define hss_hash_length LMS_NAMESPACE(hss_hash_length) +#define hss_init_hash_context LMS_NAMESPACE(hss_init_hash_context) +#define hss_update_hash_context LMS_NAMESPACE(hss_update_hash_context) +#define hss_extra_info_set_threads LMS_NAMESPACE(hss_extra_info_set_threads) +#define hss_extra_info_test_error_code LMS_NAMESPACE(hss_extra_info_test_error_code) +#define hss_extra_info_test_last_signature LMS_NAMESPACE(hss_extra_info_test_last_signature) +#define hss_generate_child_seed_I_value LMS_NAMESPACE(hss_generate_child_seed_I_value) +#define hss_generate_root_seed_I_value LMS_NAMESPACE(hss_generate_root_seed_I_value) +#define hss_init_extra_info LMS_NAMESPACE(hss_init_extra_info) +#define hss_load_private_key LMS_NAMESPACE(hss_load_private_key) + +#define allocate_working_key LMS_NAMESPACE(allocate_working_key) + +#define hss_free_working_key LMS_NAMESPACE(hss_free_working_key) +#define hss_smallest_subtree_size LMS_NAMESPACE(hss_smallest_subtree_size) +#define hss_expand_aux_data LMS_NAMESPACE(hss_expand_aux_data) +#define hss_extract_aux_data LMS_NAMESPACE(hss_extract_aux_data) +#define hss_finalize_aux_data LMS_NAMESPACE(hss_finalize_aux_data) +#define hss_get_aux_data_len LMS_NAMESPACE(hss_get_aux_data_len) +#define hss_optimal_aux_level LMS_NAMESPACE(hss_optimal_aux_level) +#define hss_save_aux_data LMS_NAMESPACE(hss_save_aux_data) +#define hss_store_aux_marker LMS_NAMESPACE(hss_store_aux_marker) + +#define hss_get_public_key_len LMS_NAMESPACE(hss_get_public_key_len) +#define hss_get_signature_len LMS_NAMESPACE(hss_get_signature_len) +#define hss_combine_internal_nodes LMS_NAMESPACE(hss_combine_internal_nodes) +#define hss_gen_intermediate_tree LMS_NAMESPACE(hss_gen_intermediate_tree) +#define hss_seed_derive LMS_NAMESPACE(hss_seed_derive) +#define hss_seed_derive_done LMS_NAMESPACE(hss_seed_derive_done) +#define hss_seed_derive_init LMS_NAMESPACE(hss_seed_derive_init) +#define hss_seed_derive_set_j LMS_NAMESPACE(hss_seed_derive_set_j) +#define hss_seed_derive_set_q LMS_NAMESPACE(hss_seed_derive_set_q) +#define hss_generate_working_key LMS_NAMESPACE(hss_generate_working_key) + +#define hss_generate_private_key LMS_NAMESPACE(hss_generate_private_key) +#define hss_get_private_key_len LMS_NAMESPACE(hss_get_private_key_len) +#define hss_compress_param_set LMS_NAMESPACE(hss_compress_param_set) +#define hss_get_parameter_set LMS_NAMESPACE(hss_get_parameter_set) +#define hss_advance_count LMS_NAMESPACE(hss_advance_count) +#define hss_reserve_signature LMS_NAMESPACE(hss_reserve_signature) +#define hss_set_autoreserve LMS_NAMESPACE(hss_set_autoreserve) +#define hss_set_reserve_count LMS_NAMESPACE(hss_set_reserve_count) +#define hss_create_signed_public_key LMS_NAMESPACE(hss_create_signed_public_key) +#define hss_generate_signature LMS_NAMESPACE(hss_generate_signature) +#define hss_get_signature_len_from_working_key LMS_NAMESPACE(hss_get_signature_len_from_working_key) +#define hss_sign_finalize LMS_NAMESPACE(hss_sign_finalize) +#define hss_sign_init LMS_NAMESPACE(hss_sign_init) +#define hss_sign_update LMS_NAMESPACE(hss_sign_update) +#define hss_thread_after_write LMS_NAMESPACE(hss_thread_after_write) +#define hss_thread_before_write LMS_NAMESPACE(hss_thread_before_write) +#define hss_thread_done LMS_NAMESPACE(hss_thread_done) +#define hss_thread_init LMS_NAMESPACE(hss_thread_init) +#define hss_thread_issue_work LMS_NAMESPACE(hss_thread_issue_work) +#define hss_thread_num_tracks LMS_NAMESPACE(hss_thread_num_tracks) +#define hss_validate_signature LMS_NAMESPACE(hss_validate_signature) + +#define validate_internal_sig LMS_NAMESPACE(validate_internal_sig) + +#define hss_validate_signature_finalize LMS_NAMESPACE(hss_validate_signature_finalize) +#define hss_validate_signature_init LMS_NAMESPACE(hss_validate_signature_init) +#define hss_validate_signature_update LMS_NAMESPACE(hss_validate_signature_update) +#define hss_zeroize LMS_NAMESPACE(hss_zeroize) + +#define lm_get_public_key_len LMS_NAMESPACE(lm_get_public_key_len) +#define lm_get_signature_len LMS_NAMESPACE(lm_get_signature_len) +#define lm_look_up_parameter_set LMS_NAMESPACE(lm_look_up_parameter_set) + +#define lm_ots_coef LMS_NAMESPACE(lm_ots_coef) +#define lm_ots_compute_checksum LMS_NAMESPACE(lm_ots_compute_checksum) +#define lm_ots_get_public_key_len LMS_NAMESPACE(lm_ots_get_public_key_len) +#define lm_ots_get_signature_len LMS_NAMESPACE(lm_ots_get_signature_len) +#define lm_ots_hashes_per_public_key LMS_NAMESPACE(lm_ots_hashes_per_public_key) +#define lm_ots_look_up_parameter_set LMS_NAMESPACE(lm_ots_look_up_parameter_set) +#define lm_ots_generate_public_key LMS_NAMESPACE(lm_ots_generate_public_key) +#define lm_ots_generate_randomizer LMS_NAMESPACE(lm_ots_generate_randomizer) +#define lm_ots_generate_signature LMS_NAMESPACE(lm_ots_generate_signature) +#define lm_ots_validate_signature_compute LMS_NAMESPACE(lm_ots_validate_signature_compute) +#define lm_validate_signature LMS_NAMESPACE(lm_validate_signature) + +#define SHA256_Final LMS_NAMESPACE(SHA256_Final) +#define SHA256_Init LMS_NAMESPACE(SHA256_Init) +#define SHA256_Update LMS_NAMESPACE(SHA256_Update) +#define LMS_randombytes LMS_NAMESPACE(LMS_randombytes) + +#endif //_LMS_NAMESPACE_H diff --git a/src/sig_stfl/lms/external/sha256.h b/src/sig_stfl/lms/external/sha256.h index a5de21c014..f7f78ad18c 100644 --- a/src/sig_stfl/lms/external/sha256.h +++ b/src/sig_stfl/lms/external/sha256.h @@ -14,6 +14,7 @@ #include #else +#include "lms_namespace.h" /* SHA256 context. */ typedef struct { diff --git a/src/sig_stfl/lms/sig_stfl_lms.c b/src/sig_stfl/lms/sig_stfl_lms.c new file mode 100644 index 0000000000..dde8dc586f --- /dev/null +++ b/src/sig_stfl/lms/sig_stfl_lms.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: MIT + +#include +#include +#include +#include "./external/config.h" +#include "sig_stfl_lms_wrap.h" +#include "sig_stfl_lms.h" + + +// ======================== LMS-SHA256 H5/W1 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, uint8_t *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)0x00000001) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = 0x00000001; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_sk; + + if (sk->length_secret_key) { + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + if (sk->secret_key_data) { + memset(sk->secret_key_data, 0, sk->length_secret_key); + } else { + OQS_SECRET_KEY_LMS_free(sk); + OQS_MEM_insecure_free(sk); + sk = NULL; + return NULL; + } + } + + sk->free_key = OQS_SECRET_KEY_LMS_free; + + return sk; +} + +void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL) { + return; + } + + //TODO: cleanup lock_key + + if (sk->sig) { + OQS_MEM_insecure_free(sk->sig); + sk->sig = NULL; + } + OQS_MEM_secure_free(sk->secret_key_data, sk->length_secret_key); + sk->secret_key_data = NULL; +} diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h new file mode 100644 index 0000000000..97104b47f8 --- /dev/null +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT + +#ifndef OQS_SIG_STFL_LMS_H +#define OQS_SIG_STFL_LMS_H + +#include + +//H5 +#define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_signature 8688 +#define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_sk 64 + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, uint8_t *secret_key); + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void); + +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(uint64_t *totaln, const uint8_t *secret_key); + +void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk); + +// ----------------------------------- WRAPPER FUNCTIONS ------------------------------------------------ +int oqs_sig_stfl_lms_keypair(uint8_t *pk, uint8_t *sk, const uint32_t oid); + +int oqs_sig_stfl_lms_sign(uint8_t *sk, uint8_t *sm, size_t *smlen, + const uint8_t *m, size_t mlen); + +int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, const uint8_t *sm, size_t smlen, + const uint8_t *pk); + +// ---------------------------- FUNCTIONS INDEPENDENT OF VARIANT ----------------------------------------- + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signature_length, const uint8_t *message, size_t message_len, uint8_t *secret_key); + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); + + +// -------------------------------------------------------------------------------------------------------- + +#endif /* OQS_SIG_STFL_LMS_H */ diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c new file mode 100644 index 0000000000..8c17ddddd0 --- /dev/null +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -0,0 +1,266 @@ +// SPDX-License-Identifier: MIT + +#include +#include "sig_stfl_lms.h" +#include "external/config.h" +#include "external/hss_verify_inc.h" +#include "external/hss_sign_inc.h" +#include "external/hss.h" +#include "sig_stfl_lms_wrap.h" +#include + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signature_length, const uint8_t *message, + size_t message_len, uint8_t *secret_key) { + + if (secret_key == NULL || message == NULL || signature == NULL) { + return OQS_ERROR; + } + + /* TODO: Make sure we have a way to update the private key */ + + if (oqs_sig_stfl_lms_sign(secret_key, signature, + signature_length, + message, message_len) != 0) { + return OQS_ERROR; + } + + /* TODO: Update private key */ + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_verify(const uint8_t *message, size_t message_len, + const uint8_t *signature, size_t signature_len, + const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_verify(message, message_len, + signature, signature_len, + public_key) != 0 ) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const uint8_t *secret_key) { + + if (remain == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + remain = 0; + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(uint64_t *total, const uint8_t *secret_key) { + + if (total == NULL || secret_key == NULL) { + return OQS_ERROR; + } + + total = 0; + return OQS_SUCCESS; +} + +/* LMS wrapper functions use internal OIDs to + * identify the parameter set to be used + */ + +bool LMS_randombytes(void *buffer, size_t length) { + + OQS_randombytes((uint8_t *)buffer, length); + return true; +} + +int oqs_sig_stfl_lms_keypair(uint8_t *pk, uint8_t *sk, const uint32_t oid) { + + int ret = -1; + bool b_ret; + int parse_err = 0; + unsigned levels = 1; + + unsigned char public_key[60]; + size_t len_public_key = 60; + unsigned char *aux_data = NULL; + size_t max_aux_data = 10916; + int aux_len = 0; + oqs_lms_key_data *oqs_data = NULL; + + param_set_t lm_type[1]; + param_set_t lm_ots_type[1]; + + if (!pk || !sk || !oid) { + return -1; + } + + /* Set lms param set */ + switch (oid) { + case 0x1: + lm_type[0] = LMS_SHA256_N32_H5; + lm_ots_type[0] = LMOTS_SHA256_N32_W1; + break; + default: + lm_type[0] = 0; + lm_ots_type[0] = 0; + parse_err = 1; + break; + } + + if (parse_err) { + return -1; + } + + /* + * This creates a private key (and the correspond public key, and optionally + * the aux data for that key) + * Parameters: + * generate_random - the function to be called to generate randomness. This + * is assumed to be a pointer to a cryptographically secure rng, + * otherwise all security is lost. This function is expected to fill + * output with 'length' uniformly distributed bits, and return 1 on + * success, 0 if something went wrong + * levels - the number of levels for the key pair (2-8) + * lm_type - an array of the LM registry entries for the various levels; + * entry 0 is the topmost + * lm_ots_type - an array of the LM-OTS registry entries for the various + * levels; again, entry 0 is the topmost + * update_private_key, context - the function that is called when the + * private key is generated; it is expected to store it to secure NVRAM + * If this is NULL, then the context pointer is reinterpretted to mean + * where in RAM the private key is expected to be placed + * public_key - where to store the public key + * len_public_key - length of the above buffer; see hss_get_public_key_len + * if you need a hint. + * aux_data - where to store the optional aux data. This is not required, but + * if provided, can be used to speed up the hss_generate_working_key + * process; + * len_aux_data - the length of the above buffer. This is not fixed length; + * the function will run different time/memory trade-offs based on the + * length provided + * + * This returns true on success, false on failure + */ + b_ret = hss_generate_private_key( + LMS_randombytes, + levels, + lm_type, + lm_ots_type, + NULL, //File handler function? + (void *)sk, + public_key, len_public_key, + aux_data, aux_len, + NULL); + if (b_ret) { + memcpy(pk, public_key, len_public_key); + } + + /* TODO: store key pair, file handler */ + + ret = 0; + return ret; +} + +int oqs_sig_stfl_lms_sign(uint8_t *sk, + uint8_t *sm, size_t *smlen, + const uint8_t *m, size_t mlen) { + + size_t sig_len; + bool status; + unsigned char *sig = NULL; + struct hss_working_key *w = NULL; + struct hss_sign_inc ctx; + w = hss_load_private_key(NULL, sk, + 0, + NULL, + 0, + 0); + if (!w) { + printf( "Error loading private key\n" ); + hss_free_working_key(w); + return 0; + } + + /* Now, go through the file list, and generate the signatures for each */ + + /* Look up the signature length */ + + sig_len = hss_get_signature_len_from_working_key(w); + if (sig_len == 0) { + printf( "Error getting signature len\n" ); + hss_free_working_key(w); + return 0; + } + + sig = malloc(sig_len); + if (!sig) { + printf( "Error during malloc\n" ); + hss_free_working_key(w); + return -1; + } + + (void)hss_sign_init( + &ctx, /* Incremental signing context */ + w, /* Working key */ + NULL, /* Routine to update the */ + sk, /* private key */ + sig, sig_len, /* Where to place the signature */ + 0); + + (void)hss_sign_update( + &ctx, /* Incremental signing context */ + m, /* Next piece of the message */ + mlen); /* Length of this piece */ + + status = hss_sign_finalize( + &ctx, /* Incremental signing context */ + w, /* Working key */ + sig, /* Signature */ + 0); + + if (!status) { + hss_free_working_key(w); + OQS_MEM_insecure_free(sig); + return -1; + } + + *smlen = sig_len; + memcpy(sm, sig, sig_len); + OQS_MEM_insecure_free(sig); + + return 0; +} + +int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, + const uint8_t *sm, size_t smlen, + const uint8_t *pk) { + + struct hss_validate_inc ctx; + (void)hss_validate_signature_init( + &ctx, /* Incremental validate context */ + (const unsigned char *)pk, /* Public key */ + (const unsigned char *)sm, + (size_t)smlen, /* Signature */ + 0); /* Use the defaults for extra info */ + + (void)hss_validate_signature_update( + &ctx, /* Incremental validate context */ + (const void *) m, /* Next piece of the message */ + (size_t)mlen); /* Length of this piece */ + + bool status = hss_validate_signature_finalize( + &ctx, /* Incremental validate context */ + (const unsigned char *)sm, /* Signature */ + 0); /* Use the defaults for extra info */ + + if (status) { + /* Signature verified */ + return 0; + } else { + /* signature NOT verified */ + return -1; + } +} + diff --git a/src/sig_stfl/lms/sig_stfl_lms_wrap.h b/src/sig_stfl/lms/sig_stfl_lms_wrap.h new file mode 100644 index 0000000000..043de2c461 --- /dev/null +++ b/src/sig_stfl/lms/sig_stfl_lms_wrap.h @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: MIT + +#ifndef OQS_SIG_STFL_LMS_WRAP_H +#define OQS_SIG_STFL_LMS_WRAP_H + +//#include +#include "external/hss.h" +#include "external/hss_sign_inc.h" + + +/** + * @brief OQS_LMS_KEY object for HSS key pair + */ +typedef struct OQS_LMS_KEY_DATA oqs_lms_key_data; + +typedef struct OQS_LMS_KEY_DATA { + + /* Tree levels. */ + unsigned levels; + + /* Array, 8 levels max, of LMS types */ + param_set_t lm_type[8]; + + /* Array, 8 levels max, of LM OTS types */ + param_set_t lm_ots_type[8]; + + /* LMS public key */ + unsigned char public_key[60]; + + /* internal nodes info of the Merkle tree */ + unsigned char *aux_data; + + /* Length of aux data */ + size_t len_aux_data; + + /* User defined data that may be used for the SAFETY functions */ + void *data; + +} oqs_lms_key_data; + + +typedef struct OQS_LMS_SIG_DATA oqs_lms_sig_data; + +typedef struct OQS_LMS_SIG_DATA { + + + /* message buffer */ + unsigned char *message; + + /* Length of msg buffer */ + size_t len_msg_buf; + + /* signature buffer */ + unsigned char *signature; + + /* Length of sig buffer */ + size_t len_sig_buf; + +} oqs_lms_sig_data; + +#endif //OQS_SIG_STFL_LMS_H + diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 20bf641b95..dd3b1ed5cc 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -42,6 +42,7 @@ OQS_API const char *OQS_SIG_STFL_alg_identifier(size_t i) { OQS_SIG_STFL_alg_xmssmt_shake128_h60_3, OQS_SIG_STFL_alg_xmssmt_shake128_h60_6, OQS_SIG_STFL_alg_xmssmt_shake128_h60_12, + OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1, }; if (i >= OQS_SIG_STFL_algs_length) { @@ -229,6 +230,12 @@ OQS_API int OQS_SIG_STFL_alg_is_enabled(const char *method_name) { return 1; #else return 0; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_LMS + return 1; +#else + return 0; #endif } else { return 0; @@ -409,6 +416,12 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { #else return NULL; #endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_LMS + return OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(); +#else + return NULL; +#endif //OQS_ENABLE_SIG_STFL_LMS } else { return NULL; } @@ -439,7 +452,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m } } -OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned long long *remain, const uint8_t *secret_key) { if (sig == NULL || sig->sigs_remaining == NULL || sig->sigs_remaining(remain, secret_key) != 0) { return OQS_ERROR; } else { @@ -447,7 +460,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, uint64_t } } -OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, uint64_t *max, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned long long *max, const uint8_t *secret_key) { if (sig == NULL || sig->sigs_total == NULL || sig->sigs_total(max, secret_key) != 0) { return OQS_ERROR; } else { @@ -636,6 +649,12 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_ return OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_12_new(); #else return NULL; +#endif + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_LMS + return OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(); +#else + return NULL; #endif } else { return NULL; diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index b2955d78ba..892054a78c 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -50,7 +50,14 @@ extern "C" { #define OQS_SIG_STFL_alg_xmssmt_shake128_h60_6 "XMSSMT-SHAKE_60/6_256" #define OQS_SIG_STFL_alg_xmssmt_shake128_h60_12 "XMSSMT-SHAKE_60/12_256" -#define OQS_SIG_STFL_algs_length 28 +/* Defined LMS parameter identifiers */ +#define OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1 "LMS_SHA256_H5_W1" //"5/1" + +#define OQS_SIG_STFL_algs_length 29 + +/* Defined LM parameter identifiers */ +/* Algorithm identifier for LMS-SHA256_N32_H5 */ +#define OQS_SIG_STFL_alg_lms_sha256_n32_h5 "LMS-SHA256_N32_H5" //0x00000005 /** * Returns identifiers for available signature schemes in liboqs. Used with OQS_SIG_STFL_new. @@ -159,7 +166,7 @@ typedef struct OQS_SIG_STFL { * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ - OQS_STATUS (*sigs_remaining)(uint64_t *remain, const uint8_t *secret_key); + OQS_STATUS (*sigs_remaining)(unsigned long long *remain, const uint8_t *secret_key); /** * Total number of signatures @@ -168,7 +175,7 @@ typedef struct OQS_SIG_STFL { * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ - OQS_STATUS (*sigs_total)(uint64_t *total, const uint8_t *secret_key); + OQS_STATUS (*sigs_total)(unsigned long long *total, const uint8_t *secret_key); } OQS_SIG_STFL; @@ -311,7 +318,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ -OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, uint64_t *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned long long *remain, const uint8_t *secret_key); /** * * Total number of signatures @@ -321,7 +328,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, uint64_t * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ -OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, uint64_t *max, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned long long *max, const uint8_t *secret_key); /** * Frees an OQS_SIG_STFL object that was constructed by OQS_SIG_STFL_new. @@ -365,4 +372,8 @@ OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk); #include #endif // OQS_ENABLE_SIG_STFL_XMSS +#ifdef OQS_ENABLE_SIG_STFL_LMS +#include +#endif // OQS_ENABLE_SIG_STFL_LMS + #endif /* OQS_SIG_STATEFUL_H */ diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index 1fbc305b29..aa326dfff5 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -57,8 +57,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -73,8 +73,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H16_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -89,8 +89,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H20_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -105,8 +105,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H10_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -121,8 +121,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H16_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -137,8 +137,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H20_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -153,8 +153,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H10_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -169,8 +169,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H16_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -185,8 +185,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H20_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -201,8 +201,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H10_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -217,8 +217,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H16_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -233,8 +233,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H20_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -249,8 +249,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_2_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -265,8 +265,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_4_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -281,8 +281,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_2_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -297,8 +297,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_4_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -313,8 +313,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -329,8 +329,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_3_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -345,8 +345,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_6_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -361,8 +361,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_12_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -377,8 +377,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_2_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -393,8 +393,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_4_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -409,8 +409,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_2_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -425,8 +425,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_4_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -441,8 +441,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -457,8 +457,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_3_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -473,8 +473,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_6_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif @@ -489,8 +489,8 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_12_new(void) OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_keypair(uint8_t *public_key, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining(uint64_t *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(uint64_t *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(unsigned long long *total, const uint8_t *secret_key); #endif diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c index aa812bd22c..9a30f7c4f0 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c @@ -89,7 +89,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, siz if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; + *signature_len = (size_t)sig_length; return OQS_SUCCESS; } @@ -100,38 +100,33 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(XMSS_UNUSED_ATT const return OQS_ERROR; } - if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { + if (xmss_sign_open(message, (unsigned long long)message_len, signature, (unsigned long long)signature_len, public_key)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmss_total_signatures(&total_signatures, secret_key)) { + if (xmss_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } - diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c index d613a4f9c0..289732ecdb 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_verify(XMSS_UNUSED_ATT const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmss_total_signatures(&total_signatures, secret_key)) { + if (xmss_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c index 5d40092b9c..936fbdd32a 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_verify(XMSS_UNUSED_ATT const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmss_total_signatures(&total_signatures, secret_key)) { + if (xmss_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c index 81a1b85c5f..488713d95a 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_verify(XMSS_UNUSED_ATT const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmss_total_signatures(&total_signatures, secret_key)) { + if (xmss_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c index b99b429fbd..6993faf83a 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_verify(XMSS_UNUSED_ATT const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmss_total_signatures(&total_signatures, secret_key)) { + if (xmss_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c index 8c618b8bd7..2ebfc9dd57 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_verify(XMSS_UNUSED_ATT const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmss_total_signatures(&total_signatures, secret_key)) { + if (xmss_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c index efc4c6ed5d..3e961c076b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_verify(XMSS_UNUSED_ATT con return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmss_total_signatures(&total_signatures, secret_key)) { + if (xmss_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c index 948e29b597..a8ed4fa37e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_verify(XMSS_UNUSED_ATT con return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmss_total_signatures(&total_signatures, secret_key)) { + if (xmss_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c index 9e9d330da7..e39f3912c2 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_verify(XMSS_UNUSED_ATT con return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmss_total_signatures(&total_signatures, secret_key)) { + if (xmss_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c index e96c5da22a..26bd706c9c 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_verify(XMSS_UNUSED_ATT con return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmss_total_signatures(&total_signatures, secret_key)) { + if (xmss_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c index b90fe2cc79..c5c44d6655 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_verify(XMSS_UNUSED_ATT con return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmss_total_signatures(&total_signatures, secret_key)) { + if (xmss_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c index 53a88db04b..439f4b3f99 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_verify(XMSS_UNUSED_ATT con return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmss_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmss_total_signatures(&total_signatures, secret_key)) { + if (xmss_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c index b5c1df16af..4cbd91beb5 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c index 2bad4a33a2..9e830571cd 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c index c1a0243e96..42181f75f6 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c index 9835724a5c..69df1302f8 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c index ed223acdd7..6d4e161d53 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c index de9253552d..377518a0da 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c index 7e54ff760c..a455e43814 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c index 49d870dec0..e57d298615 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c index 5a66fc4e96..331949be1f 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c index 163689fc33..0acc511e7a 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c index 9e59b72d19..cc379336b2 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c index 4dbd11f836..11030a2494 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c index 91223579b6..cec3c1cd73 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c index e480d2d5e7..3cb5f20300 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_verify(XMSS_UNUSED_AT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c index 3904bd43b5..bc8f7a96bb 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c index b6cf53cfe0..8bcb4dc0dd 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c @@ -107,30 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining(uint64_t *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t remaining_signatures = 0; - if (xmssmt_remaining_signatures(&remaining_signatures, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key)) { return OQS_ERROR; } - *remain = (uint64_t) remaining_signatures; return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(unsigned long long *total, const uint8_t *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - uint64_t total_signatures = 0; - if (xmssmt_total_signatures(&total_signatures, secret_key)) { + if (xmssmt_total_signatures(total, secret_key)) { return OQS_ERROR; } - *total = (uint64_t) total_signatures; return OQS_SUCCESS; } \ No newline at end of file diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 26385ab063..a393dc6cf4 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -393,7 +393,7 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { } printf("================================================================================\n"); - printf("Create for statefull Secret Key %s\n", method_name); + printf("Create stateful Secret Key %s\n", method_name); printf("================================================================================\n"); if (!sk->secret_key_data) { From 4d773d785e1640889e8c3d84dfb3139c9804587b Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Sat, 12 Aug 2023 12:00:59 -0400 Subject: [PATCH 10/68] Convert to use OQS_SIG_STFL_SECRET_KEY struct (#1525) * Convert API to use OQS_SIG_STFL_SECRET_KEY * Update formatting --- src/sig_stfl/sig_stfl.c | 10 ++++++---- src/sig_stfl/sig_stfl.h | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index dd3b1ed5cc..c440e9e95d 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -428,15 +428,17 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { } -OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public_key, uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { if (sig == NULL || sig->keypair == NULL || sig->keypair(public_key, secret_key) != 0) { return OQS_ERROR; } else { return OQS_SUCCESS; } + return OQS_ERROR; } -OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, + size_t message_len, const OQS_SIG_STFL_SECRET_KEY *secret_key) { if (sig == NULL || sig->sign == NULL || sig->sign(signature, signature_len, message, message_len, secret_key) != 0) { return OQS_ERROR; } else { @@ -452,7 +454,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m } } -OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned long long *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { if (sig == NULL || sig->sigs_remaining == NULL || sig->sigs_remaining(remain, secret_key) != 0) { return OQS_ERROR; } else { @@ -460,7 +462,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned } } -OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned long long *max, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned long long *max, const OQS_SIG_STFL_SECRET_KEY *secret_key) { if (sig == NULL || sig->sigs_total == NULL || sig->sigs_total(max, secret_key) != 0) { return OQS_ERROR; } else { diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index 892054a78c..5ef5317376 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -59,6 +59,8 @@ extern "C" { /* Algorithm identifier for LMS-SHA256_N32_H5 */ #define OQS_SIG_STFL_alg_lms_sha256_n32_h5 "LMS-SHA256_N32_H5" //0x00000005 +typedef struct OQS_SIG_STFL_SECRET_KEY OQS_SIG_STFL_SECRET_KEY; + /** * Returns identifiers for available signature schemes in liboqs. Used with OQS_SIG_STFL_new. * @@ -129,7 +131,7 @@ typedef struct OQS_SIG_STFL { * @param[out] secret_key The secret key represented as a byt string * @return OQS_SUCCESS or OQS_ERROR */ - OQS_STATUS (*keypair)(uint8_t *public_key, uint8_t *secret_key); + OQS_STATUS (*keypair)(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); /** * Signature generation algorithm. @@ -145,7 +147,7 @@ typedef struct OQS_SIG_STFL { * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ - OQS_STATUS (*sign)(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); + OQS_STATUS (*sign)(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const OQS_SIG_STFL_SECRET_KEY *secret_key); /** * Signature verification algorithm. @@ -166,7 +168,7 @@ typedef struct OQS_SIG_STFL { * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ - OQS_STATUS (*sigs_remaining)(unsigned long long *remain, const uint8_t *secret_key); + OQS_STATUS (*sigs_remaining)(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); /** * Total number of signatures @@ -175,14 +177,13 @@ typedef struct OQS_SIG_STFL { * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ - OQS_STATUS (*sigs_total)(unsigned long long *total, const uint8_t *secret_key); + OQS_STATUS (*sigs_total)(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); } OQS_SIG_STFL; /** * @brief OQS_SIG_STFL_SECRET_KEY object for stateful signature schemes */ -typedef struct OQS_SIG_STFL_SECRET_KEY OQS_SIG_STFL_SECRET_KEY; typedef struct OQS_SIG_STFL_SECRET_KEY { @@ -278,7 +279,7 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name); * @param[out] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ -OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *pk, uint8_t *sk); +OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk); /** * Signature generation algorithm. @@ -295,7 +296,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *pk, ui * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ -OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const OQS_SIG_STFL_SECRET_KEY *secret_key); /** * Signature verification algorithm. @@ -318,7 +319,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ -OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned long long *remain, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); /** * * Total number of signatures @@ -328,7 +329,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ -OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned long long *max, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned long long *max, const OQS_SIG_STFL_SECRET_KEY *secret_key); /** * Frees an OQS_SIG_STFL object that was constructed by OQS_SIG_STFL_new. From 4694fc3b6e03720b25a8bb1ab292111dccb5bb28 Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Fri, 18 Aug 2023 14:12:14 -0400 Subject: [PATCH 11/68] Add secret key object to XMSS (#1530) * Initial addition of sig_stfl API and dummy XMSS variant * add secret key object * allocate and free using wrapper function instead of malloc/free * cleaner function signature * Fix comment * Delete old file * Missing newline * Missing newlines --- src/CMakeLists.txt | 2 + src/sig_stfl/sig_stfl.c | 2 +- src/sig_stfl/sig_stfl.h | 6 +- src/sig_stfl/xmss/external/core_hash.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss.h | 224 +++++++++--------- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c | 24 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c | 26 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c | 26 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c | 26 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c | 26 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c | 26 +- .../xmss/sig_stfl_xmss_shake128_h10.c | 26 +- .../xmss/sig_stfl_xmss_shake128_h16.c | 26 +- .../xmss/sig_stfl_xmss_shake128_h20.c | 26 +- .../xmss/sig_stfl_xmss_shake256_h10.c | 26 +- .../xmss/sig_stfl_xmss_shake256_h16.c | 26 +- .../xmss/sig_stfl_xmss_shake256_h20.c | 26 +- .../xmss/sig_stfl_xmssmt_sha256_h20_2.c | 26 +- .../xmss/sig_stfl_xmssmt_sha256_h20_4.c | 26 +- .../xmss/sig_stfl_xmssmt_sha256_h40_2.c | 26 +- .../xmss/sig_stfl_xmssmt_sha256_h40_4.c | 26 +- .../xmss/sig_stfl_xmssmt_sha256_h40_8.c | 26 +- .../xmss/sig_stfl_xmssmt_sha256_h60_12.c | 26 +- .../xmss/sig_stfl_xmssmt_sha256_h60_3.c | 26 +- .../xmss/sig_stfl_xmssmt_sha256_h60_6.c | 26 +- .../xmss/sig_stfl_xmssmt_shake128_h20_2.c | 26 +- .../xmss/sig_stfl_xmssmt_shake128_h20_4.c | 26 +- .../xmss/sig_stfl_xmssmt_shake128_h40_2.c | 26 +- .../xmss/sig_stfl_xmssmt_shake128_h40_4.c | 26 +- .../xmss/sig_stfl_xmssmt_shake128_h40_8.c | 26 +- .../xmss/sig_stfl_xmssmt_shake128_h60_12.c | 26 +- .../xmss/sig_stfl_xmssmt_shake128_h60_3.c | 26 +- .../xmss/sig_stfl_xmssmt_shake128_h60_6.c | 26 +- tests/kat_sig_stfl.c | 10 +- tests/test_sig_stfl.c | 21 +- 35 files changed, 493 insertions(+), 500 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a5b64fd294..b6772ee9ff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -73,6 +73,8 @@ add_library(oqs kem/kem.c ${SIG_OBJS} sig_stfl/sig_stfl.c ${SIG_STFL_OBJS} + sig_stfl/sig_stfl.c + ${SIG_STFL_OBJS} ${COMMON_OBJS}) # Internal library to be used only by test programs diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index c440e9e95d..c77139e20a 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -438,7 +438,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public } OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, - size_t message_len, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { if (sig == NULL || sig->sign == NULL || sig->sign(signature, signature_len, message, message_len, secret_key) != 0) { return OQS_ERROR; } else { diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index 5ef5317376..b795853c5c 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -147,7 +147,7 @@ typedef struct OQS_SIG_STFL { * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ - OQS_STATUS (*sign)(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const OQS_SIG_STFL_SECRET_KEY *secret_key); + OQS_STATUS (*sign)(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); /** * Signature verification algorithm. @@ -296,7 +296,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *pk, OQ * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ -OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); /** * Signature verification algorithm. @@ -315,7 +315,6 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m * Query number of remaining signatures * * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. - * @param[out] remain The number of remaining signatures * @param[in] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ @@ -334,7 +333,6 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned lon /** * Frees an OQS_SIG_STFL object that was constructed by OQS_SIG_STFL_new. * - * @param[in] sig The OQS_SIG_STFL object to free. */ OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig); diff --git a/src/sig_stfl/xmss/external/core_hash.c b/src/sig_stfl/xmss/external/core_hash.c index 565e571e36..b27ad2ca9b 100644 --- a/src/sig_stfl/xmss/external/core_hash.c +++ b/src/sig_stfl/xmss/external/core_hash.c @@ -35,4 +35,4 @@ int core_hash(const xmss_params *params, #endif return 0; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index aa326dfff5..1cf29900f3 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -54,11 +54,11 @@ void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -70,11 +70,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(unsigned long lon OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h16_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H16_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -86,11 +86,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(unsigned long lon OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h20_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H20_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -102,11 +102,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(unsigned long lon OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h10_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H10_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -118,11 +118,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(unsigned long l OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h16_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H16_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -134,11 +134,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(unsigned long l OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h20_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H20_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -150,11 +150,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(unsigned long l OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h10_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H10_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -166,11 +166,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(unsigned long lon OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h16_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H16_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -182,11 +182,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(unsigned long lon OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h20_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H20_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -198,11 +198,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(unsigned long lon OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h10_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H10_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -214,11 +214,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(unsigned long l OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h16_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H16_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -230,11 +230,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(unsigned long l OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h20_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H20_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -246,11 +246,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(unsigned long l OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_2_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -262,11 +262,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(unsigned long OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_4_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -278,11 +278,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(unsigned long OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_2_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -294,11 +294,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(unsigned long OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_4_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -310,11 +310,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(unsigned long OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -326,11 +326,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(unsigned long OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_3_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -342,11 +342,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(unsigned long OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_6_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -358,11 +358,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(unsigned long OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_12_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -374,11 +374,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(unsigned lon OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_2_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -390,11 +390,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(unsigned lo OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_4_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -406,11 +406,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(unsigned lo OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_2_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -422,11 +422,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(unsigned lo OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_4_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -438,11 +438,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(unsigned lo OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -454,11 +454,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(unsigned lo OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_3_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -470,11 +470,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(unsigned lo OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_6_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif @@ -486,11 +486,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(unsigned lo OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_12_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_keypair(uint8_t *public_key, uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(unsigned long long *total, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); #endif diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c index 9a30f7c4f0..4ff8f24e7d 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmss_sha256_h10_oid = 0x01; - if (xmss_keypair(public_key, secret_key, xmss_sha256_h10_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_sha256_h10_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t)sig_length; @@ -107,24 +107,24 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(XMSS_UNUSED_ATT const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_remaining_signatures(remain, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_total_signatures(total, secret_key)) { + if (xmss_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c index 289732ecdb..f467b67595 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H16_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmss_sha256_h16_oid = 0x02; - if (xmss_keypair(public_key, secret_key, xmss_sha256_h16_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_sha256_h16_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_verify(XMSS_UNUSED_ATT const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_remaining_signatures(remain, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_total_signatures(total, secret_key)) { + if (xmss_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c index 936fbdd32a..ab7a74410f 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H20_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmss_sha256_h20_oid = 0x03; - if (xmss_keypair(public_key, secret_key, xmss_sha256_h20_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_sha256_h20_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_verify(XMSS_UNUSED_ATT const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_remaining_signatures(remain, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_total_signatures(total, secret_key)) { + if (xmss_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c index 488713d95a..b38207c86b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H10_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmss_sha512_h10_oid = 0x04; - if (xmss_keypair(public_key, secret_key, xmss_sha512_h10_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_sha512_h10_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_verify(XMSS_UNUSED_ATT const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_remaining_signatures(remain, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_total_signatures(total, secret_key)) { + if (xmss_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c index 6993faf83a..050026311a 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H16_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmss_sha512_h16_oid = 0x05; - if (xmss_keypair(public_key, secret_key, xmss_sha512_h16_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_sha512_h16_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_verify(XMSS_UNUSED_ATT const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_remaining_signatures(remain, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_total_signatures(total, secret_key)) { + if (xmss_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c index 2ebfc9dd57..b5084201fd 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H20_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmss_sha512_h20_oid = 0x06; - if (xmss_keypair(public_key, secret_key, xmss_sha512_h20_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_sha512_h20_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_verify(XMSS_UNUSED_ATT const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_remaining_signatures(remain, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_total_signatures(total, secret_key)) { + if (xmss_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c index 3e961c076b..ac43b57b3c 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H10_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmss_shake128_h10_oid = 0x07; - if (xmss_keypair(public_key, secret_key, xmss_shake128_h10_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_shake128_h10_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_verify(XMSS_UNUSED_ATT con return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_remaining_signatures(remain, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_total_signatures(total, secret_key)) { + if (xmss_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c index a8ed4fa37e..596939f155 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H16_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmss_shake128_h16_oid = 0x08; - if (xmss_keypair(public_key, secret_key, xmss_shake128_h16_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_shake128_h16_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_verify(XMSS_UNUSED_ATT con return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_remaining_signatures(remain, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_total_signatures(total, secret_key)) { + if (xmss_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c index e39f3912c2..37da02a13b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H20_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmss_shake128_h20_oid = 0x09; - if (xmss_keypair(public_key, secret_key, xmss_shake128_h20_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_shake128_h20_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_verify(XMSS_UNUSED_ATT con return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_remaining_signatures(remain, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_total_signatures(total, secret_key)) { + if (xmss_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c index 26bd706c9c..f0d27e2033 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H10_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmss_shake256_h10_oid = 0x0a; - if (xmss_keypair(public_key, secret_key, xmss_shake256_h10_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_shake256_h10_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_verify(XMSS_UNUSED_ATT con return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_remaining_signatures(remain, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_total_signatures(total, secret_key)) { + if (xmss_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c index c5c44d6655..38cd5603a9 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H16_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmss_shake256_h16_oid = 0x0b; - if (xmss_keypair(public_key, secret_key, xmss_shake256_h16_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_shake256_h16_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_verify(XMSS_UNUSED_ATT con return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_remaining_signatures(remain, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_total_signatures(total, secret_key)) { + if (xmss_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c index 439f4b3f99..ed1989876e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H20_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmss_shake256_h20_oid = 0x0c; - if (xmss_keypair(public_key, secret_key, xmss_shake256_h20_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_shake256_h20_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmss_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_verify(XMSS_UNUSED_ATT con return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_remaining_signatures(remain, secret_key)) { + if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmss_total_signatures(total, secret_key)) { + if (xmss_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c index 4cbd91beb5..792d7a3559 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_2_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_sha256_h20_2_oid = 0x01; - if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h20_2_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h20_2_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c index 9e830571cd..4a1d1cad52 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_4_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_sha256_h20_4_oid = 0x02; - if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h20_4_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h20_4_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c index 42181f75f6..9bb9c61445 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_2_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_sha256_h40_2_oid = 0x03; - if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h40_2_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h40_2_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c index 69df1302f8..64a2da1331 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_4_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_sha256_h40_4_oid = 0x04; - if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h40_4_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h40_4_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c index 6d4e161d53..13843351ee 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_8_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_sha256_h40_8_oid = 0x05; - if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h40_8_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h40_8_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c index 377518a0da..06873a58db 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_12_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_sha256_h60_12_oid = 0x08; - if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h60_12_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h60_12_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c index a455e43814..67183fee79 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_3_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_sha256_h60_3_oid = 0x06; - if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h60_3_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h60_3_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c index e57d298615..8ab9134684 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_6_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_sha256_h60_6_oid = 0x07; - if (xmssmt_keypair(public_key, secret_key, xmssmt_sha256_h60_6_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h60_6_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_verify(XMSS_UNUSED_ATT c return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c index 331949be1f..279146a010 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_2_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_shake128_h20_2_oid = 0x11; - if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h20_2_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h20_2_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c index 0acc511e7a..961fd8c0a7 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_4_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_shake128_h20_4_oid = 0x12; - if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h20_4_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h20_4_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c index cc379336b2..a72d9b7e67 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_2_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_shake128_h40_2_oid = 0x13; - if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h40_2_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h40_2_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c index 11030a2494..64c2f8cea3 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_4_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_shake128_h40_4_oid = 0x14; - if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h40_4_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h40_4_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c index cec3c1cd73..7b1c137e8a 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_8_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_shake128_h40_8_oid = 0x15; - if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h40_8_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h40_8_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c index 3cb5f20300..41c4317ad9 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_12_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_shake128_h60_12_oid = 0x18; - if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h60_12_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h60_12_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_verify(XMSS_UNUSED_AT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c index bc8f7a96bb..5a38219f83 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_3_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_shake128_h60_3_oid = 0x16; - if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h60_3_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h60_3_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c index 8bcb4dc0dd..9c860051d7 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c @@ -65,28 +65,28 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_6_new(void) { return sk; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (public_key == NULL || secret_key == NULL) { + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } const uint32_t xmssmt_shake128_h60_6_oid = 0x17; - if (xmssmt_keypair(public_key, secret_key, xmssmt_shake128_h60_6_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h60_6_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL) { + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key, signature, &sig_length, message, message_len)) { + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { return OQS_ERROR; } *signature_len = (size_t) sig_length; @@ -107,26 +107,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_verify(XMSS_UNUSED_ATT return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining(unsigned long long *remain, const uint8_t *secret_key) { - if (remain == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_remaining_signatures(remain, secret_key)) { + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(unsigned long long *total, const uint8_t *secret_key) { - if (total == NULL || secret_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - if (xmssmt_total_signatures(total, secret_key)) { + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { return OQS_ERROR; } return OQS_SUCCESS; -} \ No newline at end of file +} diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index 8e56bac5b8..9a5cdd7a6d 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -131,7 +131,7 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { uint8_t *msg = NULL, *msg_rand = NULL; size_t msg_len = 0; uint8_t *public_key = NULL; - uint8_t *secret_key = NULL; + OQS_SIG_STFL_SECRET_KEY *secret_key = NULL; uint8_t *signature = NULL, *signature_kat = NULL; uint8_t *signed_msg = NULL; size_t signature_len = 0; @@ -159,7 +159,7 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { // Grab the pk and sk from KAT file public_key = malloc(sig->length_public_key); - secret_key = calloc(sig->length_secret_key, sizeof(uint8_t)); + secret_key = OQS_SIG_STFL_SECRET_KEY_new(sig->method_name); signature = calloc(sig->length_signature, sizeof(uint8_t)); signature_kat = calloc(sig->length_signature, sizeof(uint8_t)); @@ -173,7 +173,7 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { goto err; } - if (!ReadHex(fp_rsp, secret_key, sig->length_secret_key, "sk = ")) { + if (!ReadHex(fp_rsp, secret_key->secret_key_data, sig->length_secret_key, "sk = ")) { fprintf(stderr, "ERROR: unable to read 'sk' from <%s>\n", katfile); goto err; } @@ -182,7 +182,7 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { fprintf(fh, "# %s\n\n", sig->method_name); OQS_fprintBstr(fh, "pk = ", public_key, sig->length_public_key); - OQS_fprintBstr(fh, "sk = ", secret_key, sig->length_secret_key); + OQS_fprintBstr(fh, "sk = ", secret_key->secret_key_data, sig->length_secret_key); fprintf(fh, "\n\n"); fprintf(fh, "count = 0\n"); @@ -271,10 +271,10 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { cleanup: if (sig != NULL) { - OQS_MEM_secure_free(secret_key, sig->length_secret_key); OQS_MEM_secure_free(signed_msg, signed_msg_len); } OQS_MEM_insecure_free(public_key); + OQS_SIG_STFL_SECRET_KEY_free(secret_key); OQS_MEM_insecure_free(signature); OQS_MEM_insecure_free(signature_kat); OQS_MEM_insecure_free(msg); diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index a393dc6cf4..770eb58f82 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -123,7 +123,7 @@ int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, char *str) { return 1; } -OQS_STATUS sig_stfl_keypair_from_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, uint8_t *secret_key) { +OQS_STATUS sig_stfl_keypair_from_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { OQS_STATUS rc; rc = OQS_SIG_STFL_keypair(sig, public_key, secret_key); OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); @@ -133,7 +133,7 @@ OQS_STATUS sig_stfl_keypair_from_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, return OQS_SUCCESS; } -OQS_STATUS sig_stfl_keypair_from_KATs(OQS_SIG_STFL *sig, uint8_t *public_key, uint8_t *secret_key, const char *katfile) { +OQS_STATUS sig_stfl_keypair_from_KATs(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key, const char *katfile) { OQS_STATUS ret = OQS_ERROR; FILE *fp_rsp = NULL; @@ -148,7 +148,7 @@ OQS_STATUS sig_stfl_keypair_from_KATs(OQS_SIG_STFL *sig, uint8_t *public_key, ui goto err; } - if (!ReadHex(fp_rsp, secret_key, sig->length_secret_key, "sk = ")) { + if (!ReadHex(fp_rsp, secret_key->secret_key_data, sig->length_secret_key, "sk = ")) { fprintf(stderr, "ERROR: unable to read 'sk' from <%s>\n", katfile); goto err; } @@ -176,7 +176,7 @@ OQS_STATUS sig_stfl_keypair_from_KATs(OQS_SIG_STFL *sig, uint8_t *public_key, ui * XMSSMT-SHAKE_40/2_256 * XMSSMT-SHAKE_60/3_256 */ -OQS_STATUS sig_stfl_KATs_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, uint8_t *secret_key, const char *katfile) { +OQS_STATUS sig_stfl_KATs_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key, const char *katfile) { printf("%s", sig->method_name); if (0) { @@ -253,7 +253,7 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char OQS_SIG_STFL *sig = NULL; uint8_t *public_key = NULL; - uint8_t *secret_key = NULL; + OQS_SIG_STFL_SECRET_KEY *secret_key = NULL; uint8_t *message = NULL; size_t message_len = 100; uint8_t *signature = NULL; @@ -275,8 +275,8 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char printf("Sample computation for stateful signature %s\n", sig->method_name); printf("================================================================================\n"); + secret_key = OQS_SIG_STFL_SECRET_KEY_new(sig->method_name); public_key = malloc(sig->length_public_key + 2 * sizeof(magic_t)); - secret_key = malloc(sig->length_secret_key + 2 * sizeof(magic_t)); message = malloc(message_len + 2 * sizeof(magic_t)); signature = malloc(sig->length_signature + 2 * sizeof(magic_t)); @@ -287,18 +287,15 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char //Set the magic numbers before memcpy(public_key, magic.val, sizeof(magic_t)); - memcpy(secret_key, magic.val, sizeof(magic_t)); memcpy(message, magic.val, sizeof(magic_t)); memcpy(signature, magic.val, sizeof(magic_t)); public_key += sizeof(magic_t); - secret_key += sizeof(magic_t); message += sizeof(magic_t); signature += sizeof(magic_t); // and after memcpy(public_key + sig->length_public_key, magic.val, sizeof(magic_t)); - memcpy(secret_key + sig->length_secret_key, magic.val, sizeof(magic_t)); memcpy(message + message_len, magic.val, sizeof(magic_t)); memcpy(signature + sig->length_signature, magic.val, sizeof(magic_t)); @@ -344,11 +341,9 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char #ifndef OQS_ENABLE_TEST_CONSTANT_TIME /* check magic values */ int rv = memcmp(public_key + sig->length_public_key, magic.val, sizeof(magic_t)); - rv |= memcmp(secret_key + sig->length_secret_key, magic.val, sizeof(magic_t)); rv |= memcmp(message + message_len, magic.val, sizeof(magic_t)); rv |= memcmp(signature + sig->length_signature, magic.val, sizeof(magic_t)); rv |= memcmp(public_key - sizeof(magic_t), magic.val, sizeof(magic_t)); - rv |= memcmp(secret_key - sizeof(magic_t), magic.val, sizeof(magic_t)); rv |= memcmp(message - sizeof(magic_t), magic.val, sizeof(magic_t)); rv |= memcmp(signature - sizeof(magic_t), magic.val, sizeof(magic_t)); if (rv) { @@ -365,9 +360,7 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char ret = OQS_ERROR; cleanup: - if (secret_key) { - OQS_MEM_secure_free(secret_key - sizeof(magic_t), sig->length_secret_key + 2 * sizeof(magic_t)); - } + OQS_SIG_STFL_SECRET_KEY_free(secret_key); if (public_key) { OQS_MEM_insecure_free(public_key - sizeof(magic_t)); } From 245aede9970934f45801aa12ed9189b42c94993a Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Tue, 29 Aug 2023 15:48:49 -0400 Subject: [PATCH 12/68] LMS updated to use new SK API (#1533) * Use secret key struct in LMS. Update de/serialize sk API * Updates per comments * Update per comments * Fix mem leak * Address scan bild issue * Removed unused variable * Remove unused struc member * Address macOS-noopenssl build failures --- src/sig_stfl/lms/sig_stfl_lms.c | 65 +++-- src/sig_stfl/lms/sig_stfl_lms.h | 25 +- src/sig_stfl/lms/sig_stfl_lms_functions.c | 277 +++++++++++++++++++--- src/sig_stfl/lms/sig_stfl_lms_wrap.h | 26 -- src/sig_stfl/sig_stfl.h | 20 +- tests/kat_sig_stfl.c | 14 +- tests/test_sig_stfl.c | 102 +++++++- 7 files changed, 421 insertions(+), 108 deletions(-) diff --git a/src/sig_stfl/lms/sig_stfl_lms.c b/src/sig_stfl/lms/sig_stfl_lms.c index dde8dc586f..1a0831f39d 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.c +++ b/src/sig_stfl/lms/sig_stfl_lms.c @@ -10,7 +10,7 @@ // ======================== LMS-SHA256 H5/W1 ======================== // -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { if (secret_key == NULL || public_key == NULL) { return OQS_ERROR; } @@ -60,34 +60,55 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void) { // Initialize the key with length_secret_key amount of bytes. sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_sk; - if (sk->length_secret_key) { - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - if (sk->secret_key_data) { - memset(sk->secret_key_data, 0, sk->length_secret_key); - } else { - OQS_SECRET_KEY_LMS_free(sk); - OQS_MEM_insecure_free(sk); - sk = NULL; - return NULL; - } - } + /* Function that returns the total number of signatures for the secret key */ + sk->sigs_total = NULL; + + /* set Function to returns the number of signatures left for the secret key */ + sk->sigs_left = NULL; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + /* + * Set Secret Key Saving Function + */ + sk->save_secret_key = NULL; + + /* + * Set Secret Key free function + */ sk->free_key = OQS_SECRET_KEY_LMS_free; return sk; } void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk) { - if (sk == NULL) { - return; - } + oqs_secret_lms_key_free(sk); +} - //TODO: cleanup lock_key +/* Convert LMS secret key object to byte string */ +size_t OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_buf) { + return oqs_serialize_lms_key(sk, sk_buf); +} - if (sk->sig) { - OQS_MEM_insecure_free(sk->sig); - sk->sig = NULL; - } - OQS_MEM_secure_free(sk->secret_key_data, sk->length_secret_key); - sk->secret_key_data = NULL; +/* Insert lms byte string in an LMS secret key object */ +OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf) { + return oqs_deserialize_lms_key(sk, key_len, sk_buf); } diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h index 97104b47f8..ab32848ac8 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.h +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -10,32 +10,43 @@ #define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_sk 64 -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void); + +/* Convert LMS secret key object to byte string */ +size_t OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_buf); + +/* Insert lms byte string in an LMS secret key object */ +OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf); + OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(uint64_t *totaln, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(uint64_t *totaln, const OQS_SIG_STFL_SECRET_KEY *secret_key); void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk); // ----------------------------------- WRAPPER FUNCTIONS ------------------------------------------------ -int oqs_sig_stfl_lms_keypair(uint8_t *pk, uint8_t *sk, const uint32_t oid); +int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uint32_t oid); -int oqs_sig_stfl_lms_sign(uint8_t *sk, uint8_t *sm, size_t *smlen, +int oqs_sig_stfl_lms_sign(OQS_SIG_STFL_SECRET_KEY *sk, uint8_t *sm, size_t *smlen, const uint8_t *m, size_t mlen); int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, const uint8_t *sm, size_t smlen, const uint8_t *pk); +void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk); + +size_t oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_key); +int oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf); + // ---------------------------- FUNCTIONS INDEPENDENT OF VARIANT ----------------------------------------- -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signature_length, const uint8_t *message, size_t message_len, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signature_length, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); - // -------------------------------------------------------------------------------------------------------- #endif /* OQS_SIG_STFL_LMS_H */ diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index 8c17ddddd0..da7f865c07 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -9,8 +9,40 @@ #include "sig_stfl_lms_wrap.h" #include +#define DEFAULT_AUX_DATA 10916 /* Use 10+k of aux data (which works well */ +/* with the above default parameter set) */ +/** + * @brief OQS_LMS_KEY object for HSS key pair + */ + +typedef struct OQS_LMS_KEY_DATA { + + /* Tree levels. */ + uint32_t levels; + + /* Array, 8 levels max, of LMS types */ + param_set_t lm_type[8]; + + /* Array, 8 levels max, of LM OTS types */ + param_set_t lm_ots_type[8]; + + /* LMS public key */ + uint8_t public_key[60]; + + /* Length of aux data */ + size_t len_aux_data; + /* internal nodes info of the Merkle tree */ + uint8_t *aux_data; + + /* Length of sec_key */ + size_t len_sec_key; + + /* secret key data */ + uint8_t *sec_key; +} oqs_lms_key_data; + OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signature_length, const uint8_t *message, - size_t message_len, uint8_t *secret_key) { + size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { if (secret_key == NULL || message == NULL || signature == NULL) { return OQS_ERROR; @@ -45,7 +77,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_verify(const uint8_t *message, size_t me return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; @@ -55,7 +87,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(uint64_t *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; @@ -75,41 +107,78 @@ bool LMS_randombytes(void *buffer, size_t length) { return true; } -int oqs_sig_stfl_lms_keypair(uint8_t *pk, uint8_t *sk, const uint32_t oid) { +int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uint32_t oid) { int ret = -1; bool b_ret; int parse_err = 0; - unsigned levels = 1; - unsigned char public_key[60]; size_t len_public_key = 60; - unsigned char *aux_data = NULL; - size_t max_aux_data = 10916; - int aux_len = 0; - oqs_lms_key_data *oqs_data = NULL; - - param_set_t lm_type[1]; - param_set_t lm_ots_type[1]; + oqs_lms_key_data *oqs_key_data = NULL; if (!pk || !sk || !oid) { return -1; } + if (sk->secret_key_data) { + //this means a key pair has already been recreated + //TODO log error. + return -1; + } + + oqs_key_data = malloc(sizeof(oqs_lms_key_data)); + if (oqs_key_data) { + oqs_key_data->levels = 1; + if (sk->length_secret_key) { + oqs_key_data->len_sec_key = sk->length_secret_key; + oqs_key_data->sec_key = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + if (oqs_key_data->sec_key) { + memset(oqs_key_data->sec_key, 0, sk->length_secret_key); + } else { + OQS_MEM_insecure_free(oqs_key_data); + oqs_key_data = NULL; + return -1; + } + } else { + OQS_MEM_insecure_free(oqs_key_data); + oqs_key_data = NULL; + return -1; + } + + //Aux Data + size_t len_aux_data = DEFAULT_AUX_DATA; + uint8_t *aux_data = malloc(sizeof(uint8_t) * len_aux_data); + if (aux_data) { + oqs_key_data->aux_data = aux_data; + oqs_key_data->len_aux_data = len_aux_data; + } else { + OQS_MEM_insecure_free( oqs_key_data->sec_key); + OQS_MEM_insecure_free(oqs_key_data); + return -1; + } + } else { + //TODO log error + return -1; + } + /* Set lms param set */ switch (oid) { case 0x1: - lm_type[0] = LMS_SHA256_N32_H5; - lm_ots_type[0] = LMOTS_SHA256_N32_W1; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H5; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W1; break; default: - lm_type[0] = 0; - lm_ots_type[0] = 0; + oqs_key_data->lm_type[0] = 0; + oqs_key_data->lm_ots_type[0] = 0; parse_err = 1; break; } if (parse_err) { + OQS_MEM_insecure_free(oqs_key_data->sec_key); + OQS_MEM_insecure_free(oqs_key_data->aux_data); + OQS_MEM_insecure_free(oqs_key_data); + oqs_key_data = NULL; return -1; } @@ -145,16 +214,23 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, uint8_t *sk, const uint32_t oid) { */ b_ret = hss_generate_private_key( LMS_randombytes, - levels, - lm_type, - lm_ots_type, + oqs_key_data->levels, + oqs_key_data->lm_type, + oqs_key_data->lm_ots_type, NULL, //File handler function? - (void *)sk, - public_key, len_public_key, - aux_data, aux_len, + oqs_key_data->sec_key, + oqs_key_data->public_key, len_public_key, + oqs_key_data->aux_data, oqs_key_data->len_aux_data, NULL); if (b_ret) { - memcpy(pk, public_key, len_public_key); + memcpy(pk, oqs_key_data->public_key, len_public_key); + sk->secret_key_data = oqs_key_data; + } else { + OQS_MEM_insecure_free(oqs_key_data->sec_key); + OQS_MEM_insecure_free(oqs_key_data->aux_data); + OQS_MEM_insecure_free(oqs_key_data); + oqs_key_data = NULL; + return -1; } /* TODO: store key pair, file handler */ @@ -163,16 +239,24 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, uint8_t *sk, const uint32_t oid) { return ret; } -int oqs_sig_stfl_lms_sign(uint8_t *sk, +int oqs_sig_stfl_lms_sign(OQS_SIG_STFL_SECRET_KEY *sk, uint8_t *sm, size_t *smlen, const uint8_t *m, size_t mlen) { size_t sig_len; bool status; - unsigned char *sig = NULL; + uint8_t *sig = NULL; + uint8_t *priv_key = NULL; + oqs_lms_key_data *oqs_key_data = NULL; struct hss_working_key *w = NULL; struct hss_sign_inc ctx; - w = hss_load_private_key(NULL, sk, + if (sk) { + oqs_key_data = sk->secret_key_data; + priv_key = oqs_key_data->sec_key; + } else { + return -1; + } + w = hss_load_private_key(NULL, priv_key, 0, NULL, 0, @@ -205,7 +289,7 @@ int oqs_sig_stfl_lms_sign(uint8_t *sk, &ctx, /* Incremental signing context */ w, /* Working key */ NULL, /* Routine to update the */ - sk, /* private key */ + priv_key, /* private key */ sig, sig_len, /* Where to place the signature */ 0); @@ -264,3 +348,140 @@ int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, } } +void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL) { + return; + } + + //TODO: cleanup lock_key + + if (sk->sig) { + OQS_MEM_insecure_free(sk->sig); + sk->sig = NULL; + } + + if (sk->secret_key_data) { + oqs_lms_key_data *key_data = (oqs_lms_key_data *)sk->secret_key_data; + if (key_data) { + OQS_MEM_secure_free(key_data->sec_key, key_data->len_sec_key); + key_data->sec_key = NULL; + + OQS_MEM_secure_free(key_data->aux_data, key_data->len_aux_data); + } + + OQS_MEM_insecure_free(key_data); + sk->secret_key_data = NULL; + } +} + +/* + * Convert LMS secret key object to byte string + * Writes secret key + aux data if present + */ +size_t oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_key) { + + oqs_lms_key_data *lms_key_data = NULL; + size_t key_len = 0; + if (sk) { + uint8_t *sk_key_buf = NULL; + lms_key_data = sk->secret_key_data; + if (lms_key_data && lms_key_data->sec_key) { + size_t buf_size_needed = lms_key_data->len_aux_data + lms_key_data->len_sec_key; + key_len = buf_size_needed; + /* pass back serialized data */ + if (sk_key) { + if (buf_size_needed) { + sk_key_buf = malloc(buf_size_needed * sizeof(uint8_t)); + if (sk_key_buf) { + + /* + * Serialized data is sec_key followed by aux data + * So aux data begins after buffer top + sec_key length + */ + if (lms_key_data->len_sec_key) { + memcpy(sk_key_buf, lms_key_data->sec_key, lms_key_data->len_sec_key); + } + + if (lms_key_data->len_aux_data) { + memcpy(sk_key_buf + lms_key_data->len_sec_key, lms_key_data->aux_data, lms_key_data->len_aux_data); + } + + *sk_key = sk_key_buf; + key_len = sk->length_secret_key + lms_key_data->len_aux_data; + } + } + } //sk_key + } + } //sk + return key_len; +} + +/* + * Convert LMS byte string to secret key object + * Writes secret key + aux data if present + * key_len is priv key length + aux length + */ +int oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf) { + int oqs_status = -1; + oqs_lms_key_data *lms_key_data = NULL; + uint8_t priv_ky_len = hss_get_private_key_len((unsigned )(1), NULL, NULL); + + if ((!sk) || (key_len == 0) || (key_len < priv_ky_len) || (!sk_buf)) { + return oqs_status; + } + + if (sk->secret_key_data) { + //Key data already present + //We dont want to trample over data + return oqs_status; + } + + uint8_t *lms_sk = NULL; + uint8_t *lms_aux = NULL; + + unsigned levels = 0; + + int key_buf_left = key_len - priv_ky_len; + + param_set_t lm_type[ MAX_HSS_LEVELS ]; + param_set_t lm_ots_type[ MAX_HSS_LEVELS ]; + + // validate sk_buf for lms params + if (hss_get_parameter_set(&levels, + lm_type, + lm_ots_type, + NULL, + (void *)sk_buf)) { + return oqs_status; + } + + lms_key_data = malloc(sizeof(oqs_lms_key_data)); + if (lms_key_data) { + lms_sk = malloc(priv_ky_len * sizeof(uint8_t)); + if (lms_sk) { + memcpy(lms_sk, sk_buf, priv_ky_len); + lms_key_data->sec_key = lms_sk; + lms_key_data->len_sec_key = priv_ky_len; + } else { + OQS_MEM_insecure_free(lms_key_data); + return oqs_status; + } + + if (key_buf_left) { + lms_aux = malloc(key_buf_left * sizeof(uint8_t)); + if (lms_aux) { + memcpy(lms_aux, (sk_buf + priv_ky_len), key_buf_left); + lms_key_data->aux_data = lms_aux; + lms_key_data->len_aux_data = key_buf_left; + } else { + OQS_MEM_insecure_free(lms_key_data); + OQS_MEM_insecure_free(lms_sk); + return oqs_status; + } + } + + sk->secret_key_data = lms_key_data; + oqs_status = 0; + } + return oqs_status; +} diff --git a/src/sig_stfl/lms/sig_stfl_lms_wrap.h b/src/sig_stfl/lms/sig_stfl_lms_wrap.h index 043de2c461..1d5486d21a 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_wrap.h +++ b/src/sig_stfl/lms/sig_stfl_lms_wrap.h @@ -13,32 +13,6 @@ */ typedef struct OQS_LMS_KEY_DATA oqs_lms_key_data; -typedef struct OQS_LMS_KEY_DATA { - - /* Tree levels. */ - unsigned levels; - - /* Array, 8 levels max, of LMS types */ - param_set_t lm_type[8]; - - /* Array, 8 levels max, of LM OTS types */ - param_set_t lm_ots_type[8]; - - /* LMS public key */ - unsigned char public_key[60]; - - /* internal nodes info of the Merkle tree */ - unsigned char *aux_data; - - /* Length of aux data */ - size_t len_aux_data; - - /* User defined data that may be used for the SAFETY functions */ - void *data; - -} oqs_lms_key_data; - - typedef struct OQS_LMS_SIG_DATA oqs_lms_sig_data; typedef struct OQS_LMS_SIG_DATA { diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index b795853c5c..a3423a667b 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -206,21 +206,23 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { * Secret Key retrieval Function * * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object - * @param[out] key_len length of the returned byte string - * @returns newly created pointer to ley byte string if none-zero length. Caller - * deletes the buffer. + * @param[out] sk_buf private key data as a byte stream + * @returns length of key material data available + * Caller deletes the buffer if memory was allocated. */ - uint8_t *(*serialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len); + size_t (*serialize_key)(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_buf); /** * set Secret Key to internal structure Function * - * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object - * @param[out] key_len length of the returned byte string - * @returns newly created pointer to ley byte string if none-zero length. Caller - * deletes the buffer. + * @param[in] sk OQS_SIG_STFL_SECRET_KEY object + * @param[in] key_len length of the returned byte string + * @param[in] sk_key The secret key represented as OQS_SIG_STFL_SECRET_KEY object + * @param[in] key_len length of the returned byte string + * @returns status of the operation populated with key material none-zero length. Caller + * deletes the buffer. if sk_buf is NULL the function returns the length */ - uint8_t *(*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, uint8_t *sk_key); + OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf); /** * Secret Key Locking Function diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index 9a5cdd7a6d..d5de696580 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -66,7 +66,8 @@ int FindMarker(FILE *infile, const char *marker) { // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) // int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, char *str) { - int i, ch, started; + int ch, started; + unsigned long i; unsigned char ich; if (Length == 0) { @@ -111,19 +112,8 @@ int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, char *str) { return 1; } -static inline uint16_t UINT16_TO_BE(const uint16_t x) { - union { - uint16_t val; - uint8_t bytes[2]; - } y; - y.bytes[0] = (x >> 8) & 0xFF; - y.bytes[1] = x & 0xFF; - return y.val; -} - OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { - uint8_t entropy_input[48]; uint8_t seed[48]; FILE *fh = NULL; FILE *fp_rsp = NULL; diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 770eb58f82..b496457b99 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -78,7 +78,8 @@ int FindMarker(FILE *infile, const char *marker) { // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) // int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, char *str) { - int i, ch, started; + int ch, started; + unsigned long i; unsigned char ich; if (Length == 0) { @@ -178,7 +179,7 @@ OQS_STATUS sig_stfl_keypair_from_KATs(OQS_SIG_STFL *sig, uint8_t *public_key, OQ */ OQS_STATUS sig_stfl_KATs_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key, const char *katfile) { - printf("%s", sig->method_name); + printf("%s ", sig->method_name); if (0) { #ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 @@ -379,6 +380,93 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { OQS_STATUS rc = OQS_SUCCESS; OQS_SIG_STFL_SECRET_KEY *sk = NULL; + OQS_SIG_STFL *sig_obj = NULL; + uint8_t *public_key = NULL; + + /* + * Temporarily skip algs with long key generation times. + */ + + if (0) { + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { + goto skip_test; +#endif + } else { + goto keep_going; + } +skip_test: + printf("Skip slow test %s.\n", method_name); + return rc; + +keep_going: + + printf("================================================================================\n"); + printf("Create stateful Signature %s\n", method_name); + printf("================================================================================\n"); + + sig_obj = OQS_SIG_STFL_new(method_name); + if (sig_obj == NULL) { + fprintf(stderr, "ERROR: OQS_SIG_STFL_new failed\n"); + goto err; + } + + public_key = malloc(sig_obj->length_public_key * sizeof(uint8_t)); + + printf("================================================================================\n"); + printf("Create stateful Secret Key %s\n", method_name); + printf("================================================================================\n"); + sk = OQS_SIG_STFL_SECRET_KEY_new(method_name); if (sk == NULL) { fprintf(stderr, "ERROR: OQS_SECRET_KEY_new failed\n"); @@ -386,21 +474,27 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { } printf("================================================================================\n"); - printf("Create stateful Secret Key %s\n", method_name); + printf("Generate keypair %s\n", method_name); printf("================================================================================\n"); + rc = OQS_SIG_STFL_keypair(sig_obj, public_key, sk); + if (!sk->secret_key_data) { fprintf(stderr, "ERROR: OQS_SECRET_KEY_new incomplete.\n"); + OQS_MEM_insecure_free(public_key); goto err; } - OQS_SIG_STFL_SECRET_KEY_free(sk); printf("Secret Key created as expected.\n"); goto end_it; err: rc = OQS_ERROR; end_it: + + OQS_SIG_STFL_SECRET_KEY_free(sk); + OQS_MEM_insecure_free(public_key); + OQS_SIG_STFL_free(sig_obj); return rc; } From 99067be855c99de792d4e25a3beb736ef9ecf80b Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Sat, 9 Sep 2023 17:24:32 -0400 Subject: [PATCH 13/68] Add XMSS Serialize/Deserialize (#1542) * Add serialize and deserialize to XMSS --------- Co-authored-by: Norman Ashley --- src/sig_stfl/lms/sig_stfl_lms.c | 9 +- src/sig_stfl/lms/sig_stfl_lms.h | 10 +- src/sig_stfl/lms/sig_stfl_lms_functions.c | 157 +++++++++--------- src/sig_stfl/sig_stfl.h | 14 +- src/sig_stfl/xmss/CMakeLists.txt | 3 + src/sig_stfl/xmss/external/sign_params.h | 142 ---------------- src/sig_stfl/xmss/sig_stfl_xmss.h | 9 + .../xmss/sig_stfl_xmss_secret_key_functions.c | 48 ++++++ src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c | 10 ++ src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c | 9 + src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c | 9 + src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c | 9 + src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c | 9 + src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c | 9 + .../xmss/sig_stfl_xmss_shake128_h10.c | 9 + .../xmss/sig_stfl_xmss_shake128_h16.c | 9 + .../xmss/sig_stfl_xmss_shake128_h20.c | 9 + .../xmss/sig_stfl_xmss_shake256_h10.c | 9 + .../xmss/sig_stfl_xmss_shake256_h16.c | 9 + .../xmss/sig_stfl_xmss_shake256_h20.c | 9 + .../xmss/sig_stfl_xmssmt_sha256_h20_2.c | 9 + .../xmss/sig_stfl_xmssmt_sha256_h20_4.c | 9 + .../xmss/sig_stfl_xmssmt_sha256_h40_2.c | 9 + .../xmss/sig_stfl_xmssmt_sha256_h40_4.c | 9 + .../xmss/sig_stfl_xmssmt_sha256_h40_8.c | 9 + .../xmss/sig_stfl_xmssmt_sha256_h60_12.c | 9 + .../xmss/sig_stfl_xmssmt_sha256_h60_3.c | 9 + .../xmss/sig_stfl_xmssmt_sha256_h60_6.c | 9 + .../xmss/sig_stfl_xmssmt_shake128_h20_2.c | 9 + .../xmss/sig_stfl_xmssmt_shake128_h20_4.c | 9 + .../xmss/sig_stfl_xmssmt_shake128_h40_2.c | 9 + .../xmss/sig_stfl_xmssmt_shake128_h40_4.c | 9 + .../xmss/sig_stfl_xmssmt_shake128_h40_8.c | 9 + .../xmss/sig_stfl_xmssmt_shake128_h60_12.c | 9 + .../xmss/sig_stfl_xmssmt_shake128_h60_3.c | 9 + .../xmss/sig_stfl_xmssmt_shake128_h60_6.c | 9 + 36 files changed, 412 insertions(+), 233 deletions(-) delete mode 100644 src/sig_stfl/xmss/external/sign_params.h create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c diff --git a/src/sig_stfl/lms/sig_stfl_lms.c b/src/sig_stfl/lms/sig_stfl_lms.c index 1a0831f39d..6ae6d1dde6 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.c +++ b/src/sig_stfl/lms/sig_stfl_lms.c @@ -7,7 +7,6 @@ #include "sig_stfl_lms_wrap.h" #include "sig_stfl_lms.h" - // ======================== LMS-SHA256 H5/W1 ======================== // OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -104,11 +103,11 @@ void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk) { } /* Convert LMS secret key object to byte string */ -size_t OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_buf) { - return oqs_serialize_lms_key(sk, sk_buf); +OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr) { + return oqs_serialize_lms_key(sk, sk_len, sk_buf_ptr); } /* Insert lms byte string in an LMS secret key object */ -OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf) { - return oqs_deserialize_lms_key(sk, key_len, sk_buf); +OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf) { + return oqs_deserialize_lms_key(sk, sk_len, sk_buf); } diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h index ab32848ac8..76de39a6e3 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.h +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -15,15 +15,15 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void); /* Convert LMS secret key object to byte string */ -size_t OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_buf); +OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr); /* Insert lms byte string in an LMS secret key object */ -OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf); +OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t key_len, const uint8_t *sk_buf); OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(uint64_t *totaln, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *totaln, const OQS_SIG_STFL_SECRET_KEY *secret_key); void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk); @@ -38,8 +38,8 @@ int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, const uint8_t *sm, si void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk); -size_t oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_key); -int oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf); +OQS_STATUS oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_key); +OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf); // ---------------------------- FUNCTIONS INDEPENDENT OF VARIANT ----------------------------------------- diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index da7f865c07..ea4f42d8af 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: MIT #include +#include #include "sig_stfl_lms.h" #include "external/config.h" #include "external/hss_verify_inc.h" @@ -87,7 +88,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(uint64_t *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; @@ -378,42 +379,46 @@ void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk) { * Convert LMS secret key object to byte string * Writes secret key + aux data if present */ -size_t oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_key) { +OQS_STATUS oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_key) { - oqs_lms_key_data *lms_key_data = NULL; - size_t key_len = 0; - if (sk) { - uint8_t *sk_key_buf = NULL; - lms_key_data = sk->secret_key_data; - if (lms_key_data && lms_key_data->sec_key) { - size_t buf_size_needed = lms_key_data->len_aux_data + lms_key_data->len_sec_key; - key_len = buf_size_needed; - /* pass back serialized data */ - if (sk_key) { - if (buf_size_needed) { - sk_key_buf = malloc(buf_size_needed * sizeof(uint8_t)); - if (sk_key_buf) { - - /* - * Serialized data is sec_key followed by aux data - * So aux data begins after buffer top + sec_key length - */ - if (lms_key_data->len_sec_key) { - memcpy(sk_key_buf, lms_key_data->sec_key, lms_key_data->len_sec_key); - } - - if (lms_key_data->len_aux_data) { - memcpy(sk_key_buf + lms_key_data->len_sec_key, lms_key_data->aux_data, lms_key_data->len_aux_data); - } - - *sk_key = sk_key_buf; - key_len = sk->length_secret_key + lms_key_data->len_aux_data; - } - } - } //sk_key - } - } //sk - return key_len; + if (sk == NULL || sk_len == NULL || sk_key == NULL) { + return OQS_ERROR; + } + + oqs_lms_key_data *lms_key_data = sk->secret_key_data; + + if (lms_key_data == NULL || lms_key_data->sec_key == NULL) { + return OQS_ERROR; + } + + size_t key_len = lms_key_data->len_aux_data + lms_key_data->len_sec_key; + + if (key_len == 0) { + return OQS_ERROR; + } + + uint8_t *sk_key_buf = malloc(key_len * sizeof(uint8_t)); + + if (sk_key_buf == NULL) { + return OQS_ERROR; + } + /* pass back serialized data */ + /* + * Serialized data is sec_key followed by aux data + * So aux data begins after buffer top + sec_key length + */ + if (lms_key_data->len_sec_key != 0) { + memcpy(sk_key_buf, lms_key_data->sec_key, lms_key_data->len_sec_key); + } + + if (lms_key_data->len_aux_data != 0) { + memcpy(sk_key_buf + lms_key_data->len_sec_key, lms_key_data->aux_data, lms_key_data->len_aux_data); + } + + *sk_key = sk_key_buf; + *sk_len = sk->length_secret_key + lms_key_data->len_aux_data; + + return OQS_SUCCESS; } /* @@ -421,28 +426,27 @@ size_t oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_ke * Writes secret key + aux data if present * key_len is priv key length + aux length */ -int oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf) { - int oqs_status = -1; +OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf) { + oqs_lms_key_data *lms_key_data = NULL; - uint8_t priv_ky_len = hss_get_private_key_len((unsigned )(1), NULL, NULL); + uint8_t *lms_sk = NULL; + uint8_t *lms_aux = NULL; + int aux_buf_len = 0; + uint8_t lms_sk_len = hss_get_private_key_len((unsigned )(1), NULL, NULL); - if ((!sk) || (key_len == 0) || (key_len < priv_ky_len) || (!sk_buf)) { - return oqs_status; + if (sk == NULL || sk_buf == NULL || (sk_len == 0) || (sk_len < lms_sk_len )) { + return OQS_ERROR; } + aux_buf_len = sk_len - lms_sk_len; if (sk->secret_key_data) { - //Key data already present - //We dont want to trample over data - return oqs_status; + // Key data already present + // We dont want to trample over data + return OQS_ERROR; } - uint8_t *lms_sk = NULL; - uint8_t *lms_aux = NULL; - unsigned levels = 0; - int key_buf_left = key_len - priv_ky_len; - param_set_t lm_type[ MAX_HSS_LEVELS ]; param_set_t lm_ots_type[ MAX_HSS_LEVELS ]; @@ -452,36 +456,41 @@ int oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const u lm_ots_type, NULL, (void *)sk_buf)) { - return oqs_status; + return OQS_ERROR; } lms_key_data = malloc(sizeof(oqs_lms_key_data)); - if (lms_key_data) { - lms_sk = malloc(priv_ky_len * sizeof(uint8_t)); - if (lms_sk) { - memcpy(lms_sk, sk_buf, priv_ky_len); - lms_key_data->sec_key = lms_sk; - lms_key_data->len_sec_key = priv_ky_len; - } else { - OQS_MEM_insecure_free(lms_key_data); - return oqs_status; - } + lms_sk = malloc(lms_sk_len * sizeof(uint8_t)); - if (key_buf_left) { - lms_aux = malloc(key_buf_left * sizeof(uint8_t)); - if (lms_aux) { - memcpy(lms_aux, (sk_buf + priv_ky_len), key_buf_left); - lms_key_data->aux_data = lms_aux; - lms_key_data->len_aux_data = key_buf_left; - } else { - OQS_MEM_insecure_free(lms_key_data); - OQS_MEM_insecure_free(lms_sk); - return oqs_status; - } + if (lms_key_data == NULL || lms_sk == NULL) { + goto err; + } + + memcpy(lms_sk, sk_buf, lms_sk_len); + lms_key_data->sec_key = lms_sk; + lms_key_data->len_sec_key = lms_sk_len; + + if (aux_buf_len) { + lms_aux = malloc(aux_buf_len * sizeof(uint8_t)); + + if (lms_aux == NULL) { + goto err; } - sk->secret_key_data = lms_key_data; - oqs_status = 0; + memcpy(lms_aux, sk_buf + lms_sk_len, aux_buf_len); + lms_key_data->aux_data = lms_aux; + lms_key_data->len_aux_data = aux_buf_len; } - return oqs_status; + + sk->secret_key_data = lms_key_data; + goto success; + +err: + OQS_MEM_secure_free(lms_key_data, sizeof(oqs_lms_key_data)); + OQS_MEM_secure_free(lms_sk, lms_sk_len); + OQS_MEM_secure_free(lms_aux, aux_buf_len); + return OQS_ERROR; + +success: + return OQS_SUCCESS; } diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index a3423a667b..eb1b4088d5 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -206,23 +206,23 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { * Secret Key retrieval Function * * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object - * @param[out] sk_buf private key data as a byte stream + * @param[out] sk_len length of private key as a byte stream + * @param[out] sk_buf_ptr pointer to private key data as a byte stream * @returns length of key material data available * Caller deletes the buffer if memory was allocated. */ - size_t (*serialize_key)(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_buf); + OQS_STATUS (*serialize_key)(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr); /** * set Secret Key to internal structure Function * - * @param[in] sk OQS_SIG_STFL_SECRET_KEY object - * @param[in] key_len length of the returned byte string - * @param[in] sk_key The secret key represented as OQS_SIG_STFL_SECRET_KEY object - * @param[in] key_len length of the returned byte string + * @param[out] sk OQS_SIG_STFL_SECRET_KEY object + * @param[in] sk_len length of the returned byte string + * @param[in] sk_buf The secret key represented as OQS_SIG_STFL_SECRET_KEY object * @returns status of the operation populated with key material none-zero length. Caller * deletes the buffer. if sk_buf is NULL the function returns the length */ - OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf); + OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf); /** * Secret Key Locking Function diff --git a/src/sig_stfl/xmss/CMakeLists.txt b/src/sig_stfl/xmss/CMakeLists.txt index b4b3038c69..1b55b20866 100644 --- a/src/sig_stfl/xmss/CMakeLists.txt +++ b/src/sig_stfl/xmss/CMakeLists.txt @@ -13,6 +13,9 @@ set(SRCS external/core_hash.c external/xmss_core_fast.c ) +add_library(sig_stfl_xmss_secret_key_functions OBJECT sig_stfl_xmss_secret_key_functions.c) +set(_XMSS_OBJS ${_XMSS_OBJS} $) + if (OQS_ENABLE_SIG_STFL_xmss_sha256_h10) add_library(xmss_sha256_h10 OBJECT sig_stfl_xmss_sha256_h10.c ${SRCS}) target_compile_options(xmss_sha256_h10 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha256_h10 -DHASH=3) diff --git a/src/sig_stfl/xmss/external/sign_params.h b/src/sig_stfl/xmss/external/sign_params.h deleted file mode 100644 index d9dce53e42..0000000000 --- a/src/sig_stfl/xmss/external/sign_params.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef NIST_PARAM_H -#define NIST_PARAM_H - -#include "params.h" -#include "xmss.h" - -#ifndef TREE_LEVEL -#define TREE_LEVEL 0 -#endif - -#ifndef XMSSMT -#define XMSSMT 0 -#endif - -#if XMSSMT == 0 - /* - * Maximum signatures: 2^h - 1 = 2^10 - 1 - */ - #if TREE_LEVEL == 0 - - #define XMSS_OID "XMSS-SHA2_10_256" - - #define XMSS_PUBLICKEYBYTES 64 - #define XMSS_SECRETKEYBYTES_SMALL 132 - #define XMSS_SECRETKEYBYTES 1373 - - #define XMSS_SIGNBYTES 2500 - - /* - * Maximum signatures: 2^h - 1 = 2^16 - 1 - */ - #elif TREE_LEVEL == 1 - - #define XMSS_OID "XMSS-SHA2_16_256" - - #define XMSS_PUBLICKEYBYTES 64 - #define XMSS_SECRETKEYBYTES_SMALL 132 - #define XMSS_SECRETKEYBYTES 2093 - - #define XMSS_SIGNBYTES 2692 - - /* - * Maximum signatures: 2^h - 1 = 2^20 - 1 - */ - #elif TREE_LEVEL == 2 - - #define XMSS_OID "XMSS-SHA2_20_256" - - #define XMSS_PUBLICKEYBYTES 64 - #define XMSS_SECRETKEYBYTES_SMALL 132 - #define XMSS_SECRETKEYBYTES 2573 - - #define XMSS_SIGNBYTES 2820 - - - #else - - #error "Unspecified TREE_LEVEL {0,1,2}" - - #endif -#else - /* - * Maximum signatures: 2^h - 1 = 2^20 - 1 - * XMSS^MT has bigger signature and secret key (secret is not transfer), but better speed - */ - #if TREE_LEVEL == 0 - - #define XMSS_OID "XMSSMT-SHA2_20/2_256" - - #define XMSS_PUBLICKEYBYTES 64 - #define XMSS_SECRETKEYBYTES_SMALL 131 - #define XMSS_SECRETKEYBYTES 5998 - - #define XMSS_SIGNBYTES 4963 - - /* - * Maximum signatures: 2^h - 1 = 2^40 - 1 - * XMSS^MT has bigger signature and secret key (secret is not transfer), but better speed - */ - #elif TREE_LEVEL == 1 - - #define XMSS_OID "XMSSMT-SHA2_40/2_256" - - #define XMSS_PUBLICKEYBYTES 64 - #define XMSS_SECRETKEYBYTES_SMALL 133 - #define XMSS_SECRETKEYBYTES 9600 - - #define XMSS_SIGNBYTES 5605 - - /* - * Maximum signatures: 2^h - 1 = 2^60 - 1 - * XMSS^MT has bigger signature and secret key (secret is not transfer), but better speed - */ - #elif TREE_LEVEL == 2 - - #define XMSS_OID "XMSSMT-SHA2_60/3_256" - - #define XMSS_PUBLICKEYBYTES 64 - #define XMSS_SECRETKEYBYTES_SMALL 136 - #define XMSS_SECRETKEYBYTES 16629 - - #define XMSS_SIGNBYTES 8392 - - - #else - - #error "Unspecified TREE_LEVEL {0,1,2}" - - #endif - -#endif - -#if XMSSMT == 1 - #define XMSS_PARSE_OID xmssmt_parse_oid - #define XMSS_STR_TO_OID xmssmt_str_to_oid - #define XMSS_KEYPAIR xmssmt_keypair - #define XMSS_SIGN xmssmt_sign - #define XMSS_SIGN_OPEN xmssmt_sign_open - #define XMSS_REMAINING_SIG xmssmt_remaining_signatures - #define XMSS_TOTAL_SIG xmssmt_total_signatures -#else - #define XMSS_PARSE_OID xmss_parse_oid - #define XMSS_STR_TO_OID xmss_str_to_oid - #define XMSS_KEYPAIR xmss_keypair - #define XMSS_SIGN xmss_sign - #define XMSS_SIGN_OPEN xmss_sign_open - #define XMSS_REMAINING_SIG xmss_remaining_signatures - #define XMSS_TOTAL_SIG xmss_total_signatures -#endif - -#if XMSS_SECRETKEYBYTES_SMALL_ENABLE -#define CRYPTO_SECRETKEYBYTES (XMSS_SECRETKEYBYTES_SMALL + XMSS_OID_LEN) -#define CRYPTO_ALGNAME XMSS_OID -#else -#define CRYPTO_SECRETKEYBYTES (XMSS_SECRETKEYBYTES + XMSS_OID_LEN) -#define CRYPTO_ALGNAME (XMSS_OID "_fast") -#endif - -#define CRYPTO_PUBLICKEYBYTES (XMSS_PUBLICKEYBYTES + XMSS_OID_LEN) -#define CRYPTO_BYTES XMSS_SIGNBYTES - -#endif diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index 1cf29900f3..d0f6ae6300 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -494,4 +494,13 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(unsigned l #endif +/* + * Secret key functions + */ +/* Serialize XMSS secret key data into a byte string */ +OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr); + +/* Deserialize XMSS byte string into an XMSS secret key data */ +OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf); + #endif /* OQS_SIG_STFL_XMSS_H */ diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c new file mode 100644 index 0000000000..9f50754ed2 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT + +#include +#include +#include "sig_stfl_xmss.h" + +/* Serialize XMSS secret key data into a byte string */ +OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr) { + if (sk == NULL || sk_len == NULL || sk_buf_ptr == NULL) { + return OQS_ERROR; + } + + uint8_t *sk_buf = malloc(sk->length_secret_key * sizeof(uint8_t)); + if (sk_buf == NULL) { + return OQS_ERROR; + } + + // Simply copy byte string of secret_key_data + memcpy(sk_buf, sk->secret_key_data, sk->length_secret_key); + + *sk_buf_ptr = sk_buf; + *sk_len = sk->length_secret_key; + + return OQS_SUCCESS; +} + +/* Deserialize XMSS byte string into an XMSS secret key data */ +OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf) { + if (sk == NULL || sk_buf == NULL || (sk_len != sk->length_secret_key)) { + return OQS_ERROR; + } + + if (sk->secret_key_data != NULL) { + // Key data already present + // We dont want to trample over data + return OQS_ERROR; + } + + // Assume key data is not present + sk->secret_key_data = malloc(sk_len); + if (sk->secret_key_data == NULL) { + return OQS_ERROR; + } + + memcpy(sk->secret_key_data, sk_buf, sk_len); + + return OQS_SUCCESS; +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c index 4ff8f24e7d..83d3c4b275 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c @@ -56,8 +56,18 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } + memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c index f467b67595..b3f72ef038 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H16_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c index ab7a74410f..660f8c797c 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H20_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c index b38207c86b..735cd012f2 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H10_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c index 050026311a..de64237cb1 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H16_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c index b5084201fd..0917020588 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H20_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c index ac43b57b3c..708981b3ac 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H10_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c index 596939f155..e6381f0209 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H16_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c index 37da02a13b..4b80a0c938 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H20_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c index f0d27e2033..bdb3243bfc 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H10_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c index 38cd5603a9..7b6b352720 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H16_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c index ed1989876e..fa6c7cc060 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H20_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c index 792d7a3559..60cb3dd8ad 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_2_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c index 4a1d1cad52..cd698b3d44 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_4_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c index 9bb9c61445..4b6d0a9021 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_2_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c index 64a2da1331..c42a6db25f 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_4_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c index 13843351ee..c29b43d2d1 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_8_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c index 06873a58db..7e53563c2d 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_12_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c index 67183fee79..c1ed78f606 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_3_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c index 8ab9134684..bc644a4223 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_6_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c index 279146a010..807eae702d 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_2_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c index 961fd8c0a7..1082dcd999 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_4_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c index a72d9b7e67..01d70f3a37 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_2_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c index 64c2f8cea3..d5935a5752 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_4_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c index 7b1c137e8a..743ff4cb96 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_8_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c index 41c4317ad9..c571bbe7ea 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_12_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c index 5a38219f83..83ed6b0b63 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_3_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c index 9c860051d7..a8c3ed07af 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c @@ -56,8 +56,17 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_6_new(void) { sk->sigs_left = NULL; sk->sigs_total = NULL; + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + // Initialize the key with length_secret_key amount of bytes. sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } memset(sk->secret_key_data, 0, sk->length_secret_key); sk->free_key = OQS_SECRET_KEY_XMSS_free; From a85a9aa172647fa42fbc3cf63a477a691ecb68c5 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Fri, 22 Sep 2023 12:00:43 -0400 Subject: [PATCH 14/68] Stateful sigs secret key storage callback (#1553) * Callback implemention updating secret key. * Block XMSS from secret key tests until after support code has been added. * Remove / from test file names * Format * Address SA issues * Fix mem leak * Fix mem leak * Address various comments * Fix SA issue --- src/sig_stfl/lms/sig_stfl_lms.c | 24 +- src/sig_stfl/lms/sig_stfl_lms.h | 9 +- src/sig_stfl/lms/sig_stfl_lms_functions.c | 79 ++++- src/sig_stfl/sig_stfl.c | 33 ++ src/sig_stfl/sig_stfl.h | 58 +++- src/sig_stfl/xmss/sig_stfl_xmss.h | 2 +- .../xmss/sig_stfl_xmss_secret_key_functions.c | 8 +- tests/test_sig_stfl.c | 281 ++++++++++++++---- 8 files changed, 404 insertions(+), 90 deletions(-) diff --git a/src/sig_stfl/lms/sig_stfl_lms.c b/src/sig_stfl/lms/sig_stfl_lms.c index 6ae6d1dde6..582b50b3e4 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.c +++ b/src/sig_stfl/lms/sig_stfl_lms.c @@ -7,6 +7,14 @@ #include "sig_stfl_lms_wrap.h" #include "sig_stfl_lms.h" +/* Convert LMS secret key object to byte string */ +static OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr); + +/* Insert lms byte string in an LMS secret key object */ +static OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); + +static void OQS_SECRET_KEY_LMS_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); + // ======================== LMS-SHA256 H5/W1 ======================== // OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -88,13 +96,15 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void) { /* * Set Secret Key Saving Function */ - sk->save_secret_key = NULL; + sk->secure_store_scrt_key = NULL; /* * Set Secret Key free function */ sk->free_key = OQS_SECRET_KEY_LMS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + return sk; } @@ -103,11 +113,17 @@ void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk) { } /* Convert LMS secret key object to byte string */ -OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr) { +static OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr) { return oqs_serialize_lms_key(sk, sk_len, sk_buf_ptr); } /* Insert lms byte string in an LMS secret key object */ -OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf) { - return oqs_deserialize_lms_key(sk, sk_len, sk_buf); +static OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context) { + return oqs_deserialize_lms_key(sk, sk_len, sk_buf, context); +} + +static void OQS_SECRET_KEY_LMS_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context) { + if (sk && store_cb && context) { + oqs_lms_key_set_store_cb(sk, store_cb, context); + } } diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h index 76de39a6e3..75ce739238 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.h +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -14,12 +14,6 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void); -/* Convert LMS secret key object to byte string */ -OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr); - -/* Insert lms byte string in an LMS secret key object */ -OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t key_len, const uint8_t *sk_buf); - OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -39,7 +33,8 @@ int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, const uint8_t *sm, si void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk); OQS_STATUS oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_key); -OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf); +OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); +void oqs_lms_key_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); // ---------------------------- FUNCTIONS INDEPENDENT OF VARIANT ----------------------------------------- diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index ea4f42d8af..d918cbdac4 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -40,25 +40,70 @@ typedef struct OQS_LMS_KEY_DATA { /* secret key data */ uint8_t *sec_key; + + /* app specific */ + void *context; } oqs_lms_key_data; OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signature_length, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || message == NULL || signature == NULL) { + OQS_STATUS rc_keyupdate = OQS_ERROR; + oqs_lms_key_data *lms_key_data = NULL; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf = NULL; + size_t sk_key_buf_len = 0; + void *context; + + if (secret_key == NULL || message == NULL || signature == NULL || signature_length == NULL) { return OQS_ERROR; } - /* TODO: Make sure we have a way to update the private key */ + /* + * Don't even attempt signing without a way to safe the updated private key + */ + if (secret_key->secure_store_scrt_key == NULL) { + goto err; + } + + lms_key_data = (oqs_lms_key_data *)secret_key->secret_key_data; + if (lms_key_data == NULL) { + goto err; + } if (oqs_sig_stfl_lms_sign(secret_key, signature, signature_length, message, message_len) != 0) { - return OQS_ERROR; + goto err; + } + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = oqs_serialize_lms_key(sk, &sk_key_buf_len, &sk_key_buf); + if (rc_keyupdate != OQS_SUCCESS) { + goto err; + } + + context = lms_key_data->context; + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf, sk_key_buf_len, context); + if (rc_keyupdate != OQS_SUCCESS) { + goto err; } - /* TODO: Update private key */ + OQS_MEM_secure_free(sk_key_buf, sk_key_buf_len); return OQS_SUCCESS; + +err: + OQS_MEM_secure_free(sk_key_buf, sk_key_buf_len); + if (*signature_length) { + memset(signature, 0, *signature_length); + } + *signature_length = 0; + return OQS_ERROR; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_verify(const uint8_t *message, size_t message_len, @@ -356,11 +401,6 @@ void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk) { //TODO: cleanup lock_key - if (sk->sig) { - OQS_MEM_insecure_free(sk->sig); - sk->sig = NULL; - } - if (sk->secret_key_data) { oqs_lms_key_data *key_data = (oqs_lms_key_data *)sk->secret_key_data; if (key_data) { @@ -426,7 +466,7 @@ OQS_STATUS oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_l * Writes secret key + aux data if present * key_len is priv key length + aux length */ -OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf) { +OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context) { oqs_lms_key_data *lms_key_data = NULL; uint8_t *lms_sk = NULL; @@ -451,11 +491,11 @@ OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_ param_set_t lm_ots_type[ MAX_HSS_LEVELS ]; // validate sk_buf for lms params - if (hss_get_parameter_set(&levels, - lm_type, - lm_ots_type, - NULL, - (void *)sk_buf)) { + if (!hss_get_parameter_set(&levels, + lm_type, + lm_ots_type, + NULL, + (void *)sk_buf)) { return OQS_ERROR; } @@ -469,6 +509,7 @@ OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_ memcpy(lms_sk, sk_buf, lms_sk_len); lms_key_data->sec_key = lms_sk; lms_key_data->len_sec_key = lms_sk_len; + lms_key_data->context = context; if (aux_buf_len) { lms_aux = malloc(aux_buf_len * sizeof(uint8_t)); @@ -494,3 +535,11 @@ OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_ success: return OQS_SUCCESS; } + +void oqs_lms_key_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context) { + oqs_lms_key_data *lms_key_data = (oqs_lms_key_data *)sk->secret_key_data; + if (lms_key_data) { + lms_key_data->context = context; + sk->secure_store_scrt_key = store_cb; + } +} diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index c77139e20a..5480af5dd2 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -683,3 +683,36 @@ OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk) { } OQS_MEM_secure_free(sk, sizeof(sk)); } + +OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context) { + if (sk) { + if (sk->set_scrt_key_store_cb) { + sk->set_scrt_key_store_cb(sk, store_cb, context); + } + } +} + +/* Convert secret key object to byte string */ +OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf) { + if ((sk == NULL) || (sk_len == NULL) || (sk_buf == NULL)) { + return 0; + } + if (sk->serialize_key) { + return sk->serialize_key(sk, sk_len, sk_buf); + } else { + return 0; + } +} + +/* Insert secret key byte string in an Stateful secret key object */ +OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t key_len, const uint8_t *sk_buf, void *context) { + if ((sk == NULL) || (sk_buf == NULL)) { + return OQS_ERROR; + } + + if (sk->deserialize_key == NULL) { + return OQS_ERROR; + } + + return sk->deserialize_key(sk, key_len, sk_buf, context); +} diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index eb1b4088d5..1320ff02d3 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -61,6 +61,15 @@ extern "C" { typedef struct OQS_SIG_STFL_SECRET_KEY OQS_SIG_STFL_SECRET_KEY; +/** + * Application provided function to securely store data + * @param[in] sk_buf pointer to the data to be saved + * @param[in] buf_len length of the the data to be store + * @param[out] context pointer to application relevant data. + * @retrun OQS_SUCCESS if successful, otherwise OQS_ERROR + */ +typedef OQS_STATUS (*secure_store_sk)(/*const*/ uint8_t *sk_buf, size_t buf_len, void *context); + /** * Returns identifiers for available signature schemes in liboqs. Used with OQS_SIG_STFL_new. * @@ -216,13 +225,14 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { /** * set Secret Key to internal structure Function * - * @param[out] sk OQS_SIG_STFL_SECRET_KEY object - * @param[in] sk_len length of the returned byte string - * @param[in] sk_buf The secret key represented as OQS_SIG_STFL_SECRET_KEY object + * @param[in] sk OQS_SIG_STFL_SECRET_KEY object + * @param[in] key_len length of the returned byte string + * @param[in] sk_buf The secret key data to populate key obj + * @param[in] context application specific data * @returns status of the operation populated with key material none-zero length. Caller * deletes the buffer. if sk_buf is NULL the function returns the length */ - OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf); + OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); /** * Secret Key Locking Function @@ -241,12 +251,16 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { OQS_STATUS (*unlock_key)(OQS_SIG_STFL_SECRET_KEY *sk); /** - * Secret Key Saving Function + * Store Secret Key Function + * Callback function used to securely store key data + * @param[in] sk_buf The serialized secret key data to secure store + * @param[in] buf_len length of data to secure + * @param[in] context aides the secure writing of data * - * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object * @return OQS_SUCCESS or OQS_ERROR + * Idealy written to secure device */ - OQS_STATUS (*save_secret_key)(const OQS_SIG_STFL_SECRET_KEY *sk); + OQS_STATUS (*secure_store_scrt_key)(/*const*/ uint8_t *sk_buf, size_t buf_len, void *context); /** * Secret Key free internal variant specific data @@ -255,6 +269,15 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { * @return none */ void (*free_key)(OQS_SIG_STFL_SECRET_KEY *sk); + + /** + * Set Secret Key store callback Function + * + * @param[in] sk secret key pointer to be updated + * @param[in] store_cb callback pointer + * @param[in] context secret key specific data/identifier + */ + void (*set_scrt_key_store_cb)(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); } OQS_SIG_STFL_SECRET_KEY; /** @@ -281,7 +304,7 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name); * @param[out] secret_key The secret key represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ -OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk); +OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); /** * Signature generation algorithm. @@ -365,6 +388,25 @@ void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk); */ OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk); + +/** + * OQS_SIG_STFL_SECRET_KEY_SET_store_cb . + * + * Can be called after creating a new stateful secret key has been generated. + * Allows the lib to securely store and update secret key after a sign operation. + * + * @param[in] sk secret key pointer to be updated + * @param[in] store_cb callback pointer + * @param[in] context secret key specific data/identifier + * + */ +void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); + +OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf); + +/* Insert lms byte string in an LMS secret key object */ +OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf, void *context); + #if defined(__cplusplus) } // extern "C" #endif diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index d0f6ae6300..54006043e1 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -501,6 +501,6 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(unsigned l OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr); /* Deserialize XMSS byte string into an XMSS secret key data */ -OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf); +OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); #endif /* OQS_SIG_STFL_XMSS_H */ diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c index 9f50754ed2..4a47c938c3 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c @@ -4,6 +4,12 @@ #include #include "sig_stfl_xmss.h" +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + /* Serialize XMSS secret key data into a byte string */ OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr) { if (sk == NULL || sk_len == NULL || sk_buf_ptr == NULL) { @@ -25,7 +31,7 @@ OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, } /* Deserialize XMSS byte string into an XMSS secret key data */ -OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf) { +OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, XMSS_UNUSED_ATT void *context) { if (sk == NULL || sk_buf == NULL || (sk_len != sk->length_secret_key)) { return OQS_ERROR; } diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index b496457b99..0a0f08cd4b 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -10,6 +10,7 @@ #include #include +#include "tmp_store.c" #if OQS_USE_PTHREADS_IN_TESTS #include @@ -32,6 +33,25 @@ */ #define MAX_MARKER_LEN 50 +/* + * Write stateful secret keys to disk. + */ +static OQS_STATUS test_save_secret_key(uint8_t *key_buf, size_t buf_len, void *context) { + uint8_t *kb = key_buf; + + if (key_buf && context && buf_len != 0) { + if (oqs_fstore("sk", (const char *)context, kb, buf_len) == OQS_SUCCESS) { + printf("\n================================================================================\n"); + printf("Updated STFL SK <%s>.\n", (const char *)context); + printf("================================================================================\n"); + return OQS_SUCCESS; + } else { + return OQS_ERROR; + } + } + return OQS_ERROR; +} + // // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) // @@ -126,6 +146,11 @@ int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, char *str) { OQS_STATUS sig_stfl_keypair_from_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { OQS_STATUS rc; + + if ((sig == NULL) || (public_key == NULL) || (secret_key == NULL)) { + return OQS_ERROR; + } + rc = OQS_SIG_STFL_keypair(sig, public_key, secret_key); OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); if (rc != OQS_SUCCESS) { @@ -255,10 +280,20 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char OQS_SIG_STFL *sig = NULL; uint8_t *public_key = NULL; OQS_SIG_STFL_SECRET_KEY *secret_key = NULL; + const OQS_SIG_STFL_SECRET_KEY *sk = NULL; + OQS_SIG_STFL_SECRET_KEY *secret_key_rd = NULL; uint8_t *message = NULL; size_t message_len = 100; uint8_t *signature = NULL; size_t signature_len; + + uint8_t *sk_buf = NULL; + uint8_t *read_pk_buf = NULL; + char *context = NULL; + const char *file_store = NULL; + size_t sk_buf_len = 0; + size_t read_pk_len = 0; + OQS_STATUS rc, ret = OQS_ERROR; //The magic numbers are random values. @@ -277,6 +312,7 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char printf("================================================================================\n"); secret_key = OQS_SIG_STFL_SECRET_KEY_new(sig->method_name); + secret_key_rd = OQS_SIG_STFL_SECRET_KEY_new(sig->method_name); public_key = malloc(sig->length_public_key + 2 * sizeof(magic_t)); message = malloc(message_len + 2 * sizeof(magic_t)); signature = malloc(sig->length_signature + 2 * sizeof(magic_t)); @@ -307,12 +343,67 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char * Some keypair generation is fast, so we only read keypair from KATs for slow XMSS parameters */ rc = sig_stfl_KATs_keygen(sig, public_key, secret_key, katfile); + sk = secret_key; OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); if (rc != OQS_SUCCESS) { fprintf(stderr, "ERROR: OQS_SIG_STFL_keypair failed\n"); goto err; } + rc = OQS_SECRET_KEY_STFL_serialize_key(sk, &sk_buf_len, &sk_buf); + if (rc != OQS_SUCCESS) { + goto err; + } + + if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_2) == 0) { + file_store = "XMSSMT-SHA2_20-2_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_4) == 0) { + file_store = "XMSSMT-SHA2_20-4_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2) == 0) { + file_store = "XMSSMT-SHA2_40-2_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_4) == 0) { + file_store = "XMSSMT-SHA2_40-4_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_8) == 0) { + file_store = "XMSSMT-SHA2_40-8_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3) == 0) { + file_store = "XMSSMT-SHA2_60-3_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_6) == 0) { + file_store = "XMSSMT-SHA2_60-6_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_12) == 0) { + file_store = "XMSSMT-SHA2_60-12_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h20_2) == 0) { + file_store = "XMSSMT-SHAKE_20-2_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h20_4) == 0) { + file_store = "XMSSMT-SHAKE_20-4_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2) == 0) { + file_store = "XMSSMT-SHAKE_40-2_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_4) == 0) { + file_store = "XMSSMT-SHAKE_40-4_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_8) == 0) { + file_store = "XMSSMT-SHAKE_40-8_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3) == 0) { + file_store = "XMSSMT-SHAKE_60-3_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_6) == 0) { + file_store = "XMSSMT-SHAKE_60-6_256"; + } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_12) == 0) { + file_store = "XMSSMT-SHAKE_60-12_256"; + } else { + file_store = sig->method_name; + } + + /* write key pair to disk */ + if (oqs_fstore("sk", file_store, sk_buf, sk_buf_len) != OQS_SUCCESS) { + goto err; + } + + if (oqs_fstore("pk", file_store, public_key, sig->length_public_key) != OQS_SUCCESS) { + goto err; + } + + /* set context and secure store callback */ + context = strdup(((file_store))); + OQS_SIG_STFL_SECRET_KEY_SET_store_cb(secret_key, test_save_secret_key, (void *)context); + rc = OQS_SIG_STFL_sign(sig, signature, &signature_len, message, message_len, secret_key); OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); if (rc != OQS_SUCCESS) { @@ -329,6 +420,17 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char goto err; } + /* Read public key and re-test verify.*/ + read_pk_buf = malloc(sig->length_public_key); + if (oqs_fload("pk", file_store, read_pk_buf, sig->length_public_key, &read_pk_len) != OQS_SUCCESS) { + goto err; + } + rc = OQS_SIG_STFL_verify(sig, message, message_len, signature, signature_len, read_pk_buf); + OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "ERROR: 2nd Verify with restored public key OQS_SIG_STFL_verify failed\n"); + } + /* modify the signature to invalidate it */ OQS_randombytes(signature, signature_len); OQS_TEST_CT_DECLASSIFY(signature, signature_len); @@ -362,6 +464,7 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char cleanup: OQS_SIG_STFL_SECRET_KEY_free(secret_key); + OQS_SIG_STFL_SECRET_KEY_free(secret_key_rd); if (public_key) { OQS_MEM_insecure_free(public_key - sizeof(magic_t)); } @@ -371,80 +474,97 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char if (signature) { OQS_MEM_insecure_free(signature - sizeof(magic_t)); } + OQS_MEM_secure_free(sk_buf, sk_buf_len); OQS_SIG_STFL_free(sig); + OQS_MEM_insecure_free(read_pk_buf); + OQS_MEM_insecure_free(context); return ret; } static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { OQS_STATUS rc = OQS_SUCCESS; OQS_SIG_STFL_SECRET_KEY *sk = NULL; + OQS_SIG_STFL_SECRET_KEY *sk_frm_file = NULL; OQS_SIG_STFL *sig_obj = NULL; uint8_t *public_key = NULL; + uint8_t *frm_file_sk_buf = NULL; + uint8_t *to_file_sk_buf = NULL; + size_t frm_file_sk_len = 0; + size_t to_file_sk_len = 0; + char *context = NULL; + char *context_2 = NULL; /* * Temporarily skip algs with long key generation times. */ - if (0) { - -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 - } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 - } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { + if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) != 0) { goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { - goto skip_test; -#endif } else { goto keep_going; } + +// if (0) { +// +//#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 +// } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { +// goto skip_test; +//#endif +//#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 +// } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { +// goto skip_test; +//#endif +// +//#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 +// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { +// goto skip_test; +//#endif +//#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 +// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { +// goto skip_test; +//#endif +// +//#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 +// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { +// goto skip_test; +//#endif +//#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 +// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { +// goto skip_test; +//#endif +// +//#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 +// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { +// goto skip_test; +//#endif +//#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 +// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { +// goto skip_test; +//#endif +// +//#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 +// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { +// goto skip_test; +//#endif +//#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 +// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { +// goto skip_test; +//#endif +// +//#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 +// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { +// goto skip_test; +//#endif +//#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 +// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { +// goto skip_test; +//#endif +// } else { +// goto keep_going; +// } + skip_test: printf("Skip slow test %s.\n", method_name); return rc; @@ -479,12 +599,58 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { rc = OQS_SIG_STFL_keypair(sig_obj, public_key, sk); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "OQS STFL key gen failed.\n"); + goto err; + } + + /* write sk key to disk */ + rc = OQS_SECRET_KEY_STFL_serialize_key(sk, &to_file_sk_len, &to_file_sk_buf); + if (rc != OQS_SUCCESS) { + goto err; + } + + if (oqs_fstore("sk", sig_obj->method_name, to_file_sk_buf, to_file_sk_len) != OQS_SUCCESS) { + goto err; + } + if (!sk->secret_key_data) { fprintf(stderr, "ERROR: OQS_SECRET_KEY_new incomplete.\n"); OQS_MEM_insecure_free(public_key); goto err; } + /* set context and secure store callback */ + if (sk->set_scrt_key_store_cb) { + context = strdup(((method_name))); + sk->set_scrt_key_store_cb(sk, test_save_secret_key, (void *)context); + } + + + /* read secret key from disk */ + frm_file_sk_buf = malloc(to_file_sk_len); + if (oqs_fload("sk", method_name, frm_file_sk_buf, to_file_sk_len, &frm_file_sk_len) != OQS_SUCCESS) { + goto err; + } + if (to_file_sk_len != frm_file_sk_len) { + fprintf(stderr, "ERROR: OQS_SECRET_KEY_new stored length not equal read length\n"); + goto err; + } + + sk_frm_file = OQS_SIG_STFL_SECRET_KEY_new(method_name); + if (sk_frm_file == NULL) { + fprintf(stderr, "ERROR: 2nd OQS_SECRET_KEY_new failed\n"); + goto err; + } + + context_2 = strdup(((method_name))); + rc = OQS_SECRET_KEY_STFL_deserialize_key(sk_frm_file, frm_file_sk_len, frm_file_sk_buf, (void *)context_2); + + if (rc != OQS_SUCCESS) { + fprintf(stderr, "OQS restore %s from file failed.\n", method_name); + goto err; + } + printf("Secret Key created as expected.\n"); goto end_it; @@ -493,8 +659,14 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { end_it: OQS_SIG_STFL_SECRET_KEY_free(sk); + OQS_SIG_STFL_SECRET_KEY_free(sk_frm_file); + OQS_MEM_insecure_free(public_key); + OQS_MEM_secure_free(to_file_sk_buf, to_file_sk_len); + OQS_MEM_secure_free(frm_file_sk_buf, frm_file_sk_len); OQS_SIG_STFL_free(sig_obj); + OQS_MEM_insecure_free(context); + OQS_MEM_insecure_free(context_2); return rc; } @@ -531,6 +703,7 @@ void *test_wrapper(void *arg) { int main(int argc, char **argv) { OQS_init(); + oqs_fstore_init(); printf("Testing stateful signature algorithms using liboqs version %s\n", OQS_version()); From 3934949d260909e22cdf347cfc32e3231ea30214 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Thu, 28 Sep 2023 13:30:50 -0400 Subject: [PATCH 15/68] Na statful sig lock (#1559) * Add mutex protection around access to stateful secret key * Formatting. * Clean up warnings * Exclude XMSS from some tests temporarily * Remove commented code. * Document use of callback functions for secret key thread safe protection and storage. --- src/sig_stfl/lms/sig_stfl_lms.c | 12 +- src/sig_stfl/lms/sig_stfl_lms_functions.c | 31 +- src/sig_stfl/sig_stfl.c | 49 +++ src/sig_stfl/sig_stfl.h | 110 +++++- tests/test_sig_stfl.c | 386 +++++++++++++++++++++- 5 files changed, 572 insertions(+), 16 deletions(-) diff --git a/src/sig_stfl/lms/sig_stfl_lms.c b/src/sig_stfl/lms/sig_stfl_lms.c index 582b50b3e4..e6c30e66d5 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.c +++ b/src/sig_stfl/lms/sig_stfl_lms.c @@ -114,7 +114,17 @@ void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk) { /* Convert LMS secret key object to byte string */ static OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr) { - return oqs_serialize_lms_key(sk, sk_len, sk_buf_ptr); + OQS_STATUS status; + if (sk->lock_key && sk->mutex) { + sk->lock_key(sk->mutex); + } + + status = oqs_serialize_lms_key(sk, sk_len, sk_buf_ptr); + + if (sk->unlock_key && sk->mutex) { + sk->unlock_key(sk->mutex); + } + return status; } /* Insert lms byte string in an LMS secret key object */ diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index d918cbdac4..59265f3110 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -47,7 +47,7 @@ typedef struct OQS_LMS_KEY_DATA { OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signature_length, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - + OQS_STATUS status = OQS_ERROR; OQS_STATUS rc_keyupdate = OQS_ERROR; oqs_lms_key_data *lms_key_data = NULL; const OQS_SIG_STFL_SECRET_KEY *sk; @@ -59,6 +59,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signatu return OQS_ERROR; } + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + /* * Don't even attempt signing without a way to safe the updated private key */ @@ -94,16 +99,23 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signatu goto err; } - OQS_MEM_secure_free(sk_key_buf, sk_key_buf_len); - return OQS_SUCCESS; + status = OQS_SUCCESS; + goto passed; err: - OQS_MEM_secure_free(sk_key_buf, sk_key_buf_len); if (*signature_length) { memset(signature, 0, *signature_length); } *signature_length = 0; - return OQS_ERROR; + +passed: + OQS_MEM_secure_free(sk_key_buf, sk_key_buf_len); + + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_verify(const uint8_t *message, size_t message_len, @@ -128,8 +140,17 @@ OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } + /* Lock secret key to ensure data integrity use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } remain = 0; + + /* Unlock secret key */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } return OQS_SUCCESS; } diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 5480af5dd2..023d4e1df3 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -716,3 +716,52 @@ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY * return sk->deserialize_key(sk, key_len, sk_buf, context); } + + + +/* OQS_SIG_STFL_SECRET_KEY_SET_lock callback function*/ +OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_lock(OQS_SIG_STFL_SECRET_KEY *sk, lock_key lock) { + if (sk == NULL) { + return; + } + sk->lock_key = lock; +} + +/* OQS_SIG_STFL_SECRET_KEY_SET_unlock callback function */ +OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_unlock(OQS_SIG_STFL_SECRET_KEY *sk, unlock_key unlock) { + if (sk == NULL) { + return; + } + sk->unlock_key = unlock; +} + +/* OQS_SIG_STFL_SECRET_KEY_SET_mutex */ +OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void *mutex) { + if (sk == NULL) { + return; + } + sk->mutex = mutex; +} + +/* OQS_SIG_STFL_SECRET_KEY_lock */ +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL) { + return OQS_ERROR; + } + if (sk->lock_key == NULL) { + return OQS_SUCCESS; + } + + return (sk->lock_key(sk->mutex)); +} + +/* OQS_SIG_STFL_SECRET_KEY_unlock */ +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL) { + return OQS_ERROR; + } + if (sk->unlock_key == NULL) { + return OQS_SUCCESS; + } + return (sk->unlock_key(sk->mutex)); +} diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index 1320ff02d3..a9bffdfdd8 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -16,6 +16,29 @@ #include +/* + * Developer's Notes: + * Stateful signatures are based on one-time use of a secret key. A pool of secret keys are created for this purpose. + * The state of these keys are tracked to ensure that they are used only once to generate a signature. + * + * As such, product specific environments do play a role in ensuring the safety of the keys. + * Secret keys must be store securely. + * The key index/counter must be updated after each signature generation. + * Secret key must be protected in a thread-save manner. + * + * Application therefore are required to provide environment specific callback functions to + * - store private key + * - lock/unlock private key + * + * See below for details + * OQS_SIG_STFL_SECRET_KEY_SET_lock + * OQS_SIG_STFL_SECRET_KEY_SET_unlock + * OQS_SIG_STFL_SECRET_KEY_SET_mutex + * OQS_SIG_STFL_SECRET_KEY_SET_store_cb + * + */ + + #if defined(__cplusplus) extern "C" { #endif @@ -66,9 +89,25 @@ typedef struct OQS_SIG_STFL_SECRET_KEY OQS_SIG_STFL_SECRET_KEY; * @param[in] sk_buf pointer to the data to be saved * @param[in] buf_len length of the the data to be store * @param[out] context pointer to application relevant data. - * @retrun OQS_SUCCESS if successful, otherwise OQS_ERROR + * return OQS_SUCCESS if successful, otherwise OQS_ERROR + */ +typedef OQS_STATUS (*secure_store_sk)(uint8_t *sk_buf, size_t buf_len, void *context); + +/** + * Application provided function to lock secret key object serialize access + * @param[in] sk pointer to secret key object to lock + * @param[in] mutex pointer to mutex struct + * return OQS_SUCCESS if successful, otherwise OQS_ERROR + */ +typedef OQS_STATUS (*lock_key)(void *mutex); + +/** + * Application provided function to unlock secret key object + * @param[in] sk pointer to secret key object to unlock + * @param[in] mutex pointer to mutex struct + * return OQS_SUCCESS if successful, otherwise OQS_ERROR */ -typedef OQS_STATUS (*secure_store_sk)(/*const*/ uint8_t *sk_buf, size_t buf_len, void *context); +typedef OQS_STATUS (*unlock_key)(void *mutex); /** * Returns identifiers for available signature schemes in liboqs. Used with OQS_SIG_STFL_new. @@ -205,6 +244,9 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { /* The variant specific secret key data */ void *secret_key_data; + /* mutual exclusion struct */ + void *mutex; + /* Function that returns the total number of signatures for the secret key */ uint64_t (*sigs_total)(const OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -237,18 +279,18 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { /** * Secret Key Locking Function * - * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object + * @param[in] mutex application defined mutex * @return OQS_SUCCESS or OQS_ERROR */ - OQS_STATUS (*lock_key)(OQS_SIG_STFL_SECRET_KEY *sk); + OQS_STATUS (*lock_key)(void *mutex); /** * Secret Key Unlocking / Releasing Function * - * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object + * @param[in] mutex application defined mutex * @return OQS_SUCCESS or OQS_ERROR */ - OQS_STATUS (*unlock_key)(OQS_SIG_STFL_SECRET_KEY *sk); + OQS_STATUS (*unlock_key)(void *mutex); /** * Store Secret Key Function @@ -260,7 +302,7 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { * @return OQS_SUCCESS or OQS_ERROR * Idealy written to secure device */ - OQS_STATUS (*secure_store_scrt_key)(/*const*/ uint8_t *sk_buf, size_t buf_len, void *context); + OQS_STATUS (*secure_store_scrt_key)(uint8_t *sk_buf, size_t buf_len, void *context); /** * Secret Key free internal variant specific data @@ -388,6 +430,60 @@ void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk); */ OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk); +/** + * OQS_SIG_STFL_SECRET_KEY_SET_lock . + * + * Sets function to prevent multiple processes from using the sk at the same time. + * + * @param[in] sk secret key pointer to be updated + * @param[in] lock function pointer + * + */ +void OQS_SIG_STFL_SECRET_KEY_SET_lock(OQS_SIG_STFL_SECRET_KEY *sk, lock_key lock); + +/** + * OQS_SIG_STFL_SECRET_KEY_SET_unlock . + * + * Sets function to prevent multiple processes from using the sk at the same time. + * + * @param[in] sk secret key pointer to be updated + * @param[in] unlock function pointer + * + */ +void OQS_SIG_STFL_SECRET_KEY_SET_unlock(OQS_SIG_STFL_SECRET_KEY *sk, unlock_key unlock); + +/** + * OQS_SIG_STFL_SECRET_KEY_SET_mutex . + * + * Sets function to prevent multiple processes from using the sk at the same time. + * + * @param[in] sk secret key pointer to be updated + * @param[in] mutex function pointer + * + */ +void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void *mutex); + +/** + * OQS_SIG_STFL_SECRET_KEY_lock . + * + * Locks sk so only one application that holds the lock can access it. + * + * @param[in] sk secret key pointer to be locked + * @return OQS_SUCCESS if successful, or OQS_ERROR if the object fails to apply the lock + * + */ +OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk); + +/** + * OQS_SIG_STFL_SECRET_KEY_unlock . + * + * Unlocks the resouces so that th enext process can access it. + * + * @param[in] sk secret key pointer + * @return OQS_SUCCESS if successful, or OQS_ERROR if the object fails to release the lock + * + */ +OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk); /** * OQS_SIG_STFL_SECRET_KEY_SET_store_cb . diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 0a0f08cd4b..8a3cb2252d 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -9,6 +9,9 @@ #include #include +#include +#include + #include #include "tmp_store.c" @@ -33,6 +36,18 @@ */ #define MAX_MARKER_LEN 50 +static OQS_SIG_STFL_SECRET_KEY *lock_test_sk = NULL; +static OQS_SIG_STFL *lock_test_sig_obj = NULL; +static uint8_t *lock_test_public_key = NULL; +static char *lock_test_context = NULL; +static uint8_t *signature_1 = NULL; +static uint8_t *signature_2 = NULL; +static size_t signature_len_1; +static size_t signature_len_2; +static uint8_t message_1[] = "The quick brown fox ..."; +static uint8_t message_2[] = "The quick brown fox jumped from the tree."; +static pthread_mutex_t *test_sk_lock = NULL; + /* * Write stateful secret keys to disk. */ @@ -52,6 +67,38 @@ static OQS_STATUS test_save_secret_key(uint8_t *key_buf, size_t buf_len, void *c return OQS_ERROR; } +#if OQS_USE_PTHREADS_IN_TESTS +static OQS_STATUS lock_sk_key(void *mutex) { + if (mutex == NULL) { + return OQS_ERROR; + } + + if (!(pthread_mutex_lock((pthread_mutex_t *)mutex))) { + return OQS_SUCCESS; + } + return OQS_ERROR; +} + +static OQS_STATUS unlock_sk_key(void *mutex) { + if (mutex == NULL) { + return OQS_ERROR; + } + + if (!(pthread_mutex_unlock((pthread_mutex_t *)mutex))) { + return OQS_SUCCESS; + } + return OQS_ERROR; +} +#else +static OQS_STATUS lock_sk_key(void *mutex) { + return sk != NULL ? OQS_SUCCESS : OQS_ERROR; +} + +static OQS_STATUS unlock_sk_key(void *mutex) { + return sk != NULL ? OQS_SUCCESS : OQS_ERROR; +} +#endif + // // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) // @@ -294,6 +341,10 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char size_t sk_buf_len = 0; size_t read_pk_len = 0; +#if OQS_USE_PTHREADS_IN_TESTS + pthread_mutex_t *sk_lock = NULL; +#endif + OQS_STATUS rc, ret = OQS_ERROR; //The magic numbers are random values. @@ -313,6 +364,21 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char secret_key = OQS_SIG_STFL_SECRET_KEY_new(sig->method_name); secret_key_rd = OQS_SIG_STFL_SECRET_KEY_new(sig->method_name); + + OQS_SIG_STFL_SECRET_KEY_SET_lock(secret_key, lock_sk_key); + OQS_SIG_STFL_SECRET_KEY_SET_unlock(secret_key, unlock_sk_key); + +#if OQS_USE_PTHREADS_IN_TESTS + sk_lock = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); + if (sk_lock == NULL) { + goto err; + } + + if (0 != pthread_mutex_init(sk_lock, 0)) { + goto err; + } + OQS_SIG_STFL_SECRET_KEY_SET_mutex(secret_key, sk_lock); +#endif public_key = malloc(sig->length_public_key + 2 * sizeof(magic_t)); message = malloc(message_len + 2 * sizeof(magic_t)); signature = malloc(sig->length_signature + 2 * sizeof(magic_t)); @@ -479,6 +545,13 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char OQS_MEM_insecure_free(read_pk_buf); OQS_MEM_insecure_free(context); + +#if OQS_USE_PTHREADS_IN_TESTS + if (sk_lock) { + pthread_mutex_destroy(sk_lock); + OQS_MEM_insecure_free(sk_lock); + } +#endif return ret; } @@ -616,7 +689,6 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { if (!sk->secret_key_data) { fprintf(stderr, "ERROR: OQS_SECRET_KEY_new incomplete.\n"); - OQS_MEM_insecure_free(public_key); goto err; } @@ -670,10 +742,240 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { return rc; } +static OQS_STATUS sig_stfl_test_query_key(const char *method_name) { + OQS_STATUS rc = OQS_SUCCESS; + + size_t message_len_1 = sizeof(message_1); + size_t message_len_2 = sizeof(message_2); + + /* + * Temporarily skip algs with long key generation times. + */ + + if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) != 0) { + goto skip_test; + } else { + goto keep_going; + } + +skip_test: + printf("Skip slow alg %s.\n", method_name); + return rc; + +keep_going: + + printf("================================================================================\n"); + printf("Testing stateful Signature Verification %s\n", method_name); + printf("================================================================================\n"); + + if ( lock_test_sk == NULL || lock_test_sig_obj == NULL || signature_1 == NULL + || signature_2 == NULL || lock_test_public_key == NULL) { + return OQS_ERROR; + } + + + printf("================================================================================\n"); + printf("Sig Verify 1 %s\n", method_name); + printf("================================================================================\n"); + + rc = OQS_SIG_STFL_verify(lock_test_sig_obj, message_1, message_len_1, signature_1, signature_len_1, lock_test_public_key); + OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "ERROR: lock thread test OQS_SIG_STFL_verify failed\n"); + goto err; + } + + printf("================================================================================\n"); + printf("Sig Verify 2 %s\n", method_name); + printf("================================================================================\n"); + + rc = OQS_SIG_STFL_verify(lock_test_sig_obj, message_2, message_len_2, signature_2, signature_len_2, lock_test_public_key); + OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "ERROR: lock thread test OQS_SIG_STFL_verify failed\n"); + goto err; + } + rc = OQS_SUCCESS; + printf("================================================================================\n"); + printf("Stateful Signature Verification %s Passed.\n", method_name); + printf("================================================================================\n"); + goto end_it; +err: + rc = OQS_ERROR; +end_it: + + return rc; +} + +static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { + OQS_STATUS rc = OQS_SUCCESS; + size_t message_len_1 = sizeof(message_1); + size_t message_len_2 = sizeof(message_2); + + /* + * Temporarily skip algs with long key generation times. + */ + + if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) != 0) { + goto skip_test; + } else { + goto keep_going; + } + +skip_test: + printf("Skip slow alg %s.\n", method_name); + return rc; + +keep_going: + + printf("================================================================================\n"); + printf("Testing stateful Signature Generation %s\n", method_name); + printf("================================================================================\n"); + + if ( lock_test_sk == NULL || lock_test_sig_obj == NULL) { + return OQS_ERROR; + } + + + printf("================================================================================\n"); + printf("Sig Gen 1 %s\n", method_name); + printf("================================================================================\n"); + + signature_1 = malloc(lock_test_sig_obj->length_signature); + + rc = OQS_SIG_STFL_sign(lock_test_sig_obj, signature_1, &signature_len_1, message_1, message_len_1, lock_test_sk); + OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "ERROR: lock thread test OQS_SIG_STFL_sign failed\n"); + goto err; + } + + sleep(3); + + printf("================================================================================\n"); + printf("Sig Gen 2 %s\n", method_name); + printf("================================================================================\n"); + + signature_2 = malloc(lock_test_sig_obj->length_signature); + + rc = OQS_SIG_STFL_sign(lock_test_sig_obj, signature_2, &signature_len_2, message_2, message_len_2, lock_test_sk); + OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "ERROR: lock thread test OQS_SIG_STFL_sign failed\n"); + goto err; + } + rc = OQS_SUCCESS; + printf("================================================================================\n"); + printf("Stateful Key Gen %s Passed.\n", method_name); + printf("================================================================================\n"); + goto end_it; +err: + rc = OQS_ERROR; +end_it: + + return rc; +} + + +static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name) { + OQS_STATUS rc = OQS_SUCCESS; + + /* + * Temporarily skip algs with long key generation times. + */ + + if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) != 0) { + goto skip_test; + } else { + goto keep_going; + } + +skip_test: + printf("Skip slow test %s.\n", method_name); + return rc; + +keep_going: + + printf("================================================================================\n"); + printf("Testing stateful Signature locks %s\n", method_name); + printf("================================================================================\n"); + + printf("================================================================================\n"); + printf("Create stateful Signature %s\n", method_name); + printf("================================================================================\n"); + + lock_test_sig_obj = OQS_SIG_STFL_new(method_name); + if (lock_test_sig_obj == NULL) { + fprintf(stderr, "ERROR: OQS_SIG_STFL_new failed\n"); + goto err; + } + + lock_test_public_key = malloc(lock_test_sig_obj->length_public_key * sizeof(uint8_t)); + + printf("================================================================================\n"); + printf("Create stateful Secret Key %s\n", method_name); + printf("================================================================================\n"); + + lock_test_sk = OQS_SIG_STFL_SECRET_KEY_new(method_name); + if (lock_test_sk == NULL) { + fprintf(stderr, "ERROR: OQS_SECRET_KEY_new failed\n"); + goto err; + } + + OQS_SIG_STFL_SECRET_KEY_SET_lock(lock_test_sk, lock_sk_key); + OQS_SIG_STFL_SECRET_KEY_SET_unlock(lock_test_sk, unlock_sk_key); + +#if OQS_USE_PTHREADS_IN_TESTS + + test_sk_lock = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); + if (test_sk_lock == NULL) { + goto err; + } + + if (0 != pthread_mutex_init(test_sk_lock, 0)) { + goto err; + } + OQS_SIG_STFL_SECRET_KEY_SET_mutex(lock_test_sk, test_sk_lock); +#endif + + printf("================================================================================\n"); + printf("Generate keypair %s\n", method_name); + printf("================================================================================\n"); + + rc = OQS_SIG_STFL_keypair(lock_test_sig_obj, lock_test_public_key, lock_test_sk); + + if (rc != OQS_SUCCESS) { + fprintf(stderr, "OQS STFL key gen failed.\n"); + goto err; + } + + + + if (!lock_test_sk->secret_key_data) { + fprintf(stderr, "ERROR: OQS_SECRET_KEY_new incomplete.\n"); + goto err; + } + + /* set context and secure store callback */ + if (lock_test_sk->set_scrt_key_store_cb) { + lock_test_context = strdup(((method_name))); + lock_test_sk->set_scrt_key_store_cb(lock_test_sk, test_save_secret_key, (void *)lock_test_context); + } + + printf("Test Secret Key Creator Thread created Stateful Signature and Secret Key objects.\n"); + goto end_it; + +err: + rc = OQS_ERROR; +end_it: + return rc; +} + #ifdef OQS_ENABLE_TEST_CONSTANT_TIME static void TEST_SIG_STFL_randombytes(uint8_t *random_array, size_t bytes_to_read) { // We can't make direct calls to the system randombytes on some platforms, // so we have to swap out the OQS_randombytes provider. + OQS_randombytes_switch_algorithm("system"); OQS_randombytes(random_array, bytes_to_read); OQS_randombytes_custom_algorithm(&TEST_SIG_STFL_randombytes); @@ -693,6 +995,35 @@ struct thread_data { OQS_STATUS rc1; }; +struct lock_test_data { + const char *alg_name; + OQS_STATUS rc; +}; + +void *test_query_key(void *arg) { + struct lock_test_data *td = arg; + printf("\n%s: Start Query Stateful Key info\n", __FUNCTION__); + td->rc = sig_stfl_test_query_key(td->alg_name); + printf("%s: End Query Stateful Key info\n\n", __FUNCTION__); + return NULL; +} + +void *test_sig_gen(void *arg) { + struct lock_test_data *td = arg; + printf("\n%s: Start Generate Stateful Signature\n", __FUNCTION__); + td->rc = sig_stfl_test_sig_gen(td->alg_name); + printf("%s: End Generate Stateful Signature\n\n", __FUNCTION__); + return NULL; +} + +void *test_create_keys(void *arg) { + struct lock_test_data *td = arg; + printf("\n%s: Start Generate Keys\n", __FUNCTION__); + td->rc = sig_stfl_test_secret_key_lock(td->alg_name); + printf("%s: End Generate Stateful Keys\n\n", __FUNCTION__); + return NULL; +} + void *test_wrapper(void *arg) { struct thread_data *td = arg; td->rc = sig_stfl_test_correctness(td->alg_name, td->katfile); @@ -737,13 +1068,26 @@ int main(int argc, char **argv) { OQS_randombytes_switch_algorithm("system"); #endif - OQS_STATUS rc, rc1; + OQS_STATUS rc, rc1, rc_lck, rc_sig, rc_qry; #if OQS_USE_PTHREADS_IN_TESTS #define MAX_LEN_SIG_NAME_ 64 + pthread_t thread; + pthread_t create_key_thread; + pthread_t sign_key_thread; + pthread_t query_key_thread; struct thread_data td; td.alg_name = alg_name; td.katfile = katfile; + + struct lock_test_data td_create; + struct lock_test_data td_sign; + struct lock_test_data td_query; + td_create.alg_name = alg_name; + td_sign.alg_name = alg_name; + td_query.alg_name = alg_name; + + int trc = pthread_create(&thread, NULL, test_wrapper, &td); if (trc) { fprintf(stderr, "ERROR: Creating pthread\n"); @@ -753,11 +1097,47 @@ int main(int argc, char **argv) { pthread_join(thread, NULL); rc = td.rc; rc1 = td.rc1; + + int trc_2 = pthread_create(&create_key_thread, NULL, test_create_keys, &td_create); + if (trc_2) { + fprintf(stderr, "ERROR: Creating pthread for stateful key gen test\n"); + OQS_destroy(); + return EXIT_FAILURE; + } + pthread_join(create_key_thread, NULL); + rc_lck = td_create.rc; + + int trc_3 = pthread_create(&sign_key_thread, NULL, test_sig_gen, &td_sign); + if (trc_3) { + fprintf(stderr, "ERROR: Creating pthread for sig gen test\n"); + OQS_destroy(); + return EXIT_FAILURE; + } + pthread_join(sign_key_thread, NULL); + rc_sig = td_sign.rc; + + int trc_4 = pthread_create(&query_key_thread, NULL, test_query_key, &td_query); + if (trc_4) { + fprintf(stderr, "ERROR: Creating pthread for query key test.\n"); + OQS_destroy(); + return EXIT_FAILURE; + } + pthread_join(query_key_thread, NULL); + rc_qry = td_query.rc; #else rc = sig_stfl_test_correctness(alg_name, katfile); rc1 = sig_stfl_test_secret_key(alg_name); #endif - if ((rc != OQS_SUCCESS) || (rc1 != OQS_SUCCESS)) { + + OQS_SIG_STFL_SECRET_KEY_free(lock_test_sk); + OQS_MEM_insecure_free(lock_test_public_key); + OQS_SIG_STFL_free(lock_test_sig_obj); + OQS_MEM_insecure_free(lock_test_context); + OQS_MEM_insecure_free(signature_1); + OQS_MEM_insecure_free(signature_2); + + if ((rc != OQS_SUCCESS) || (rc1 != OQS_SUCCESS) || (rc_lck != OQS_SUCCESS) || (rc_sig != OQS_SUCCESS) + || (rc_qry != OQS_SUCCESS)) { OQS_destroy(); return EXIT_FAILURE; } From 3db6b44f775fdb57440678c42153c57660ad50c1 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Thu, 5 Oct 2023 14:19:13 -0400 Subject: [PATCH 16/68] Secret Key Query (#1572) * Added functions to query the total, as well as, the remaining numbers of signing operation for a given secret key. * Cleanup unused variable * Fix code style --- src/sig_stfl/lms/sig_stfl_lms_functions.c | 61 +++++++++++++++--- tests/test_sig_stfl.c | 77 ++++++++++++++++++++++- 2 files changed, 128 insertions(+), 10 deletions(-) diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index 59265f3110..018b04b21e 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -7,8 +7,9 @@ #include "external/hss_verify_inc.h" #include "external/hss_sign_inc.h" #include "external/hss.h" +#include "external/endian.h" +#include "external/hss_internal.h" #include "sig_stfl_lms_wrap.h" -#include #define DEFAULT_AUX_DATA 10916 /* Use 10+k of aux data (which works well */ /* with the above default parameter set) */ @@ -136,17 +137,39 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_verify(const uint8_t *message, size_t me } OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS status; + uint8_t *priv_key = NULL; + unsigned long long total_sigs = 0; + sequence_t current_count = 0; + oqs_lms_key_data *oqs_key_data = NULL; if (remain == NULL || secret_key == NULL) { return OQS_ERROR; } + + status = OQS_SIG_STFL_lms_sigs_total(&total_sigs, secret_key); + if (status != OQS_SUCCESS) { + return OQS_ERROR; + } + /* Lock secret key to ensure data integrity use */ if ((secret_key->lock_key) && (secret_key->mutex)) { secret_key->lock_key(secret_key->mutex); } - remain = 0; + oqs_key_data = secret_key->secret_key_data; + if (oqs_key_data == NULL) { + goto err; + } + priv_key = oqs_key_data->sec_key; + if (priv_key == NULL) { + goto err; + } + + current_count = get_bigendian(priv_key + PRIVATE_KEY_INDEX, PRIVATE_KEY_INDEX_LEN /*0, 8 */); + *remain = (total_sigs - (unsigned long long)current_count); +err: /* Unlock secret key */ if ((secret_key->unlock_key) && (secret_key->mutex)) { secret_key->unlock_key(secret_key->mutex); @@ -156,11 +179,38 @@ OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + uint8_t *priv_key = NULL; + oqs_lms_key_data *oqs_key_data = NULL; + struct hss_working_key *working_key = NULL; + + if (total == NULL || secret_key == NULL) { return OQS_ERROR; } - total = 0; + oqs_key_data = secret_key->secret_key_data; + if (!oqs_key_data) { + return OQS_ERROR; + } + + priv_key = oqs_key_data->sec_key; + if (!priv_key) { + return OQS_ERROR; + } + + working_key = hss_load_private_key(NULL, priv_key, + 0, + NULL, + 0, + 0); + if (!working_key) { + return OQS_ERROR; + } + + + + *total = (unsigned long long)working_key->max_count; + OQS_MEM_secure_free(working_key, sizeof(struct hss_working_key)); return OQS_SUCCESS; } @@ -293,7 +343,7 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uin memcpy(pk, oqs_key_data->public_key, len_public_key); sk->secret_key_data = oqs_key_data; } else { - OQS_MEM_insecure_free(oqs_key_data->sec_key); + OQS_MEM_secure_free(oqs_key_data->sec_key, sk->length_secret_key * sizeof(uint8_t)); OQS_MEM_insecure_free(oqs_key_data->aux_data); OQS_MEM_insecure_free(oqs_key_data); oqs_key_data = NULL; @@ -329,7 +379,6 @@ int oqs_sig_stfl_lms_sign(OQS_SIG_STFL_SECRET_KEY *sk, 0, 0); if (!w) { - printf( "Error loading private key\n" ); hss_free_working_key(w); return 0; } @@ -340,14 +389,12 @@ int oqs_sig_stfl_lms_sign(OQS_SIG_STFL_SECRET_KEY *sk, sig_len = hss_get_signature_len_from_working_key(w); if (sig_len == 0) { - printf( "Error getting signature len\n" ); hss_free_working_key(w); return 0; } sig = malloc(sig_len); if (!sig) { - printf( "Error during malloc\n" ); hss_free_working_key(w); return -1; } diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 8a3cb2252d..2f2b176016 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -559,7 +559,7 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { OQS_STATUS rc = OQS_SUCCESS; OQS_SIG_STFL_SECRET_KEY *sk = NULL; OQS_SIG_STFL_SECRET_KEY *sk_frm_file = NULL; - + unsigned long long num_sig_left = 0, max_num_sigs = 0; OQS_SIG_STFL *sig_obj = NULL; uint8_t *public_key = NULL; uint8_t *frm_file_sk_buf = NULL; @@ -677,6 +677,23 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { goto err; } + /* + * Get max num signature and the amount remaining + */ + rc = OQS_SIG_STFL_sigs_total((const OQS_SIG_STFL *)sig_obj, &max_num_sigs, (const OQS_SIG_STFL_SECRET_KEY *)sk); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "OQS STFL key: Failed to get max number of sig from %s.\n", method_name); + goto err; + } + printf("%s Maximum num of sign operations = %llu\n", method_name, max_num_sigs); + + rc = OQS_SIG_STFL_sigs_remaining((const OQS_SIG_STFL *)sig_obj, &num_sig_left, (const OQS_SIG_STFL_SECRET_KEY *)sk); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "OQS STFL key: Failed to get the remaining number of sig from %s.\n", method_name); + goto err; + } + printf("%s Remaining number of sign operations = %llu\n", method_name, num_sig_left); + /* write sk key to disk */ rc = OQS_SECRET_KEY_STFL_serialize_key(sk, &to_file_sk_len, &to_file_sk_buf); if (rc != OQS_SUCCESS) { @@ -837,6 +854,25 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { } + /* + * Get max num signature and the amount remaining + */ + unsigned long long num_sig_left = 0, max_num_sigs = 0; + rc = OQS_SIG_STFL_sigs_total((const OQS_SIG_STFL *)lock_test_sig_obj, &max_num_sigs, (const OQS_SIG_STFL_SECRET_KEY *)lock_test_sk); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "OQS STFL key: Failed to get max number of sig from %s.\n", method_name); + goto err; + } + printf("%s Maximum num of sign operations = %llu\n", method_name, max_num_sigs); + + rc = OQS_SIG_STFL_sigs_remaining((const OQS_SIG_STFL *)lock_test_sig_obj, &num_sig_left, (const OQS_SIG_STFL_SECRET_KEY *)lock_test_sk); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "OQS STFL key: Failed to get the remaining number of sig from %s.\n", method_name); + goto err; + } + printf("%s Remaining number of sign operations = %llu\n", method_name, num_sig_left); + + printf("================================================================================\n"); printf("Sig Gen 1 %s\n", method_name); printf("================================================================================\n"); @@ -850,7 +886,23 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { goto err; } - sleep(3); + /* + * Get max num signature and the amount remaining + */ + num_sig_left = 0, max_num_sigs = 0; + rc = OQS_SIG_STFL_sigs_total((const OQS_SIG_STFL *)lock_test_sig_obj, &max_num_sigs, (const OQS_SIG_STFL_SECRET_KEY *)lock_test_sk); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "OQS STFL key: Failed to get max number of sig from %s.\n", method_name); + goto err; + } + printf("%s Maximum num of sign operations = %llu\n", method_name, max_num_sigs); + + rc = OQS_SIG_STFL_sigs_remaining((const OQS_SIG_STFL *)lock_test_sig_obj, &num_sig_left, (const OQS_SIG_STFL_SECRET_KEY *)lock_test_sk); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "OQS STFL key: Failed to get the remaining number of sig from %s.\n", method_name); + goto err; + } + printf("%s Remaining number of sign operations = %llu\n", method_name, num_sig_left); printf("================================================================================\n"); printf("Sig Gen 2 %s\n", method_name); @@ -864,10 +916,29 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { fprintf(stderr, "ERROR: lock thread test OQS_SIG_STFL_sign failed\n"); goto err; } - rc = OQS_SUCCESS; + printf("================================================================================\n"); printf("Stateful Key Gen %s Passed.\n", method_name); printf("================================================================================\n"); + + /* + * Get max num signature and the amount remaining + */ + num_sig_left = 0, max_num_sigs = 0; + rc = OQS_SIG_STFL_sigs_total((const OQS_SIG_STFL *)lock_test_sig_obj, &max_num_sigs, (const OQS_SIG_STFL_SECRET_KEY *)lock_test_sk); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "OQS STFL key: Failed to get max number of sig from %s.\n", method_name); + goto err; + } + printf("%s Maximum num of sign operations = %llu\n", method_name, max_num_sigs); + + rc = OQS_SIG_STFL_sigs_remaining((const OQS_SIG_STFL *)lock_test_sig_obj, &num_sig_left, (const OQS_SIG_STFL_SECRET_KEY *)lock_test_sk); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "OQS STFL key: Failed to get the remaining number of sig from %s.\n", method_name); + goto err; + } + printf("%s Remaining number of sign operations = %llu\n", method_name, num_sig_left); + goto end_it; err: rc = OQS_ERROR; From 2446c64b3fd067452f6d07d283a660ac9af7b2cd Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Tue, 10 Oct 2023 12:21:19 -0400 Subject: [PATCH 17/68] Na stateful sigs lms var (#1574) * Added new LMS varients. Removed unneeded vector functions from secret key data struc. * Add LMS variants * Fix formatting --- src/sig_stfl/lms/sig_stfl_lms.c | 1659 ++++++++++++++++- src/sig_stfl/lms/sig_stfl_lms.h | 183 +- src/sig_stfl/lms/sig_stfl_lms_functions.c | 87 +- src/sig_stfl/sig_stfl.c | 180 +- src/sig_stfl/sig_stfl.h | 33 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c | 4 - src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c | 4 - src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c | 4 - src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c | 4 - src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c | 4 - src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c | 4 - .../xmss/sig_stfl_xmss_shake128_h10.c | 4 - .../xmss/sig_stfl_xmss_shake128_h16.c | 4 - .../xmss/sig_stfl_xmss_shake128_h20.c | 4 - .../xmss/sig_stfl_xmss_shake256_h10.c | 4 - .../xmss/sig_stfl_xmss_shake256_h16.c | 4 - .../xmss/sig_stfl_xmss_shake256_h20.c | 4 - .../xmss/sig_stfl_xmssmt_sha256_h20_2.c | 4 - .../xmss/sig_stfl_xmssmt_sha256_h20_4.c | 4 - .../xmss/sig_stfl_xmssmt_sha256_h40_2.c | 4 - .../xmss/sig_stfl_xmssmt_sha256_h40_4.c | 4 - .../xmss/sig_stfl_xmssmt_sha256_h40_8.c | 4 - .../xmss/sig_stfl_xmssmt_sha256_h60_12.c | 4 - .../xmss/sig_stfl_xmssmt_sha256_h60_3.c | 4 - .../xmss/sig_stfl_xmssmt_sha256_h60_6.c | 4 - .../xmss/sig_stfl_xmssmt_shake128_h20_2.c | 4 - .../xmss/sig_stfl_xmssmt_shake128_h20_4.c | 4 - .../xmss/sig_stfl_xmssmt_shake128_h40_2.c | 4 - .../xmss/sig_stfl_xmssmt_shake128_h40_4.c | 4 - .../xmss/sig_stfl_xmssmt_shake128_h40_8.c | 4 - .../xmss/sig_stfl_xmssmt_shake128_h60_12.c | 4 - .../xmss/sig_stfl_xmssmt_shake128_h60_3.c | 4 - .../xmss/sig_stfl_xmssmt_shake128_h60_6.c | 4 - tests/test_sig_stfl.c | 56 +- 34 files changed, 2132 insertions(+), 178 deletions(-) diff --git a/src/sig_stfl/lms/sig_stfl_lms.c b/src/sig_stfl/lms/sig_stfl_lms.c index e6c30e66d5..3503c7447b 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.c +++ b/src/sig_stfl/lms/sig_stfl_lms.c @@ -22,7 +22,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)0x00000001) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h5_w1) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -36,7 +36,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = 0x00000001; + sig->oid = OQS_LMS_ID_sha256_n32_h5_w1; sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -67,11 +67,1658 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void) { // Initialize the key with length_secret_key amount of bytes. sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_sk; - /* Function that returns the total number of signatures for the secret key */ - sk->sigs_total = NULL; + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H5/W2 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h5_w2) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w2_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h5_w2; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h5_w2_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W2_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H5/W4 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h5_w4) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w4_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h5_w4; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h5_w4_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W4_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H5/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h5_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h5_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h5_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H10/W1 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h10_w1) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w1_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h10_w1; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h10_w1_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w1_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w1_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w1_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W1_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w1_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H10/W2 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h10_w2) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w2_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h10_w2; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h10_w2; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w2_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W2_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H10/W4 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h10_w4) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h10_w4; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h10_w4; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w4_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H10/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h10_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h10_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h10_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H15/W1 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h15_w1) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w1_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h15_w1; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h15_w1_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w1_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w1_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w1_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W1_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w1_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H15/W2 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h15_w2) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w2_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h15_w2; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h15_w2; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w2_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W2_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H15/W4 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h15_w4) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w4_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h15_w4; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h15_w4; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w4_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W4_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H15/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h15_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h15_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h15_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H20/W1 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h20_w1) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w1_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h20_w1; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h20_w1; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h20_w1_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w1_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w1_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w1_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W1_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w1_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H20/W2 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h20_w2) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w2_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h20_w2; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h20_w2; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w2_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W2_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H20/W4 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h20_w4) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w4_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h20_w4; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h20_w4; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w4_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W4_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H20/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h20_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h20_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h20_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H25/W1 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h25_w1) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w1_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h25_w1; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h25_w1; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h25_w1_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h25_w1_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w1_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h25_w1_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W1_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w1_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H25/W2 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h25_w2) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w2_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h25_w2; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h25_w2; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h25_w2_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W2_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H25/W4 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h25_w4) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w4_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h25_w4; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h25_w4; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h25_w4_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W4_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_sk; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - /* set Function to returns the number of signatures left for the secret key */ - sk->sigs_left = NULL; + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H25/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h25_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_n32_h25_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h25_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_pk; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_sk; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h25_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_sk; /* * Secret Key retrieval Function diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h index 75ce739238..e42450fd15 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.h +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -5,16 +5,193 @@ #include +//OQS LMS parameter identifiers +/* Defined LM parameter sets */ +#define OQS_LMS_ID_sha256_n32_h5_w1 0x1 //"5/1" +#define OQS_LMS_ID_sha256_n32_h5_w2 0x2 //"5/2" +#define OQS_LMS_ID_sha256_n32_h5_w4 0x3 //"5/4" +#define OQS_LMS_ID_sha256_n32_h5_w8 0x4 //"5/8" + +#define OQS_LMS_ID_sha256_n32_h10_w1 0x5 //"10/1" +#define OQS_LMS_ID_sha256_n32_h10_w2 0x7 //"10/2" +#define OQS_LMS_ID_sha256_n32_h10_w4 0x8 //"10/4" +#define OQS_LMS_ID_sha256_n32_h10_w8 0x9 //"10/8" + +#define OQS_LMS_ID_sha256_n32_h15_w1 0xa //"15/1" +#define OQS_LMS_ID_sha256_n32_h15_w2 0xb //"15/2" +#define OQS_LMS_ID_sha256_n32_h15_w4 0xc//"15/4" +#define OQS_LMS_ID_sha256_n32_h15_w8 0xd //"15/8" + +#define OQS_LMS_ID_sha256_n32_h20_w1 0xe //"20/1" +#define OQS_LMS_ID_sha256_n32_h20_w2 0xf //"20/2" +#define OQS_LMS_ID_sha256_n32_h20_w4 0x10 //"20/4" +#define OQS_LMS_ID_sha256_n32_h20_w8 0x11 //"20/8" + +#define OQS_LMS_ID_sha256_n32_h25_w1 0x12 //"25/1" +#define OQS_LMS_ID_sha256_n32_h25_w2 0x13 //"25/2" +#define OQS_LMS_ID_sha256_n32_h25_w4 0x14 //"25/4" +#define OQS_LMS_ID_sha256_n32_h25_w8 0x15 //"25/8" + //H5 #define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_signature 8688 #define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_sk 64 - +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void); +#define OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_signature 4464 +#define OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_sk 64 +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w2_new(void); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W2_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); + +#define OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_signature 2352 +#define OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_sk 64 +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w4_new(void); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W4_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); + +#define OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_signature 1296 +#define OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_sk 64 +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w8_new(void); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W8_new(void); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); + +//H10 +// H10 W1 60 8848 64 +// H10 W2 60 4624 64 +// H10 W4 60 2512 64 +// H10 W8 60 1456 64 +#define OQS_SIG_STFL_alg_lms_sha256_h10_w1_length_signature 8848 +#define OQS_SIG_STFL_alg_lms_sha256_h10_w1_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h10_w1_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W1_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w1_new(void); + +#define OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_signature 4624 +#define OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W2_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w2_new(void); + +#define OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_signature 2512 +#define OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_new(void); + +#define OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_signature 1456 +#define OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_new(void); + +//H15 +// H15 W1 60 9008 64 +// H15 W2 60 4784 64 +// H15 W4 60 2672 64 +// H15 W8 60 1616 64 +#define OQS_SIG_STFL_alg_lms_sha256_h15_w1_length_signature 9008 +#define OQS_SIG_STFL_alg_lms_sha256_h15_w1_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h15_w1_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W1_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w1_new(void); + +#define OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_signature 4784 +#define OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W2_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w2_new(void); + +#define OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_signature 2672 +#define OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W4_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w4_new(void); + +#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_signature 1616 +#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_new(void); + +//H20 +// H20 W1 60 9168 64 +// H20 W2 60 4944 64 +// H20 W4 60 2832 64 +// H20 W8 60 1776 64 +#define OQS_SIG_STFL_alg_lms_sha256_h20_w1_length_signature 9168 +#define OQS_SIG_STFL_alg_lms_sha256_h20_w1_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h20_w1_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W1_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w1_new(void); + +#define OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_signature 4944 +#define OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W2_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w2_new(void); + +#define OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_signature 2832 +#define OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W4_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w4_new(void); + +#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_signature 1776 +#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_new(void); + +//H25 +// H25 W1 60 9328 64 +// H25 W2 60 5104 64 +// H25 W4 60 2992 64 +// H25 W8 60 1936 64 +#define OQS_SIG_STFL_alg_lms_sha256_h25_w1_length_signature 9328 +#define OQS_SIG_STFL_alg_lms_sha256_h25_w1_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h25_w1_length_sk 64 -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W1_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w1_new(void); + +#define OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_signature 5104 +#define OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W2_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w2_new(void); + +#define OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_signature 2992 +#define OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W4_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w4_new(void); + +#define OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_signature 1936 +#define OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_pk 60 +#define OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_sk 64 + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *totaln, const OQS_SIG_STFL_SECRET_KEY *secret_key); diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index 018b04b21e..f18d8c445b 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -183,7 +183,6 @@ OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *total, const oqs_lms_key_data *oqs_key_data = NULL; struct hss_working_key *working_key = NULL; - if (total == NULL || secret_key == NULL) { return OQS_ERROR; } @@ -207,8 +206,6 @@ OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *total, const return OQS_ERROR; } - - *total = (unsigned long long)working_key->max_count; OQS_MEM_secure_free(working_key, sizeof(struct hss_working_key)); return OQS_SUCCESS; @@ -280,11 +277,91 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uin /* Set lms param set */ switch (oid) { - case 0x1: + case OQS_LMS_ID_sha256_n32_h5_w1: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H5; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W1; break; - default: + case OQS_LMS_ID_sha256_n32_h5_w2: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H5; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W2; + break; + case OQS_LMS_ID_sha256_n32_h5_w4: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H5; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W4; + break; + case OQS_LMS_ID_sha256_n32_h5_w8: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H5; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + break; + + case OQS_LMS_ID_sha256_n32_h10_w1: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W1; + break; + case OQS_LMS_ID_sha256_n32_h10_w2: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W2; + break; + case OQS_LMS_ID_sha256_n32_h10_w4: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W4; + break; + case OQS_LMS_ID_sha256_n32_h10_w8: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + break; + + case OQS_LMS_ID_sha256_n32_h15_w1: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H15; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W1; + break; + case OQS_LMS_ID_sha256_n32_h15_w2: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H15; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W2; + break; + case OQS_LMS_ID_sha256_n32_h15_w4: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H15; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W4; + break; + case OQS_LMS_ID_sha256_n32_h15_w8: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H15; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + break; + + case OQS_LMS_ID_sha256_n32_h20_w1: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H20; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W1; + break; + case OQS_LMS_ID_sha256_n32_h20_w2: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H20; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W2; + break; + case OQS_LMS_ID_sha256_n32_h20_w4: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H20; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W4; + break; + case OQS_LMS_ID_sha256_n32_h20_w8: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H20; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + break; + + case OQS_LMS_ID_sha256_n32_h25_w1: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H25; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W1; + break; + case OQS_LMS_ID_sha256_n32_h25_w2: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H25; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W2; + break; + case OQS_LMS_ID_sha256_n32_h25_w4: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H25; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W4; + break; + case OQS_LMS_ID_sha256_n32_h25_w8: + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H25; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + break; + oqs_key_data->lm_type[0] = 0; oqs_key_data->lm_ots_type[0] = 0; parse_err = 1; diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 023d4e1df3..b434f54715 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -43,6 +43,29 @@ OQS_API const char *OQS_SIG_STFL_alg_identifier(size_t i) { OQS_SIG_STFL_alg_xmssmt_shake128_h60_6, OQS_SIG_STFL_alg_xmssmt_shake128_h60_12, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1, + OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2, + OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4, + OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8, + + OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1, + OQS_SIG_STFL_alg_lms_sha256_n32_h10_w2, + OQS_SIG_STFL_alg_lms_sha256_n32_h10_w4, + OQS_SIG_STFL_alg_lms_sha256_n32_h10_w8, + + OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1, + OQS_SIG_STFL_alg_lms_sha256_n32_h15_w2, + OQS_SIG_STFL_alg_lms_sha256_n32_h15_w4, + OQS_SIG_STFL_alg_lms_sha256_n32_h15_w8, + + OQS_SIG_STFL_alg_lms_sha256_n32_h20_w1, + OQS_SIG_STFL_alg_lms_sha256_n32_h20_w2, + OQS_SIG_STFL_alg_lms_sha256_n32_h20_w4, + OQS_SIG_STFL_alg_lms_sha256_n32_h20_w8, + + OQS_SIG_STFL_alg_lms_sha256_n32_h25_w1, + OQS_SIG_STFL_alg_lms_sha256_n32_h25_w2, + OQS_SIG_STFL_alg_lms_sha256_n32_h25_w4, + OQS_SIG_STFL_alg_lms_sha256_n32_h25_w8, }; if (i >= OQS_SIG_STFL_algs_length) { @@ -52,12 +75,10 @@ OQS_API const char *OQS_SIG_STFL_alg_identifier(size_t i) { } } - OQS_API int OQS_SIG_STFL_alg_count(void) { return OQS_SIG_STFL_algs_length; } - OQS_API int OQS_SIG_STFL_alg_is_enabled(const char *method_name) { assert(method_name != NULL); @@ -231,18 +252,61 @@ OQS_API int OQS_SIG_STFL_alg_is_enabled(const char *method_name) { #else return 0; #endif - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1)) { + } #ifdef OQS_ENABLE_SIG_STFL_LMS + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1)) { return 1; -#else - return 0; -#endif - } else { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w2)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w4)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w8)) { + return 1; + } + + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w2)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w4)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w8)) { + return 1; + } + + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w1)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w2)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w4)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w8)) { + return 1; + } + + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w1)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w2)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w4)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w8)) { + return 1; + } +#endif //OQS_ENABLE_SIG_STFL_LMS + else { return 0; } } - OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { assert(method_name != NULL); @@ -416,18 +480,55 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { #else return NULL; #endif - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1)) { + } #ifdef OQS_ENABLE_SIG_STFL_LMS + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1)) { return OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(); -#else - return NULL; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2)) { + return OQS_SIG_STFL_alg_lms_sha256_h5_w2_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4)) { + return OQS_SIG_STFL_alg_lms_sha256_h5_w4_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h5_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1)) { + return OQS_SIG_STFL_alg_lms_sha256_h10_w1_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w2)) { + return OQS_SIG_STFL_alg_lms_sha256_h10_w2_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w4)) { + return OQS_SIG_STFL_alg_lms_sha256_h10_w4_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h10_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1)) { + return OQS_SIG_STFL_alg_lms_sha256_h15_w1_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w2)) { + return OQS_SIG_STFL_alg_lms_sha256_h15_w2_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w4)) { + return OQS_SIG_STFL_alg_lms_sha256_h15_w4_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h15_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w1)) { + return OQS_SIG_STFL_alg_lms_sha256_h20_w1_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w2)) { + return OQS_SIG_STFL_alg_lms_sha256_h20_w2_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w4)) { + return OQS_SIG_STFL_alg_lms_sha256_h20_w4_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h20_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w1)) { + return OQS_SIG_STFL_alg_lms_sha256_h25_w1_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w2)) { + return OQS_SIG_STFL_alg_lms_sha256_h25_w2_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w4)) { + return OQS_SIG_STFL_alg_lms_sha256_h25_w4_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h25_w8_new(); + } #endif //OQS_ENABLE_SIG_STFL_LMS - } else { + else { return NULL; } } - OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { if (sig == NULL || sig->keypair == NULL || sig->keypair(public_key, secret_key) != 0) { return OQS_ERROR; @@ -474,11 +575,8 @@ OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig) { OQS_MEM_insecure_free(sig); } - - // ================================= OQS_SIG_STFL_SECRET_KEY FUNCTION =============================================== - OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_name) { assert(method_name != NULL); @@ -652,13 +750,51 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_ #else return NULL; #endif - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1)) { + } #ifdef OQS_ENABLE_SIG_STFL_LMS + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1)) { return OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(); -#else - return NULL; -#endif - } else { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2)) { + return OQS_SECRET_KEY_LMS_SHA256_H5_W2_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4)) { + return OQS_SECRET_KEY_LMS_SHA256_H5_W4_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H5_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1)) { + return OQS_SECRET_KEY_LMS_SHA256_H10_W1_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w2)) { + return OQS_SECRET_KEY_LMS_SHA256_H10_W2_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w4)) { + return OQS_SECRET_KEY_LMS_SHA256_H10_W4_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H10_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1)) { + return OQS_SECRET_KEY_LMS_SHA256_H15_W1_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w2)) { + return OQS_SECRET_KEY_LMS_SHA256_H15_W2_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w4)) { + return OQS_SECRET_KEY_LMS_SHA256_H15_W4_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H15_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w1)) { + return OQS_SECRET_KEY_LMS_SHA256_H20_W1_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w2)) { + return OQS_SECRET_KEY_LMS_SHA256_H20_W2_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w4)) { + return OQS_SECRET_KEY_LMS_SHA256_H20_W4_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H20_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w1)) { + return OQS_SECRET_KEY_LMS_SHA256_H25_W1_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w2)) { + return OQS_SECRET_KEY_LMS_SHA256_H25_W2_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w4)) { + return OQS_SECRET_KEY_LMS_SHA256_H25_W4_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H25_W8_new(); + } +#endif //OQS_ENABLE_SIG_STFL_LMS + else { return NULL; } } @@ -717,8 +853,6 @@ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY * return sk->deserialize_key(sk, key_len, sk_buf, context); } - - /* OQS_SIG_STFL_SECRET_KEY_SET_lock callback function*/ OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_lock(OQS_SIG_STFL_SECRET_KEY *sk, lock_key lock) { if (sk == NULL) { diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index a9bffdfdd8..33177e829e 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -38,7 +38,6 @@ * */ - #if defined(__cplusplus) extern "C" { #endif @@ -75,8 +74,31 @@ extern "C" { /* Defined LMS parameter identifiers */ #define OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1 "LMS_SHA256_H5_W1" //"5/1" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2 "LMS_SHA256_H5_W2" //"5/2" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4 "LMS_SHA256_H5_W4" //"5/4" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8 "LMS_SHA256_H5_W8" //"5/8" + +#define OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1 "LMS_SHA256_H10_W1" //"10/1" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h10_w2 "LMS_SHA256_H10_W2" //"10/2" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h10_w4 "LMS_SHA256_H10_W4" //"10/4" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h10_w8 "LMS_SHA256_H10_W8" //"10/8" + +#define OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1 "LMS_SHA256_H15_W1" //"15/1" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h15_w2 "LMS_SHA256_H15_W2" //"15/2" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h15_w4 "LMS_SHA256_H15_W4" //"15/4" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h15_w8 "LMS_SHA256_H15_W8" //"15/8" + +#define OQS_SIG_STFL_alg_lms_sha256_n32_h20_w1 "LMS_SHA256_H20_W1" //"20/1" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h20_w2 "LMS_SHA256_H20_W2" //"20/2" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h20_w4 "LMS_SHA256_H20_W4" //"20/4" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h20_w8 "LMS_SHA256_H20_W8" //"20/8" -#define OQS_SIG_STFL_algs_length 29 +#define OQS_SIG_STFL_alg_lms_sha256_n32_h25_w1 "LMS_SHA256_H25_W1" //"25/1" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h25_w2 "LMS_SHA256_H25_W2" //"25/2" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h25_w4 "LMS_SHA256_H25_W4" //"25/4" +#define OQS_SIG_STFL_alg_lms_sha256_n32_h25_w8 "LMS_SHA256_H25_W8" //"25/8" + +#define OQS_SIG_STFL_algs_length 48 /* Defined LM parameter identifiers */ /* Algorithm identifier for LMS-SHA256_N32_H5 */ @@ -167,7 +189,6 @@ typedef struct OQS_SIG_STFL { /** The (maximum) length, in bytes, of signatures for this signature scheme. */ size_t length_signature; - /** * Keypair generation algorithm. * @@ -247,12 +268,6 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { /* mutual exclusion struct */ void *mutex; - /* Function that returns the total number of signatures for the secret key */ - uint64_t (*sigs_total)(const OQS_SIG_STFL_SECRET_KEY *secret_key); - - /* Function that returns the number of signatures left for the secret key */ - uint64_t (*sigs_left)(const OQS_SIG_STFL_SECRET_KEY *secret_key); - /** * Secret Key retrieval Function * diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c index 83d3c4b275..20a8f87af0 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c index b3f72ef038..d32ad7df05 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H16_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h16_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c index 660f8c797c..9675fb1151 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H20_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h20_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c index 735cd012f2..c4589175c6 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H10_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h10_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c index de64237cb1..bab2bda1f2 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H16_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h16_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c index 0917020588..5c931a35c4 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H20_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h20_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c index 708981b3ac..fde4331e66 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H10_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h10_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c index e6381f0209..d1587260f3 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H16_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h16_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c index 4b80a0c938..c618ce8260 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H20_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h20_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c index bdb3243bfc..84e5772280 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H10_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h10_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c index 7b6b352720..788eb8f1e7 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H16_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h16_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c index fa6c7cc060..7029f669f8 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H20_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h20_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c index 60cb3dd8ad..c4862f728e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_2_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c index cd698b3d44..efa097b262 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_4_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c index 4b6d0a9021..04c8fd52fb 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_2_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c index c42a6db25f..dfa69325e8 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_4_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c index c29b43d2d1..7b4640ed40 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_8_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c index 7e53563c2d..84f0f589d3 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_12_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c index c1ed78f606..c9616932eb 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_3_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c index bc644a4223..7ab46f56ad 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_6_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c index 807eae702d..19421bb2ae 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_2_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c index 1082dcd999..1b51a87c76 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_4_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c index 01d70f3a37..8e3617fbd0 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_2_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c index d5935a5752..9a5f66ccef 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_4_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c index 743ff4cb96..9b6fc160ed 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_8_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c index c571bbe7ea..dfad288f23 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_12_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c index 83ed6b0b63..acd7b70165 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_3_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c index a8c3ed07af..889e831775 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c @@ -52,10 +52,6 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_6_new(void) { sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_sk; - // Assign the sigs_left and sigs_max functions - sk->sigs_left = NULL; - sk->sigs_total = NULL; - // Secret serialize/deserialize function sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 2f2b176016..9abd8dbe73 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -573,10 +573,16 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { * Temporarily skip algs with long key generation times. */ - if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) != 0) { - goto skip_test; - } else { + if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8) == 0 + + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1) == 0) { goto keep_going; + } else { + goto skip_test; } // if (0) { @@ -715,7 +721,6 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { sk->set_scrt_key_store_cb(sk, test_save_secret_key, (void *)context); } - /* read secret key from disk */ frm_file_sk_buf = malloc(to_file_sk_len); if (oqs_fload("sk", method_name, frm_file_sk_buf, to_file_sk_len, &frm_file_sk_len) != OQS_SUCCESS) { @@ -769,10 +774,16 @@ static OQS_STATUS sig_stfl_test_query_key(const char *method_name) { * Temporarily skip algs with long key generation times. */ - if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) != 0) { - goto skip_test; - } else { + if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8) == 0 + + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1) == 0) { goto keep_going; + } else { + goto skip_test; } skip_test: @@ -790,7 +801,6 @@ static OQS_STATUS sig_stfl_test_query_key(const char *method_name) { return OQS_ERROR; } - printf("================================================================================\n"); printf("Sig Verify 1 %s\n", method_name); printf("================================================================================\n"); @@ -833,10 +843,16 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { * Temporarily skip algs with long key generation times. */ - if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) != 0) { - goto skip_test; + if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8) == 0 + + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1) == 0) { + goto keep_going; } else { - goto keep_going; + goto skip_test; } skip_test: @@ -853,7 +869,6 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { return OQS_ERROR; } - /* * Get max num signature and the amount remaining */ @@ -872,7 +887,6 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { } printf("%s Remaining number of sign operations = %llu\n", method_name, num_sig_left); - printf("================================================================================\n"); printf("Sig Gen 1 %s\n", method_name); printf("================================================================================\n"); @@ -947,7 +961,6 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { return rc; } - static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name) { OQS_STATUS rc = OQS_SUCCESS; @@ -955,10 +968,16 @@ static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name) { * Temporarily skip algs with long key generation times. */ - if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) != 0) { - goto skip_test; - } else { + if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8) == 0 + + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1) == 0 + || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1) == 0) { goto keep_going; + } else { + goto skip_test; } skip_test: @@ -1020,8 +1039,6 @@ static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name) { goto err; } - - if (!lock_test_sk->secret_key_data) { fprintf(stderr, "ERROR: OQS_SECRET_KEY_new incomplete.\n"); goto err; @@ -1158,7 +1175,6 @@ int main(int argc, char **argv) { td_sign.alg_name = alg_name; td_query.alg_name = alg_name; - int trc = pthread_create(&thread, NULL, test_wrapper, &td); if (trc) { fprintf(stderr, "ERROR: Creating pthread\n"); From 8df253944127c4da39d8a7068b98244c1619baea Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Fri, 20 Oct 2023 14:58:20 -0400 Subject: [PATCH 18/68] Stateful sigs XMSS updates (#1590) * Update XMSS to use callbacks. Update test cases. * Fix format * Fix SA issues * Fix format * Fix SA issue * set secure function callback for KAT tests. Block slow tests * set secure function callback for KAT tests. Block slow tests. --- src/sig_stfl/lms/sig_stfl_lms_functions.c | 74 +-- src/sig_stfl/sig_stfl.h | 3 + src/sig_stfl/xmss/sig_stfl_xmss.h | 3 + .../xmss/sig_stfl_xmss_secret_key_functions.c | 15 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c | 47 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c | 49 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c | 49 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c | 49 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c | 49 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c | 49 +- .../xmss/sig_stfl_xmss_shake128_h10.c | 49 +- .../xmss/sig_stfl_xmss_shake128_h16.c | 49 +- .../xmss/sig_stfl_xmss_shake128_h20.c | 49 +- .../xmss/sig_stfl_xmss_shake256_h10.c | 49 +- .../xmss/sig_stfl_xmss_shake256_h16.c | 49 +- .../xmss/sig_stfl_xmss_shake256_h20.c | 49 +- .../xmss/sig_stfl_xmssmt_sha256_h20_2.c | 49 +- .../xmss/sig_stfl_xmssmt_sha256_h20_4.c | 49 +- .../xmss/sig_stfl_xmssmt_sha256_h40_2.c | 50 +- .../xmss/sig_stfl_xmssmt_sha256_h40_4.c | 49 +- .../xmss/sig_stfl_xmssmt_sha256_h40_8.c | 49 +- .../xmss/sig_stfl_xmssmt_sha256_h60_12.c | 50 +- .../xmss/sig_stfl_xmssmt_sha256_h60_3.c | 49 +- .../xmss/sig_stfl_xmssmt_sha256_h60_6.c | 49 +- .../xmss/sig_stfl_xmssmt_shake128_h20_2.c | 49 +- .../xmss/sig_stfl_xmssmt_shake128_h20_4.c | 49 +- .../xmss/sig_stfl_xmssmt_shake128_h40_2.c | 49 +- .../xmss/sig_stfl_xmssmt_shake128_h40_4.c | 49 +- .../xmss/sig_stfl_xmssmt_shake128_h40_8.c | 49 +- .../xmss/sig_stfl_xmssmt_shake128_h60_12.c | 49 +- .../xmss/sig_stfl_xmssmt_shake128_h60_3.c | 49 +- .../xmss/sig_stfl_xmssmt_shake128_h60_6.c | 2 + tests/kat_sig_stfl.c | 8 + tests/test_sig_stfl.c | 515 +++++++++++++----- 34 files changed, 1653 insertions(+), 290 deletions(-) diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index f18d8c445b..63db4c49f1 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -69,6 +69,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signatu * Don't even attempt signing without a way to safe the updated private key */ if (secret_key->secure_store_scrt_key == NULL) { + fprintf(stderr, "No Secure-store set for secret key.\n."); goto err; } @@ -94,7 +95,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signatu goto err; } - context = lms_key_data->context; + context = secret_key->context; rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf, sk_key_buf_len, context); if (rc_keyupdate != OQS_SUCCESS) { goto err; @@ -241,40 +242,41 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uin } oqs_key_data = malloc(sizeof(oqs_lms_key_data)); - if (oqs_key_data) { - oqs_key_data->levels = 1; - if (sk->length_secret_key) { - oqs_key_data->len_sec_key = sk->length_secret_key; - oqs_key_data->sec_key = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - if (oqs_key_data->sec_key) { - memset(oqs_key_data->sec_key, 0, sk->length_secret_key); - } else { - OQS_MEM_insecure_free(oqs_key_data); - oqs_key_data = NULL; - return -1; - } - } else { - OQS_MEM_insecure_free(oqs_key_data); - oqs_key_data = NULL; - return -1; - } + if (oqs_key_data == NULL) { + return -1; + } - //Aux Data - size_t len_aux_data = DEFAULT_AUX_DATA; - uint8_t *aux_data = malloc(sizeof(uint8_t) * len_aux_data); - if (aux_data) { - oqs_key_data->aux_data = aux_data; - oqs_key_data->len_aux_data = len_aux_data; - } else { - OQS_MEM_insecure_free( oqs_key_data->sec_key); - OQS_MEM_insecure_free(oqs_key_data); - return -1; - } - } else { - //TODO log error + memset(oqs_key_data, 0, sizeof(oqs_lms_key_data)); + if (sk->length_secret_key == 0) { + OQS_MEM_insecure_free(oqs_key_data); + oqs_key_data = NULL; + return -1; + } + + oqs_key_data->levels = 1; + oqs_key_data->len_sec_key = sk->length_secret_key; + oqs_key_data->sec_key = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + if (oqs_key_data->sec_key == NULL) { + OQS_MEM_insecure_free(oqs_key_data); + oqs_key_data = NULL; return -1; } + memset(oqs_key_data->sec_key, 0, sk->length_secret_key); + + //Aux Data + size_t len_aux_data = DEFAULT_AUX_DATA; + uint8_t *aux_data = malloc(sizeof(uint8_t) * len_aux_data); + if (aux_data == NULL) { + OQS_MEM_insecure_free( oqs_key_data->sec_key); + OQS_MEM_insecure_free(oqs_key_data); + return -1; + } + + oqs_key_data->aux_data = aux_data; + oqs_key_data->len_aux_data = len_aux_data; + oqs_key_data->context = sk->context; + /* Set lms param set */ switch (oid) { case OQS_LMS_ID_sha256_n32_h5_w1: @@ -668,6 +670,7 @@ OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_ lms_key_data->len_aux_data = aux_buf_len; } + sk->context = context; sk->secret_key_data = lms_key_data; goto success; @@ -682,9 +685,10 @@ OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_ } void oqs_lms_key_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context) { - oqs_lms_key_data *lms_key_data = (oqs_lms_key_data *)sk->secret_key_data; - if (lms_key_data) { - lms_key_data->context = context; - sk->secure_store_scrt_key = store_cb; + + if (sk == NULL) { + return; } + sk->secure_store_scrt_key = store_cb; + sk->context = context; } diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index 33177e829e..e4b7d42c9c 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -268,6 +268,9 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { /* mutual exclusion struct */ void *mutex; + /* file storage handle */ + void *context; + /** * Secret Key retrieval Function * diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index 54006043e1..8b9536daed 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -503,4 +503,7 @@ OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, /* Deserialize XMSS byte string into an XMSS secret key data */ OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); +/* Set XMSS byte string into an XMSS secret key data */ +void OQS_SECRET_KEY_XMSS_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); + #endif /* OQS_SIG_STFL_XMSS_H */ diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c index 4a47c938c3..a9ea864cdb 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c @@ -37,9 +37,8 @@ OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, cons } if (sk->secret_key_data != NULL) { - // Key data already present - // We dont want to trample over data - return OQS_ERROR; + OQS_MEM_secure_free(sk->secret_key_data, sk->length_secret_key); + sk->secret_key_data = NULL; } // Assume key data is not present @@ -48,7 +47,17 @@ OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, cons return OQS_ERROR; } + sk->context = context; memcpy(sk->secret_key_data, sk_buf, sk_len); return OQS_SUCCESS; } + +void OQS_SECRET_KEY_XMSS_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context) { + if (!sk || !store_cb || !context) { + return; + } + + sk->context = context; + sk->secure_store_scrt_key = store_cb; +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c index 20a8f87af0..2affc67195 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c @@ -68,6 +68,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -87,17 +89,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(XMSS_UNUSED_ATT uint OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } + + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } *signature_len = (size_t)sig_length; - return OQS_SUCCESS; + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c index d32ad7df05..cfaa958dd7 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H16_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_keypair(XMSS_UNUSED_ATT uint OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c index 9675fb1151..1145d17e2b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H20_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_keypair(XMSS_UNUSED_ATT uint OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c index c4589175c6..c7ca88eee7 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H10_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_keypair(XMSS_UNUSED_ATT uint OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c index bab2bda1f2..70123ccb16 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H16_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_keypair(XMSS_UNUSED_ATT uint OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c index 5c931a35c4..ebb03643a6 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H20_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_keypair(XMSS_UNUSED_ATT uint OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c index fde4331e66..4d15d86461 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H10_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_keypair(XMSS_UNUSED_ATT ui OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c index d1587260f3..499ba294ad 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H16_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_keypair(XMSS_UNUSED_ATT ui OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c index c618ce8260..8f47a4f825 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H20_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_keypair(XMSS_UNUSED_ATT ui OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = oqs_serialize_lms_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c index 84e5772280..944a34d9de 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H10_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_keypair(XMSS_UNUSED_ATT ui OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c index 788eb8f1e7..93e8791bf8 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H16_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_keypair(XMSS_UNUSED_ATT ui OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c index 7029f669f8..e701614e79 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H20_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_keypair(XMSS_UNUSED_ATT ui OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c index c4862f728e..f333b08a0e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_2_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_keypair(XMSS_UNUSED_ATT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c index efa097b262..76febd3103 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_4_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_keypair(XMSS_UNUSED_ATT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c index 04c8fd52fb..b2b39b51ec 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_2_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,57 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_keypair(XMSS_UNUSED_ATT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { + fprintf(stderr, "No secret key secure-store set.\n"); return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c index dfa69325e8..4781f49cfe 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_4_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_keypair(XMSS_UNUSED_ATT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c index 7b4640ed40..2acbc1046e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_8_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_keypair(XMSS_UNUSED_ATT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c index 84f0f589d3..d9b98a749f 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_12_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,57 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_keypair(XMSS_UNUSED_ATT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c index c9616932eb..c45fef5959 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_3_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_keypair(XMSS_UNUSED_ATT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c index 7ab46f56ad..f43f87c6b4 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_6_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_keypair(XMSS_UNUSED_ATT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c index 19421bb2ae..16d7270593 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_2_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_keypair(XMSS_UNUSED_AT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c index 1b51a87c76..941a2ecb3c 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_4_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_keypair(XMSS_UNUSED_AT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c index 8e3617fbd0..adc47b4d11 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_2_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_keypair(XMSS_UNUSED_AT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c index 9a5f66ccef..3312f25477 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_4_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_keypair(XMSS_UNUSED_AT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c index 9b6fc160ed..43afdfeeff 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_8_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_keypair(XMSS_UNUSED_AT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c index dfad288f23..bf7c0c56d2 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_12_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_keypair(XMSS_UNUSED_A OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c index acd7b70165..f8b6ab6ec5 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_3_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } @@ -86,17 +88,56 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_keypair(XMSS_UNUSED_AT OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; + const OQS_SIG_STFL_SECRET_KEY *sk; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { return OQS_ERROR; } - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + /* check for secret key update function */ + if (secret_key->secure_store_scrt_key == NULL) { return OQS_ERROR; } - *signature_len = (size_t) sig_length; - return OQS_SUCCESS; + /* Lock secret to ensure OTS use */ + if ((secret_key->lock_key) && (secret_key->mutex)) { + secret_key->lock_key(secret_key->mutex); + } + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + + /* + * serialize and securely store the updated private key + * but, delete signature and the serialized key other wise + */ + + sk = secret_key; + rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + goto err; + } + + rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + if (rc_keyupdate != OQS_SUCCESS) { + status = OQS_ERROR; + } + + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); +err: + /* Unlock secret to ensure OTS use */ + if ((secret_key->unlock_key) && (secret_key->mutex)) { + secret_key->unlock_key(secret_key->mutex); + } + return status; } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c index 889e831775..1821340645 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c @@ -67,6 +67,8 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_6_new(void) { sk->free_key = OQS_SECRET_KEY_XMSS_free; + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + return sk; } diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index d5de696580..33dce7e897 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -20,6 +20,12 @@ #define MAX_MARKER_LEN 50 +static OQS_STATUS do_nothing_save(uint8_t *key_buf, size_t buf_len, void *context) { + (void)(context); + (void)(buf_len); + return key_buf != NULL ? OQS_SUCCESS : OQS_ERROR; +} + // // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) // @@ -150,6 +156,8 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { // Grab the pk and sk from KAT file public_key = malloc(sig->length_public_key); secret_key = OQS_SIG_STFL_SECRET_KEY_new(sig->method_name); + OQS_SIG_STFL_SECRET_KEY_SET_store_cb(secret_key, do_nothing_save, NULL); + signature = calloc(sig->length_signature, sizeof(uint8_t)); signature_kat = calloc(sig->length_signature, sizeof(uint8_t)); diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 9abd8dbe73..305001a462 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -322,6 +322,52 @@ typedef struct magic_s { uint8_t val[31]; } magic_t; +static char *convert_method_name_to_file_name(const char *method_name) { + + const char *file_store = NULL; + char *name = NULL; + if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_2) == 0) { + file_store = "XMSSMT-SHA2_20-2_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_4) == 0) { + file_store = "XMSSMT-SHA2_20-4_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2) == 0) { + file_store = "XMSSMT-SHA2_40-2_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_4) == 0) { + file_store = "XMSSMT-SHA2_40-4_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_8) == 0) { + file_store = "XMSSMT-SHA2_40-8_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3) == 0) { + file_store = "XMSSMT-SHA2_60-3_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_6) == 0) { + file_store = "XMSSMT-SHA2_60-6_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_12) == 0) { + file_store = "XMSSMT-SHA2_60-12_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h20_2) == 0) { + file_store = "XMSSMT-SHAKE_20-2_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h20_4) == 0) { + file_store = "XMSSMT-SHAKE_20-4_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2) == 0) { + file_store = "XMSSMT-SHAKE_40-2_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_4) == 0) { + file_store = "XMSSMT-SHAKE_40-4_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_8) == 0) { + file_store = "XMSSMT-SHAKE_40-8_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3) == 0) { + file_store = "XMSSMT-SHAKE_60-3_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_6) == 0) { + file_store = "XMSSMT-SHAKE_60-6_256"; + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_12) == 0) { + file_store = "XMSSMT-SHAKE_60-12_256"; + } else { + file_store = method_name; + } + + if (file_store) { + name = strdup(file_store); + } + return name; +} + static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char *katfile) { OQS_SIG_STFL *sig = NULL; @@ -337,19 +383,86 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char uint8_t *sk_buf = NULL; uint8_t *read_pk_buf = NULL; char *context = NULL; - const char *file_store = NULL; + char *file_store = NULL; size_t sk_buf_len = 0; size_t read_pk_len = 0; + magic_t magic; + #if OQS_USE_PTHREADS_IN_TESTS pthread_mutex_t *sk_lock = NULL; #endif OQS_STATUS rc, ret = OQS_ERROR; + if (0) { + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { + goto skip_test; +#endif + } else { + goto test_on; + } +skip_test: + printf("skipping slow test %s\n", method_name); + return OQS_SUCCESS; + +test_on: + //The magic numbers are random values. //The length of the magic number was chosen to be 31 to break alignment - magic_t magic; + + OQS_randombytes(magic.val, sizeof(magic_t)); sig = OQS_SIG_STFL_new(method_name); @@ -368,6 +481,16 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char OQS_SIG_STFL_SECRET_KEY_SET_lock(secret_key, lock_sk_key); OQS_SIG_STFL_SECRET_KEY_SET_unlock(secret_key, unlock_sk_key); + file_store = convert_method_name_to_file_name(sig->method_name); + if (file_store == NULL) { + fprintf(stderr, "%s: file_store is null\n", __FUNCTION__); + goto err; + } + + /* set context and secure store callback */ + context = strdup(((file_store))); + OQS_SIG_STFL_SECRET_KEY_SET_store_cb(secret_key, test_save_secret_key, (void *)context); + #if OQS_USE_PTHREADS_IN_TESTS sk_lock = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); if (sk_lock == NULL) { @@ -421,42 +544,6 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char goto err; } - if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_2) == 0) { - file_store = "XMSSMT-SHA2_20-2_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_4) == 0) { - file_store = "XMSSMT-SHA2_20-4_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2) == 0) { - file_store = "XMSSMT-SHA2_40-2_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_4) == 0) { - file_store = "XMSSMT-SHA2_40-4_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_8) == 0) { - file_store = "XMSSMT-SHA2_40-8_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3) == 0) { - file_store = "XMSSMT-SHA2_60-3_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_6) == 0) { - file_store = "XMSSMT-SHA2_60-6_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_12) == 0) { - file_store = "XMSSMT-SHA2_60-12_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h20_2) == 0) { - file_store = "XMSSMT-SHAKE_20-2_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h20_4) == 0) { - file_store = "XMSSMT-SHAKE_20-4_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2) == 0) { - file_store = "XMSSMT-SHAKE_40-2_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_4) == 0) { - file_store = "XMSSMT-SHAKE_40-4_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_8) == 0) { - file_store = "XMSSMT-SHAKE_40-8_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3) == 0) { - file_store = "XMSSMT-SHAKE_60-3_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_6) == 0) { - file_store = "XMSSMT-SHAKE_60-6_256"; - } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_12) == 0) { - file_store = "XMSSMT-SHAKE_60-12_256"; - } else { - file_store = sig->method_name; - } - /* write key pair to disk */ if (oqs_fstore("sk", file_store, sk_buf, sk_buf_len) != OQS_SUCCESS) { goto err; @@ -466,10 +553,6 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char goto err; } - /* set context and secure store callback */ - context = strdup(((file_store))); - OQS_SIG_STFL_SECRET_KEY_SET_store_cb(secret_key, test_save_secret_key, (void *)context); - rc = OQS_SIG_STFL_sign(sig, signature, &signature_len, message, message_len, secret_key); OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); if (rc != OQS_SUCCESS) { @@ -545,6 +628,7 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char OQS_MEM_insecure_free(read_pk_buf); OQS_MEM_insecure_free(context); + OQS_MEM_insecure_free(file_store); #if OQS_USE_PTHREADS_IN_TESTS if (sk_lock) { @@ -568,81 +652,70 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { size_t to_file_sk_len = 0; char *context = NULL; char *context_2 = NULL; + char *file_store_name = NULL; /* * Temporarily skip algs with long key generation times. */ - if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8) == 0 + if (0) { - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1) == 0) { - goto keep_going; - } else { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { goto skip_test; - } +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { + goto skip_test; +#endif -// if (0) { -// -//#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 -// } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { -// goto skip_test; -//#endif -//#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 -// } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { -// goto skip_test; -//#endif -// -//#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 -// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { -// goto skip_test; -//#endif -//#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 -// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { -// goto skip_test; -//#endif -// -//#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 -// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { -// goto skip_test; -//#endif -//#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 -// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { -// goto skip_test; -//#endif -// -//#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 -// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { -// goto skip_test; -//#endif -//#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 -// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { -// goto skip_test; -//#endif -// -//#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 -// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { -// goto skip_test; -//#endif -//#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 -// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { -// goto skip_test; -//#endif -// -//#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 -// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { -// goto skip_test; -//#endif -//#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 -// } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { -// goto skip_test; -//#endif -// } else { -// goto keep_going; -// } +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { + goto skip_test; +#endif + } else { + goto keep_going; + } skip_test: printf("Skip slow test %s.\n", method_name); @@ -706,7 +779,8 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { goto err; } - if (oqs_fstore("sk", sig_obj->method_name, to_file_sk_buf, to_file_sk_len) != OQS_SUCCESS) { + file_store_name = convert_method_name_to_file_name(sig_obj->method_name); + if (oqs_fstore("sk", file_store_name, to_file_sk_buf, to_file_sk_len) != OQS_SUCCESS) { goto err; } @@ -717,13 +791,13 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { /* set context and secure store callback */ if (sk->set_scrt_key_store_cb) { - context = strdup(((method_name))); + context = strdup(file_store_name); sk->set_scrt_key_store_cb(sk, test_save_secret_key, (void *)context); } /* read secret key from disk */ frm_file_sk_buf = malloc(to_file_sk_len); - if (oqs_fload("sk", method_name, frm_file_sk_buf, to_file_sk_len, &frm_file_sk_len) != OQS_SUCCESS) { + if (oqs_fload("sk", file_store_name, frm_file_sk_buf, to_file_sk_len, &frm_file_sk_len) != OQS_SUCCESS) { goto err; } if (to_file_sk_len != frm_file_sk_len) { @@ -737,7 +811,7 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { goto err; } - context_2 = strdup(((method_name))); + context_2 = strdup(file_store_name); rc = OQS_SECRET_KEY_STFL_deserialize_key(sk_frm_file, frm_file_sk_len, frm_file_sk_buf, (void *)context_2); if (rc != OQS_SUCCESS) { @@ -761,12 +835,12 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { OQS_SIG_STFL_free(sig_obj); OQS_MEM_insecure_free(context); OQS_MEM_insecure_free(context_2); + OQS_MEM_insecure_free(file_store_name); return rc; } static OQS_STATUS sig_stfl_test_query_key(const char *method_name) { OQS_STATUS rc = OQS_SUCCESS; - size_t message_len_1 = sizeof(message_1); size_t message_len_2 = sizeof(message_2); @@ -774,20 +848,67 @@ static OQS_STATUS sig_stfl_test_query_key(const char *method_name) { * Temporarily skip algs with long key generation times. */ - if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8) == 0 + if (0) { - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1) == 0) { - goto keep_going; - } else { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { + goto skip_test; +#endif + } else { + goto keep_going; } skip_test: - printf("Skip slow alg %s.\n", method_name); + printf("Skip slow test %s.\n", method_name); return rc; keep_going: @@ -839,24 +960,74 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { size_t message_len_1 = sizeof(message_1); size_t message_len_2 = sizeof(message_2); + char *context = NULL; + char *key_store_name = NULL; + /* * Temporarily skip algs with long key generation times. */ - if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8) == 0 + if (0) { - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1) == 0) { - goto keep_going; - } else { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { + goto skip_test; +#endif + } else { + goto keep_going; } skip_test: - printf("Skip slow alg %s.\n", method_name); + printf("Skip slow test %s.\n", method_name); return rc; keep_going: @@ -869,6 +1040,11 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { return OQS_ERROR; } + key_store_name = convert_method_name_to_file_name(method_name); + /* set context and secure store callback */ + context = strdup(((key_store_name))); + OQS_SIG_STFL_SECRET_KEY_SET_store_cb(lock_test_sk, test_save_secret_key, (void *)context); + /* * Get max num signature and the amount remaining */ @@ -957,6 +1133,8 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { err: rc = OQS_ERROR; end_it: + OQS_MEM_insecure_free(context); + OQS_MEM_insecure_free(key_store_name); return rc; } @@ -964,20 +1142,71 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name) { OQS_STATUS rc = OQS_SUCCESS; + printf("================================================================================\n"); + printf("Testing stateful Signature locks %s\n", method_name); + printf("================================================================================\n"); + /* * Temporarily skip algs with long key generation times. */ - if (strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8) == 0 + if (0) { - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1) == 0 - || strcmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1) == 0) { - goto keep_going; - } else { +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { + goto skip_test; +#endif + } else { + goto keep_going; } skip_test: @@ -986,10 +1215,6 @@ static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name) { keep_going: - printf("================================================================================\n"); - printf("Testing stateful Signature locks %s\n", method_name); - printf("================================================================================\n"); - printf("================================================================================\n"); printf("Create stateful Signature %s\n", method_name); printf("================================================================================\n"); @@ -1046,7 +1271,7 @@ static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name) { /* set context and secure store callback */ if (lock_test_sk->set_scrt_key_store_cb) { - lock_test_context = strdup(((method_name))); + lock_test_context = convert_method_name_to_file_name(method_name); lock_test_sk->set_scrt_key_store_cb(lock_test_sk, test_save_secret_key, (void *)lock_test_context); } From 2dbfc400734501386fd51d50c2739b3f09d25b3d Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Wed, 1 Nov 2023 13:34:21 -0400 Subject: [PATCH 19/68] Update XMSS secret key object APIs, sync with LMS (#1588) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Init * convert all variable length array to malloc/free fix astyle fixed all memory errors * refactor XMSS and XMSS^MT, shorten LOC * clean up unused function * TODO: restore core_hash.c later * Add activate_lock and activate_unlock functions * Add `bool is_locked` to retain lock information, and adjust function signatures * cleanup test_sig_stfl.c * remove const in LMS_serialize_key and add `is_locked` to OQS_SIG_STFL_SECRET_KEY initialization * fix astyle error * fix astyle. I have to update local astyle to 3.4.10 * remove incorrect comments * remove unsued variables * fix if guard * fix const warnings * fix namespace error. revert core_hash.c to original namespace separation * move XMSS_free to internal of XMSS * Fix memory leaks * fix astyle format * fix typo * improve readablity * Update OID comment. * Trim the space * Remove mutex status bool * Remove use of mutex status bool. Use recursive mutex” src/sig_stfl/lms/sig_stfl_lms.c src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c tests/test_sig_stfl.c * rename lock function * simplify the check with 0 * Fix grammar * add `const` back to serialize. Reorder parameters to follow liboqs convention * use inner_serialize to avoid recursive lock * add return code in case pthread API has errors * fix scan_build NULL error --------- Co-authored-by: Norman Ashley --- src/sig_stfl/lms/sig_stfl_lms.c | 6 +- src/sig_stfl/lms/sig_stfl_lms.h | 2 +- src/sig_stfl/lms/sig_stfl_lms_functions.c | 9 +- src/sig_stfl/lms/sig_stfl_lms_wrap.h | 3 - src/sig_stfl/sig_stfl.c | 46 +- src/sig_stfl/sig_stfl.h | 110 ++- src/sig_stfl/xmss/CMakeLists.txt | 56 +- src/sig_stfl/xmss/external/hash.c | 41 +- src/sig_stfl/xmss/external/sign.c | 139 ---- src/sig_stfl/xmss/external/sign.h | 90 --- src/sig_stfl/xmss/external/utils.h | 2 +- src/sig_stfl/xmss/external/wots.c | 25 +- src/sig_stfl/xmss/external/xmss_commons.c | 28 +- src/sig_stfl/xmss/external/xmss_core_fast.c | 110 ++- src/sig_stfl/xmss/sig_stfl_xmss.h | 149 +++- src/sig_stfl/xmss/sig_stfl_xmss_functions.c | 99 +++ .../xmss/sig_stfl_xmss_secret_key_functions.c | 129 +++- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c | 121 +-- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c | 120 +-- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c | 120 +-- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c | 120 +-- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c | 120 +-- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c | 120 +-- .../xmss/sig_stfl_xmss_shake128_h10.c | 120 +-- .../xmss/sig_stfl_xmss_shake128_h16.c | 121 +-- .../xmss/sig_stfl_xmss_shake128_h20.c | 120 +-- .../xmss/sig_stfl_xmss_shake256_h10.c | 120 +-- .../xmss/sig_stfl_xmss_shake256_h16.c | 121 +-- .../xmss/sig_stfl_xmss_shake256_h20.c | 120 +-- src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c | 99 +++ .../xmss/sig_stfl_xmssmt_sha256_h20_2.c | 120 +-- .../xmss/sig_stfl_xmssmt_sha256_h20_4.c | 120 +-- .../xmss/sig_stfl_xmssmt_sha256_h40_2.c | 121 +-- .../xmss/sig_stfl_xmssmt_sha256_h40_4.c | 120 +-- .../xmss/sig_stfl_xmssmt_sha256_h40_8.c | 120 +-- .../xmss/sig_stfl_xmssmt_sha256_h60_12.c | 121 +-- .../xmss/sig_stfl_xmssmt_sha256_h60_3.c | 120 +-- .../xmss/sig_stfl_xmssmt_sha256_h60_6.c | 120 +-- .../xmss/sig_stfl_xmssmt_shake128_h20_2.c | 120 +-- .../xmss/sig_stfl_xmssmt_shake128_h20_4.c | 120 +-- .../xmss/sig_stfl_xmssmt_shake128_h40_2.c | 120 +-- .../xmss/sig_stfl_xmssmt_shake128_h40_4.c | 120 +-- .../xmss/sig_stfl_xmssmt_shake128_h40_8.c | 120 +-- .../xmss/sig_stfl_xmssmt_shake128_h60_12.c | 121 +-- .../xmss/sig_stfl_xmssmt_shake128_h60_3.c | 120 +-- .../xmss/sig_stfl_xmssmt_shake128_h60_6.c | 81 +- tests/kat_sig_stfl.c | 2 +- tests/test_sig_stfl.c | 702 +++++------------- 48 files changed, 1097 insertions(+), 4077 deletions(-) delete mode 100644 src/sig_stfl/xmss/external/sign.c delete mode 100644 src/sig_stfl/xmss/external/sign.h create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_functions.c create mode 100644 src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c diff --git a/src/sig_stfl/lms/sig_stfl_lms.c b/src/sig_stfl/lms/sig_stfl_lms.c index 3503c7447b..b6d57902ee 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.c +++ b/src/sig_stfl/lms/sig_stfl_lms.c @@ -8,7 +8,7 @@ #include "sig_stfl_lms.h" /* Convert LMS secret key object to byte string */ -static OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr); +static OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); /* Insert lms byte string in an LMS secret key object */ static OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); @@ -1760,13 +1760,13 @@ void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk) { } /* Convert LMS secret key object to byte string */ -static OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr) { +static OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk) { OQS_STATUS status; if (sk->lock_key && sk->mutex) { sk->lock_key(sk->mutex); } - status = oqs_serialize_lms_key(sk, sk_len, sk_buf_ptr); + status = oqs_serialize_lms_key(sk_buf_ptr, sk_len, sk); if (sk->unlock_key && sk->mutex) { sk->unlock_key(sk->mutex); diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h index e42450fd15..b75446d2e3 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.h +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -209,7 +209,7 @@ int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, const uint8_t *sm, si void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk); -OQS_STATUS oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_key); +OQS_STATUS oqs_serialize_lms_key(uint8_t **sk_key, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); void oqs_lms_key_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index 63db4c49f1..1e3154b009 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -51,7 +51,6 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signatu OQS_STATUS status = OQS_ERROR; OQS_STATUS rc_keyupdate = OQS_ERROR; oqs_lms_key_data *lms_key_data = NULL; - const OQS_SIG_STFL_SECRET_KEY *sk; uint8_t *sk_key_buf = NULL; size_t sk_key_buf_len = 0; void *context; @@ -89,8 +88,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signatu * but, delete signature and the serialized key other wise */ - sk = secret_key; - rc_keyupdate = oqs_serialize_lms_key(sk, &sk_key_buf_len, &sk_key_buf); + rc_keyupdate = oqs_serialize_lms_key(&sk_key_buf, &sk_key_buf_len, secret_key); if (rc_keyupdate != OQS_SUCCESS) { goto err; } @@ -121,8 +119,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signatu } OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_verify(const uint8_t *message, size_t message_len, - const uint8_t *signature, size_t signature_len, - const uint8_t *public_key) { + const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { if (message == NULL || signature == NULL || public_key == NULL) { return OQS_ERROR; @@ -566,7 +563,7 @@ void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk) { * Convert LMS secret key object to byte string * Writes secret key + aux data if present */ -OQS_STATUS oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_key) { +OQS_STATUS oqs_serialize_lms_key(uint8_t **sk_key, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk) { if (sk == NULL || sk_len == NULL || sk_key == NULL) { return OQS_ERROR; diff --git a/src/sig_stfl/lms/sig_stfl_lms_wrap.h b/src/sig_stfl/lms/sig_stfl_lms_wrap.h index 1d5486d21a..e113a16ed6 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_wrap.h +++ b/src/sig_stfl/lms/sig_stfl_lms_wrap.h @@ -7,7 +7,6 @@ #include "external/hss.h" #include "external/hss_sign_inc.h" - /** * @brief OQS_LMS_KEY object for HSS key pair */ @@ -17,7 +16,6 @@ typedef struct OQS_LMS_SIG_DATA oqs_lms_sig_data; typedef struct OQS_LMS_SIG_DATA { - /* message buffer */ unsigned char *message; @@ -33,4 +31,3 @@ typedef struct OQS_LMS_SIG_DATA { } oqs_lms_sig_data; #endif //OQS_SIG_STFL_LMS_H - diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index b434f54715..9bdee77780 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -14,6 +14,7 @@ OQS_API const char *OQS_SIG_STFL_alg_identifier(size_t i) { const char *a[OQS_SIG_STFL_algs_length] = { + // XMSS OQS_SIG_STFL_alg_xmss_sha256_h10, OQS_SIG_STFL_alg_xmss_sha256_h16, OQS_SIG_STFL_alg_xmss_sha256_h20, @@ -42,6 +43,7 @@ OQS_API const char *OQS_SIG_STFL_alg_identifier(size_t i) { OQS_SIG_STFL_alg_xmssmt_shake128_h60_3, OQS_SIG_STFL_alg_xmssmt_shake128_h60_6, OQS_SIG_STFL_alg_xmssmt_shake128_h60_12, + // LMS OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4, @@ -799,54 +801,38 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_ } } -void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk) { - if (sk == NULL) { - return; - } - - OQS_MEM_secure_free(sk->secret_key_data, sk->length_secret_key); - sk->secret_key_data = NULL; -} - OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk) { - if (sk == NULL) { + if (sk == NULL || sk->free_key == NULL) { return; } /* Call object specific free */ - if (sk->free_key) { - sk->free_key(sk); - } + sk->free_key(sk); + + /* Free sk object */ OQS_MEM_secure_free(sk, sizeof(sk)); + sk = NULL; } OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context) { - if (sk) { - if (sk->set_scrt_key_store_cb) { - sk->set_scrt_key_store_cb(sk, store_cb, context); - } + if (sk == NULL || sk->set_scrt_key_store_cb == NULL) { + return; } + sk->set_scrt_key_store_cb(sk, store_cb, context); } /* Convert secret key object to byte string */ -OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf) { - if ((sk == NULL) || (sk_len == NULL) || (sk_buf == NULL)) { - return 0; - } - if (sk->serialize_key) { - return sk->serialize_key(sk, sk_len, sk_buf); - } else { - return 0; +OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL || sk_len == NULL || sk_buf_ptr == NULL || sk->serialize_key == NULL) { + return OQS_ERROR; } + + return sk->serialize_key(sk_buf_ptr, sk_len, sk); } /* Insert secret key byte string in an Stateful secret key object */ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t key_len, const uint8_t *sk_buf, void *context) { - if ((sk == NULL) || (sk_buf == NULL)) { - return OQS_ERROR; - } - - if (sk->deserialize_key == NULL) { + if (sk == NULL || sk_buf == NULL || sk->deserialize_key == NULL) { return OQS_ERROR; } diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index e4b7d42c9c..ad55b11d1a 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -18,15 +18,15 @@ /* * Developer's Notes: - * Stateful signatures are based on one-time use of a secret key. A pool of secret keys are created for this purpose. - * The state of these keys are tracked to ensure that they are used only once to generate a signature. + * Stateful signatures are based on the one-time use of a secret key. A pool of secret keys is created for this purpose. + * The state of these keys is tracked to ensure that they are used only once to generate a signature. * - * As such, product specific environments do play a role in ensuring the safety of the keys. - * Secret keys must be store securely. + * As such, product-specific environments do play a role in ensuring the safety of the keys. + * Secret keys must be stored securely. * The key index/counter must be updated after each signature generation. - * Secret key must be protected in a thread-save manner. + * The secret key must be protected in a thread-safe manner. * - * Application therefore are required to provide environment specific callback functions to + * Applications therefore are required to provide environment-specific callback functions to * - store private key * - lock/unlock private key * @@ -109,7 +109,7 @@ typedef struct OQS_SIG_STFL_SECRET_KEY OQS_SIG_STFL_SECRET_KEY; /** * Application provided function to securely store data * @param[in] sk_buf pointer to the data to be saved - * @param[in] buf_len length of the the data to be store + * @param[in] buf_len length of the data to be stored * @param[out] context pointer to application relevant data. * return OQS_SUCCESS if successful, otherwise OQS_ERROR */ @@ -117,7 +117,7 @@ typedef OQS_STATUS (*secure_store_sk)(uint8_t *sk_buf, size_t buf_len, void *con /** * Application provided function to lock secret key object serialize access - * @param[in] sk pointer to secret key object to lock + * @param[in] sk pointer to the secret key object to lock * @param[in] mutex pointer to mutex struct * return OQS_SUCCESS if successful, otherwise OQS_ERROR */ @@ -125,7 +125,7 @@ typedef OQS_STATUS (*lock_key)(void *mutex); /** * Application provided function to unlock secret key object - * @param[in] sk pointer to secret key object to unlock + * @param[in] sk pointer to the secret key object to unlock * @param[in] mutex pointer to mutex struct * return OQS_SUCCESS if successful, otherwise OQS_ERROR */ @@ -165,7 +165,10 @@ OQS_API int OQS_SIG_STFL_alg_is_enabled(const char *method_name); */ typedef struct OQS_SIG_STFL { - /** A local ordinal representing the LMS parameter of the signature scheme. */ + /** + * A local ordinal representing the LMS/XMSS OID parameter of the signature scheme. + * This OID is unrelated to ASN.1 OID or anything, it's only for LMS/XMSS internal usage. + */ uint32_t oid; /** Printable string representing the name of the signature scheme. */ @@ -196,8 +199,8 @@ typedef struct OQS_SIG_STFL { * based on the `length_*` members in this object or the per-scheme * compile-time macros `OQS_SIG_STFL_*_length_*`. * - * @param[out] public_key The public key represented as a byte string. - * @param[out] secret_key The secret key represented as a byt string + * @param[out] public_key The public key is represented as a byte string. + * @param[out] secret_key The secret key is represented as a byte string * @return OQS_SUCCESS or OQS_ERROR */ OQS_STATUS (*keypair)(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -209,11 +212,11 @@ typedef struct OQS_SIG_STFL { * based on the `length_*` members in this object or the per-scheme * compile-time macros `OQS_SIG_STFL_*_length_*`. * - * @param[out] signature The signature on the message represented as a byte string. + * @param[out] signature The signature on the message is represented as a byte string. * @param[out] signature_len The length of the signature. - * @param[in] message The message to sign represented as a byte string. + * @param[in] message The message to sign is represented as a byte string. * @param[in] message_len The length of the message to sign. - * @param[in] secret_key The secret key represented as a byte string. + * @param[in] secret_key The secret key is represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ OQS_STATUS (*sign)(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -221,11 +224,11 @@ typedef struct OQS_SIG_STFL { /** * Signature verification algorithm. * - * @param[in] message The message represented as a byte string. + * @param[in] message The message is represented as a byte string. * @param[in] message_len The length of the message. - * @param[in] signature The signature on the message represented as a byte string. + * @param[in] signature The signature on the message is represented as a byte string. * @param[in] signature_len The length of the signature. - * @param[in] public_key The public key represented as a byte string. + * @param[in] public_key The public key is represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ OQS_STATUS (*verify)(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); @@ -234,7 +237,7 @@ typedef struct OQS_SIG_STFL { * Query number of remaining signatures * * @param[out] remain The number of remaining signatures - * @param[in] secret_key The secret key represented as a byte string. + * @param[in] secret_key The secret key is represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ OQS_STATUS (*sigs_remaining)(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -243,7 +246,7 @@ typedef struct OQS_SIG_STFL { * Total number of signatures * * @param[out] total The total number of signatures - * @param[in] secret_key The secret key represented as a byte string. + * @param[in] secret_key The secret key is represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ OQS_STATUS (*sigs_total)(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -262,7 +265,7 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { /* The (maximum) length, in bytes, of secret keys for this signature scheme. */ size_t length_secret_key; - /* The variant specific secret key data */ + /* The variant-specific secret key data, must be allocated at the initialization. */ void *secret_key_data; /* mutual exclusion struct */ @@ -275,22 +278,22 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { * Secret Key retrieval Function * * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object - * @param[out] sk_len length of private key as a byte stream + * @param[out] sk_len length of the private key as a byte stream * @param[out] sk_buf_ptr pointer to private key data as a byte stream * @returns length of key material data available - * Caller deletes the buffer if memory was allocated. + * Caller is responsible for **deallocating** the pointer to buffer `sk_buf_ptr`. */ - OQS_STATUS (*serialize_key)(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr); + OQS_STATUS (*serialize_key)(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); /** - * set Secret Key to internal structure Function + * Secret Key to internal structure Function * * @param[in] sk OQS_SIG_STFL_SECRET_KEY object * @param[in] key_len length of the returned byte string - * @param[in] sk_buf The secret key data to populate key obj - * @param[in] context application specific data - * @returns status of the operation populated with key material none-zero length. Caller - * deletes the buffer. if sk_buf is NULL the function returns the length + * @param[in] sk_buf The secret key data to populate the key object + * @param[in] context application-specific data + * @returns status of the operation populated with key material none zero length. + * Caller is responsible to **unallocate** the buffer `sk_buf`. */ OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); @@ -315,15 +318,15 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { * Callback function used to securely store key data * @param[in] sk_buf The serialized secret key data to secure store * @param[in] buf_len length of data to secure - * @param[in] context aides the secure writing of data + * @param[in] context aids the secure writing of data * * @return OQS_SUCCESS or OQS_ERROR - * Idealy written to secure device + * Ideally written to secure device */ OQS_STATUS (*secure_store_scrt_key)(uint8_t *sk_buf, size_t buf_len, void *context); /** - * Secret Key free internal variant specific data + * Free internal variant-specific data * * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object * @return none @@ -356,12 +359,12 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name); * * Caller is responsible for allocating sufficient memory for `public_key` based * on the `length_*` members in this object or the per-scheme compile-time macros - * `OQS_SIG_STFL_*_length_*`. Caller is also responsible for initializing + * `OQS_SIG_STFL_*_length_*`. The caller is also responsible for initializing * `secret_key` using the OQS_SIG_STFL_SECRET_KEY(*) function * * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. - * @param[out] public_key The public key represented as a byte string. - * @param[out] secret_key The secret key represented as a byte string. + * @param[out] public_key The public key is represented as a byte string. + * @param[out] secret_key The secret key is represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -374,11 +377,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public * compile-time macros `OQS_SIG_STFL_*_length_*`. * * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. - * @param[out] signature The signature on the message represented as a byte string. + * @param[out] signature The signature on the message is represented as a byte string. * @param[out] signature_len The length of the signature. - * @param[in] message The message to sign represented as a byte string. + * @param[in] message The message to sign is represented as a byte string. * @param[in] message_len The length of the message to sign. - * @param[in] secret_key The secret key represented as a byte string. + * @param[in] secret_key The secret key is represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -387,11 +390,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature * Signature verification algorithm. * * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. - * @param[in] message The message represented as a byte string. + * @param[in] message The message is represented as a byte string. * @param[in] message_len The length of the message. - * @param[in] signature The signature on the message represented as a byte string. + * @param[in] signature The signature on the message is represented as a byte string. * @param[in] signature_len The length of the signature. - * @param[in] public_key The public key represented as a byte string. + * @param[in] public_key The public key is represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); @@ -400,7 +403,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m * Query number of remaining signatures * * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. - * @param[in] secret_key The secret key represented as a byte string. + * @param[in] secret_key The secret key is represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -410,7 +413,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned * * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. * @param[out] max The number of remaining signatures - * @param[in] secret_key The secret key represented as a byte string. + * @param[in] secret_key The secret key is represented as a byte string. * @return OQS_SUCCESS or OQS_ERROR */ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned long long *max, const OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -432,19 +435,11 @@ OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig); */ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_name); -/** - * Frees an OQS_SIG_STFL_SECRET_KEY **inner** data that was constructed by OQS_SECRET_KEY_new. - * - * @param[in] sig The OQS_SIG_STFL_SECRET_KEY object to free. - * @return OQS_SUCCESS if successful, or OQS_ERROR if the object could not be freed. - */ -void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk); - /** * Frees an OQS_SIG_STFL_SECRET_KEY object that was constructed by OQS_SECRET_KEY_new. * * @param[in] sig The OQS_SIG_STFL_SECRET_KEY object to free. - * @return OQS_SUCCESS if successful, or OQS_ERROR if the object could not be freed. + * @return OQS_SUCCESS if successful, or OQS_ERROR if the object cannot be freed. */ OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk); @@ -484,7 +479,7 @@ void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void *mutex) /** * OQS_SIG_STFL_SECRET_KEY_lock . * - * Locks sk so only one application that holds the lock can access it. + * Locks the secret key so only one application that holds the lock can access it. * * @param[in] sk secret key pointer to be locked * @return OQS_SUCCESS if successful, or OQS_ERROR if the object fails to apply the lock @@ -495,7 +490,7 @@ OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk); /** * OQS_SIG_STFL_SECRET_KEY_unlock . * - * Unlocks the resouces so that th enext process can access it. + * Unlocks the secret key so that the next process can access it. * * @param[in] sk secret key pointer * @return OQS_SUCCESS if successful, or OQS_ERROR if the object fails to release the lock @@ -507,7 +502,7 @@ OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk); * OQS_SIG_STFL_SECRET_KEY_SET_store_cb . * * Can be called after creating a new stateful secret key has been generated. - * Allows the lib to securely store and update secret key after a sign operation. + * Allows the lib to securely store and update the secret key after a sign operation. * * @param[in] sk secret key pointer to be updated * @param[in] store_cb callback pointer @@ -516,9 +511,10 @@ OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk); */ void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); -OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf); +/* Serialize stateful secret key data into a byte string, and return an allocated buffer. Users are responsible for deallocating the buffer `sk_buf`. */ +OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); -/* Insert lms byte string in an LMS secret key object */ +/* Insert stateful byte string into a secret key object. Users are responsible for deallocating buffer `sk_buf`. */ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf, void *context); #if defined(__cplusplus) diff --git a/src/sig_stfl/xmss/CMakeLists.txt b/src/sig_stfl/xmss/CMakeLists.txt index 1b55b20866..e1d287472f 100644 --- a/src/sig_stfl/xmss/CMakeLists.txt +++ b/src/sig_stfl/xmss/CMakeLists.txt @@ -17,169 +17,169 @@ add_library(sig_stfl_xmss_secret_key_functions OBJECT sig_stfl_xmss_secret_key_f set(_XMSS_OBJS ${_XMSS_OBJS} $) if (OQS_ENABLE_SIG_STFL_xmss_sha256_h10) - add_library(xmss_sha256_h10 OBJECT sig_stfl_xmss_sha256_h10.c ${SRCS}) + add_library(xmss_sha256_h10 OBJECT sig_stfl_xmss_sha256_h10.c sig_stfl_xmss_functions.c ${SRCS}) target_compile_options(xmss_sha256_h10 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha256_h10 -DHASH=3) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmss_sha256_h16) - add_library(xmss_sha256_h16 OBJECT sig_stfl_xmss_sha256_h16.c ${SRCS}) + add_library(xmss_sha256_h16 OBJECT sig_stfl_xmss_sha256_h16.c sig_stfl_xmss_functions.c ${SRCS}) target_compile_options(xmss_sha256_h16 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha256_h16 -DHASH=3) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmss_sha256_h20) - add_library(xmss_sha256_h20 OBJECT sig_stfl_xmss_sha256_h20.c ${SRCS}) + add_library(xmss_sha256_h20 OBJECT sig_stfl_xmss_sha256_h20.c sig_stfl_xmss_functions.c ${SRCS}) target_compile_options(xmss_sha256_h20 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha256_h20 -DHASH=3) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmss_shake128_h10) - add_library(xmss_shake128_h10 OBJECT sig_stfl_xmss_shake128_h10.c ${SRCS}) + add_library(xmss_shake128_h10 OBJECT sig_stfl_xmss_shake128_h10.c sig_stfl_xmss_functions.c ${SRCS}) target_compile_options(xmss_shake128_h10 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_shake128_h10 -DHASH=4) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmss_shake128_h16) - add_library(xmss_shake128_h16 OBJECT sig_stfl_xmss_shake128_h16.c ${SRCS}) + add_library(xmss_shake128_h16 OBJECT sig_stfl_xmss_shake128_h16.c sig_stfl_xmss_functions.c ${SRCS}) target_compile_options(xmss_shake128_h16 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_shake128_h16 -DHASH=4) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmss_shake128_h20) - add_library(xmss_shake128_h20 OBJECT sig_stfl_xmss_shake128_h20.c ${SRCS}) + add_library(xmss_shake128_h20 OBJECT sig_stfl_xmss_shake128_h20.c sig_stfl_xmss_functions.c ${SRCS}) target_compile_options(xmss_shake128_h20 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_shake128_h20 -DHASH=4) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmss_sha512_h10) - add_library(xmss_sha512_h10 OBJECT sig_stfl_xmss_sha512_h10.c ${SRCS}) + add_library(xmss_sha512_h10 OBJECT sig_stfl_xmss_sha512_h10.c sig_stfl_xmss_functions.c ${SRCS}) target_compile_options(xmss_sha512_h10 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha512_h10 -DHASH=6) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmss_sha512_h16) - add_library(xmss_sha512_h16 OBJECT sig_stfl_xmss_sha512_h16.c ${SRCS}) + add_library(xmss_sha512_h16 OBJECT sig_stfl_xmss_sha512_h16.c sig_stfl_xmss_functions.c ${SRCS}) target_compile_options(xmss_sha512_h16 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha512_h16 -DHASH=6) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmss_sha512_h20) - add_library(xmss_sha512_h20 OBJECT sig_stfl_xmss_sha512_h20.c ${SRCS}) + add_library(xmss_sha512_h20 OBJECT sig_stfl_xmss_sha512_h20.c sig_stfl_xmss_functions.c ${SRCS}) target_compile_options(xmss_sha512_h20 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha512_h20 -DHASH=6) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmss_shake256_h10) - add_library(xmss_shake256_h10 OBJECT sig_stfl_xmss_shake256_h10.c ${SRCS}) + add_library(xmss_shake256_h10 OBJECT sig_stfl_xmss_shake256_h10.c sig_stfl_xmss_functions.c ${SRCS}) target_compile_options(xmss_shake256_h10 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_shake256_h10 -DHASH=7) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmss_shake256_h16) - add_library(xmss_shake256_h16 OBJECT sig_stfl_xmss_shake256_h16.c ${SRCS}) + add_library(xmss_shake256_h16 OBJECT sig_stfl_xmss_shake256_h16.c sig_stfl_xmss_functions.c ${SRCS}) target_compile_options(xmss_shake256_h16 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_shake256_h16 -DHASH=7) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmss_shake256_h20) - add_library(xmss_shake256_h20 OBJECT sig_stfl_xmss_shake256_h20.c ${SRCS}) + add_library(xmss_shake256_h20 OBJECT sig_stfl_xmss_shake256_h20.c sig_stfl_xmss_functions.c ${SRCS}) target_compile_options(xmss_shake256_h20 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_shake256_h20 -DHASH=7) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_2) - add_library(xmssmt_sha256_h20_2 OBJECT sig_stfl_xmssmt_sha256_h20_2.c ${SRCS}) + add_library(xmssmt_sha256_h20_2 OBJECT sig_stfl_xmssmt_sha256_h20_2.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_sha256_h20_2 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h20_2 -DHASH=3) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_4) - add_library(xmssmt_sha256_h20_4 OBJECT sig_stfl_xmssmt_sha256_h20_4.c ${SRCS}) + add_library(xmssmt_sha256_h20_4 OBJECT sig_stfl_xmssmt_sha256_h20_4.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_sha256_h20_4 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h20_4 -DHASH=3) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2) - add_library(xmssmt_sha256_h40_2 OBJECT sig_stfl_xmssmt_sha256_h40_2.c ${SRCS}) + add_library(xmssmt_sha256_h40_2 OBJECT sig_stfl_xmssmt_sha256_h40_2.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_sha256_h40_2 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h40_2 -DHASH=3) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_4) - add_library(xmssmt_sha256_h40_4 OBJECT sig_stfl_xmssmt_sha256_h40_4.c ${SRCS}) + add_library(xmssmt_sha256_h40_4 OBJECT sig_stfl_xmssmt_sha256_h40_4.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_sha256_h40_4 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h40_4 -DHASH=3) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_8) - add_library(xmssmt_sha256_h40_8 OBJECT sig_stfl_xmssmt_sha256_h40_8.c ${SRCS}) + add_library(xmssmt_sha256_h40_8 OBJECT sig_stfl_xmssmt_sha256_h40_8.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_sha256_h40_8 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h40_8 -DHASH=3) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3) - add_library(xmssmt_sha256_h60_3 OBJECT sig_stfl_xmssmt_sha256_h60_3.c ${SRCS}) + add_library(xmssmt_sha256_h60_3 OBJECT sig_stfl_xmssmt_sha256_h60_3.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_sha256_h60_3 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h60_3 -DHASH=3) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_6) - add_library(xmssmt_sha256_h60_6 OBJECT sig_stfl_xmssmt_sha256_h60_6.c ${SRCS}) + add_library(xmssmt_sha256_h60_6 OBJECT sig_stfl_xmssmt_sha256_h60_6.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_sha256_h60_6 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h60_6 -DHASH=3) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_12) - add_library(xmssmt_sha256_h60_12 OBJECT sig_stfl_xmssmt_sha256_h60_12.c ${SRCS}) + add_library(xmssmt_sha256_h60_12 OBJECT sig_stfl_xmssmt_sha256_h60_12.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_sha256_h60_12 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_sha256_h60_12 -DHASH=3) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_2) - add_library(xmssmt_shake128_h20_2 OBJECT sig_stfl_xmssmt_shake128_h20_2.c ${SRCS}) + add_library(xmssmt_shake128_h20_2 OBJECT sig_stfl_xmssmt_shake128_h20_2.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_shake128_h20_2 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h20_2 -DHASH=4) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_4) - add_library(xmssmt_shake128_h20_4 OBJECT sig_stfl_xmssmt_shake128_h20_4.c ${SRCS}) + add_library(xmssmt_shake128_h20_4 OBJECT sig_stfl_xmssmt_shake128_h20_4.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_shake128_h20_4 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h20_4 -DHASH=4) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2) - add_library(xmssmt_shake128_h40_2 OBJECT sig_stfl_xmssmt_shake128_h40_2.c ${SRCS}) + add_library(xmssmt_shake128_h40_2 OBJECT sig_stfl_xmssmt_shake128_h40_2.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_shake128_h40_2 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h40_2 -DHASH=4) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_4) - add_library(xmssmt_shake128_h40_4 OBJECT sig_stfl_xmssmt_shake128_h40_4.c ${SRCS}) + add_library(xmssmt_shake128_h40_4 OBJECT sig_stfl_xmssmt_shake128_h40_4.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_shake128_h40_4 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h40_4 -DHASH=4) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_8) - add_library(xmssmt_shake128_h40_8 OBJECT sig_stfl_xmssmt_shake128_h40_8.c ${SRCS}) + add_library(xmssmt_shake128_h40_8 OBJECT sig_stfl_xmssmt_shake128_h40_8.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_shake128_h40_8 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h40_8 -DHASH=4) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3) - add_library(xmssmt_shake128_h60_3 OBJECT sig_stfl_xmssmt_shake128_h60_3.c ${SRCS}) + add_library(xmssmt_shake128_h60_3 OBJECT sig_stfl_xmssmt_shake128_h60_3.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_shake128_h60_3 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h60_3 -DHASH=4) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6) - add_library(xmssmt_shake128_h60_6 OBJECT sig_stfl_xmssmt_shake128_h60_6.c ${SRCS}) + add_library(xmssmt_shake128_h60_6 OBJECT sig_stfl_xmssmt_shake128_h60_6.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_shake128_h60_6 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h60_6 -DHASH=4) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() if (OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12) - add_library(xmssmt_shake128_h60_12 OBJECT sig_stfl_xmssmt_shake128_h60_12.c ${SRCS}) + add_library(xmssmt_shake128_h60_12 OBJECT sig_stfl_xmssmt_shake128_h60_12.c sig_stfl_xmssmt_functions.c ${SRCS}) target_compile_options(xmssmt_shake128_h60_12 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmssmt_shake128_h60_12 -DHASH=4) set(_XMSS_OBJS ${_XMSS_OBJS} $) endif() diff --git a/src/sig_stfl/xmss/external/hash.c b/src/sig_stfl/xmss/external/hash.c index c335d7d680..a6bac00724 100644 --- a/src/sig_stfl/xmss/external/hash.c +++ b/src/sig_stfl/xmss/external/hash.c @@ -30,13 +30,17 @@ int prf(const xmss_params *params, unsigned char *out, const unsigned char in[32], const unsigned char *key) { - unsigned char buf[params->padding_len + params->n + 32]; + unsigned char* buf = malloc(params->padding_len + params->n + 32); ull_to_bytes(buf, params->padding_len, XMSS_HASH_PADDING_PRF); memcpy(buf + params->padding_len, key, params->n); memcpy(buf + params->padding_len + params->n, in, 32); - return core_hash(params, out, buf, params->padding_len + params->n + 32); + int ret = core_hash(params, out, buf, params->padding_len + params->n + 32); + + OQS_MEM_insecure_free(buf); + + return ret; } /* @@ -47,13 +51,17 @@ int prf_keygen(const xmss_params *params, unsigned char *out, const unsigned char *in, const unsigned char *key) { - unsigned char buf[params->padding_len + 2*params->n + 32]; + unsigned char *buf = malloc(params->padding_len + 2*params->n + 32); ull_to_bytes(buf, params->padding_len, XMSS_HASH_PADDING_PRF_KEYGEN); memcpy(buf + params->padding_len, key, params->n); memcpy(buf + params->padding_len + params->n, in, params->n + 32); - return core_hash(params, out, buf, params->padding_len + 2*params->n + 32); + int ret = core_hash(params, out, buf, params->padding_len + 2*params->n + 32); + + OQS_MEM_insecure_free(buf); + + return ret; } /* @@ -85,8 +93,11 @@ int thash_h(const xmss_params *params, unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8]) { - unsigned char buf[params->padding_len + 3 * params->n]; - unsigned char bitmask[2 * params->n]; + unsigned char *tmp = malloc(params->padding_len + 3 * params->n + 2 * params->n); + + unsigned char *buf = tmp; + unsigned char *bitmask = tmp + (params->padding_len + 3 * params->n); + unsigned char addr_as_bytes[32]; unsigned int i; @@ -110,15 +121,21 @@ int thash_h(const xmss_params *params, for (i = 0; i < 2 * params->n; i++) { buf[params->padding_len + params->n + i] = in[i] ^ bitmask[i]; } - return core_hash(params, out, buf, params->padding_len + 3 * params->n); + int ret = core_hash(params, out, buf, params->padding_len + 3 * params->n); + + OQS_MEM_insecure_free(tmp); + + return ret; } int thash_f(const xmss_params *params, unsigned char *out, const unsigned char *in, const unsigned char *pub_seed, uint32_t addr[8]) { - unsigned char buf[params->padding_len + 2 * params->n]; - unsigned char bitmask[params->n]; + unsigned char *tmp = malloc(params->padding_len + 2 * params->n + params->n); + unsigned char *buf = tmp; + unsigned char *bitmask = tmp + (params->padding_len + 2 * params->n); + unsigned char addr_as_bytes[32]; unsigned int i; @@ -138,5 +155,9 @@ int thash_f(const xmss_params *params, for (i = 0; i < params->n; i++) { buf[params->padding_len + params->n + i] = in[i] ^ bitmask[i]; } - return core_hash(params, out, buf, params->padding_len + 2 * params->n); + int ret = core_hash(params, out, buf, params->padding_len + 2 * params->n); + + OQS_MEM_insecure_free(tmp); + + return ret; } diff --git a/src/sig_stfl/xmss/external/sign.c b/src/sig_stfl/xmss/external/sign.c deleted file mode 100644 index 8bffc7f516..0000000000 --- a/src/sig_stfl/xmss/external/sign.c +++ /dev/null @@ -1,139 +0,0 @@ -/*============================================================================= - * Copyright (c) 2022 by SandboxAQ Inc - * Author: Duc Tri Nguyen (ductri.nguyen@sandboxaq.com) - * SPDX-License-Identifier: MIT -=============================================================================*/ -#include -#include - -#include "sign.h" -#include "sign_params.h" - -/************************************************* - * Name: XMSS_crypto_sign_keypair - * - * Description: Generates public and private key. - * - * Arguments: - uint8_t *pk: pointer to output public key (allocated - * array of CRYPTO_PUBLICKEYBYTES bytes) - * - uint8_t *sk: pointer to output private key (allocated - * array of CRYPTO_SECRETKEYBYTES bytes) - * - * Returns 0 (success), -1 otherwise - **************************************************/ -int crypto_sign_keypair(unsigned char *pk, unsigned char *sk) -{ - xmss_params params; - uint32_t oid; - int ret = 0; - - ret |= XMSS_STR_TO_OID(&oid, XMSS_OID); - if (ret) - { - return OQS_ERROR; - } - - ret |= XMSS_PARSE_OID(¶ms, oid); - if (ret) - { - return OQS_ERROR; - } - - // TODO: set OID directly here - ret |= XMSS_KEYPAIR(pk, sk, oid); - if (ret) - { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -/************************************************* - * Name: XMSS_crypto_sign - * - * Description: Computes signature. - * - * Arguments: - uint8_t *sm: pointer to output signature (of length CRYPTO_BYTES) - * - uint64_t *smlen: pointer to output length of signature - * - uint8_t *m: pointer to message to be signed - * - uint64_t mlen: length of message - * - uint8_t *sk: pointer to bit-packed secret key - * - * Returns 0 (success), -1 otherwise - **************************************************/ -int crypto_sign(unsigned char *sm, unsigned long long *smlen, - const unsigned char *m, unsigned long long mlen, unsigned char *sk) -{ - int ret = XMSS_SIGN(sk, sm, smlen, m, mlen); - if (ret) - { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -/************************************************* - * Name: XMSS_crypto_sign_open - * - * Description: Verify signed message. - * - * Arguments: - * - uint8_t *m: pointer to output message (allocated - * array with smlen bytes), can be equal to sm - * - uint64_t *mlen: pointer to output length of message - * - uint8_t *sm: pointer to signed message - * - uint64_t smlen: length of signed message - * - uint8_t *pk: pointer to bit-packed public key - * - * Returns 0 if signed message could be verified correctly and -1 otherwise - **************************************************/ -int crypto_sign_open(const unsigned char *m, unsigned long long mlen, - const unsigned char *sm, unsigned long long smlen, const unsigned char *pk) -{ - if (XMSS_SIGN_OPEN(m, mlen, sm, smlen, pk)) - { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -/************************************************* - * Name: XMSS_crypto_remaining_signatures - * - * Description: Return number of remaining signatures - * - * Arguments: - uint64_t *remain: remaining signatures - * - uint8_t *sk: pointer to bit-packed private key - * - * Returns 0 (sucess), -1 otherwise - **************************************************/ -int crypto_remaining_signatures(unsigned long long *remain, const unsigned char *sk) -{ - if (XMSS_REMAINING_SIG(remain, sk)) - { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -/************************************************* - * Name: XMSS_crypto_total_signatures - * - * Description: Return number of total signatures - * - * Arguments: - uint64_t *max: maximum number of signatures - * - uint8_t *sk: pointer to bit-packed private key - * - * Returns 0 (sucess), -1 otherwise - **************************************************/ -int crypto_total_signatures(unsigned long long *max, const unsigned char *sk) -{ - if (XMSS_TOTAL_SIG(max, sk)) - { - return OQS_ERROR; - } - return OQS_SUCCESS; -} diff --git a/src/sig_stfl/xmss/external/sign.h b/src/sig_stfl/xmss/external/sign.h deleted file mode 100644 index df2c2fb7ca..0000000000 --- a/src/sig_stfl/xmss/external/sign.h +++ /dev/null @@ -1,90 +0,0 @@ -/*============================================================================= - * Copyright (c) 2022 by SandboxAQ Inc - * Author: Duc Tri Nguyen (ductri.nguyen@sandboxaq.com) - * SPDX-License-Identifier: MIT -=============================================================================*/ -#ifndef API_H -#define API_H - -#include -#include "namespace.h" -/************************************************* - * Name: XMSS_crypto_sign_keypair - * - * Description: Generates public and private key. - * - * Arguments: - uint8_t *pk: pointer to output public key (allocated - * array of CRYPTO_PUBLICKEYBYTES bytes) - * - uint8_t *sk: pointer to output private key (allocated - * array of CRYPTO_SECRETKEYBYTES bytes) - * - * Returns 0 (success), -1 otherwise - **************************************************/ -#define crypto_sign_keypair XMSS_NAMESPACE(crypto_sign_keypair) -int crypto_sign_keypair(unsigned char *pk, unsigned char *sk); - -/************************************************* - * Name: XMSS_crypto_sign - * - * Description: Computes signature. - * - * Arguments: - uint8_t *sm: pointer to output signature (of length CRYPTO_BYTES) - * - uint64_t *smlen: pointer to output length of signature - * - uint8_t *m: pointer to message to be signed - * - uint64_t mlen: length of message - * - uint8_t *sk: pointer to bit-packed secret key - * - * Returns 0 (success), -1 otherwise - **************************************************/ -#define crypto_sign XMSS_NAMESPACE(crypto_sign) -int crypto_sign(unsigned char *sm, unsigned long long *smlen, - const unsigned char *m, unsigned long long mlen, unsigned char *sk); - -/************************************************* - * Name: XMSS_crypto_sign_open - * - * Description: Verify signed message. - * - * Arguments: - * - uint8_t *m: pointer to output message (allocated - * array with smlen bytes), can be equal to sm - * - uint64_t *mlen: pointer to output length of message - * - uint8_t *sm: pointer to signed message - * - uint64_t smlen: length of signed message - * - uint8_t *pk: pointer to bit-packed public key - * - * Returns 0 if signed message could be verified correctly and -1 otherwise - **************************************************/ -#define crypto_sign_open XMSS_NAMESPACE(crypto_sign_open) -int crypto_sign_open(const unsigned char *m, unsigned long long mlen, - const unsigned char *sm, unsigned long long smlen, const unsigned char *pk); - -/************************************************* - * Name: XMSS_crypto_remaining_signatures - * - * Description: Return number of signatures left - * - * Arguments: - uint64_t *remain: remaining signatures - * - uint8_t *sk: pointer to bit-packed private key - * - * Returns 0 (sucess), -1 otherwise - **************************************************/ -#define crypto_remaining_signatures XMSS_NAMESPACE(crypto_remaining_signatures) -int crypto_remaining_signatures(unsigned long long *remain, const unsigned char *sk); - - -/************************************************* - * Name: XMSS_crypto_total_signatures - * - * Description: Return number of total signatures - * - * Arguments: - uint64_t *max: maximum number of signatures - * - uint8_t *sk: pointer to bit-packed private key - * - * Returns 0 (sucess), -1 otherwise - **************************************************/ -#define crypto_total_signatures XMSS_NAMESPACE(crypto_total_signatures) -int crypto_total_signatures(unsigned long long *max, const unsigned char *sk); - -#endif - diff --git a/src/sig_stfl/xmss/external/utils.h b/src/sig_stfl/xmss/external/utils.h index 0cdf79475a..fc5df634a6 100644 --- a/src/sig_stfl/xmss/external/utils.h +++ b/src/sig_stfl/xmss/external/utils.h @@ -2,7 +2,7 @@ #define XMSS_UTILS_H #include "namespace.h" - +#include /** * Converts the value of 'in' to 'outlen' bytes in big-endian byte order. */ diff --git a/src/sig_stfl/xmss/external/wots.c b/src/sig_stfl/xmss/external/wots.c index 90a6bd74d0..09db90e55c 100644 --- a/src/sig_stfl/xmss/external/wots.c +++ b/src/sig_stfl/xmss/external/wots.c @@ -12,11 +12,11 @@ * Expands an n-byte array into a len*n byte array using the `prf_keygen` function. */ static void expand_seed(const xmss_params *params, - unsigned char *outseeds, const unsigned char *inseed, + unsigned char *outseeds, const unsigned char *inseed, const unsigned char *pub_seed, uint32_t addr[8]) { unsigned int i; - unsigned char buf[params->n + 32]; + unsigned char *buf = malloc(params->n + 32); set_hash_addr(addr, 0); set_key_and_mask(addr, 0); @@ -26,6 +26,8 @@ static void expand_seed(const xmss_params *params, addr_to_bytes(buf + params->n, addr); prf_keygen(params, outseeds + i*params->n, buf, inseed); } + + OQS_MEM_insecure_free(buf); } /** @@ -83,7 +85,8 @@ static void wots_checksum(const xmss_params *params, unsigned int *csum_base_w, const unsigned int *msg_base_w) { int csum = 0; - unsigned char csum_bytes[(params->wots_len2 * params->wots_log_w + 7) / 8]; + unsigned int csum_bytes_length = (params->wots_len2 * params->wots_log_w + 7) / 8; + unsigned char *csum_bytes = malloc(csum_bytes_length); unsigned int i; /* Compute checksum. */ @@ -94,8 +97,10 @@ static void wots_checksum(const xmss_params *params, /* Convert checksum to base_w. */ /* Make sure expected empty zero bits are the least significant bits. */ csum = csum << (8 - ((params->wots_len2 * params->wots_log_w) % 8)); - ull_to_bytes(csum_bytes, sizeof(csum_bytes), csum); + ull_to_bytes(csum_bytes, csum_bytes_length, csum); base_w(params, csum_base_w, params->wots_len2, csum_bytes); + + OQS_MEM_insecure_free(csum_bytes); } /* Takes a message and derives the matching chain lengths. */ @@ -139,11 +144,9 @@ void wots_sign(const xmss_params *params, const unsigned char *seed, const unsigned char *pub_seed, uint32_t addr[8]) { - unsigned int lengths[params->wots_len]; + unsigned int *lengths = calloc(params->wots_len, sizeof(unsigned int)); unsigned int i; - memset(lengths, 0, sizeof(unsigned int)*params->wots_len); - chain_lengths(params, lengths, msg); /* The WOTS+ private key is derived from the seed. */ @@ -154,6 +157,8 @@ void wots_sign(const xmss_params *params, gen_chain(params, sig + i*params->n, sig + i*params->n, 0, lengths[i], pub_seed, addr); } + + OQS_MEM_insecure_free(lengths); } /** @@ -165,11 +170,9 @@ void wots_pk_from_sig(const xmss_params *params, unsigned char *pk, const unsigned char *sig, const unsigned char *msg, const unsigned char *pub_seed, uint32_t addr[8]) { - unsigned int lengths[params->wots_len]; + unsigned int *lengths = calloc(params->wots_len, sizeof(unsigned int )); unsigned int i; - memset(lengths, 0, sizeof(unsigned int)*params->wots_len); - chain_lengths(params, lengths, msg); for (i = 0; i < params->wots_len; i++) { @@ -177,4 +180,6 @@ void wots_pk_from_sig(const xmss_params *params, unsigned char *pk, gen_chain(params, pk + i*params->n, sig + i*params->n, lengths[i], params->wots_w - 1 - lengths[i], pub_seed, addr); } + + OQS_MEM_insecure_free(lengths); } diff --git a/src/sig_stfl/xmss/external/xmss_commons.c b/src/sig_stfl/xmss/external/xmss_commons.c index 882a3e39d6..9838f755b0 100644 --- a/src/sig_stfl/xmss/external/xmss_commons.c +++ b/src/sig_stfl/xmss/external/xmss_commons.c @@ -57,7 +57,7 @@ static void compute_root(const xmss_params *params, unsigned char *root, const unsigned char *pub_seed, uint32_t addr[8]) { uint32_t i; - unsigned char buffer[2*params->n]; + unsigned char *buffer = malloc(2*params->n); /* If leafidx is odd (last bit = 1), current path element is a right child and auth_path has to go left. Otherwise it is the other way around. */ @@ -93,6 +93,8 @@ static void compute_root(const xmss_params *params, unsigned char *root, leafidx >>= 1; set_tree_index(addr, leafidx); thash_h(params, root, buffer, pub_seed, addr); + + OQS_MEM_insecure_free(buffer); } @@ -105,11 +107,13 @@ void gen_leaf_wots(const xmss_params *params, unsigned char *leaf, const unsigned char *sk_seed, const unsigned char *pub_seed, uint32_t ltree_addr[8], uint32_t ots_addr[8]) { - unsigned char pk[params->wots_sig_bytes]; + unsigned char *pk = malloc(params->wots_sig_bytes); wots_pkgen(params, pk, sk_seed, pub_seed, ots_addr); l_tree(params, leaf, pk, pub_seed, ltree_addr); + + OQS_MEM_insecure_free(pk); } @@ -140,16 +144,18 @@ int xmssmt_core_sign_open(const xmss_params *params, { const unsigned char *pub_root = pk; const unsigned char *pub_seed = pk + params->n; - unsigned char wots_pk[params->wots_sig_bytes]; - unsigned char leaf[params->n]; - unsigned char root[params->n]; + + unsigned char *tmp = malloc(params->wots_sig_bytes + params->n + params->n); + unsigned char *wots_pk = tmp; + unsigned char *leaf = tmp + params->wots_sig_bytes; + unsigned char *root = leaf + params->n; unsigned long long prefix_length = params->padding_len + 3*params->n; unsigned char m_with_prefix[mlen + prefix_length]; - + unsigned char *mhash = root; unsigned long long idx = 0; - unsigned int i; + unsigned int i, ret; uint32_t idx_leaf; uint32_t ots_addr[8] = {0}; @@ -209,8 +215,12 @@ int xmssmt_core_sign_open(const xmss_params *params, /* Check if the root node equals the root node in the public key. */ if (memcmp(root, pub_root, params->n)) { /* If not, return fail */ - return -1; + ret = -1; + goto fail; } + ret = 0; +fail: + OQS_MEM_insecure_free(tmp); + return ret; - return 0; } diff --git a/src/sig_stfl/xmss/external/xmss_core_fast.c b/src/sig_stfl/xmss/external/xmss_core_fast.c index b3de5f17f0..4dd4c9b41d 100644 --- a/src/sig_stfl/xmss/external/xmss_core_fast.c +++ b/src/sig_stfl/xmss/external/xmss_core_fast.c @@ -170,11 +170,11 @@ static void deep_state_swap(const xmss_params *params, } // TODO this is extremely ugly and should be refactored // TODO right now, this ensures that both 'stack' and 'retain' fit - unsigned char t[ + unsigned char *t = malloc( ((params->tree_height + 1) > ((1 << params->bds_k) - params->bds_k - 1) ? (params->tree_height + 1) : ((1 << params->bds_k) - params->bds_k - 1)) - * params->n]; + * params->n); unsigned int i; memswap(a->stack, b->stack, t, (params->tree_height + 1) * params->n); @@ -193,6 +193,8 @@ static void deep_state_swap(const xmss_params *params, memswap(a->retain, b->retain, t, ((1 << params->bds_k) - params->bds_k - 1) * params->n); memswap(&a->next_leaf, &b->next_leaf, t, sizeof(a->next_leaf)); + + OQS_MEM_insecure_free(t); } static int treehash_minheight_on_stack(const xmss_params *params, @@ -235,7 +237,7 @@ static void treehash_init(const xmss_params *params, uint32_t lastnode, i; unsigned char *stack = calloc((height+1)*params->n, sizeof(unsigned char)); - unsigned int stacklevels[height+1]; + unsigned int *stacklevels = malloc((height + 1)*sizeof(unsigned int)); unsigned int stackoffset=0; unsigned int nodeh; @@ -283,6 +285,7 @@ static void treehash_init(const xmss_params *params, node[i] = stack[i]; } + OQS_MEM_insecure_free(stacklevels); OQS_MEM_insecure_free(stack); } @@ -307,7 +310,7 @@ static void treehash_update(const xmss_params *params, set_ltree_addr(ltree_addr, treehash->next_idx); set_ots_addr(ots_addr, treehash->next_idx); - unsigned char nodebuffer[2 * params->n]; + unsigned char *nodebuffer = malloc(2 * params->n); unsigned int nodeheight = 0; gen_leaf_wots(params, nodebuffer, sk_seed, pub_seed, ltree_addr, ots_addr); while (treehash->stackusage > 0 && state->stacklevels[state->stackoffset-1] == nodeheight) { @@ -331,6 +334,8 @@ static void treehash_update(const xmss_params *params, state->stackoffset++; treehash->next_idx++; } + + OQS_MEM_insecure_free(nodebuffer); } /** @@ -454,7 +459,7 @@ static void bds_round(const xmss_params *params, unsigned int tau = params->tree_height; unsigned int startidx; unsigned int offset, rowidx; - unsigned char buf[2 * params->n]; + unsigned char *buf = malloc(2 * params->n); uint32_t ots_addr[8] = {0}; uint32_t ltree_addr[8] = {0}; @@ -514,6 +519,8 @@ static void bds_round(const xmss_params *params, } } } + + OQS_MEM_insecure_free(buf); } /** @@ -551,7 +558,7 @@ int xmss_core_keypair(const xmss_params *params, // TODO refactor BDS state not to need separate treehash instances bds_state state; - treehash_inst treehash[params->tree_height - params->bds_k]; + treehash_inst *treehash = calloc(params->tree_height - params->bds_k, sizeof(treehash_inst)); state.treehash = treehash; xmss_deserialize_state(params, &state, sk); @@ -580,6 +587,8 @@ int xmss_core_keypair(const xmss_params *params, /* Write the BDS state into sk. */ xmss_serialize_state(params, sk, &state); + OQS_MEM_insecure_free(treehash); + return 0; } @@ -601,12 +610,13 @@ int xmss_core_sign(const xmss_params *params, } const unsigned char *pub_root = sk + params->index_bytes + 2*params->n; + int ret; uint16_t i = 0; // TODO refactor BDS state not to need separate treehash instances bds_state state; - treehash_inst treehash[params->tree_height - params->bds_k]; + treehash_inst *treehash = calloc(params->tree_height - params->bds_k, sizeof(treehash_inst)); state.treehash = treehash; /* Load the BDS state from sk. */ @@ -617,29 +627,33 @@ int xmss_core_sign(const xmss_params *params, /* Check if we can still sign with this sk. * If not, return -2 - * - * If this is the last possible signature (because the max index value - * is reached), production implementations should delete the secret key + * + * If this is the last possible signature (because the max index value + * is reached), production implementations should delete the secret key * to prevent accidental further use. - * - * For the case of total tree height of 64 we do not use the last signature - * to be on the safe side (there is no index value left to indicate that the + * + * For the case of total tree height of 64 we do not use the last signature + * to be on the safe side (there is no index value left to indicate that the * key is finished, hence external handling would be necessary) - */ + */ if (idx >= ((1ULL << params->full_height) - 1)) { // Delete secret key here. We only do this in memory, production code // has to make sure that this happens on disk. memset(sk, 0xFF, params->index_bytes); memset(sk + params->index_bytes, 0, (params->sk_bytes - params->index_bytes)); - if (idx > ((1ULL << params->full_height) - 1)) - return -2; // We already used all one-time keys + if (idx > ((1ULL << params->full_height) - 1)) { + ret = -2; // We already used all one-time keys + goto cleanup; + } } - - unsigned char sk_seed[params->n]; + unsigned char *tmp = malloc(5 * params->n); + + unsigned char *sk_seed = tmp; + unsigned char *sk_prf = sk_seed + params->n; + unsigned char *pub_seed = sk_prf + params->n; + memcpy(sk_seed, sk + params->index_bytes, params->n); - unsigned char sk_prf[params->n]; memcpy(sk_prf, sk + params->index_bytes + params->n, params->n); - unsigned char pub_seed[params->n]; memcpy(pub_seed, sk + params->index_bytes + 3*params->n, params->n); // index as 32 bytes string @@ -656,8 +670,8 @@ int xmss_core_sign(const xmss_params *params, // and write the updated secret key at this point! // Init working params - unsigned char R[params->n]; - unsigned char msg_h[params->n]; + unsigned char *R = pub_seed + params->n; + unsigned char *msg_h = R + params->n; uint32_t ots_addr[8] = {0}; // --------------------------------- @@ -671,7 +685,7 @@ int xmss_core_sign(const xmss_params *params, /* Already put the message in the right place, to make it easier to prepend * things when computing the hash over the message. */ unsigned long long prefix_length = params->padding_len + 3*params->n; - unsigned char m_with_prefix[mlen + prefix_length]; + unsigned char *m_with_prefix = malloc(mlen + prefix_length); memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, prefix_length); memcpy(m_with_prefix + prefix_length, m, mlen); @@ -727,7 +741,15 @@ int xmss_core_sign(const xmss_params *params, /* Write the updated BDS state back into sk. */ xmss_serialize_state(params, sk, &state); - return 0; + ret = 0; + + OQS_MEM_insecure_free(m_with_prefix); + OQS_MEM_insecure_free(tmp); + +cleanup: + OQS_MEM_insecure_free(treehash); + + return ret; } /* @@ -743,8 +765,8 @@ int xmssmt_core_keypair(const xmss_params *params, unsigned char *wots_sigs; // TODO refactor BDS state not to need separate treehash instances - bds_state states[2*params->d - 1]; - treehash_inst treehash[(2*params->d - 1) * (params->tree_height - params->bds_k)]; + bds_state *states = calloc(2*params->d - 1, sizeof(bds_state)); + treehash_inst *treehash = calloc((2*params->d - 1) * (params->tree_height - params->bds_k), sizeof(treehash_inst)); for (i = 0; i < 2*params->d - 1; i++) { states[i].treehash = treehash + i * (params->tree_height - params->bds_k); } @@ -783,6 +805,9 @@ int xmssmt_core_keypair(const xmss_params *params, xmssmt_serialize_state(params, sk, states); + OQS_MEM_insecure_free(treehash); + OQS_MEM_insecure_free(states); + return 0; } @@ -811,12 +836,14 @@ int xmssmt_core_sign(const xmss_params *params, int needswap_upto = -1; unsigned int updates; - unsigned char sk_seed[params->n]; - unsigned char sk_prf[params->n]; - unsigned char pub_seed[params->n]; + unsigned char *tmp = malloc(5 * params->n); + + unsigned char *sk_seed = tmp; + unsigned char *sk_prf = sk_seed + params->n; + unsigned char *pub_seed = sk_prf + params->n; // Init working params - unsigned char R[params->n]; - unsigned char msg_h[params->n]; + unsigned char *R = pub_seed + params->n; + unsigned char *msg_h = R + params->n; uint32_t addr[8] = {0}; uint32_t ots_addr[8] = {0}; unsigned char idx_bytes_32[32]; @@ -828,7 +855,7 @@ int xmssmt_core_sign(const xmss_params *params, // TODO refactor BDS state not to need separate treehash instances bds_state *states = calloc(2*params->d - 1, sizeof(bds_state)); - treehash_inst treehash[(2*params->d - 1) * (params->tree_height - params->bds_k)]; + treehash_inst *treehash = calloc((2*params->d - 1) * (params->tree_height - params->bds_k), sizeof(treehash_inst)); for (i = 0; i < 2*params->d - 1; i++) { states[i].stack = NULL; states[i].stackoffset = 0; @@ -850,15 +877,15 @@ int xmssmt_core_sign(const xmss_params *params, /* Check if we can still sign with this sk. * If not, return -2 - * - * If this is the last possible signature (because the max index value - * is reached), production implementations should delete the secret key + * + * If this is the last possible signature (because the max index value + * is reached), production implementations should delete the secret key * to prevent accidental further use. - * - * For the case of total tree height of 64 we do not use the last signature - * to be on the safe side (there is no index value left to indicate that the + * + * For the case of total tree height of 64 we do not use the last signature + * to be on the safe side (there is no index value left to indicate that the * key is finished, hence external handling would be necessary) - */ + */ if (idx >= ((1ULL << params->full_height) - 1)) { // Delete secret key here. We only do this in memory, production code // has to make sure that this happens on disk. @@ -870,7 +897,7 @@ int xmssmt_core_sign(const xmss_params *params, goto cleanup; } } - + memcpy(sk_seed, sk+params->index_bytes, params->n); memcpy(sk_prf, sk+params->index_bytes+params->n, params->n); memcpy(pub_seed, sk+params->index_bytes+3*params->n, params->n); @@ -1012,10 +1039,11 @@ int xmssmt_core_sign(const xmss_params *params, } xmssmt_serialize_state(params, sk, states); - goto cleanup; cleanup: + OQS_MEM_insecure_free(treehash); OQS_MEM_insecure_free(states); + OQS_MEM_insecure_free(tmp); return ret; } diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index 8b9536daed..d1663f1720 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -4,50 +4,55 @@ #define OQS_SIG_STFL_XMSS_H #include +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif #define XMSS_OID_LEN 4 -void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk); /* - * | Algorithms | oid | sk | pk | sig | n | - * |-------------------------------|------|--------|-----|------|----| - * | XMSS-SHA2_10_256 | 0x01 | 1373 | 64 | 2500 | 32 | - * | XMSS-SHA2_16_256 | 0x02 | 2093 | 64 | 2692 | 32 | - * | XMSS-SHA2_20_256 | 0x03 | 2573 | 64 | 2820 | 32 | + * | Algorithms | oid | sk (b) | pk (b) | sig (b) | n | + * |-------------------------------|------|--------|--------|---------|----| + * | XMSS-SHA2_10_256 | 0x01 | 1373 | 64 | 2500 | 32 | + * | XMSS-SHA2_16_256 | 0x02 | 2093 | 64 | 2692 | 32 | + * | XMSS-SHA2_20_256 | 0x03 | 2573 | 64 | 2820 | 32 | * - * | XMSS-SHAKE_10_256 | 0x07 | 1373 | 64 | 2500 | 32 | - * | XMSS-SHAKE_16_256 | 0x08 | 2093 | 64 | 2692 | 32 | - * | XMSS-SHAKE_20_256 | 0x09 | 2573 | 64 | 2820 | 32 | + * | XMSS-SHAKE_10_256 | 0x07 | 1373 | 64 | 2500 | 32 | + * | XMSS-SHAKE_16_256 | 0x08 | 2093 | 64 | 2692 | 32 | + * | XMSS-SHAKE_20_256 | 0x09 | 2573 | 64 | 2820 | 32 | * - * | XMSS-SHA2_10_512 | 0x04 | 2653 | 128 | 9092 | 64 | - * | XMSS-SHA2_16_512 | 0x05 | 4045 | 128 | 9476 | 64 | - * | XMSS-SHA2_20_512 | 0x06 | 4973 | 128 | 9732 | 64 | + * | XMSS-SHA2_10_512 | 0x04 | 2653 | 128 | 9092 | 64 | + * | XMSS-SHA2_16_512 | 0x05 | 4045 | 128 | 9476 | 64 | + * | XMSS-SHA2_20_512 | 0x06 | 4973 | 128 | 9732 | 64 | * - * | XMSS-SHAKE_10_512 | 0x0a | 2653 | 128 | 9092 | 64 | - * | XMSS-SHAKE_16_512 | 0x0b | 4045 | 128 | 9476 | 64 | - * | XMSS-SHAKE_20_512 | 0x0c | 4973 | 128 | 9732 | 64 | + * | XMSS-SHAKE_10_512 | 0x0a | 2653 | 128 | 9092 | 64 | + * | XMSS-SHAKE_16_512 | 0x0b | 4045 | 128 | 9476 | 64 | + * | XMSS-SHAKE_20_512 | 0x0c | 4973 | 128 | 9732 | 64 | * - * | XMSSMT-SHA2_20/2_256 | 0x01 | 5998 | 64 | 4963 | 32 | - * | XMSSMT-SHA2_20/4_256 | 0x02 | 10938 | 64 | 9251 | 32 | - * | XMSSMT-SHA2_40/2_256 | 0x03 | 9600 | 64 | 5605 | 32 | - * | XMSSMT-SHA2_40/4_256 | 0x04 | 15252 | 64 | 9893 | 32 | - * | XMSSMT-SHA2_40/8_256 | 0x05 | 24516 | 64 | 18469 | 32 | - * | XMSSMT-SHA2_60/3_256 | 0x06 | 16629 | 64 | 8392 | 32 | - * | XMSSMT-SHA2_60/6_256 | 0x07 | 24507 | 64 | 14824 | 32 | - * | XMSSMT-SHA2_60/12_256 | 0x08 | 38095 | 64 | 27688 | 32 | + * | XMSSMT-SHA2_20/2_256 | 0x01 | 5998 | 64 | 4963 | 32 | + * | XMSSMT-SHA2_20/4_256 | 0x02 | 10938 | 64 | 9251 | 32 | + * | XMSSMT-SHA2_40/2_256 | 0x03 | 9600 | 64 | 5605 | 32 | + * | XMSSMT-SHA2_40/4_256 | 0x04 | 15252 | 64 | 9893 | 32 | + * | XMSSMT-SHA2_40/8_256 | 0x05 | 24516 | 64 | 18469 | 32 | + * | XMSSMT-SHA2_60/3_256 | 0x06 | 16629 | 64 | 8392 | 32 | + * | XMSSMT-SHA2_60/6_256 | 0x07 | 24507 | 64 | 14824 | 32 | + * | XMSSMT-SHA2_60/12_256 | 0x08 | 38095 | 64 | 27688 | 32 | * - * | XMSSMT-SHAKE_20/2_256 | 0x11 | 5998 | 64 | 4963 | 32 | - * | XMSSMT-SHAKE_20/4_256 | 0x12 | 10938 | 64 | 9251 | 32 | - * | XMSSMT-SHAKE_40/2_256 | 0x13 | 9600 | 64 | 5605 | 32 | - * | XMSSMT-SHAKE_40/4_256 | 0x14 | 15252 | 64 | 9893 | 32 | - * | XMSSMT-SHAKE_40/8_256 | 0x15 | 24516 | 64 | 18469 | 32 | - * | XMSSMT-SHAKE_60/3_256 | 0x16 | 16629 | 64 | 8392 | 32 | - * | XMSSMT-SHAKE_60/6_256 | 0x17 | 24507 | 64 | 14824 | 32 | - * | XMSSMT-SHAKE_60/12_256 | 0x18 | 38095 | 64 | 27688 | 32 | + * | XMSSMT-SHAKE_20/2_256 | 0x11 | 5998 | 64 | 4963 | 32 | + * | XMSSMT-SHAKE_20/4_256 | 0x12 | 10938 | 64 | 9251 | 32 | + * | XMSSMT-SHAKE_40/2_256 | 0x13 | 9600 | 64 | 5605 | 32 | + * | XMSSMT-SHAKE_40/4_256 | 0x14 | 15252 | 64 | 9893 | 32 | + * | XMSSMT-SHAKE_40/8_256 | 0x15 | 24516 | 64 | 18469 | 32 | + * | XMSSMT-SHAKE_60/3_256 | 0x16 | 16629 | 64 | 8392 | 32 | + * | XMSSMT-SHAKE_60/6_256 | 0x17 | 24507 | 64 | 14824 | 32 | + * | XMSSMT-SHAKE_60/12_256 | 0x18 | 38095 | 64 | 27688 | 32 | */ #ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h10 +#define OQS_SIG_STFL_alg_xmss_sha256_h10_oid 0x01 #define OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk (1373 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_sha256_h10_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature 2500 @@ -64,6 +69,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(unsigned long lon #ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 +#define OQS_SIG_STFL_alg_xmss_sha256_h16_oid 0x02 #define OQS_SIG_STFL_alg_xmss_sha256_h16_length_sk (2093 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_sha256_h16_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_sha256_h16_length_signature 2692 @@ -80,6 +86,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(unsigned long lon #ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 +#define OQS_SIG_STFL_alg_xmss_sha256_h20_oid 0x03 #define OQS_SIG_STFL_alg_xmss_sha256_h20_length_sk (2573 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_sha256_h20_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_sha256_h20_length_signature 2820 @@ -96,6 +103,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(unsigned long lon #ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h10 +#define OQS_SIG_STFL_alg_xmss_shake128_h10_oid 0x07 #define OQS_SIG_STFL_alg_xmss_shake128_h10_length_sk (1373 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_shake128_h10_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_shake128_h10_length_signature 2500 @@ -112,6 +120,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(unsigned long l #ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 +#define OQS_SIG_STFL_alg_xmss_shake128_h16_oid 0x08 #define OQS_SIG_STFL_alg_xmss_shake128_h16_length_sk (2093 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_shake128_h16_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_shake128_h16_length_signature 2692 @@ -128,6 +137,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(unsigned long l #ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 +#define OQS_SIG_STFL_alg_xmss_shake128_h20_oid 0x09 #define OQS_SIG_STFL_alg_xmss_shake128_h20_length_sk (2573 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_shake128_h20_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_shake128_h20_length_signature 2820 @@ -144,6 +154,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(unsigned long l #ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h10 +#define OQS_SIG_STFL_alg_xmss_sha512_h10_oid 0x04 #define OQS_SIG_STFL_alg_xmss_sha512_h10_length_sk (2653 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_sha512_h10_length_pk (128 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_sha512_h10_length_signature 9092 @@ -160,6 +171,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(unsigned long lon #ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 +#define OQS_SIG_STFL_alg_xmss_sha512_h16_oid 0x05 #define OQS_SIG_STFL_alg_xmss_sha512_h16_length_sk (4045 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_sha512_h16_length_pk (128 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_sha512_h16_length_signature 9476 @@ -176,6 +188,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(unsigned long lon #ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 +#define OQS_SIG_STFL_alg_xmss_sha512_h20_oid 0x06 #define OQS_SIG_STFL_alg_xmss_sha512_h20_length_sk (4973 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_sha512_h20_length_pk (128 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_sha512_h20_length_signature 9732 @@ -192,6 +205,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(unsigned long lon #ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h10 +#define OQS_SIG_STFL_alg_xmss_shake256_h10_oid 0x0a #define OQS_SIG_STFL_alg_xmss_shake256_h10_length_sk (2653 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_shake256_h10_length_pk (128 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_shake256_h10_length_signature 9092 @@ -208,6 +222,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(unsigned long l #ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 +#define OQS_SIG_STFL_alg_xmss_shake256_h16_oid 0x0b #define OQS_SIG_STFL_alg_xmss_shake256_h16_length_sk (4045 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_shake256_h16_length_pk (128 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_shake256_h16_length_signature 9476 @@ -224,6 +239,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(unsigned long l #ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 +#define OQS_SIG_STFL_alg_xmss_shake256_h20_oid 0x0c #define OQS_SIG_STFL_alg_xmss_shake256_h20_length_sk (4973 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_shake256_h20_length_pk (128 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmss_shake256_h20_length_signature 9732 @@ -240,6 +256,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(unsigned long l #ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_2 +#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_oid 0x01 #define OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_sk (5998 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_signature 4963 @@ -256,6 +273,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(unsigned long #ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h20_4 +#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_oid 0x02 #define OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_sk (10938 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_signature 9251 @@ -272,6 +290,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(unsigned long #ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_oid 0x03 #define OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_sk (9600 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_signature 5605 @@ -288,6 +307,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(unsigned long #ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_4 +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_oid 0x04 #define OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_sk (15252 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_signature 9893 @@ -304,6 +324,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(unsigned long #ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_8 +#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_oid 0x05 #define OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_sk (24516 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_signature 18469 @@ -320,6 +341,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(unsigned long #ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_oid 0x06 #define OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_sk (16629 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_signature 8392 @@ -336,6 +358,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(unsigned long #ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_6 +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_oid 0x07 #define OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_sk (24507 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_signature 14824 @@ -352,6 +375,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(unsigned long #ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_12 +#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_oid 0x08 #define OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_sk (38095 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_signature 27688 @@ -368,6 +392,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(unsigned lon #ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_2 +#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_oid 0x11 #define OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_sk (5998 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_signature 4963 @@ -384,6 +409,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(unsigned lo #ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h20_4 +#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_oid 0x12 #define OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_sk (10938 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_signature 9251 @@ -400,6 +426,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(unsigned lo #ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_oid 0x13 #define OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_sk (9600 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_signature 5605 @@ -416,6 +443,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(unsigned lo #ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_4 +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_oid 0x14 #define OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_sk (15252 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_signature 9893 @@ -432,6 +460,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(unsigned lo #ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_8 +#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_oid 0x15 #define OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_sk (24516 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_signature 18469 @@ -448,6 +477,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(unsigned lo #ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_oid 0x16 #define OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_sk (16629 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_signature 8392 @@ -464,6 +494,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(unsigned lo #ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6 +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_oid 0x17 #define OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_sk (24507 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_signature 14824 @@ -480,6 +511,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(unsigned lo #ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 +#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_oid 0x18 #define OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_sk (38095 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_pk (64 + XMSS_OID_LEN) #define OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_signature 27688 @@ -494,16 +526,65 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(unsigned l #endif +#define __alg_xmss_XMSS(funcname, postfix) funcname##_##postfix +#define _alg_xmss_XMSS(funcname, postfix) __alg_xmss_XMSS(funcname, postfix) +#define OQS_SIG_STFL_alg_xmss_NAMESPACE(funcname) _alg_xmss_XMSS(funcname, XMSS_PARAMS_NAMESPACE) + +/* + * Generic XMSS APIs + */ +#define OQS_SIG_STFL_alg_xmss_sign OQS_SIG_STFL_alg_xmss_NAMESPACE(OQS_SIG_STFL_alg_xmss_sign) +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key); + +#define OQS_SIG_STFL_alg_xmss_verify OQS_SIG_STFL_alg_xmss_NAMESPACE(OQS_SIG_STFL_alg_xmss_verify) +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key); + +#define OQS_SIG_STFL_alg_xmss_sigs_remaining OQS_SIG_STFL_alg_xmss_NAMESPACE(OQS_SIG_STFL_alg_xmss_sigs_remaining) +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); + +#define OQS_SIG_STFL_alg_xmss_sigs_total OQS_SIG_STFL_alg_xmss_NAMESPACE(OQS_SIG_STFL_alg_xmss_sigs_total) +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); + +/* + * Generic XMSS^MT APIs + */ +#define OQS_SIG_STFL_alg_xmssmt_sign OQS_SIG_STFL_alg_xmss_NAMESPACE(OQS_SIG_STFL_alg_xmssmt_sign) +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key); + +#define OQS_SIG_STFL_alg_xmssmt_verify OQS_SIG_STFL_alg_xmss_NAMESPACE(OQS_SIG_STFL_alg_xmssmt_verify) +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key); + +#define OQS_SIG_STFL_alg_xmssmt_sigs_remaining OQS_SIG_STFL_alg_xmss_NAMESPACE(OQS_SIG_STFL_alg_xmssmt_sigs_remaining) +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); + +#define OQS_SIG_STFL_alg_xmssmt_sigs_total OQS_SIG_STFL_alg_xmss_NAMESPACE(OQS_SIG_STFL_alg_xmssmt_sigs_total) +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); + /* * Secret key functions */ -/* Serialize XMSS secret key data into a byte string */ -OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr); +/* Generic XMSS SECRET_KEY object initialization */ +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_new(size_t length_secret_key); + +/* Serialize XMSS secret key data into a byte string, and return an allocated buffer. Users must deallocate the buffer. */ +OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); + +/* Only for internal use. Similar to OQS_SECRET_KEY_XMSS_serialize_key, this function does not acquire and release a lock. */ +OQS_STATUS OQS_SECRET_KEY_XMSS_inner_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); /* Deserialize XMSS byte string into an XMSS secret key data */ OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); -/* Set XMSS byte string into an XMSS secret key data */ +/* Store Secret Key Function, ideally written to secure device */ void OQS_SECRET_KEY_XMSS_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); +/* Free Secret key object */ +void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk); + +/* Lock the key if possible */ +void OQS_SECRET_KEY_XMSS_acquire_lock(const OQS_SIG_STFL_SECRET_KEY *sk); + +/* Unlock the key if possible */ +void OQS_SECRET_KEY_XMSS_release_lock(const OQS_SIG_STFL_SECRET_KEY *sk); + #endif /* OQS_SIG_STFL_XMSS_H */ diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c new file mode 100644 index 0000000000..bfdf3e023b --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +/* -------------- XMSS -------------- */ + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + + OQS_STATUS status = OQS_SUCCESS; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { + return OQS_ERROR; + } + + /* Don't even attempt signing without a way to safe the updated private key */ + if (secret_key->secure_store_scrt_key == NULL) { + return OQS_ERROR; + } + + /* Lock secret to ensure OTS use */ + OQS_SECRET_KEY_XMSS_acquire_lock(secret_key); + + if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + /* + * serialize and securely store the updated private key + * regardless, delete signature and the serialized key other wise + */ + + status = OQS_SECRET_KEY_XMSS_inner_serialize_key(&sk_key_buf_ptr, &sk_key_buf_len, secret_key); + if (status != OQS_SUCCESS) { + goto err; + } + + // Store updated private key securely + status = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); + +err: + /* Unlock secret to ensure OTS use */ + OQS_SECRET_KEY_XMSS_release_lock(secret_key); + + return status; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmss_sign_open(message, (unsigned long long)message_len, signature, (unsigned long long)signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { + return OQS_ERROR; + } + + if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { + return OQS_ERROR; + } + + if (xmss_total_signatures(total, secret_key->secret_key_data)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c index a9ea864cdb..cfeab4548e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c @@ -2,6 +2,7 @@ #include #include +#include #include "sig_stfl_xmss.h" #if defined(__GNUC__) || defined(__clang__) @@ -10,12 +11,68 @@ #define XMSS_UNUSED_ATT #endif -/* Serialize XMSS secret key data into a byte string */ -OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr) { +extern inline +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_new(size_t length_secret_key) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + sk->length_secret_key = length_secret_key; + + // Secret serialize/deserialize function + sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; + sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; + + // Initialize the key with length_secret_key amount of bytes. + sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + + if (sk->secret_key_data == NULL) { + OQS_MEM_insecure_free(sk); + return NULL; + } + + memset(sk->secret_key_data, 0, sk->length_secret_key); + + // Set application specific context + sk->context = NULL; + + // Point to associated OQS_SIG_STFL object + sk->sig = NULL; + + // Mutual exclusion struct + sk->mutex = NULL; + + // Set Secret Key locking function + sk->lock_key = NULL; + + // Set Secret Key unlocking / releasing function + sk->unlock_key = NULL; + + // Set Secret Key saving function + sk->secure_store_scrt_key = NULL; + + // Set Secret Key store callback function + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; + + // Set Secret Key free function + sk->free_key = OQS_SECRET_KEY_XMSS_free; + + return sk; +} + +/* Serialize XMSS secret key data into a byte string, return an allocated buffer. Users have to unallocated the buffer. */ +OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk) { if (sk == NULL || sk_len == NULL || sk_buf_ptr == NULL) { return OQS_ERROR; } + /* Lock the key if possible */ + OQS_SECRET_KEY_XMSS_acquire_lock(sk); + uint8_t *sk_buf = malloc(sk->length_secret_key * sizeof(uint8_t)); if (sk_buf == NULL) { return OQS_ERROR; @@ -27,37 +84,79 @@ OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, *sk_buf_ptr = sk_buf; *sk_len = sk->length_secret_key; + /* Unlock the key if possible */ + OQS_SECRET_KEY_XMSS_release_lock(sk); + return OQS_SUCCESS; } -/* Deserialize XMSS byte string into an XMSS secret key data */ -OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, XMSS_UNUSED_ATT void *context) { - if (sk == NULL || sk_buf == NULL || (sk_len != sk->length_secret_key)) { +/* Only for internal use. Similar to OQS_SECRET_KEY_XMSS_serialize_key, but this function does not aquire and release lock. */ +OQS_STATUS OQS_SECRET_KEY_XMSS_inner_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL || sk_len == NULL || sk_buf_ptr == NULL) { return OQS_ERROR; } - if (sk->secret_key_data != NULL) { - OQS_MEM_secure_free(sk->secret_key_data, sk->length_secret_key); - sk->secret_key_data = NULL; + uint8_t *sk_buf = malloc(sk->length_secret_key * sizeof(uint8_t)); + if (sk_buf == NULL) { + return OQS_ERROR; } - // Assume key data is not present - sk->secret_key_data = malloc(sk_len); - if (sk->secret_key_data == NULL) { + // Simply copy byte string of secret_key_data + memcpy(sk_buf, sk->secret_key_data, sk->length_secret_key); + + *sk_buf_ptr = sk_buf; + *sk_len = sk->length_secret_key; + + return OQS_SUCCESS; +} + +/* Deserialize XMSS byte string into an XMSS secret key data. */ +OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, XMSS_UNUSED_ATT void *context) { + if (sk == NULL || sk_buf == NULL || (sk_len != sk->length_secret_key)) { return OQS_ERROR; } + memcpy(sk->secret_key_data, sk_buf, sk->length_secret_key); sk->context = context; - memcpy(sk->secret_key_data, sk_buf, sk_len); return OQS_SUCCESS; } void OQS_SECRET_KEY_XMSS_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context) { - if (!sk || !store_cb || !context) { + if (sk == NULL || store_cb == NULL) { return; } - - sk->context = context; sk->secure_store_scrt_key = store_cb; + sk->context = context; +} + +void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL) { + return; + } + + OQS_MEM_secure_free(sk->secret_key_data, sk->length_secret_key); + sk->secret_key_data = NULL; +} + +void OQS_SECRET_KEY_XMSS_acquire_lock(const OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL) { + return; + } + + /* Lock the key if possible */ + if ((sk->lock_key != NULL) && (sk->mutex != NULL)) { + sk->lock_key(sk->mutex); + } +} + +void OQS_SECRET_KEY_XMSS_release_lock(const OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL) { + return; + } + + /* Unlock the key if possible */ + if ((sk->unlock_key != NULL) && (sk->mutex != NULL)) { + sk->unlock_key(sk->mutex); + } } diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c index 2affc67195..849839ef0d 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmss_sha256_h10_oid; sig->method_name = "XMSS-SHA2_10_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,35 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -79,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(XMSS_UNUSED_ATT uint return OQS_ERROR; } - const uint32_t xmss_sha256_h10_oid = 0x01; - if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_sha256_h10_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_sha256_h10_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmss_sign_open(message, (unsigned long long)message_len, signature, (unsigned long long)signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c index cfaa958dd7..53fd443a44 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h16_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmss_sha256_h16_oid; sig->method_name = "XMSS-SHA2_16_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h16_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H16_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h16_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_sha256_h16_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_keypair(XMSS_UNUSED_ATT uint return OQS_ERROR; } - const uint32_t xmss_sha256_h16_oid = 0x02; - if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_sha256_h16_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_sha256_h16_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c index 1145d17e2b..a95007730b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h20_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmss_sha256_h20_oid; sig->method_name = "XMSS-SHA2_20_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h20_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H20_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h20_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_sha256_h20_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_keypair(XMSS_UNUSED_ATT uint return OQS_ERROR; } - const uint32_t xmss_sha256_h20_oid = 0x03; - if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_sha256_h20_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_sha256_h20_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c index c7ca88eee7..6c382dcabb 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h10_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmss_sha512_h10_oid; sig->method_name = "XMSS-SHA2_10_512"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h10_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H10_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h10_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_sha512_h10_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_keypair(XMSS_UNUSED_ATT uint return OQS_ERROR; } - const uint32_t xmss_sha512_h10_oid = 0x04; - if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_sha512_h10_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_sha512_h10_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c index 70123ccb16..c9b2a3e51e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h16_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmss_sha512_h16_oid; sig->method_name = "XMSS-SHA2_16_512"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h16_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H16_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h16_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_sha512_h16_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_keypair(XMSS_UNUSED_ATT uint return OQS_ERROR; } - const uint32_t xmss_sha512_h16_oid = 0x05; - if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_sha512_h16_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_sha512_h16_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c index ebb03643a6..817004658b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h20_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmss_sha512_h20_oid; sig->method_name = "XMSS-SHA2_20_512"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h20_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H20_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h20_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_sha512_h20_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_keypair(XMSS_UNUSED_ATT uint return OQS_ERROR; } - const uint32_t xmss_sha512_h20_oid = 0x06; - if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_sha512_h20_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_sha512_h20_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c index 4d15d86461..971b3de4ed 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h10_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmss_shake128_h10_oid; sig->method_name = "XMSS-SHAKE_10_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h10_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H10_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h10_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_shake128_h10_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_keypair(XMSS_UNUSED_ATT ui return OQS_ERROR; } - const uint32_t xmss_shake128_h10_oid = 0x07; - if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_shake128_h10_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_shake128_h10_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c index 499ba294ad..93abb5d6e2 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h16_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmss_shake128_h16_oid; sig->method_name = "XMSS-SHAKE_16_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h16_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H16_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h16_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_shake128_h16_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_keypair(XMSS_UNUSED_ATT ui return OQS_ERROR; } - const uint32_t xmss_shake128_h16_oid = 0x08; - if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_shake128_h16_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_shake128_h16_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); } + diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c index 8f47a4f825..1e320ed7ba 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h20_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmss_shake128_h20_oid; sig->method_name = "XMSS-SHAKE_20_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h20_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H20_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h20_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_shake128_h20_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_keypair(XMSS_UNUSED_ATT ui return OQS_ERROR; } - const uint32_t xmss_shake128_h20_oid = 0x09; - if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_shake128_h20_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_shake128_h20_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = oqs_serialize_lms_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c index 944a34d9de..d67c17015b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h10_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmss_shake256_h10_oid; sig->method_name = "XMSS-SHAKE_10_512"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h10_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H10_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h10_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_shake256_h10_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_keypair(XMSS_UNUSED_ATT ui return OQS_ERROR; } - const uint32_t xmss_shake256_h10_oid = 0x0a; - if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_shake256_h10_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_shake256_h10_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c index 93e8791bf8..e938187119 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h16_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmss_shake256_h16_oid; sig->method_name = "XMSS-SHAKE_16_512"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h16_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H16_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h16_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_shake256_h16_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_keypair(XMSS_UNUSED_ATT ui return OQS_ERROR; } - const uint32_t xmss_shake256_h16_oid = 0x0b; - if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_shake256_h16_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_shake256_h16_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); } + diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c index e701614e79..15f591466e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h20_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmss_shake256_h20_oid; sig->method_name = "XMSS-SHAKE_20_512"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h20_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H20_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h20_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_shake256_h20_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_keypair(XMSS_UNUSED_ATT ui return OQS_ERROR; } - const uint32_t xmss_shake256_h20_oid = 0x0c; - if (xmss_keypair(public_key, secret_key->secret_key_data, xmss_shake256_h20_oid)) { + if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_shake256_h20_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmss_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c new file mode 100644 index 0000000000..d1aa9e923d --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + +/* -------------- XMSSMT -------------- */ + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + + OQS_STATUS status = OQS_SUCCESS; + uint8_t *sk_key_buf_ptr = NULL; + unsigned long long sig_length = 0; + size_t sk_key_buf_len = 0; + + if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { + return OQS_ERROR; + } + + /* Don't even attempt signing without a way to safe the updated private key */ + if (secret_key->secure_store_scrt_key == NULL) { + return OQS_ERROR; + } + + /* Lock secret to ensure OTS use */ + OQS_SECRET_KEY_XMSS_acquire_lock(secret_key); + + if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { + status = OQS_ERROR; + goto err; + } + *signature_len = (size_t)sig_length; + /* + * serialize and securely store the updated private key + * regardless, delete signature and the serialized key other wise + */ + + status = OQS_SECRET_KEY_XMSS_inner_serialize_key(&sk_key_buf_ptr, &sk_key_buf_len, secret_key); + if (status != OQS_SUCCESS) { + goto err; + } + + // Store updated private key securely + status = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); + OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); + +err: + /* Unlock secret to ensure OTS use */ + OQS_SECRET_KEY_XMSS_release_lock(secret_key); + + return status; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { + + if (message == NULL || signature == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (xmssmt_sign_open(message, (unsigned long long)message_len, signature, (unsigned long long)signature_len, public_key)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { + return OQS_ERROR; + } + + if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { + return OQS_ERROR; + } + + if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { + return OQS_ERROR; + } + + return OQS_SUCCESS; +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c index f333b08a0e..ab3c2d6765 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_oid; sig->method_name = "XMSSMT-SHA2_20/2_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_2_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_keypair(XMSS_UNUSED_ATT return OQS_ERROR; } - const uint32_t xmssmt_sha256_h20_2_oid = 0x01; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h20_2_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c index 76febd3103..62df91e621 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_oid; sig->method_name = "XMSSMT-SHA2_20/4_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_4_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_keypair(XMSS_UNUSED_ATT return OQS_ERROR; } - const uint32_t xmssmt_sha256_h20_4_oid = 0x02; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h20_4_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c index b2b39b51ec..0ff6054cc6 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_oid; sig->method_name = "XMSSMT-SHA2_40/2_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_2_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,102 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_keypair(XMSS_UNUSED_ATT return OQS_ERROR; } - const uint32_t xmssmt_sha256_h40_2_oid = 0x03; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h40_2_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - fprintf(stderr, "No secret key secure-store set.\n"); - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c index 4781f49cfe..721eba5f9f 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_oid; sig->method_name = "XMSSMT-SHA2_40/4_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_4_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_keypair(XMSS_UNUSED_ATT return OQS_ERROR; } - const uint32_t xmssmt_sha256_h40_4_oid = 0x04; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h40_4_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c index 2acbc1046e..9433c61944 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_oid; sig->method_name = "XMSSMT-SHA2_40/8_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_keypair(XMSS_UNUSED_ATT return OQS_ERROR; } - const uint32_t xmssmt_sha256_h40_8_oid = 0x05; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h40_8_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c index d9b98a749f..edfc7239d6 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_oid; sig->method_name = "XMSSMT-SHA2_60/12_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_12_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,102 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_keypair(XMSS_UNUSED_ATT return OQS_ERROR; } - const uint32_t xmssmt_sha256_h60_12_oid = 0x08; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h60_12_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c index c45fef5959..1d66ba99cc 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_oid; sig->method_name = "XMSSMT-SHA2_60/3_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_3_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_keypair(XMSS_UNUSED_ATT return OQS_ERROR; } - const uint32_t xmssmt_sha256_h60_3_oid = 0x06; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h60_3_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c index f43f87c6b4..e445cb05f8 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_oid; sig->method_name = "XMSSMT-SHA2_60/6_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_6_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_keypair(XMSS_UNUSED_ATT return OQS_ERROR; } - const uint32_t xmssmt_sha256_h60_6_oid = 0x07; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_sha256_h60_6_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c index 16d7270593..13e9ae5d8e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_oid; sig->method_name = "XMSSMT-SHAKE_20/2_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_2_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_keypair(XMSS_UNUSED_AT return OQS_ERROR; } - const uint32_t xmssmt_shake128_h20_2_oid = 0x11; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h20_2_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c index 941a2ecb3c..1e1ac0915d 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_oid; sig->method_name = "XMSSMT-SHAKE_20/4_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_4_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_keypair(XMSS_UNUSED_AT return OQS_ERROR; } - const uint32_t xmssmt_shake128_h20_4_oid = 0x12; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h20_4_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c index adc47b4d11..3bc608f484 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_oid; sig->method_name = "XMSSMT-SHAKE_40/2_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_2_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_keypair(XMSS_UNUSED_AT return OQS_ERROR; } - const uint32_t xmssmt_shake128_h40_2_oid = 0x13; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h40_2_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c index 3312f25477..0bee9336da 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_oid; sig->method_name = "XMSSMT-SHAKE_40/4_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_4_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_keypair(XMSS_UNUSED_AT return OQS_ERROR; } - const uint32_t xmssmt_shake128_h40_4_oid = 0x14; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h40_4_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c index 43afdfeeff..994393935f 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_oid; sig->method_name = "XMSSMT-SHAKE_40/8_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_keypair(XMSS_UNUSED_AT return OQS_ERROR; } - const uint32_t xmssmt_shake128_h40_8_oid = 0x15; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h40_8_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c index bf7c0c56d2..c60eecd101 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_oid; sig->method_name = "XMSSMT-SHAKE_60/12_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_12_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,26 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_keypair(XMSS_UNUSED_A return OQS_ERROR; } - const uint32_t xmssmt_shake128_h60_12_oid = 0x18; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h60_12_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } + diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c index f8b6ab6ec5..5c3242a8e1 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_oid; sig->method_name = "XMSSMT-SHAKE_60/3_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_3_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,101 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_keypair(XMSS_UNUSED_AT return OQS_ERROR; } - const uint32_t xmssmt_shake128_h60_3_oid = 0x16; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h60_3_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - OQS_STATUS rc_keyupdate, status = OQS_SUCCESS; - const OQS_SIG_STFL_SECRET_KEY *sk; - uint8_t *sk_key_buf_ptr = NULL; - unsigned long long sig_length = 0; - size_t sk_key_buf_len = 0; - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - /* check for secret key update function */ - if (secret_key->secure_store_scrt_key == NULL) { - return OQS_ERROR; - } - - /* Lock secret to ensure OTS use */ - if ((secret_key->lock_key) && (secret_key->mutex)) { - secret_key->lock_key(secret_key->mutex); - } - - if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - status = OQS_ERROR; - goto err; - } - *signature_len = (size_t)sig_length; - - /* - * serialize and securely store the updated private key - * but, delete signature and the serialized key other wise - */ - - sk = secret_key; - rc_keyupdate = OQS_SECRET_KEY_XMSS_serialize_key(sk, &sk_key_buf_len, &sk_key_buf_ptr); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - goto err; - } - - rc_keyupdate = secret_key->secure_store_scrt_key(sk_key_buf_ptr, sk_key_buf_len, secret_key->context); - if (rc_keyupdate != OQS_SUCCESS) { - status = OQS_ERROR; - } - - OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); -err: - /* Unlock secret to ensure OTS use */ - if ((secret_key->unlock_key) && (secret_key->mutex)) { - secret_key->unlock_key(secret_key->mutex); - } - return status; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c index 1821340645..3874589c2f 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c @@ -24,6 +24,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); + sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_oid; sig->method_name = "XMSSMT-SHAKE_60/6_256"; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; sig->euf_cma = true; @@ -42,34 +43,7 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_new(void) { } OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_6_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - sk->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_sk; - - // Secret serialize/deserialize function - sk->serialize_key = OQS_SECRET_KEY_XMSS_serialize_key; - sk->deserialize_key = OQS_SECRET_KEY_XMSS_deserialize_key; - - // Initialize the key with length_secret_key amount of bytes. - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - - if (sk->secret_key_data == NULL) { - OQS_MEM_insecure_free(sk); - return NULL; - } - memset(sk->secret_key_data, 0, sk->length_secret_key); - - sk->free_key = OQS_SECRET_KEY_XMSS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_XMSS_set_store_cb; - - return sk; + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_sk); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { @@ -78,62 +52,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_keypair(XMSS_UNUSED_AT return OQS_ERROR; } - const uint32_t xmssmt_shake128_h60_6_oid = 0x17; - if (xmssmt_keypair(public_key, secret_key->secret_key_data, xmssmt_shake128_h60_6_oid)) { + if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_oid)) { return OQS_ERROR; } return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (signature == NULL || signature_len == NULL || message == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - unsigned long long sig_length = 0; - if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { - return OQS_ERROR; - } - *signature_len = (size_t) sig_length; - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); } -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { - - if (message == NULL || signature == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (xmssmt_sign_open(message, (unsigned long long) message_len, signature, (unsigned long long) signature_len, public_key)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { + return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (remain == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_remaining_signatures(remain, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); } OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (total == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_total_signatures(total, secret_key->secret_key_data)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; + return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); } diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index 33dce7e897..4607977065 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -71,7 +71,7 @@ int FindMarker(FILE *infile, const char *marker) { // // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) // -int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, char *str) { +int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, const char *str) { int ch, started; unsigned long i; unsigned char ich; diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 305001a462..dd75b8a916 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -14,9 +14,13 @@ #include #include "tmp_store.c" +#include "system_info.c" #if OQS_USE_PTHREADS_IN_TESTS #include + +static pthread_mutex_t *test_sk_lock = NULL; +static pthread_mutex_t *sk_lock = NULL; #endif #ifdef OQS_ENABLE_TEST_CONSTANT_TIME @@ -28,77 +32,12 @@ #define OQS_TEST_CT_DECLASSIFY(addr, len) #endif -#include "system_info.c" - /* * For stateful signature, we skip key generation because it can takes hours to complete. * So the ReadHex and and FindMarker serve the purpose of reading pre-generate keypair from KATs. */ #define MAX_MARKER_LEN 50 -static OQS_SIG_STFL_SECRET_KEY *lock_test_sk = NULL; -static OQS_SIG_STFL *lock_test_sig_obj = NULL; -static uint8_t *lock_test_public_key = NULL; -static char *lock_test_context = NULL; -static uint8_t *signature_1 = NULL; -static uint8_t *signature_2 = NULL; -static size_t signature_len_1; -static size_t signature_len_2; -static uint8_t message_1[] = "The quick brown fox ..."; -static uint8_t message_2[] = "The quick brown fox jumped from the tree."; -static pthread_mutex_t *test_sk_lock = NULL; - -/* - * Write stateful secret keys to disk. - */ -static OQS_STATUS test_save_secret_key(uint8_t *key_buf, size_t buf_len, void *context) { - uint8_t *kb = key_buf; - - if (key_buf && context && buf_len != 0) { - if (oqs_fstore("sk", (const char *)context, kb, buf_len) == OQS_SUCCESS) { - printf("\n================================================================================\n"); - printf("Updated STFL SK <%s>.\n", (const char *)context); - printf("================================================================================\n"); - return OQS_SUCCESS; - } else { - return OQS_ERROR; - } - } - return OQS_ERROR; -} - -#if OQS_USE_PTHREADS_IN_TESTS -static OQS_STATUS lock_sk_key(void *mutex) { - if (mutex == NULL) { - return OQS_ERROR; - } - - if (!(pthread_mutex_lock((pthread_mutex_t *)mutex))) { - return OQS_SUCCESS; - } - return OQS_ERROR; -} - -static OQS_STATUS unlock_sk_key(void *mutex) { - if (mutex == NULL) { - return OQS_ERROR; - } - - if (!(pthread_mutex_unlock((pthread_mutex_t *)mutex))) { - return OQS_SUCCESS; - } - return OQS_ERROR; -} -#else -static OQS_STATUS lock_sk_key(void *mutex) { - return sk != NULL ? OQS_SUCCESS : OQS_ERROR; -} - -static OQS_STATUS unlock_sk_key(void *mutex) { - return sk != NULL ? OQS_SUCCESS : OQS_ERROR; -} -#endif - // // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) // @@ -191,12 +130,70 @@ int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, char *str) { return 1; } -OQS_STATUS sig_stfl_keypair_from_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - OQS_STATUS rc; +static OQS_SIG_STFL_SECRET_KEY *lock_test_sk = NULL; +static OQS_SIG_STFL *lock_test_sig_obj = NULL; +static uint8_t *lock_test_public_key = NULL; +static char *lock_test_context = NULL; +static uint8_t *signature_1 = NULL; +static uint8_t *signature_2 = NULL; +static size_t signature_len_1; +static size_t signature_len_2; +static uint8_t message_1[] = "The quick brown fox ..."; +static uint8_t message_2[] = "The quick brown fox jumped from the tree."; + +/* + * Write stateful secret keys to disk. + */ +static OQS_STATUS save_secret_key(uint8_t *key_buf, size_t buf_len, void *context) { + if (key_buf == NULL || buf_len == 0 || context == NULL) { + return OQS_ERROR; + } + const char *context_char = context; - if ((sig == NULL) || (public_key == NULL) || (secret_key == NULL)) { + if (oqs_fstore("sk", context_char, key_buf, buf_len) == OQS_SUCCESS) { + printf("\n================================================================================\n"); + printf("Updated STFL SK <%s>.\n", context_char); + printf("================================================================================\n"); + return OQS_SUCCESS; + } + + return OQS_ERROR; +} + +#if OQS_USE_PTHREADS_IN_TESTS +static OQS_STATUS lock_sk_key(void *mutex) { + if (mutex == NULL) { + return OQS_ERROR; + } + + if (pthread_mutex_lock((pthread_mutex_t *)mutex)) { return OQS_ERROR; } + return OQS_SUCCESS; +} + +static OQS_STATUS unlock_sk_key(void *mutex) { + if (mutex == NULL) { + return OQS_ERROR; + } + + if (pthread_mutex_unlock((pthread_mutex_t *)mutex)) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} +#else +static OQS_STATUS lock_sk_key(void *mutex) { + return OQS_SUCCESS; +} + +static OQS_STATUS unlock_sk_key(void *mutex) { + return OQS_SUCCESS; +} +#endif + +OQS_STATUS sig_stfl_keypair_from_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + OQS_STATUS rc; rc = OQS_SIG_STFL_keypair(sig, public_key, secret_key); OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); @@ -250,8 +247,10 @@ OQS_STATUS sig_stfl_keypair_from_KATs(OQS_SIG_STFL *sig, uint8_t *public_key, OQ * XMSSMT-SHAKE_60/3_256 */ OQS_STATUS sig_stfl_KATs_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key, const char *katfile) { + if (sig == NULL || public_key == NULL || secret_key == NULL ) { + return OQS_ERROR; + } - printf("%s ", sig->method_name); if (0) { #ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 @@ -323,9 +322,11 @@ typedef struct magic_s { } magic_t; static char *convert_method_name_to_file_name(const char *method_name) { + if (method_name == NULL) { + return NULL; + } const char *file_store = NULL; - char *name = NULL; if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_2) == 0) { file_store = "XMSSMT-SHA2_20-2_256"; } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h20_4) == 0) { @@ -362,10 +363,7 @@ static char *convert_method_name_to_file_name(const char *method_name) { file_store = method_name; } - if (file_store) { - name = strdup(file_store); - } - return name; + return strdup(file_store); } static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char *katfile) { @@ -373,7 +371,6 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char OQS_SIG_STFL *sig = NULL; uint8_t *public_key = NULL; OQS_SIG_STFL_SECRET_KEY *secret_key = NULL; - const OQS_SIG_STFL_SECRET_KEY *sk = NULL; OQS_SIG_STFL_SECRET_KEY *secret_key_rd = NULL; uint8_t *message = NULL; size_t message_len = 100; @@ -389,80 +386,10 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char magic_t magic; -#if OQS_USE_PTHREADS_IN_TESTS - pthread_mutex_t *sk_lock = NULL; -#endif - OQS_STATUS rc, ret = OQS_ERROR; - if (0) { - -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 - } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 - } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { - goto skip_test; -#endif - } else { - goto test_on; - } -skip_test: - printf("skipping slow test %s\n", method_name); - return OQS_SUCCESS; - -test_on: - //The magic numbers are random values. //The length of the magic number was chosen to be 31 to break alignment - - OQS_randombytes(magic.val, sizeof(magic_t)); sig = OQS_SIG_STFL_new(method_name); @@ -489,17 +416,9 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char /* set context and secure store callback */ context = strdup(((file_store))); - OQS_SIG_STFL_SECRET_KEY_SET_store_cb(secret_key, test_save_secret_key, (void *)context); + OQS_SIG_STFL_SECRET_KEY_SET_store_cb(secret_key, save_secret_key, (void *)context); #if OQS_USE_PTHREADS_IN_TESTS - sk_lock = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); - if (sk_lock == NULL) { - goto err; - } - - if (0 != pthread_mutex_init(sk_lock, 0)) { - goto err; - } OQS_SIG_STFL_SECRET_KEY_SET_mutex(secret_key, sk_lock); #endif public_key = malloc(sig->length_public_key + 2 * sizeof(magic_t)); @@ -532,14 +451,13 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char * Some keypair generation is fast, so we only read keypair from KATs for slow XMSS parameters */ rc = sig_stfl_KATs_keygen(sig, public_key, secret_key, katfile); - sk = secret_key; OQS_TEST_CT_DECLASSIFY(&rc, sizeof rc); if (rc != OQS_SUCCESS) { fprintf(stderr, "ERROR: OQS_SIG_STFL_keypair failed\n"); goto err; } - rc = OQS_SECRET_KEY_STFL_serialize_key(sk, &sk_buf_len, &sk_buf); + rc = OQS_SECRET_KEY_STFL_serialize_key(&sk_buf, &sk_buf_len, secret_key); if (rc != OQS_SUCCESS) { goto err; } @@ -604,7 +522,6 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char } #endif - printf("verification passes as expected\n"); ret = OQS_SUCCESS; goto cleanup; @@ -630,25 +547,19 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char OQS_MEM_insecure_free(context); OQS_MEM_insecure_free(file_store); -#if OQS_USE_PTHREADS_IN_TESTS - if (sk_lock) { - pthread_mutex_destroy(sk_lock); - OQS_MEM_insecure_free(sk_lock); - } -#endif return ret; } -static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { +static OQS_STATUS sig_stfl_test_secret_key(const char *method_name, const char *katfile) { OQS_STATUS rc = OQS_SUCCESS; OQS_SIG_STFL_SECRET_KEY *sk = NULL; - OQS_SIG_STFL_SECRET_KEY *sk_frm_file = NULL; + OQS_SIG_STFL_SECRET_KEY *sk_from_file = NULL; unsigned long long num_sig_left = 0, max_num_sigs = 0; OQS_SIG_STFL *sig_obj = NULL; uint8_t *public_key = NULL; - uint8_t *frm_file_sk_buf = NULL; + uint8_t *from_file_sk_buf = NULL; uint8_t *to_file_sk_buf = NULL; - size_t frm_file_sk_len = 0; + size_t from_file_sk_len = 0; size_t to_file_sk_len = 0; char *context = NULL; char *context_2 = NULL; @@ -658,71 +569,6 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { * Temporarily skip algs with long key generation times. */ - if (0) { - -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 - } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 - } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { - goto skip_test; -#endif - } else { - goto keep_going; - } - -skip_test: - printf("Skip slow test %s.\n", method_name); - return rc; - -keep_going: - printf("================================================================================\n"); printf("Create stateful Signature %s\n", method_name); printf("================================================================================\n"); @@ -749,7 +595,7 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { printf("Generate keypair %s\n", method_name); printf("================================================================================\n"); - rc = OQS_SIG_STFL_keypair(sig_obj, public_key, sk); + rc = sig_stfl_KATs_keygen(sig_obj, public_key, sk, katfile); if (rc != OQS_SUCCESS) { fprintf(stderr, "OQS STFL key gen failed.\n"); @@ -764,17 +610,15 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { fprintf(stderr, "OQS STFL key: Failed to get max number of sig from %s.\n", method_name); goto err; } - printf("%s Maximum num of sign operations = %llu\n", method_name, max_num_sigs); rc = OQS_SIG_STFL_sigs_remaining((const OQS_SIG_STFL *)sig_obj, &num_sig_left, (const OQS_SIG_STFL_SECRET_KEY *)sk); if (rc != OQS_SUCCESS) { fprintf(stderr, "OQS STFL key: Failed to get the remaining number of sig from %s.\n", method_name); goto err; } - printf("%s Remaining number of sign operations = %llu\n", method_name, num_sig_left); /* write sk key to disk */ - rc = OQS_SECRET_KEY_STFL_serialize_key(sk, &to_file_sk_len, &to_file_sk_buf); + rc = OQS_SECRET_KEY_STFL_serialize_key(&to_file_sk_buf, &to_file_sk_len, sk); if (rc != OQS_SUCCESS) { goto err; } @@ -784,54 +628,54 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { goto err; } - if (!sk->secret_key_data) { + if (sk->secret_key_data == NULL) { fprintf(stderr, "ERROR: OQS_SECRET_KEY_new incomplete.\n"); goto err; } /* set context and secure store callback */ - if (sk->set_scrt_key_store_cb) { + if (sk->set_scrt_key_store_cb != NULL) { context = strdup(file_store_name); - sk->set_scrt_key_store_cb(sk, test_save_secret_key, (void *)context); + sk->set_scrt_key_store_cb(sk, save_secret_key, (void *)context); } /* read secret key from disk */ - frm_file_sk_buf = malloc(to_file_sk_len); - if (oqs_fload("sk", file_store_name, frm_file_sk_buf, to_file_sk_len, &frm_file_sk_len) != OQS_SUCCESS) { + from_file_sk_buf = malloc(to_file_sk_len); + if (oqs_fload("sk", file_store_name, from_file_sk_buf, to_file_sk_len, &from_file_sk_len) != OQS_SUCCESS) { goto err; } - if (to_file_sk_len != frm_file_sk_len) { + if (to_file_sk_len != from_file_sk_len) { fprintf(stderr, "ERROR: OQS_SECRET_KEY_new stored length not equal read length\n"); goto err; } - sk_frm_file = OQS_SIG_STFL_SECRET_KEY_new(method_name); - if (sk_frm_file == NULL) { + sk_from_file = OQS_SIG_STFL_SECRET_KEY_new(method_name); + if (sk_from_file == NULL) { fprintf(stderr, "ERROR: 2nd OQS_SECRET_KEY_new failed\n"); goto err; } context_2 = strdup(file_store_name); - rc = OQS_SECRET_KEY_STFL_deserialize_key(sk_frm_file, frm_file_sk_len, frm_file_sk_buf, (void *)context_2); + rc = OQS_SECRET_KEY_STFL_deserialize_key(sk_from_file, from_file_sk_len, from_file_sk_buf, (void *)context_2); if (rc != OQS_SUCCESS) { fprintf(stderr, "OQS restore %s from file failed.\n", method_name); goto err; } - printf("Secret Key created as expected.\n"); - goto end_it; + rc = OQS_SUCCESS; + goto cleanup; err: rc = OQS_ERROR; -end_it: +cleanup: OQS_SIG_STFL_SECRET_KEY_free(sk); - OQS_SIG_STFL_SECRET_KEY_free(sk_frm_file); + OQS_SIG_STFL_SECRET_KEY_free(sk_from_file); OQS_MEM_insecure_free(public_key); OQS_MEM_secure_free(to_file_sk_buf, to_file_sk_len); - OQS_MEM_secure_free(frm_file_sk_buf, frm_file_sk_len); + OQS_MEM_secure_free(from_file_sk_buf, from_file_sk_len); OQS_SIG_STFL_free(sig_obj); OQS_MEM_insecure_free(context); OQS_MEM_insecure_free(context_2); @@ -848,77 +692,13 @@ static OQS_STATUS sig_stfl_test_query_key(const char *method_name) { * Temporarily skip algs with long key generation times. */ - if (0) { - -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 - } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 - } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { - goto skip_test; -#endif - } else { - goto keep_going; - } - -skip_test: - printf("Skip slow test %s.\n", method_name); - return rc; - -keep_going: - printf("================================================================================\n"); printf("Testing stateful Signature Verification %s\n", method_name); printf("================================================================================\n"); - if ( lock_test_sk == NULL || lock_test_sig_obj == NULL || signature_1 == NULL - || signature_2 == NULL || lock_test_public_key == NULL) { + if ( lock_test_sk == NULL || lock_test_sig_obj == NULL || + signature_1 == NULL || signature_2 == NULL || + lock_test_public_key == NULL) { return OQS_ERROR; } @@ -943,16 +723,14 @@ static OQS_STATUS sig_stfl_test_query_key(const char *method_name) { fprintf(stderr, "ERROR: lock thread test OQS_SIG_STFL_verify failed\n"); goto err; } - rc = OQS_SUCCESS; printf("================================================================================\n"); printf("Stateful Signature Verification %s Passed.\n", method_name); printf("================================================================================\n"); - goto end_it; -err: - rc = OQS_ERROR; -end_it: - return rc; + return OQS_SUCCESS; + +err: + return OQS_ERROR; } static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { @@ -967,71 +745,6 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { * Temporarily skip algs with long key generation times. */ - if (0) { - -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 - } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 - } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { - goto skip_test; -#endif - } else { - goto keep_going; - } - -skip_test: - printf("Skip slow test %s.\n", method_name); - return rc; - -keep_going: - printf("================================================================================\n"); printf("Testing stateful Signature Generation %s\n", method_name); printf("================================================================================\n"); @@ -1043,7 +756,7 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { key_store_name = convert_method_name_to_file_name(method_name); /* set context and secure store callback */ context = strdup(((key_store_name))); - OQS_SIG_STFL_SECRET_KEY_SET_store_cb(lock_test_sk, test_save_secret_key, (void *)context); + OQS_SIG_STFL_SECRET_KEY_SET_store_cb(lock_test_sk, save_secret_key, (void *)context); /* * Get max num signature and the amount remaining @@ -1054,14 +767,12 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { fprintf(stderr, "OQS STFL key: Failed to get max number of sig from %s.\n", method_name); goto err; } - printf("%s Maximum num of sign operations = %llu\n", method_name, max_num_sigs); rc = OQS_SIG_STFL_sigs_remaining((const OQS_SIG_STFL *)lock_test_sig_obj, &num_sig_left, (const OQS_SIG_STFL_SECRET_KEY *)lock_test_sk); if (rc != OQS_SUCCESS) { fprintf(stderr, "OQS STFL key: Failed to get the remaining number of sig from %s.\n", method_name); goto err; } - printf("%s Remaining number of sign operations = %llu\n", method_name, num_sig_left); printf("================================================================================\n"); printf("Sig Gen 1 %s\n", method_name); @@ -1085,14 +796,12 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { fprintf(stderr, "OQS STFL key: Failed to get max number of sig from %s.\n", method_name); goto err; } - printf("%s Maximum num of sign operations = %llu\n", method_name, max_num_sigs); rc = OQS_SIG_STFL_sigs_remaining((const OQS_SIG_STFL *)lock_test_sig_obj, &num_sig_left, (const OQS_SIG_STFL_SECRET_KEY *)lock_test_sk); if (rc != OQS_SUCCESS) { fprintf(stderr, "OQS STFL key: Failed to get the remaining number of sig from %s.\n", method_name); goto err; } - printf("%s Remaining number of sign operations = %llu\n", method_name, num_sig_left); printf("================================================================================\n"); printf("Sig Gen 2 %s\n", method_name); @@ -1120,26 +829,25 @@ static OQS_STATUS sig_stfl_test_sig_gen(const char *method_name) { fprintf(stderr, "OQS STFL key: Failed to get max number of sig from %s.\n", method_name); goto err; } - printf("%s Maximum num of sign operations = %llu\n", method_name, max_num_sigs); rc = OQS_SIG_STFL_sigs_remaining((const OQS_SIG_STFL *)lock_test_sig_obj, &num_sig_left, (const OQS_SIG_STFL_SECRET_KEY *)lock_test_sk); if (rc != OQS_SUCCESS) { fprintf(stderr, "OQS STFL key: Failed to get the remaining number of sig from %s.\n", method_name); goto err; } - printf("%s Remaining number of sign operations = %llu\n", method_name, num_sig_left); - goto end_it; + rc = OQS_SUCCESS; + goto cleanup; err: rc = OQS_ERROR; -end_it: +cleanup: OQS_MEM_insecure_free(context); OQS_MEM_insecure_free(key_store_name); return rc; } -static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name) { +static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name, const char *katfile) { OQS_STATUS rc = OQS_SUCCESS; printf("================================================================================\n"); @@ -1150,71 +858,6 @@ static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name) { * Temporarily skip algs with long key generation times. */ - if (0) { - -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 - } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 - } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { - goto skip_test; -#endif - -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { - goto skip_test; -#endif -#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { - goto skip_test; -#endif - } else { - goto keep_going; - } - -skip_test: - printf("Skip slow test %s.\n", method_name); - return rc; - -keep_going: - printf("================================================================================\n"); printf("Create stateful Signature %s\n", method_name); printf("================================================================================\n"); @@ -1241,15 +884,6 @@ static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name) { OQS_SIG_STFL_SECRET_KEY_SET_unlock(lock_test_sk, unlock_sk_key); #if OQS_USE_PTHREADS_IN_TESTS - - test_sk_lock = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); - if (test_sk_lock == NULL) { - goto err; - } - - if (0 != pthread_mutex_init(test_sk_lock, 0)) { - goto err; - } OQS_SIG_STFL_SECRET_KEY_SET_mutex(lock_test_sk, test_sk_lock); #endif @@ -1257,14 +891,14 @@ static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name) { printf("Generate keypair %s\n", method_name); printf("================================================================================\n"); - rc = OQS_SIG_STFL_keypair(lock_test_sig_obj, lock_test_public_key, lock_test_sk); + rc = sig_stfl_KATs_keygen(lock_test_sig_obj, lock_test_public_key, lock_test_sk, katfile); if (rc != OQS_SUCCESS) { fprintf(stderr, "OQS STFL key gen failed.\n"); goto err; } - if (!lock_test_sk->secret_key_data) { + if (lock_test_sk->secret_key_data == NULL) { fprintf(stderr, "ERROR: OQS_SECRET_KEY_new incomplete.\n"); goto err; } @@ -1272,16 +906,13 @@ static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name) { /* set context and secure store callback */ if (lock_test_sk->set_scrt_key_store_cb) { lock_test_context = convert_method_name_to_file_name(method_name); - lock_test_sk->set_scrt_key_store_cb(lock_test_sk, test_save_secret_key, (void *)lock_test_context); + lock_test_sk->set_scrt_key_store_cb(lock_test_sk, save_secret_key, (void *)lock_test_context); } - printf("Test Secret Key Creator Thread created Stateful Signature and Secret Key objects.\n"); - goto end_it; + return OQS_SUCCESS; err: - rc = OQS_ERROR; -end_it: - return rc; + return OQS_ERROR; } #ifdef OQS_ENABLE_TEST_CONSTANT_TIME @@ -1301,17 +932,18 @@ static void TEST_SIG_STFL_randombytes(uint8_t *random_array, size_t bytes_to_rea #endif #if OQS_USE_PTHREADS_IN_TESTS -struct thread_data { +typedef struct thread_data { const char *alg_name; const char *katfile; OQS_STATUS rc; OQS_STATUS rc1; -}; +} thread_data_t; -struct lock_test_data { +typedef struct lock_test_data { const char *alg_name; + const char *katfile; OQS_STATUS rc; -}; +} lock_test_data_t; void *test_query_key(void *arg) { struct lock_test_data *td = arg; @@ -1332,7 +964,7 @@ void *test_sig_gen(void *arg) { void *test_create_keys(void *arg) { struct lock_test_data *td = arg; printf("\n%s: Start Generate Keys\n", __FUNCTION__); - td->rc = sig_stfl_test_secret_key_lock(td->alg_name); + td->rc = sig_stfl_test_secret_key_lock(td->alg_name, td->katfile); printf("%s: End Generate Stateful Keys\n\n", __FUNCTION__); return NULL; } @@ -1340,7 +972,7 @@ void *test_create_keys(void *arg) { void *test_wrapper(void *arg) { struct thread_data *td = arg; td->rc = sig_stfl_test_correctness(td->alg_name, td->katfile); - td->rc1 = sig_stfl_test_secret_key(td->alg_name); + td->rc1 = sig_stfl_test_secret_key(td->alg_name, td->katfile); return NULL; } #endif @@ -1381,64 +1013,81 @@ int main(int argc, char **argv) { OQS_randombytes_switch_algorithm("system"); #endif - OQS_STATUS rc, rc1, rc_lck, rc_sig, rc_qry; + OQS_STATUS rc = OQS_ERROR, rc1 = OQS_ERROR; + int exit_status = EXIT_SUCCESS; + #if OQS_USE_PTHREADS_IN_TESTS #define MAX_LEN_SIG_NAME_ 64 + OQS_STATUS rc_create = OQS_ERROR, rc_sign = OQS_ERROR, rc_query = OQS_ERROR; pthread_t thread; pthread_t create_key_thread; pthread_t sign_key_thread; pthread_t query_key_thread; - struct thread_data td; - td.alg_name = alg_name; - td.katfile = katfile; - - struct lock_test_data td_create; - struct lock_test_data td_sign; - struct lock_test_data td_query; - td_create.alg_name = alg_name; - td_sign.alg_name = alg_name; - td_query.alg_name = alg_name; - - int trc = pthread_create(&thread, NULL, test_wrapper, &td); - if (trc) { - fprintf(stderr, "ERROR: Creating pthread\n"); - OQS_destroy(); - return EXIT_FAILURE; + + thread_data_t td = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR, .rc1 = OQS_ERROR}; + lock_test_data_t td_create = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR}; + lock_test_data_t td_sign = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR}; + lock_test_data_t td_query = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR}; + + test_sk_lock = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); + if (test_sk_lock == NULL) { + goto err; + } + sk_lock = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); + if (sk_lock == NULL) { + goto err; + } + + if (pthread_mutex_init(test_sk_lock, NULL) || pthread_mutex_init(sk_lock, NULL)) { + fprintf(stderr, "ERROR: Initializing mutex\n"); + exit_status = EXIT_FAILURE; + goto err; + } + + if (pthread_create(&thread, NULL, test_wrapper, &td)) { + fprintf(stderr, "ERROR: Creating pthread for test_wrapper\n"); + exit_status = EXIT_FAILURE; + goto err; } pthread_join(thread, NULL); rc = td.rc; rc1 = td.rc1; - int trc_2 = pthread_create(&create_key_thread, NULL, test_create_keys, &td_create); - if (trc_2) { - fprintf(stderr, "ERROR: Creating pthread for stateful key gen test\n"); - OQS_destroy(); - return EXIT_FAILURE; + if (pthread_create(&create_key_thread, NULL, test_create_keys, &td_create)) { + fprintf(stderr, "ERROR: Creating pthread for test_create_keys\n"); + exit_status = EXIT_FAILURE; + goto err; } pthread_join(create_key_thread, NULL); - rc_lck = td_create.rc; + rc_create = td_create.rc; - int trc_3 = pthread_create(&sign_key_thread, NULL, test_sig_gen, &td_sign); - if (trc_3) { - fprintf(stderr, "ERROR: Creating pthread for sig gen test\n"); - OQS_destroy(); - return EXIT_FAILURE; + if (pthread_create(&sign_key_thread, NULL, test_sig_gen, &td_sign)) { + fprintf(stderr, "ERROR: Creating pthread for test_sig_gen\n"); + exit_status = EXIT_FAILURE; + goto err; } pthread_join(sign_key_thread, NULL); - rc_sig = td_sign.rc; + rc_sign = td_sign.rc; - int trc_4 = pthread_create(&query_key_thread, NULL, test_query_key, &td_query); - if (trc_4) { - fprintf(stderr, "ERROR: Creating pthread for query key test.\n"); - OQS_destroy(); - return EXIT_FAILURE; + if (pthread_create(&query_key_thread, NULL, test_query_key, &td_query)) { + fprintf(stderr, "ERROR: Creating pthread for test_query_key\n"); + exit_status = EXIT_FAILURE; + goto err; } pthread_join(query_key_thread, NULL); - rc_qry = td_query.rc; + rc_query = td_query.rc; + +err: + if (test_sk_lock) { + pthread_mutex_destroy(test_sk_lock); + } + if (sk_lock) { + pthread_mutex_destroy(sk_lock); + } #else rc = sig_stfl_test_correctness(alg_name, katfile); - rc1 = sig_stfl_test_secret_key(alg_name); + rc1 = sig_stfl_test_secret_key(alg_name, katfile); #endif OQS_SIG_STFL_SECRET_KEY_free(lock_test_sk); @@ -1448,11 +1097,10 @@ int main(int argc, char **argv) { OQS_MEM_insecure_free(signature_1); OQS_MEM_insecure_free(signature_2); - if ((rc != OQS_SUCCESS) || (rc1 != OQS_SUCCESS) || (rc_lck != OQS_SUCCESS) || (rc_sig != OQS_SUCCESS) - || (rc_qry != OQS_SUCCESS)) { - OQS_destroy(); + OQS_destroy(); + if (rc != OQS_SUCCESS || rc1 != OQS_SUCCESS || + rc_create != OQS_SUCCESS || rc_sign != OQS_SUCCESS || rc_query != OQS_SUCCESS) { return EXIT_FAILURE; } - OQS_destroy(); - return EXIT_SUCCESS; + return exit_status; } From 47740ad98cc5361c9916abca1944f1e6a24c0158 Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Wed, 15 Nov 2023 14:41:47 -0500 Subject: [PATCH 20/68] Enforce idx from unsigned int to uint32_t. (#1611) --- src/sig_stfl/xmss/external/xmss_core_fast.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/sig_stfl/xmss/external/xmss_core_fast.c b/src/sig_stfl/xmss/external/xmss_core_fast.c index 4dd4c9b41d..deaedefa8a 100644 --- a/src/sig_stfl/xmss/external/xmss_core_fast.c +++ b/src/sig_stfl/xmss/external/xmss_core_fast.c @@ -221,7 +221,6 @@ static void treehash_init(const xmss_params *params, bds_state *state, const unsigned char *sk_seed, const unsigned char *pub_seed, const uint32_t addr[8]) { - unsigned int idx = index; // use three different addresses because at this point we use all three formats in parallel uint32_t ots_addr[8] = {0}; uint32_t ltree_addr[8] = {0}; @@ -235,14 +234,14 @@ static void treehash_init(const xmss_params *params, copy_subtree_addr(node_addr, addr); set_type(node_addr, 2); - uint32_t lastnode, i; + /* The subtree has at most 2^20 leafs, so uint32_t suffices. */ + uint32_t idx = index; + uint32_t lastnode = index +(1<n, sizeof(unsigned char)); unsigned int *stacklevels = malloc((height + 1)*sizeof(unsigned int)); unsigned int stackoffset=0; unsigned int nodeh; - lastnode = idx+(1<tree_height-params->bds_k; i++) { state->treehash[i].h = i; state->treehash[i].completed = 1; @@ -281,9 +280,7 @@ static void treehash_init(const xmss_params *params, i++; } - for (i = 0; i < params->n; i++) { - node[i] = stack[i]; - } + memcpy(node, stack, params->n); OQS_MEM_insecure_free(stacklevels); OQS_MEM_insecure_free(stack); From a7b29874fd7aec76165626c2e6ea8a66de91e0b9 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Mon, 27 Nov 2023 17:26:08 -0500 Subject: [PATCH 21/68] SHA2 Increment with arbitrary length (non-block sizes) (#1614) * Enhanced with new SHA2 API that allows arbitary length updates * Fix style * Fix format * Document struct members * Fix comparison sign * Use OQS SHA2 API * Add nl at end * Use OQS_MEM_secure_free instead of free * Updated per review... mem check after malloc, use memcpy * Fix style --- src/common/sha2/sha2.c | 4 + src/common/sha2/sha2.h | 38 +++++ src/common/sha2/sha2_armv8.c | 99 ++++++++++-- src/common/sha2/sha2_c.c | 114 ++++++++++++-- src/common/sha2/sha2_impl.c | 8 + src/common/sha2/sha2_local.h | 10 ++ src/common/sha2/sha2_ossl.c | 5 + src/sig_stfl/lms/CMakeLists.txt | 1 - src/sig_stfl/lms/external/hash.c | 13 +- src/sig_stfl/lms/external/hash.h | 5 +- src/sig_stfl/lms/external/lms_namespace.h | 2 - src/sig_stfl/lms/external/sha256.c | 183 ---------------------- src/sig_stfl/lms/external/sha256.h | 44 ------ tests/test_hash.c | 54 ++++++- 14 files changed, 317 insertions(+), 263 deletions(-) delete mode 100644 src/sig_stfl/lms/external/sha256.c delete mode 100644 src/sig_stfl/lms/external/sha256.h diff --git a/src/common/sha2/sha2.c b/src/common/sha2/sha2.c index 9cc732d1d3..e0d3902e3b 100644 --- a/src/common/sha2/sha2.c +++ b/src/common/sha2/sha2.c @@ -22,6 +22,10 @@ void OQS_SHA2_sha256_inc_blocks(OQS_SHA2_sha256_ctx *state, const uint8_t *in, s callbacks->SHA2_sha256_inc_blocks(state, in, inblocks); } +void OQS_SHA2_sha256_inc(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t len) { + callbacks->SHA2_sha256_inc(state, in, len); +} + void OQS_SHA2_sha256_inc_finalize(uint8_t *out, OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inlen) { callbacks->SHA2_sha256_inc_finalize(out, state, in, inlen); } diff --git a/src/common/sha2/sha2.h b/src/common/sha2/sha2.h index 41562f8f5e..cd993e69c8 100644 --- a/src/common/sha2/sha2.h +++ b/src/common/sha2/sha2.h @@ -24,6 +24,16 @@ extern "C" { #endif +/** Data structure for the state of the SHA-224 incremental hashing API. */ +typedef struct { + /** Internal state */ + void *ctx; + /** current number of bytes in data */ + size_t data_len; + /** unprocessed data buffer */ + uint8_t data[128]; +} OQS_SHA2_sha224_ctx; + /** * \brief Process a message with SHA-256 and return the hash code in the output byte array. * @@ -39,6 +49,10 @@ void OQS_SHA2_sha256(uint8_t *output, const uint8_t *input, size_t inplen); typedef struct { /** Internal state */ void *ctx; + /** current number of bytes in data */ + size_t data_len; + /** unprocessed data buffer */ + uint8_t data[128]; } OQS_SHA2_sha256_ctx; /** @@ -74,6 +88,17 @@ void OQS_SHA2_sha256_inc_ctx_clone(OQS_SHA2_sha256_ctx *dest, const OQS_SHA2_sha */ void OQS_SHA2_sha256_inc_blocks(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inblocks); +/** + * \brief Process message bytes with SHA-256 and update the state. + * + * \warning The state must be initialized by OQS_SHA2_sha256_inc_init or OQS_SHA2_sha256_inc_ctx_clone. + * + * \param state The state to update + * \param in Message input byte array + * \param len The number of bytes of message to process + */ +void OQS_SHA2_sha256_inc(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t len); + /** * \brief Process more message bytes with SHA-256 and return the hash code in the output byte array. * @@ -113,6 +138,10 @@ void OQS_SHA2_sha384(uint8_t *output, const uint8_t *input, size_t inplen); typedef struct { /** Internal state. */ void *ctx; + /** current number of bytes in data */ + size_t data_len; + /** unprocessed data buffer */ + uint8_t data[128]; } OQS_SHA2_sha384_ctx; /** @@ -187,6 +216,10 @@ void OQS_SHA2_sha512(uint8_t *output, const uint8_t *input, size_t inplen); typedef struct { /** Internal state. */ void *ctx; + /** current number of bytes in data */ + size_t data_len; + /** unprocessed data buffer */ + uint8_t data[128]; } OQS_SHA2_sha512_ctx; /** @@ -264,6 +297,11 @@ struct OQS_SHA2_callbacks { */ void (*SHA2_sha256_inc_ctx_clone)(OQS_SHA2_sha256_ctx *dest, const OQS_SHA2_sha256_ctx *src); + /** + * Implementation of function OQS_SHA2_sha256_inc. + */ + void (*SHA2_sha256_inc)(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t len); + /** * Implementation of function OQS_SHA2_sha256_inc_blocks. */ diff --git a/src/common/sha2/sha2_armv8.c b/src/common/sha2/sha2_armv8.c index 49a63448aa..f3bbf573a1 100644 --- a/src/common/sha2/sha2_armv8.c +++ b/src/common/sha2/sha2_armv8.c @@ -3,7 +3,7 @@ #include #include "sha2_local.h" - +#include #include // ARM includes #ifndef WIN32 @@ -169,23 +169,43 @@ static size_t crypto_hashblocks_sha256_armv8(uint8_t *statebytes, return length; } + void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const uint8_t *in, size_t inlen) { uint8_t padded[128]; - uint64_t bytes = load_bigendian_64(state->ctx + 32) + inlen; - crypto_hashblocks_sha256_armv8(state->ctx, in, inlen); - in += inlen; - inlen &= 63; - in -= inlen; + size_t new_inlen = state->data_len + inlen; + size_t tmp_len = new_inlen; + const uint8_t *new_in; + uint8_t *tmp_in = NULL; + + if (new_inlen == inlen) { + new_in = in; + } else { //Combine incremental data with final input + tmp_in = malloc(tmp_len); + if (tmp_in == NULL) { + exit(111); + } + + memcpy(tmp_in, state->data, state->data_len); + memcpy(tmp_in + state->data_len, in, inlen); + new_in = tmp_in; + } + + uint64_t bytes = load_bigendian_64(state->ctx + 32) + new_inlen; + + crypto_hashblocks_sha256_armv8(state->ctx, new_in, new_inlen); + new_in += new_inlen; + new_inlen &= 63; + new_in -= new_inlen; - for (size_t i = 0; i < inlen; ++i) { - padded[i] = in[i]; + for (size_t i = 0; i < new_inlen; ++i) { + padded[i] = new_in[i]; } - padded[inlen] = 0x80; + padded[new_inlen] = 0x80; - if (inlen < 56) { - for (size_t i = inlen + 1; i < 56; ++i) { + if (new_inlen < 56) { + for (size_t i = new_inlen + 1; i < 56; ++i) { padded[i] = 0; } padded[56] = (uint8_t) (bytes >> 53); @@ -198,7 +218,7 @@ void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const ui padded[63] = (uint8_t) (bytes << 3); crypto_hashblocks_sha256_armv8(state->ctx, padded, 64); } else { - for (size_t i = inlen + 1; i < 120; ++i) { + for (size_t i = new_inlen + 1; i < 120; ++i) { padded[i] = 0; } padded[120] = (uint8_t) (bytes >> 53); @@ -216,6 +236,7 @@ void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const ui out[i] = state->ctx[i]; } oqs_sha2_sha256_inc_ctx_release_c(state); + OQS_MEM_secure_free(tmp_in, tmp_len); } void oqs_sha2_sha224_inc_finalize_armv8(uint8_t *out, sha224ctx *state, const uint8_t *in, size_t inlen) { @@ -229,11 +250,63 @@ void oqs_sha2_sha224_inc_finalize_armv8(uint8_t *out, sha224ctx *state, const ui void oqs_sha2_sha256_inc_blocks_armv8(sha256ctx *state, const uint8_t *in, size_t inblocks) { uint64_t bytes = load_bigendian_64(state->ctx + 32); + const uint8_t *new_in; + size_t buf_len = 64 * inblocks; + uint8_t *tmp_in = NULL; + + /* Process any existing incremental data first */ + if (state->data_len) { + tmp_in = malloc(buf_len); + if (tmp_in == NULL) { + exit(111); + } + + memcpy(tmp_in, state->data, state->data_len); + memcpy(tmp_in + state->data_len, in, buf_len - state->data_len); + + /* store the reminder input as incremental data */ + memcpy(state->data, in + (buf_len - state->data_len), state->data_len); + new_in = tmp_in; + } else { + new_in = in; + } - crypto_hashblocks_sha256_armv8(state->ctx, in, 64 * inblocks); + crypto_hashblocks_sha256_armv8(state->ctx, new_in, 64 * inblocks); bytes += 64 * inblocks; store_bigendian_64(state->ctx + 32, bytes); + OQS_MEM_secure_free(tmp_in, buf_len); +} + +void oqs_sha2_sha256_inc_armv8(sha256ctx *state, const uint8_t *in, size_t len) { + uint64_t bytes = 0; + while (len) { + size_t incr = 64 - state->data_len; + if (incr > len) { + incr = len; + } + + for (size_t i = 0; i < incr; ++i, state->data_len++) { + state->data[state->data_len] = in[i]; + } + + if (state->data_len < 64) { + break; + } + + /* + * Process a complete block now + */ + bytes = load_bigendian_64(state->ctx + 32) + 64; + crypto_hashblocks_sha256_armv8(state->ctx, state->data, 64); + store_bigendian_64(state->ctx + 32, bytes); + + /* + * update the remaining input + */ + len -= incr; + state->data_len = 0; + } } void oqs_sha2_sha224_inc_blocks_armv8(sha224ctx *state, const uint8_t *in, size_t inblocks) { diff --git a/src/common/sha2/sha2_c.c b/src/common/sha2/sha2_c.c index 1de100c306..33863f8040 100644 --- a/src/common/sha2/sha2_c.c +++ b/src/common/sha2/sha2_c.c @@ -512,9 +512,12 @@ void oqs_sha2_sha224_inc_init_c(sha224ctx *state) { for (size_t i = 32; i < 40; ++i) { state->ctx[i] = 0; } + state->data_len = 0; + memset(state->data, 0, 128); } void oqs_sha2_sha256_inc_init_c(sha256ctx *state) { + state->data_len = 0; state->ctx = malloc(PQC_SHA256CTX_BYTES); if (state->ctx == NULL) { exit(111); @@ -525,6 +528,8 @@ void oqs_sha2_sha256_inc_init_c(sha256ctx *state) { for (size_t i = 32; i < 40; ++i) { state->ctx[i] = 0; } + state->data_len = 0; + memset(state->data, 0, 128); } void oqs_sha2_sha384_inc_init_c(sha384ctx *state) { @@ -538,6 +543,8 @@ void oqs_sha2_sha384_inc_init_c(sha384ctx *state) { for (size_t i = 64; i < 72; ++i) { state->ctx[i] = 0; } + state->data_len = 0; + memset(state->data, 0, 128); } void oqs_sha2_sha512_inc_init_c(sha512ctx *state) { @@ -551,6 +558,8 @@ void oqs_sha2_sha512_inc_init_c(sha512ctx *state) { for (size_t i = 64; i < 72; ++i) { state->ctx[i] = 0; } + state->data_len = 0; + memset(state->data, 0, 128); } void oqs_sha2_sha224_inc_ctx_clone_c(sha224ctx *stateout, const sha224ctx *statein) { @@ -558,6 +567,8 @@ void oqs_sha2_sha224_inc_ctx_clone_c(sha224ctx *stateout, const sha224ctx *state if (stateout->ctx == NULL) { exit(111); } + stateout->data_len = statein->data_len; + memcpy(stateout->data, statein->data, 128); memcpy(stateout->ctx, statein->ctx, PQC_SHA256CTX_BYTES); } @@ -566,6 +577,8 @@ void oqs_sha2_sha256_inc_ctx_clone_c(sha256ctx *stateout, const sha256ctx *state if (stateout->ctx == NULL) { exit(111); } + stateout->data_len = statein->data_len; + memcpy(stateout->data, statein->data, 128); memcpy(stateout->ctx, statein->ctx, PQC_SHA256CTX_BYTES); } @@ -574,6 +587,8 @@ void oqs_sha2_sha384_inc_ctx_clone_c(sha384ctx *stateout, const sha384ctx *state if (stateout->ctx == NULL) { exit(111); } + stateout->data_len = statein->data_len; + memcpy(stateout->data, statein->data, 128); memcpy(stateout->ctx, statein->ctx, PQC_SHA512CTX_BYTES); } @@ -582,6 +597,8 @@ void oqs_sha2_sha512_inc_ctx_clone_c(sha512ctx *stateout, const sha512ctx *state if (stateout->ctx == NULL) { exit(111); } + stateout->data_len = statein->data_len; + memcpy(stateout->data, statein->data, 128); memcpy(stateout->ctx, statein->ctx, PQC_SHA512CTX_BYTES); } @@ -607,11 +624,64 @@ void oqs_sha2_sha512_inc_ctx_release_c(sha512ctx *state) { void oqs_sha2_sha256_inc_blocks_c(sha256ctx *state, const uint8_t *in, size_t inblocks) { uint64_t bytes = load_bigendian_64(state->ctx + 32); + size_t tmp_buflen = 64 * inblocks; + const uint8_t *new_in; + uint8_t *tmp_in = NULL; + + /* Process any existing incremental data first */ + if (state->data_len) { + tmp_in = malloc(tmp_buflen); + if (tmp_in == NULL) { + exit(111); + } + + memcpy(tmp_in, state->data, state->data_len); + memcpy(tmp_in + state->data_len, in, tmp_buflen - state->data_len); + + /* store the reminder input as incremental data */ + memcpy(state->data, in + (tmp_buflen - state->data_len), state->data_len); + new_in = tmp_in; + } else { + new_in = in; + } - crypto_hashblocks_sha256_c(state->ctx, in, 64 * inblocks); + crypto_hashblocks_sha256_c(state->ctx, new_in, 64 * inblocks); bytes += 64 * inblocks; store_bigendian_64(state->ctx + 32, bytes); + OQS_MEM_secure_free(tmp_in, tmp_buflen); +} + +void oqs_sha2_sha256_inc_c(sha256ctx *state, const uint8_t *in, size_t len) { + uint64_t bytes = 0; + while (len) { + size_t incr = 64 - state->data_len; + if (incr > len) { + incr = len; + } + + for (size_t i = 0; i < incr; ++i, state->data_len++) { + state->data[state->data_len] = in[i]; + } + + if (state->data_len < 64) { + break; + } + + /* + * Process a complete block now + */ + bytes = load_bigendian_64(state->ctx + 32); + crypto_hashblocks_sha256_c(state->ctx, state->data, 64); + bytes += 64; + store_bigendian_64(state->ctx + 32, bytes); + + /* + * update the remaining input + */ + len -= incr; + state->data_len = 0; + } } void oqs_sha2_sha224_inc_blocks_c(sha224ctx *state, const uint8_t *in, size_t inblocks) { @@ -633,20 +703,39 @@ void oqs_sha2_sha384_inc_blocks_c(sha384ctx *state, const uint8_t *in, size_t in void oqs_sha2_sha256_inc_finalize_c(uint8_t *out, sha256ctx *state, const uint8_t *in, size_t inlen) { uint8_t padded[128]; - uint64_t bytes = load_bigendian_64(state->ctx + 32) + inlen; - crypto_hashblocks_sha256_c(state->ctx, in, inlen); - in += inlen; - inlen &= 63; - in -= inlen; + size_t new_inlen = state->data_len + inlen; + size_t tmp_len = new_inlen; + const uint8_t *new_in; + uint8_t *tmp_in = NULL; + + if (new_inlen == inlen) { + new_in = in; + } else { //Combine incremental data with final input + tmp_in = malloc(tmp_len); + if (tmp_in == NULL) { + exit(111); + } - for (size_t i = 0; i < inlen; ++i) { - padded[i] = in[i]; + memcpy(tmp_in, state->data, state->data_len); + memcpy(tmp_in + state->data_len, in, inlen); + new_in = tmp_in; } - padded[inlen] = 0x80; - if (inlen < 56) { - for (size_t i = inlen + 1; i < 56; ++i) { + uint64_t bytes = load_bigendian_64(state->ctx + 32) + new_inlen; + + crypto_hashblocks_sha256_c(state->ctx, new_in, new_inlen); + new_in += new_inlen; + new_inlen &= 63; + new_in -= new_inlen; + + for (size_t i = 0; i < new_inlen; ++i) { + padded[i] = new_in[i]; + } + padded[new_inlen] = 0x80; + + if (new_inlen < 56) { + for (size_t i = new_inlen + 1; i < 56; ++i) { padded[i] = 0; } padded[56] = (uint8_t) (bytes >> 53); @@ -659,7 +748,7 @@ void oqs_sha2_sha256_inc_finalize_c(uint8_t *out, sha256ctx *state, const uint8_ padded[63] = (uint8_t) (bytes << 3); crypto_hashblocks_sha256_c(state->ctx, padded, 64); } else { - for (size_t i = inlen + 1; i < 120; ++i) { + for (size_t i = new_inlen + 1; i < 120; ++i) { padded[i] = 0; } padded[120] = (uint8_t) (bytes >> 53); @@ -677,6 +766,7 @@ void oqs_sha2_sha256_inc_finalize_c(uint8_t *out, sha256ctx *state, const uint8_ out[i] = state->ctx[i]; } oqs_sha2_sha256_inc_ctx_release_c(state); + OQS_MEM_secure_free(tmp_in, tmp_len); } void oqs_sha2_sha224_inc_finalize_c(uint8_t *out, sha224ctx *state, const uint8_t *in, size_t inlen) { diff --git a/src/common/sha2/sha2_impl.c b/src/common/sha2/sha2_impl.c index f7f01b24f5..1d6d4fb323 100644 --- a/src/common/sha2/sha2_impl.c +++ b/src/common/sha2/sha2_impl.c @@ -31,6 +31,13 @@ static void SHA2_sha256_inc_ctx_clone(OQS_SHA2_sha256_ctx *dest, const OQS_SHA2_ oqs_sha2_sha256_inc_ctx_clone_c((sha256ctx *) dest, (const sha256ctx *) src); } +static void SHA2_sha256_inc(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t len) { + C_OR_ARM( + oqs_sha2_sha256_inc_c((sha256ctx *) state, in, len), + oqs_sha2_sha256_inc_armv8((sha256ctx *) state, in, len) + ); +} + static void SHA2_sha256_inc_blocks(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inblocks) { C_OR_ARM( oqs_sha2_sha256_inc_blocks_c((sha256ctx *) state, in, inblocks), @@ -105,6 +112,7 @@ struct OQS_SHA2_callbacks sha2_default_callbacks = { SHA2_sha256, SHA2_sha256_inc_init, SHA2_sha256_inc_ctx_clone, + SHA2_sha256_inc, SHA2_sha256_inc_blocks, SHA2_sha256_inc_finalize, SHA2_sha256_inc_ctx_release, diff --git a/src/common/sha2/sha2_local.h b/src/common/sha2/sha2_local.h index dcb1392841..969e791d20 100644 --- a/src/common/sha2/sha2_local.h +++ b/src/common/sha2/sha2_local.h @@ -23,18 +23,26 @@ extern "C" { typedef struct { uint8_t *ctx; + size_t data_len; /* current number of bytes in data */ + uint8_t data[128]; /* msg buffer */ } sha224ctx; typedef struct { uint8_t *ctx; + size_t data_len; /* current number of bytes in data */ + uint8_t data[128]; /* msg buffer */ } sha256ctx; typedef struct { uint8_t *ctx; + size_t data_len; /* current number of bytes in data */ + uint8_t data[128]; /* msg buffer */ } sha384ctx; typedef struct { uint8_t *ctx; + size_t data_len; /* current number of bytes in data */ + uint8_t data[128]; /* msg buffer */ } sha512ctx; void oqs_sha2_sha224_inc_init_c(sha224ctx *state); @@ -46,6 +54,7 @@ void oqs_sha2_sha224_inc_ctx_release_c(sha224ctx *state); void oqs_sha2_sha256_inc_init_c(sha256ctx *state); void oqs_sha2_sha256_inc_ctx_clone_c(sha256ctx *dest, const sha256ctx *src); void oqs_sha2_sha256_inc_blocks_c(sha256ctx *state, const uint8_t *in, size_t inblocks); +void oqs_sha2_sha256_inc_c(sha256ctx *state, const uint8_t *in, size_t len); void oqs_sha2_sha256_inc_finalize_c(uint8_t *out, sha256ctx *state, const uint8_t *in, size_t inlen); void oqs_sha2_sha256_inc_ctx_release_c(sha256ctx *state); @@ -66,6 +75,7 @@ void oqs_sha2_sha512_inc_ctx_release_c(sha512ctx *state); void oqs_sha2_sha224_inc_blocks_armv8(sha224ctx *state, const uint8_t *in, size_t inblocks); void oqs_sha2_sha224_armv8(uint8_t *out, const uint8_t *in, size_t inlen); void oqs_sha2_sha256_inc_blocks_armv8(sha256ctx *state, const uint8_t *in, size_t inblocks); +void oqs_sha2_sha256_inc_armv8(sha256ctx *state, const uint8_t *in, size_t len); void oqs_sha2_sha256_armv8(uint8_t *out, const uint8_t *in, size_t inlen); void oqs_sha2_sha384_inc_init_armv8(sha384ctx *state); diff --git a/src/common/sha2/sha2_ossl.c b/src/common/sha2/sha2_ossl.c index 0953feb194..064fb61ad8 100644 --- a/src/common/sha2/sha2_ossl.c +++ b/src/common/sha2/sha2_ossl.c @@ -58,6 +58,10 @@ static void SHA2_sha256_inc_init(OQS_SHA2_sha256_ctx *state) { state->ctx = mdctx; } +static void SHA2_sha256_inc(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t len) { + OQS_OPENSSL_GUARD(EVP_DigestUpdate((EVP_MD_CTX *) state->ctx, in, len)); +} + static void SHA2_sha256_inc_blocks(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inblocks) { OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestUpdate)((EVP_MD_CTX *) state->ctx, in, inblocks * SHA2_BLOCK_SIZE)); } @@ -153,6 +157,7 @@ struct OQS_SHA2_callbacks sha2_default_callbacks = { SHA2_sha256, SHA2_sha256_inc_init, SHA2_sha256_inc_ctx_clone, + SHA2_sha256_inc, SHA2_sha256_inc_blocks, SHA2_sha256_inc_finalize, SHA2_sha256_inc_ctx_release, diff --git a/src/sig_stfl/lms/CMakeLists.txt b/src/sig_stfl/lms/CMakeLists.txt index 93fa290084..e47452eb50 100644 --- a/src/sig_stfl/lms/CMakeLists.txt +++ b/src/sig_stfl/lms/CMakeLists.txt @@ -26,7 +26,6 @@ set(SRCS external/lm_ots_sign.c external/lm_ots_verify.c external/lm_verify.c - external/sha256.c sig_stfl_lms.c sig_stfl_lms_functions.c ) diff --git a/src/sig_stfl/lms/external/hash.c b/src/sig_stfl/lms/external/hash.c index dffcdaf6a6..0fe23ecc62 100644 --- a/src/sig_stfl/lms/external/hash.c +++ b/src/sig_stfl/lms/external/hash.c @@ -1,6 +1,5 @@ #include #include "hash.h" -#include "sha256.h" #include "hss_zeroize.h" #define ALLOW_VERBOSE 0 /* 1 -> we allow the dumping of intermediate */ @@ -39,8 +38,8 @@ void hss_hash_ctx(void *result, int hash_type, union hash_context *ctx, switch (hash_type) { case HASH_SHA256: { - SHA256_Init(&ctx->sha256); - SHA256_Update(&ctx->sha256, message, message_len); + OQS_SHA2_sha256_inc_init(&ctx->sha256); + OQS_SHA2_sha256_inc(&ctx->sha256, message, message_len); SHA256_Final(result, &ctx->sha256); #if ALLOW_VERBOSE if (hss_verbose) { @@ -69,7 +68,7 @@ void hss_hash(void *result, int hash_type, void hss_init_hash_context(int h, union hash_context *ctx) { switch (h) { case HASH_SHA256: - SHA256_Init( &ctx->sha256 ); + OQS_SHA2_sha256_inc_init( &ctx->sha256 ); break; } } @@ -83,7 +82,7 @@ void hss_update_hash_context(int h, union hash_context *ctx, #endif switch (h) { case HASH_SHA256: - SHA256_Update(&ctx->sha256, msg, len_msg); + OQS_SHA2_sha256_inc(&ctx->sha256, msg, len_msg); break; } } @@ -117,3 +116,7 @@ unsigned hss_hash_blocksize(int hash_type) { } return 0; } + +void SHA256_Final(unsigned char *output, OQS_SHA2_sha256_ctx *ctx) { + OQS_SHA2_sha256_inc_finalize(output, ctx, NULL, 0); +} diff --git a/src/sig_stfl/lms/external/hash.h b/src/sig_stfl/lms/external/hash.h index 5e8fb3134d..8b1891f108 100644 --- a/src/sig_stfl/lms/external/hash.h +++ b/src/sig_stfl/lms/external/hash.h @@ -1,6 +1,6 @@ #if !defined( HASH_H__ ) #define HASH_H__ -#include "sha256.h" +#include #include #include #include "lms_namespace.h" @@ -19,7 +19,7 @@ enum { }; union hash_context { - SHA256_CTX sha256; + OQS_SHA2_sha256_ctx sha256; /* Any other hash contexts would go here */ }; @@ -54,5 +54,6 @@ void hss_update_hash_context( int h, union hash_context *ctx, const void *msg, size_t len_msg ); void hss_finalize_hash_context( int h, union hash_context *ctx, void *buffer); +void SHA256_Final(unsigned char *output, OQS_SHA2_sha256_ctx *ctx); #endif /* HASH_H__ */ diff --git a/src/sig_stfl/lms/external/lms_namespace.h b/src/sig_stfl/lms/external/lms_namespace.h index 56898589ee..c1b8f142ae 100644 --- a/src/sig_stfl/lms/external/lms_namespace.h +++ b/src/sig_stfl/lms/external/lms_namespace.h @@ -89,8 +89,6 @@ #define lm_validate_signature LMS_NAMESPACE(lm_validate_signature) #define SHA256_Final LMS_NAMESPACE(SHA256_Final) -#define SHA256_Init LMS_NAMESPACE(SHA256_Init) -#define SHA256_Update LMS_NAMESPACE(SHA256_Update) #define LMS_randombytes LMS_NAMESPACE(LMS_randombytes) #endif //_LMS_NAMESPACE_H diff --git a/src/sig_stfl/lms/external/sha256.c b/src/sig_stfl/lms/external/sha256.c deleted file mode 100644 index fb18892a31..0000000000 --- a/src/sig_stfl/lms/external/sha256.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * SHA-256 - * Implementation derived from LibTomCrypt (Tom St Denis) - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org - */ - -#include -#include "sha256.h" -#include "endian.h" - -#if !USE_OPENSSL && !defined(EXT_SHA256_H) - -/* If we don't have OpenSSL, here's a SHA256 implementation */ -#define SHA256_FINALCOUNT_SIZE 8 -#define SHA256_K_SIZE 64 -static const unsigned long K[SHA256_K_SIZE] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, - 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, - 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, - 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, - 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, - 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, - 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, - 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, - 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, - 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL -}; - -/* Various logical functions */ - -/* Rotate x right by rot bits */ -static unsigned long RORc(unsigned long x, int rot) { - rot &= 31; if (rot == 0) return x; - unsigned long right = ((x&0xFFFFFFFFUL)>>rot ); - unsigned long left = ((x&0xFFFFFFFFUL)<<(32-rot) ); - return (right|left) & 0xFFFFFFFFUL; -} -#define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) (((x | y) & z) | (x & y)) -#define S(x, n) RORc((x),(n)) -#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) -#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) -#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) -#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) -#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) - -static void sha256_compress (SHA256_CTX * ctx, const void *buf) -{ - unsigned long S0, S1, S2, S3, S4, S5, S6, S7, W[SHA256_K_SIZE], t0, t1, t; - int i; - const unsigned char *p; - - /* copy state into S */ - S0 = ctx->h[0]; - S1 = ctx->h[1]; - S2 = ctx->h[2]; - S3 = ctx->h[3]; - S4 = ctx->h[4]; - S5 = ctx->h[5]; - S6 = ctx->h[6]; - S7 = ctx->h[7]; - - /* - * We've been asked to perform the hash computation on this 512-bit string. - * SHA256 interprets that as an array of 16 bigendian 32 bit numbers; copy - * it, and convert it into 16 unsigned long's of the CPU's native format - */ - p = buf; - for (i=0; i<16; i++) { - W[i] = get_bigendian( p, 4 ); - p += 4; - } - - /* fill W[16..63] */ - for (i = 16; i < SHA256_K_SIZE; i++) { - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; - } - - /* Compress */ -#define RND(a,b,c,d,e,f,g,h,i) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ - h = t0 + t1; - - for (i = 0; i < SHA256_K_SIZE; ++i) { - RND(S0,S1,S2,S3,S4,S5,S6,S7,i); - t = S7; S7 = S6; S6 = S5; S5 = S4; - S4 = S3; S3 = S2; S2 = S1; S1 = S0; S0 = t; - } -#undef RND - - /* feedback */ - ctx->h[0] += S0; - ctx->h[1] += S1; - ctx->h[2] += S2; - ctx->h[3] += S3; - ctx->h[4] += S4; - ctx->h[5] += S5; - ctx->h[6] += S6; - ctx->h[7] += S7; -} - -void SHA256_Init (SHA256_CTX *ctx) -{ - ctx->Nl = 0; - ctx->Nh = 0; - ctx->num = 0; - ctx->h[0] = 0x6A09E667UL; - ctx->h[1] = 0xBB67AE85UL; - ctx->h[2] = 0x3C6EF372UL; - ctx->h[3] = 0xA54FF53AUL; - ctx->h[4] = 0x510E527FUL; - ctx->h[5] = 0x9B05688CUL; - ctx->h[6] = 0x1F83D9ABUL; - ctx->h[7] = 0x5BE0CD19UL; -} - -void SHA256_Update (SHA256_CTX *ctx, const void *src, unsigned int count) -{ - unsigned new_count = (ctx->Nl + (count << 3)) & 0xffffffff; - if (new_count < ctx->Nl) { - ctx->Nh += 1; - } - ctx->Nl = new_count; - - while (count) { - unsigned int this_step = 64 - ctx->num; - if (this_step > count) this_step = count; - memcpy( ctx->data + ctx->num, src, this_step); - - if (this_step + ctx->num < 64) { - ctx->num += this_step; - break; - } - - src = (const unsigned char *)src + this_step; - count -= this_step; - ctx->num = 0; - - sha256_compress( ctx, ctx->data ); - } -} - -/* - * Add padding and return the message digest. - */ -void SHA256_Final (unsigned char *digest, SHA256_CTX *ctx) -{ - unsigned int i; - unsigned char finalcount[SHA256_FINALCOUNT_SIZE]; - - put_bigendian( &finalcount[0], ctx->Nh, 4 ); - put_bigendian( &finalcount[4], ctx->Nl, 4 ); - - SHA256_Update(ctx, "\200", 1); - - if (ctx->num > 56) { - SHA256_Update(ctx, "\0\0\0\0\0\0\0\0", 8); - } - memset( ctx->data + ctx->num, 0, 56 - ctx->num ); - ctx->num = 56; - SHA256_Update(ctx, finalcount, SHA256_FINALCOUNT_SIZE); /* Should cause a sha256_compress() */ - - /* - * The final state is an array of unsigned long's; place them as a series - * of bigendian 4-byte words onto the output - */ - for (i=0; i<8; i++) { - put_bigendian( digest + 4*i, ctx->h[i], 4 ); - } -} -#endif diff --git a/src/sig_stfl/lms/external/sha256.h b/src/sig_stfl/lms/external/sha256.h deleted file mode 100644 index f7f78ad18c..0000000000 --- a/src/sig_stfl/lms/external/sha256.h +++ /dev/null @@ -1,44 +0,0 @@ -#if !defined(SHA256_H_) -#define SHA256_H_ - -#if defined( EXT_SHA256_H ) -#include EXT_SHA256_H -#else - -#define USE_OPENSSL 0 /* We use the OpenSSL implementation for SHA-256 */ - /* (which is quite a bit faster than our portable */ - /* C version) */ - -#if USE_OPENSSL - -#include - -#else -#include "lms_namespace.h" - -/* SHA256 context. */ -typedef struct { - unsigned long int h[8]; /* state; this is in the CPU native format */ - unsigned long Nl, Nh; /* number of bits processed so far */ - unsigned num; /* number of bytes within the below */ - /* buffer */ - unsigned char data[64]; /* input buffer. This is in byte vector format */ -} SHA256_CTX; - -void SHA256_Init(SHA256_CTX *); /* context */ - -void SHA256_Update(SHA256_CTX *, /* context */ - const void *, /* input block */ - unsigned int);/* length of input block */ - -void SHA256_Final(unsigned char *, - SHA256_CTX *); -#endif - -#endif /* EXT_SHA256_H */ - -#if !defined( SHA256_LEN ) -#define SHA256_LEN 32 /* The length of a SHA256 hash output */ -#endif - -#endif /* ifdef(SHA256_H_) */ diff --git a/tests/test_hash.c b/tests/test_hash.c index 022fb61a7b..3fea2f00ad 100644 --- a/tests/test_hash.c +++ b/tests/test_hash.c @@ -50,16 +50,24 @@ static int do_sha256(void) { fprintf(stderr, "ERROR reading from stdin\n"); return -1; } + // run main SHA-256 API uint8_t output[32]; OQS_SHA2_sha256(output, msg, msg_len); + // run incremental SHA-256 API uint8_t output_inc[32]; + uint8_t output_inc_2[32]; OQS_SHA2_sha256_ctx state; OQS_SHA2_sha256_inc_init(&state); + // clone state - OQS_SHA2_sha256_ctx state2; + OQS_SHA2_sha256_ctx state2, state3, state4, state5; OQS_SHA2_sha256_inc_ctx_clone(&state2, &state); + OQS_SHA2_sha256_inc_ctx_clone(&state3, &state); + OQS_SHA2_sha256_inc_ctx_clone(&state4, &state); + OQS_SHA2_sha256_inc_ctx_clone(&state5, &state); + // hash with first state if (msg_len > 64) { OQS_SHA2_sha256_inc_blocks(&state, msg, 1); @@ -67,6 +75,7 @@ static int do_sha256(void) { } else { OQS_SHA2_sha256_inc_finalize(output_inc, &state, msg, msg_len); } + if (memcmp(output, output_inc, 32) != 0) { fprintf(stderr, "ERROR: Incremental API does not match main API\n"); free(msg); @@ -84,6 +93,49 @@ static int do_sha256(void) { free(msg); return -3; } + + // hash with increment API less than block size + size_t i = 0; + for (i = 0; i < msg_len; i++) { + OQS_SHA2_sha256_inc(&state3, &msg[i], 1); + } + OQS_SHA2_sha256_inc_finalize(output_inc_2, &state3, &msg[i], 0); + if (memcmp(output, output_inc_2, 32) != 0) { + fprintf(stderr, "ERROR: Non-block Incremental API with cloned state does not match main API\n"); + free(msg); + return -4; + } + + // hash with combination of block-size increments and non block-size increments [64 bytes] + [n < 64 bytes] + if (msg_len > 64) { + OQS_SHA2_sha256_inc_blocks(&state4, msg, 1); + for (i = 0; i < (msg_len - 64); i++) { + OQS_SHA2_sha256_inc(&state4, &msg[64 + i], 1); + } + OQS_SHA2_sha256_inc_finalize(output_inc_2, &state4, &msg[msg_len - 1], 0); + } else { + OQS_SHA2_sha256_inc_finalize(output_inc_2, &state4, msg, msg_len); + } + if (memcmp(output, output_inc_2, 32) != 0) { + fprintf(stderr, "ERROR: Combined block increments with non-block size failed to match main API\n"); + free(msg); + return -5; + } + + // hash with combination of non block-size and block-size [n < 64 bytes] + [64 bytes] + if (msg_len > 64) { + OQS_SHA2_sha256_inc(&state5, msg, 1); + OQS_SHA2_sha256_inc_blocks(&state5, &msg[1], 1); + OQS_SHA2_sha256_inc_finalize(output_inc_2, &state5, &msg[65], msg_len - 65); + } else { + OQS_SHA2_sha256_inc_finalize(output_inc_2, &state5, msg, msg_len); + } + if (memcmp(output, output_inc_2, 32) != 0) { + fprintf(stderr, "ERROR: Combined non-block size and block increments failed to match main API\n"); + free(msg); + return -5; + } + //Test inc API print_hex(output, 32); free(msg); return 0; From 2dd9e07e07802c9afaf4cd3461d9473bccf44844 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Wed, 13 Dec 2023 18:48:20 -0500 Subject: [PATCH 22/68] Na lms kat multi level (#1620) * 2-level LMS Support * Add LMS KAT from RFC 8554 * Fix format * Add multi level LMS variants supported by other libraried * Added 2-Level LMS Variants. Updated test vector format per code review comments. Updated tests accordingly. * Removed unused variable * Update per comments * Added stateful example application and review comments * Fixed use of uninit var * Update some comments * rename LMS KAT files * rename LMS KAT files * Added LMS KAT * rename KAT file * add individual options * add missing N32 in algorithm name * Use strip to remove new line, instead of [1:-2]. Add algo_dir = lms * Rename KATs.json for LMS * Shorten LMS names * Supported KAT files for LMS * Remove unsupported KAT files * Fix format * Fix mem leak * Add testcase for hash corner. Fix hash increment problem. * Fix formatting --------- Co-authored-by: Duc Nguyen --- .CMake/alg_support.cmake | 2 + README.md | 4 + src/common/sha2/sha2_armv8.c | 38 +- src/common/sha2/sha2_c.c | 10 +- src/oqsconfig.h.cmake | 2 + src/sig_stfl/lms/sig_stfl_lms.c | 1235 ++++++++++++++++- src/sig_stfl/lms/sig_stfl_lms.h | 181 ++- src/sig_stfl/lms/sig_stfl_lms_functions.c | 136 +- src/sig_stfl/sig_stfl.c | 270 ++-- src/sig_stfl/sig_stfl.h | 144 +- tests/CMakeLists.txt | 4 + tests/KATs/sig_stfl/kats.json | 4 +- .../sig_stfl/lms/LMS_SHA256_H10_W4_H5_W8.rsp | 8 + .../sig_stfl/lms/LMS_SHA256_H5_W8_H5_W8.rsp | 8 + tests/example_sig_stfl.c | 133 ++ tests/helpers.py | 14 +- tests/kat_sig_stfl.c | 143 +- tests/test_hash.c | 14 +- tests/test_sig_stfl.c | 1 + 19 files changed, 2085 insertions(+), 266 deletions(-) create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4_H5_W8.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8_H5_W8.rsp create mode 100644 tests/example_sig_stfl.c diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index da79308dfd..27ce29c1da 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -529,6 +529,8 @@ cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 "" ON "OQS_ENA option(OQS_ENABLE_SIG_STFL_LMS "Enable LMS algorithm family" ON) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) if((OQS_MINIMAL_BUILD STREQUAL "ON")) message(FATAL_ERROR "OQS_MINIMAL_BUILD option ${OQS_MINIMAL_BUILD} no longer supported") diff --git a/README.md b/README.md index 53ef332e24..f91e39dea0 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,8 @@ All names other than `ML-KEM` and `ML-DSA` are subject to change. `liboqs` makes - **ML-DSA**: ML-DSA-44-ipd (alias: ML-DSA-44), ML-DSA-65-ipd (alias: ML-DSA-65), ML-DSA-87-ipd (alias: ML-DSA-87) - **SPHINCS+-SHA2**: SPHINCS+-SHA2-128f-simple, SPHINCS+-SHA2-128s-simple, SPHINCS+-SHA2-192f-simple, SPHINCS+-SHA2-192s-simple, SPHINCS+-SHA2-256f-simple, SPHINCS+-SHA2-256s-simple - **SPHINCS+-SHAKE**: SPHINCS+-SHAKE-128f-simple, SPHINCS+-SHAKE-128s-simple, SPHINCS+-SHAKE-192f-simple, SPHINCS+-SHAKE-192s-simple, SPHINCS+-SHAKE-256f-simple, SPHINCS+-SHAKE-256s-simple +- **XMSS**: XMSS-SHA2_10_256, XMSS-SHA2_16_256, XMSS-SHA2_20_256, XMSS-SHAKE_10_256, XMSS-SHAKE_16_256, XMSS-SHAKE_20_256, XMSS-SHA2_10_512, XMSS-SHA2_16_512, XMSS-SHA2_20_512, XMSS-SHAKE_10_512, XMSS-SHAKE_16_512, XMSS-SHAKE_20_512, XMSSMT-SHA2_20/2_256, XMSSMT-SHA2_20/4_256, XMSSMT-SHA2_40/2_256, XMSSMT-SHA2_40/4_256, XMSSMT-SHA2_40/8_256, XMSSMT-SHA2_60/3_256, XMSSMT-SHA2_60/6_256, XMSSMT-SHA2_60/12_256, XMSSMT-SHAKE_20/2_256, XMSSMT-SHAKE_20/4_256, XMSSMT-SHAKE_40/2_256, XMSSMT-SHAKE_40/4_256, XMSSMT-SHAKE_40/8_256, XMSSMT-SHAKE_60/3_256, XMSSMT-SHAKE_60/6_256, XMSSMT-SHAKE_60/12_256 +- **LMS**: LMS_SHA256_H5_W1, LMS_SHA256_H5_W2, LMS_SHA256_H5_W4, LMS_SHA256_H5_W8, LMS_SHA256_H10_W1, LMS_SHA256_H10_W2, LMS_SHA256_H10_W4, LMS_SHA256_H10_W8, LMS_SHA256_H15_W1, LMS_SHA256_H15_W2, LMS_SHA256_H15_W4, LMS_SHA256_H15_W8, LMS_SHA256_H20_W1, LMS_SHA256_H20_W2, LMS_SHA256_H20_W4, LMS_SHA256_H20_W8, LMS_SHA256_H25_W1, LMS_SHA256_H25_W2, LMS_SHA256_H25_W4, LMS_SHA256_H25_W8, LMS_SHA256_H5_W8_H5_W8, LMS_SHA256_H10_W4_H5_W8, LMS_SHA256_H10_W8_H5_W8, LMS_SHA256_H10_W2_H10_W2, LMS_SHA256_H10_W4_H10_W4, LMS_SHA256_H10_W8_H10_W8, LMS_SHA256_H15_W8_H5_W8, LMS_SHA256_H15_W8_H10_W8, LMS_SHA256_H15_W8_H15_W8, LMS_SHA256_H20_W8_H5_W8, LMS_SHA256_H20_W8_H10_W8, LMS_SHA256_H20_W8_H15_W8, LMS_SHA256_H20_W8_H20_W8 Note that for algorithms marked with a dagger (†), liboqs contains at least one implementation that uses a large amount of stack space; this may cause failures when run in threads or in constrained environments. For more information, consult the algorithm information sheets in the [docs/algorithms](https://github.com/open-quantum-safe/liboqs/tree/main/docs/algorithms) folder. @@ -124,10 +126,12 @@ The following instructions assume we are in `build`. - `test_kem`: Simple test harness for key encapsulation mechanisms - `test_sig`: Simple test harness for key signature schemes + - `test_sig_stfl`: Simple test harness for stateful key signature schemes - `test_kem_mem`: Simple test harness for checking memory consumption of key encapsulation mechanisms - `test_sig_mem`: Simple test harness for checking memory consumption of key signature schemes - `kat_kem`: Program that generates known answer test (KAT) values for key encapsulation mechanisms using the same procedure as the NIST submission requirements, for checking against submitted KAT values using `tests/test_kat.py` - `kat_sig`: Program that generates known answer test (KAT) values for signature schemes using the same procedure as the NIST submission requirements, for checking against submitted KAT values using `tests/test_kat.py` + - `kat_stfl_sig`: Program for checking results against submitted KAT values using `tests/test_kat.py` - `speed_kem`: Benchmarking program for key encapsulation mechanisms; see `./speed_kem --help` for usage instructions - `speed_sig`: Benchmarking program for signature mechanisms; see `./speed_sig --help` for usage instructions - `example_kem`: Minimal runnable example showing the usage of the KEM API diff --git a/src/common/sha2/sha2_armv8.c b/src/common/sha2/sha2_armv8.c index f3bbf573a1..71d2cebb59 100644 --- a/src/common/sha2/sha2_armv8.c +++ b/src/common/sha2/sha2_armv8.c @@ -187,8 +187,11 @@ void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const ui } memcpy(tmp_in, state->data, state->data_len); - memcpy(tmp_in + state->data_len, in, inlen); + if (in && inlen) { + memcpy(tmp_in + state->data_len, in, inlen); + } new_in = tmp_in; + state->data_len = 0; } uint64_t bytes = load_bigendian_64(state->ctx + 32) + new_inlen; @@ -280,33 +283,34 @@ void oqs_sha2_sha256_inc_blocks_armv8(sha256ctx *state, const uint8_t *in, size_ void oqs_sha2_sha256_inc_armv8(sha256ctx *state, const uint8_t *in, size_t len) { uint64_t bytes = 0; + size_t in_index = 0; while (len) { size_t incr = 64 - state->data_len; if (incr > len) { incr = len; } - for (size_t i = 0; i < incr; ++i, state->data_len++) { - state->data[state->data_len] = in[i]; + for (size_t i = 0; i < incr; ++i, state->data_len++, in_index++)) { + state->data[state->data_len] = in[in_index++)]; } if (state->data_len < 64) { - break; - } + break; + } - /* - * Process a complete block now - */ - bytes = load_bigendian_64(state->ctx + 32) + 64; - crypto_hashblocks_sha256_armv8(state->ctx, state->data, 64); - store_bigendian_64(state->ctx + 32, bytes); + /* + * Process a complete block now + */ + bytes = load_bigendian_64(state->ctx + 32) + 64; + crypto_hashblocks_sha256_armv8(state->ctx, state->data, 64); + store_bigendian_64(state->ctx + 32, bytes); - /* - * update the remaining input - */ - len -= incr; - state->data_len = 0; - } + /* + * update the remaining input + */ + len -= incr; + state->data_len = 0; +} } void oqs_sha2_sha224_inc_blocks_armv8(sha224ctx *state, const uint8_t *in, size_t inblocks) { diff --git a/src/common/sha2/sha2_c.c b/src/common/sha2/sha2_c.c index 33863f8040..b0f628136a 100644 --- a/src/common/sha2/sha2_c.c +++ b/src/common/sha2/sha2_c.c @@ -654,14 +654,15 @@ void oqs_sha2_sha256_inc_blocks_c(sha256ctx *state, const uint8_t *in, size_t in void oqs_sha2_sha256_inc_c(sha256ctx *state, const uint8_t *in, size_t len) { uint64_t bytes = 0; + size_t in_index = 0; while (len) { size_t incr = 64 - state->data_len; if (incr > len) { incr = len; } - for (size_t i = 0; i < incr; ++i, state->data_len++) { - state->data[state->data_len] = in[i]; + for (size_t i = 0; i < incr; ++i, state->data_len++, in_index++) { + state->data[state->data_len] = in[in_index]; } if (state->data_len < 64) { @@ -718,8 +719,11 @@ void oqs_sha2_sha256_inc_finalize_c(uint8_t *out, sha256ctx *state, const uint8_ } memcpy(tmp_in, state->data, state->data_len); - memcpy(tmp_in + state->data_len, in, inlen); + if (in && inlen) { + memcpy(tmp_in + state->data_len, in, inlen); + } new_in = tmp_in; + state->data_len = 0; } uint64_t bytes = load_bigendian_64(state->ctx + 32) + new_inlen; diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index 9626119e71..c2de65c545 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -222,3 +222,5 @@ #cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 1 #cmakedefine OQS_ENABLE_SIG_STFL_LMS 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 1 diff --git a/src/sig_stfl/lms/sig_stfl_lms.c b/src/sig_stfl/lms/sig_stfl_lms.c index b6d57902ee..9e65a5e442 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.c +++ b/src/sig_stfl/lms/sig_stfl_lms.c @@ -22,7 +22,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h5_w1) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h5_w1) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -36,8 +36,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h5_w1; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1; + sig->oid = OQS_LMS_ID_sha256_h5_w1; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h5_w1; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -109,7 +109,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w2_keypair(uint8_t *public_key return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h5_w2) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h5_w2) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -123,8 +123,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w2_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h5_w2; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2; + sig->oid = OQS_LMS_ID_sha256_h5_w2; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h5_w2; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -196,7 +196,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w4_keypair(uint8_t *public_key return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h5_w4) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h5_w4) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -210,8 +210,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w4_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h5_w4; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4; + sig->oid = OQS_LMS_ID_sha256_h5_w4; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h5_w4; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -283,7 +283,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_keypair(uint8_t *public_key return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h5_w8) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h5_w8) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -297,8 +297,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w8_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h5_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8; + sig->oid = OQS_LMS_ID_sha256_h5_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h5_w8; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -370,7 +370,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w1_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h10_w1) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w1) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -384,8 +384,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w1_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h10_w1; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1; + sig->oid = OQS_LMS_ID_sha256_h10_w1; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w1; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -457,7 +457,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w2_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h10_w2) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w2) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -471,8 +471,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w2_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h10_w2; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h10_w2; + sig->oid = OQS_LMS_ID_sha256_h10_w2; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w2; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -544,7 +544,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h10_w4) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w4) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -558,8 +558,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h10_w4; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h10_w4; + sig->oid = OQS_LMS_ID_sha256_h10_w4; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w4; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -631,7 +631,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h10_w8) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w8) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -645,8 +645,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h10_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h10_w8; + sig->oid = OQS_LMS_ID_sha256_h10_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w8; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -718,7 +718,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w1_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h15_w1) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w1) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -732,8 +732,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w1_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h15_w1; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1; + sig->oid = OQS_LMS_ID_sha256_h15_w1; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w1; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -805,7 +805,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w2_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h15_w2) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w2) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -819,8 +819,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w2_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h15_w2; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h15_w2; + sig->oid = OQS_LMS_ID_sha256_h15_w2; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w2; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -892,7 +892,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w4_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h15_w4) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w4) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -906,8 +906,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w4_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h15_w4; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h15_w4; + sig->oid = OQS_LMS_ID_sha256_h15_w4; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w4; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -979,7 +979,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h15_w8) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w8) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -993,8 +993,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h15_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h15_w8; + sig->oid = OQS_LMS_ID_sha256_h15_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w8; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -1066,7 +1066,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w1_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h20_w1) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w1) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -1080,8 +1080,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w1_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h20_w1; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h20_w1; + sig->oid = OQS_LMS_ID_sha256_h20_w1; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w1; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -1153,7 +1153,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w2_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h20_w2) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w2) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -1167,8 +1167,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w2_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h20_w2; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h20_w2; + sig->oid = OQS_LMS_ID_sha256_h20_w2; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w2; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -1240,7 +1240,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w4_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h20_w4) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w4) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -1254,8 +1254,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w4_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h20_w4; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h20_w4; + sig->oid = OQS_LMS_ID_sha256_h20_w4; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w4; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -1327,7 +1327,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h20_w8) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w8) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -1341,8 +1341,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h20_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h20_w8; + sig->oid = OQS_LMS_ID_sha256_h20_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w8; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -1414,7 +1414,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w1_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h25_w1) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h25_w1) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -1428,8 +1428,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w1_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h25_w1; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h25_w1; + sig->oid = OQS_LMS_ID_sha256_h25_w1; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h25_w1; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -1501,7 +1501,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w2_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h25_w2) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h25_w2) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -1515,8 +1515,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w2_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h25_w2; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h25_w2; + sig->oid = OQS_LMS_ID_sha256_h25_w2; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h25_w2; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -1588,7 +1588,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w4_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h25_w4) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h25_w4) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -1602,8 +1602,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w4_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h25_w4; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h25_w4; + sig->oid = OQS_LMS_ID_sha256_h25_w4; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h25_w4; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -1675,7 +1675,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w8_keypair(uint8_t *public_ke return OQS_ERROR; } - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_n32_h25_w8) != 0) { + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h25_w8) != 0) { return OQS_ERROR; } return OQS_SUCCESS; @@ -1689,8 +1689,8 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w8_new(void) { } memset(sig, 0, sizeof(OQS_SIG_STFL)); - sig->oid = OQS_LMS_ID_sha256_n32_h25_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_n32_h25_w8; + sig->oid = OQS_LMS_ID_sha256_h25_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h25_w8; sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; sig->euf_cma = true; @@ -1755,6 +1755,1121 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W8_new(void) { return sk; } +// +//2-Level LMS +// ======================== LMS-SHA256 H5/W8, H5/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h5_w8_h5_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_h5_w8_h5_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W8_H5_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H10/W2, H10/W2 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w2_h10_w2) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_h10_w2_h10_w2; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W2_H10_W2_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H10/W4, H5/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w4_h5_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_h10_w4_h5_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_H5_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H10/W4, H10/W4 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w4_h10_w4) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_h10_w4_h10_w4; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_H10_W4_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H10/W8, H5/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w8_h5_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_h10_w8_h5_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_H5_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H10/W8, H10/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w8_h10_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_h15_w4; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_H10_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H15/W8, H5/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w8_h5_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_h15_w8_h5_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H5_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H15/W8, H10/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w8_h10_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_h15_w8_h10_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H10_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H15/W8, H15/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w8_h15_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_h15_w8_h15_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H15_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H20/W8, H5/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w8_h5_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_h20_w8_h5_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H5_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H20/W8, H10/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w8_h10_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_h20_w8_h10_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H10_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H20/W8, H15/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w8_h15_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_h20_w8_h15_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H15_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} + +// ======================== LMS-SHA256 H20/W8, H20/W8 ======================== // + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { + if (secret_key == NULL || public_key == NULL) { + return OQS_ERROR; + } + + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w8_h20_w8) != 0) { + return OQS_ERROR; + } + return OQS_SUCCESS; +} + +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_new(void) { + + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); + if (sig == NULL) { + return NULL; + } + memset(sig, 0, sizeof(OQS_SIG_STFL)); + + sig->oid = OQS_LMS_ID_sha256_h20_w8_h20_w8; + sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8; + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; + sig->euf_cma = true; + + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; + sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_length_signature; + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_keypair; + sig->sign = OQS_SIG_STFL_alg_lms_sign; + sig->verify = OQS_SIG_STFL_alg_lms_verify; + + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; + + return sig; +} + +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H20_W8_new(void) { + + // Initialize the secret key in the heap with adequate memory + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); + if (sk == NULL) { + return NULL; + } + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); + + // Initialize the key with length_secret_key amount of bytes. + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + + /* + * Set Secret Key Saving Function + */ + sk->secure_store_scrt_key = NULL; + + /* + * Set Secret Key free function + */ + sk->free_key = OQS_SECRET_KEY_LMS_free; + + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; + + return sk; +} +//2-Level LMS + + void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk) { oqs_secret_lms_key_free(sk); } diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h index b75446d2e3..8380656eb0 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.h +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -7,30 +7,88 @@ //OQS LMS parameter identifiers /* Defined LM parameter sets */ -#define OQS_LMS_ID_sha256_n32_h5_w1 0x1 //"5/1" -#define OQS_LMS_ID_sha256_n32_h5_w2 0x2 //"5/2" -#define OQS_LMS_ID_sha256_n32_h5_w4 0x3 //"5/4" -#define OQS_LMS_ID_sha256_n32_h5_w8 0x4 //"5/8" - -#define OQS_LMS_ID_sha256_n32_h10_w1 0x5 //"10/1" -#define OQS_LMS_ID_sha256_n32_h10_w2 0x7 //"10/2" -#define OQS_LMS_ID_sha256_n32_h10_w4 0x8 //"10/4" -#define OQS_LMS_ID_sha256_n32_h10_w8 0x9 //"10/8" - -#define OQS_LMS_ID_sha256_n32_h15_w1 0xa //"15/1" -#define OQS_LMS_ID_sha256_n32_h15_w2 0xb //"15/2" -#define OQS_LMS_ID_sha256_n32_h15_w4 0xc//"15/4" -#define OQS_LMS_ID_sha256_n32_h15_w8 0xd //"15/8" - -#define OQS_LMS_ID_sha256_n32_h20_w1 0xe //"20/1" -#define OQS_LMS_ID_sha256_n32_h20_w2 0xf //"20/2" -#define OQS_LMS_ID_sha256_n32_h20_w4 0x10 //"20/4" -#define OQS_LMS_ID_sha256_n32_h20_w8 0x11 //"20/8" - -#define OQS_LMS_ID_sha256_n32_h25_w1 0x12 //"25/1" -#define OQS_LMS_ID_sha256_n32_h25_w2 0x13 //"25/2" -#define OQS_LMS_ID_sha256_n32_h25_w4 0x14 //"25/4" -#define OQS_LMS_ID_sha256_n32_h25_w8 0x15 //"25/8" +/* + * Convention + * Where ... + * L = number of Levels + * H = LMS H ID + * LMS_SHA256_M32_H5 0x05 + * LMS_SHA256_M32_H10 0x06 + * LMS_SHA256_M32_H15 0x07 + * LMS_SHA256_M32_H20 0x08 + * LMS_SHA256_M32_H25 0x09 + * + * W = Winternitz value + * LMOTS_SHA256_N32_W1 0x01 + * LMOTS_SHA256_N32_W2 0x02 + * LMOTS_SHA256_N32_W4 0x03 + * LMOTS_SHA256_N32_W8 0x04 + * + * e.g. + * OQS_LMS_ID_sha256_h5_w1 -- "5/1" ----- 0x0151 + * "5/1,5/2" ----- 0x025152 + * Number of levels L {1, 2, 3, ..., 8} + * 0x0LH(l1))W(l1)H(l2)W(l2) + * e.g + * For OQS_LMS_ID_sha256_h5_w1 the oid is 0x0151 + * Number of levels is.....0x01 + * H5 ID is.........5 + * W1 ID is..........1 + * +* For OQS_LMS_ID_sha256_h10_w4_h5_w8 the is 0x026354 + * Number of levels is.......0x02 + * Level 1 H10 ID is...........6 + * Level 1 W4 ID is............3 + * Level 2 H5 ID is.............5 + * Level 2 W8 ID is..............4 + */ +#define OQS_LMS_ID_sha256_h5_w1 0x0151 //"5/1" +#define OQS_LMS_ID_sha256_h5_w2 0x0152 //"5/2" +#define OQS_LMS_ID_sha256_h5_w4 0x0153 //"5/4" +#define OQS_LMS_ID_sha256_h5_w8 0x0154 //"5/8" + +#define OQS_LMS_ID_sha256_h10_w1 0x0161 //"10/1" +#define OQS_LMS_ID_sha256_h10_w2 0x0162 //"10/2" +#define OQS_LMS_ID_sha256_h10_w4 0x0163 //"10/4" +#define OQS_LMS_ID_sha256_h10_w8 0x0164 //"10/8" + +#define OQS_LMS_ID_sha256_h15_w1 0x0171 //"15/1" +#define OQS_LMS_ID_sha256_h15_w2 0x0172 //"15/2" +#define OQS_LMS_ID_sha256_h15_w4 0x0173 //"15/4" +#define OQS_LMS_ID_sha256_h15_w8 0x0174 //"15/8" + +#define OQS_LMS_ID_sha256_h20_w1 0x0181 //"20/1" +#define OQS_LMS_ID_sha256_h20_w2 0x0182 //"20/2" +#define OQS_LMS_ID_sha256_h20_w4 0x0183 //"20/4" +#define OQS_LMS_ID_sha256_h20_w8 0x0184 //"20/8" + +#define OQS_LMS_ID_sha256_h25_w1 0x0191 //"25/1" +#define OQS_LMS_ID_sha256_h25_w2 0x0192 //"25/2" +#define OQS_LMS_ID_sha256_h25_w4 0x0193 //"25/4" +#define OQS_LMS_ID_sha256_h25_w8 0x0194 //"25/8" + +//2-Level LMS + +//RFC 8554 example +#define OQS_LMS_ID_sha256_h5_w8_h5_w8 0x025454 //"5/8,5/8" + +//RFC 8554 example +#define OQS_LMS_ID_sha256_h10_w4_h5_w8 0x026354 //"10/4,5/8" + +//Wolf +#define OQS_LMS_ID_sha256_h10_w2_h10_w2 0x026262 //"10/2,10/2" +#define OQS_LMS_ID_sha256_h10_w4_h10_w4 0x026363 //"10/4,10/4" + +#define OQS_LMS_ID_sha256_h10_w8_h5_w8 0x026454 //"10/8,5/8" +//Wolf +#define OQS_LMS_ID_sha256_h10_w8_h10_w8 0x026464 //"10/8,10/8" +#define OQS_LMS_ID_sha256_h15_w8_h5_w8 0x027454 //"15/8,5/8" +#define OQS_LMS_ID_sha256_h15_w8_h10_w8 0x027464 //"15/8,10/8" +#define OQS_LMS_ID_sha256_h15_w8_h15_w8 0x027474 //"15/8,15/8" +#define OQS_LMS_ID_sha256_h20_w8_h5_w8 0x028454 //"20/8,5/8" +#define OQS_LMS_ID_sha256_h20_w8_h10_w8 0x028464 //"20/8,10/8" +#define OQS_LMS_ID_sha256_h20_w8_h15_w8 0x028474 //"20/8,15/8" +#define OQS_LMS_ID_sha256_h20_w8_h20_w8 0x028484 //"20/8,20/8" //H5 #define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_signature 8688 @@ -198,6 +256,81 @@ OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *totaln, const void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk); + +//2-Level LMS +#define OQS_SIG_STFL_alg_lms_length_private_key 64 +#define OQS_SIG_STFL_alg_lms_length_public_key 60 +#define OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_length_signature 2644 + +#define OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_length_signature 2804 + +#define OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_length_signature 3860 + +#define OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_length_signature 9300 +#define OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_length_signature 5076 +#define OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_length_signature 2964 + +#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_length_signature 2964 +#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_length_signature 3124 +#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_length_signature 3284 + +#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_length_signature 3124 +#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_length_signature 3284 +#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_length_signature 3444 +#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_length_signature 3604 + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W8_H5_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_new(void); + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_H5_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_new(void); + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_H5_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_new(void); + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W2_H10_W2_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_new(void); + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_H10_W4_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_new(void); + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_H10_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_new(void); + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H5_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_new(void); + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H10_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_new(void); + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H15_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_new(void); + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H5_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_new(void); + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H10_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_new(void); + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H15_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_new(void); + +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H20_W8_new(void); +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_new(void); + // ----------------------------------- WRAPPER FUNCTIONS ------------------------------------------------ int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uint32_t oid); diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index 1e3154b009..b05910d089 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -205,7 +205,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *total, const } *total = (unsigned long long)working_key->max_count; - OQS_MEM_secure_free(working_key, sizeof(struct hss_working_key)); + hss_free_working_key(working_key); return OQS_SUCCESS; } @@ -276,91 +276,182 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uin /* Set lms param set */ switch (oid) { - case OQS_LMS_ID_sha256_n32_h5_w1: + case OQS_LMS_ID_sha256_h5_w1: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H5; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W1; break; - case OQS_LMS_ID_sha256_n32_h5_w2: + case OQS_LMS_ID_sha256_h5_w2: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H5; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W2; break; - case OQS_LMS_ID_sha256_n32_h5_w4: + case OQS_LMS_ID_sha256_h5_w4: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H5; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W4; break; - case OQS_LMS_ID_sha256_n32_h5_w8: + case OQS_LMS_ID_sha256_h5_w8: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H5; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; break; - case OQS_LMS_ID_sha256_n32_h10_w1: + case OQS_LMS_ID_sha256_h10_w1: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H10; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W1; break; - case OQS_LMS_ID_sha256_n32_h10_w2: + case OQS_LMS_ID_sha256_h10_w2: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H10; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W2; break; - case OQS_LMS_ID_sha256_n32_h10_w4: + case OQS_LMS_ID_sha256_h10_w4: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H10; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W4; break; - case OQS_LMS_ID_sha256_n32_h10_w8: + case OQS_LMS_ID_sha256_h10_w8: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H10; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; break; - case OQS_LMS_ID_sha256_n32_h15_w1: + case OQS_LMS_ID_sha256_h15_w1: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H15; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W1; break; - case OQS_LMS_ID_sha256_n32_h15_w2: + case OQS_LMS_ID_sha256_h15_w2: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H15; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W2; break; - case OQS_LMS_ID_sha256_n32_h15_w4: + case OQS_LMS_ID_sha256_h15_w4: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H15; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W4; break; - case OQS_LMS_ID_sha256_n32_h15_w8: + case OQS_LMS_ID_sha256_h15_w8: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H15; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; break; - case OQS_LMS_ID_sha256_n32_h20_w1: + case OQS_LMS_ID_sha256_h20_w1: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H20; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W1; break; - case OQS_LMS_ID_sha256_n32_h20_w2: + case OQS_LMS_ID_sha256_h20_w2: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H20; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W2; break; - case OQS_LMS_ID_sha256_n32_h20_w4: + case OQS_LMS_ID_sha256_h20_w4: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H20; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W4; break; - case OQS_LMS_ID_sha256_n32_h20_w8: + case OQS_LMS_ID_sha256_h20_w8: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H20; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; break; - case OQS_LMS_ID_sha256_n32_h25_w1: + case OQS_LMS_ID_sha256_h25_w1: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H25; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W1; break; - case OQS_LMS_ID_sha256_n32_h25_w2: + case OQS_LMS_ID_sha256_h25_w2: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H25; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W2; break; - case OQS_LMS_ID_sha256_n32_h25_w4: + case OQS_LMS_ID_sha256_h25_w4: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H25; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W4; break; - case OQS_LMS_ID_sha256_n32_h25_w8: + case OQS_LMS_ID_sha256_h25_w8: oqs_key_data->lm_type[0] = LMS_SHA256_N32_H25; oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; break; - + case OQS_LMS_ID_sha256_h5_w8_h5_w8: + oqs_key_data->levels = 2; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H5; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + oqs_key_data->lm_type[1] = LMS_SHA256_N32_H5; + oqs_key_data->lm_ots_type[1] = LMOTS_SHA256_N32_W8; + break; + case OQS_LMS_ID_sha256_h10_w8_h5_w8: + oqs_key_data->levels = 2; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + oqs_key_data->lm_type[1] = LMS_SHA256_N32_H5; + oqs_key_data->lm_ots_type[1] = LMOTS_SHA256_N32_W8; + break; + case OQS_LMS_ID_sha256_h10_w2_h10_w2: + oqs_key_data->levels = 2; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W2; + oqs_key_data->lm_type[1] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[1] = LMOTS_SHA256_N32_W2; + break; + case OQS_LMS_ID_sha256_h10_w4_h5_w8: + oqs_key_data->levels = 2; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W4; + oqs_key_data->lm_type[1] = LMS_SHA256_N32_H5; + oqs_key_data->lm_ots_type[1] = LMOTS_SHA256_N32_W8; + break; + case OQS_LMS_ID_sha256_h10_w4_h10_w4: + oqs_key_data->levels = 2; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W4; + oqs_key_data->lm_type[1] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[1] = LMOTS_SHA256_N32_W4; + break; + case OQS_LMS_ID_sha256_h10_w8_h10_w8: + oqs_key_data->levels = 2; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + oqs_key_data->lm_type[1] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[1] = LMOTS_SHA256_N32_W8; + break; + case OQS_LMS_ID_sha256_h15_w8_h5_w8: + oqs_key_data->levels = 2; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H15; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + oqs_key_data->lm_type[1] = LMS_SHA256_N32_H5; + oqs_key_data->lm_ots_type[1] = LMOTS_SHA256_N32_W8; + break; + case OQS_LMS_ID_sha256_h15_w8_h10_w8: + oqs_key_data->levels = 2; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H15; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + oqs_key_data->lm_type[1] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[1] = LMOTS_SHA256_N32_W8; + break; + case OQS_LMS_ID_sha256_h15_w8_h15_w8: + oqs_key_data->levels = 2; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H15; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + oqs_key_data->lm_type[1] = LMS_SHA256_N32_H15; + oqs_key_data->lm_ots_type[1] = LMOTS_SHA256_N32_W8; + break; + case OQS_LMS_ID_sha256_h20_w8_h5_w8: + oqs_key_data->levels = 2; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H20; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + oqs_key_data->lm_type[1] = LMS_SHA256_N32_H5; + oqs_key_data->lm_ots_type[1] = LMOTS_SHA256_N32_W8; + break; + case OQS_LMS_ID_sha256_h20_w8_h10_w8: + oqs_key_data->levels = 2; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H20; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + oqs_key_data->lm_type[1] = LMS_SHA256_N32_H10; + oqs_key_data->lm_ots_type[1] = LMOTS_SHA256_N32_W8; + break; + case OQS_LMS_ID_sha256_h20_w8_h15_w8: + oqs_key_data->levels = 2; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H20; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + oqs_key_data->lm_type[1] = LMS_SHA256_N32_H15; + oqs_key_data->lm_ots_type[1] = LMOTS_SHA256_N32_W8; + break; + case OQS_LMS_ID_sha256_h20_w8_h20_w8: + oqs_key_data->levels = 2; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H20; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W8; + oqs_key_data->lm_type[1] = LMS_SHA256_N32_H20; + oqs_key_data->lm_ots_type[1] = LMOTS_SHA256_N32_W8; + break; + default: oqs_key_data->lm_type[0] = 0; oqs_key_data->lm_ots_type[0] = 0; parse_err = 1; @@ -503,6 +594,7 @@ int oqs_sig_stfl_lms_sign(OQS_SIG_STFL_SECRET_KEY *sk, *smlen = sig_len; memcpy(sm, sig, sig_len); OQS_MEM_insecure_free(sig); + hss_free_working_key(w); return 0; } diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 9bdee77780..dafbcd8aa5 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -44,30 +44,48 @@ OQS_API const char *OQS_SIG_STFL_alg_identifier(size_t i) { OQS_SIG_STFL_alg_xmssmt_shake128_h60_6, OQS_SIG_STFL_alg_xmssmt_shake128_h60_12, // LMS - OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1, - OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2, - OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4, - OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8, - - OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1, - OQS_SIG_STFL_alg_lms_sha256_n32_h10_w2, - OQS_SIG_STFL_alg_lms_sha256_n32_h10_w4, - OQS_SIG_STFL_alg_lms_sha256_n32_h10_w8, - - OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1, - OQS_SIG_STFL_alg_lms_sha256_n32_h15_w2, - OQS_SIG_STFL_alg_lms_sha256_n32_h15_w4, - OQS_SIG_STFL_alg_lms_sha256_n32_h15_w8, - - OQS_SIG_STFL_alg_lms_sha256_n32_h20_w1, - OQS_SIG_STFL_alg_lms_sha256_n32_h20_w2, - OQS_SIG_STFL_alg_lms_sha256_n32_h20_w4, - OQS_SIG_STFL_alg_lms_sha256_n32_h20_w8, - - OQS_SIG_STFL_alg_lms_sha256_n32_h25_w1, - OQS_SIG_STFL_alg_lms_sha256_n32_h25_w2, - OQS_SIG_STFL_alg_lms_sha256_n32_h25_w4, - OQS_SIG_STFL_alg_lms_sha256_n32_h25_w8, + OQS_SIG_STFL_alg_lms_sha256_h5_w1, + OQS_SIG_STFL_alg_lms_sha256_h5_w2, + OQS_SIG_STFL_alg_lms_sha256_h5_w4, + OQS_SIG_STFL_alg_lms_sha256_h5_w8, + + OQS_SIG_STFL_alg_lms_sha256_h10_w1, + OQS_SIG_STFL_alg_lms_sha256_h10_w2, + OQS_SIG_STFL_alg_lms_sha256_h10_w4, + OQS_SIG_STFL_alg_lms_sha256_h10_w8, + + OQS_SIG_STFL_alg_lms_sha256_h15_w1, + OQS_SIG_STFL_alg_lms_sha256_h15_w2, + OQS_SIG_STFL_alg_lms_sha256_h15_w4, + OQS_SIG_STFL_alg_lms_sha256_h15_w8, + + OQS_SIG_STFL_alg_lms_sha256_h20_w1, + OQS_SIG_STFL_alg_lms_sha256_h20_w2, + OQS_SIG_STFL_alg_lms_sha256_h20_w4, + OQS_SIG_STFL_alg_lms_sha256_h20_w8, + + OQS_SIG_STFL_alg_lms_sha256_h25_w1, + OQS_SIG_STFL_alg_lms_sha256_h25_w2, + OQS_SIG_STFL_alg_lms_sha256_h25_w4, + OQS_SIG_STFL_alg_lms_sha256_h25_w8, + + //2-Level LMS + OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8, + OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8, + + OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8, + OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2, + OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4, + OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8, + + OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8, + OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8, + OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8, + + OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8, + OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8, + OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8, + OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8, }; if (i >= OQS_SIG_STFL_algs_length) { @@ -256,51 +274,79 @@ OQS_API int OQS_SIG_STFL_alg_is_enabled(const char *method_name) { #endif } #ifdef OQS_ENABLE_SIG_STFL_LMS - else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1)) { + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w1)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w2)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w4)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w8)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w1)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w2)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8)) { return 1; } - else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1)) { + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w1)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w2)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w4)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8)) { return 1; } - else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w1)) { + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w1)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w2)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w4)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8)) { return 1; } - else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w1)) { + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w1)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w2)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w4)) { return 1; - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w8)) { + return 1; + } + //2-Level LMS + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8)) { + return 1; + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8)) { return 1; } #endif //OQS_ENABLE_SIG_STFL_LMS @@ -484,47 +530,75 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { #endif } #ifdef OQS_ENABLE_SIG_STFL_LMS - else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1)) { + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w1)) { return OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w2)) { return OQS_SIG_STFL_alg_lms_sha256_h5_w2_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w4)) { return OQS_SIG_STFL_alg_lms_sha256_h5_w4_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w8)) { return OQS_SIG_STFL_alg_lms_sha256_h5_w8_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w1)) { return OQS_SIG_STFL_alg_lms_sha256_h10_w1_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w2)) { return OQS_SIG_STFL_alg_lms_sha256_h10_w2_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4)) { return OQS_SIG_STFL_alg_lms_sha256_h10_w4_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8)) { return OQS_SIG_STFL_alg_lms_sha256_h10_w8_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w1)) { return OQS_SIG_STFL_alg_lms_sha256_h15_w1_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w2)) { return OQS_SIG_STFL_alg_lms_sha256_h15_w2_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w4)) { return OQS_SIG_STFL_alg_lms_sha256_h15_w4_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8)) { return OQS_SIG_STFL_alg_lms_sha256_h15_w8_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w1)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w1)) { return OQS_SIG_STFL_alg_lms_sha256_h20_w1_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w2)) { return OQS_SIG_STFL_alg_lms_sha256_h20_w2_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w4)) { return OQS_SIG_STFL_alg_lms_sha256_h20_w4_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8)) { return OQS_SIG_STFL_alg_lms_sha256_h20_w8_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w1)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w1)) { return OQS_SIG_STFL_alg_lms_sha256_h25_w1_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w2)) { return OQS_SIG_STFL_alg_lms_sha256_h25_w2_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w4)) { return OQS_SIG_STFL_alg_lms_sha256_h25_w4_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w8)) { return OQS_SIG_STFL_alg_lms_sha256_h25_w8_new(); } +//2-Level LMS + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2)) { + return OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4)) { + return OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8)) { + return OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_new(); + } #endif //OQS_ENABLE_SIG_STFL_LMS else { return NULL; @@ -754,47 +828,75 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_ #endif } #ifdef OQS_ENABLE_SIG_STFL_LMS - else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1)) { + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w1)) { return OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w2)) { return OQS_SECRET_KEY_LMS_SHA256_H5_W2_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w4)) { return OQS_SECRET_KEY_LMS_SHA256_H5_W4_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w8)) { return OQS_SECRET_KEY_LMS_SHA256_H5_W8_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w1)) { return OQS_SECRET_KEY_LMS_SHA256_H10_W1_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w2)) { return OQS_SECRET_KEY_LMS_SHA256_H10_W2_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4)) { return OQS_SECRET_KEY_LMS_SHA256_H10_W4_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h10_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8)) { return OQS_SECRET_KEY_LMS_SHA256_H10_W8_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w1)) { return OQS_SECRET_KEY_LMS_SHA256_H15_W1_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w2)) { return OQS_SECRET_KEY_LMS_SHA256_H15_W2_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w4)) { return OQS_SECRET_KEY_LMS_SHA256_H15_W4_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h15_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8)) { return OQS_SECRET_KEY_LMS_SHA256_H15_W8_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w1)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w1)) { return OQS_SECRET_KEY_LMS_SHA256_H20_W1_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w2)) { return OQS_SECRET_KEY_LMS_SHA256_H20_W2_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w4)) { return OQS_SECRET_KEY_LMS_SHA256_H20_W4_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h20_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8)) { return OQS_SECRET_KEY_LMS_SHA256_H20_W8_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w1)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w1)) { return OQS_SECRET_KEY_LMS_SHA256_H25_W1_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w2)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w2)) { return OQS_SECRET_KEY_LMS_SHA256_H25_W2_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w4)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w4)) { return OQS_SECRET_KEY_LMS_SHA256_H25_W4_new(); - } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_n32_h25_w8)) { + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w8)) { return OQS_SECRET_KEY_LMS_SHA256_H25_W8_new(); } +//2-Level LMS + else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H5_W8_H5_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H10_W8_H5_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2)) { + return OQS_SECRET_KEY_LMS_SHA256_H10_W2_H10_W2_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4)) { + return OQS_SECRET_KEY_LMS_SHA256_H10_W4_H10_W4_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H10_W4_H5_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H10_W8_H10_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H15_W8_H5_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H15_W8_H10_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H15_W8_H15_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H20_W8_H5_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H20_W8_H10_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H20_W8_H15_W8_new(); + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8)) { + return OQS_SECRET_KEY_LMS_SHA256_H20_W8_H20_W8_new(); + } #endif //OQS_ENABLE_SIG_STFL_LMS else { return NULL; diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index ad55b11d1a..aa83e4c486 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -73,36 +73,55 @@ extern "C" { #define OQS_SIG_STFL_alg_xmssmt_shake128_h60_12 "XMSSMT-SHAKE_60/12_256" /* Defined LMS parameter identifiers */ -#define OQS_SIG_STFL_alg_lms_sha256_n32_h5_w1 "LMS_SHA256_H5_W1" //"5/1" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h5_w2 "LMS_SHA256_H5_W2" //"5/2" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h5_w4 "LMS_SHA256_H5_W4" //"5/4" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h5_w8 "LMS_SHA256_H5_W8" //"5/8" +#define OQS_SIG_STFL_alg_lms_sha256_h5_w1 "LMS_SHA256_H5_W1" //"5/1" +#define OQS_SIG_STFL_alg_lms_sha256_h5_w2 "LMS_SHA256_H5_W2" //"5/2" +#define OQS_SIG_STFL_alg_lms_sha256_h5_w4 "LMS_SHA256_H5_W4" //"5/4" +#define OQS_SIG_STFL_alg_lms_sha256_h5_w8 "LMS_SHA256_H5_W8" //"5/8" + +#define OQS_SIG_STFL_alg_lms_sha256_h10_w1 "LMS_SHA256_H10_W1" //"10/1" +#define OQS_SIG_STFL_alg_lms_sha256_h10_w2 "LMS_SHA256_H10_W2" //"10/2" +#define OQS_SIG_STFL_alg_lms_sha256_h10_w4 "LMS_SHA256_H10_W4" //"10/4" +#define OQS_SIG_STFL_alg_lms_sha256_h10_w8 "LMS_SHA256_H10_W8" //"10/8" + +#define OQS_SIG_STFL_alg_lms_sha256_h15_w1 "LMS_SHA256_H15_W1" //"15/1" +#define OQS_SIG_STFL_alg_lms_sha256_h15_w2 "LMS_SHA256_H15_W2" //"15/2" +#define OQS_SIG_STFL_alg_lms_sha256_h15_w4 "LMS_SHA256_H15_W4" //"15/4" +#define OQS_SIG_STFL_alg_lms_sha256_h15_w8 "LMS_SHA256_H15_W8" //"15/8" + +#define OQS_SIG_STFL_alg_lms_sha256_h20_w1 "LMS_SHA256_H20_W1" //"20/1" +#define OQS_SIG_STFL_alg_lms_sha256_h20_w2 "LMS_SHA256_H20_W2" //"20/2" +#define OQS_SIG_STFL_alg_lms_sha256_h20_w4 "LMS_SHA256_H20_W4" //"20/4" +#define OQS_SIG_STFL_alg_lms_sha256_h20_w8 "LMS_SHA256_H20_W8" //"20/8" + +#define OQS_SIG_STFL_alg_lms_sha256_h25_w1 "LMS_SHA256_H25_W1" //"25/1" +#define OQS_SIG_STFL_alg_lms_sha256_h25_w2 "LMS_SHA256_H25_W2" //"25/2" +#define OQS_SIG_STFL_alg_lms_sha256_h25_w4 "LMS_SHA256_H25_W4" //"25/4" +#define OQS_SIG_STFL_alg_lms_sha256_h25_w8 "LMS_SHA256_H25_W8" //"25/8" + +//2-Level LMS +#define OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8 "LMS_SHA256_H5_W8_H5_W8" //"5/8, 5/8" + +//RFC 6554 +#define OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8 "LMS_SHA256_H10_W4_H5_W8" //"10/4, 5/8" + +#define OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8 "LMS_SHA256_H10_W8_H5_W8" //"10/8, 5/8" +#define OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2 "LMS_SHA256_H10_W2_H10_W2" //"10/2, 10/2" +#define OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4 "LMS_SHA256_H10_W4_H10_W4" //"10/4, 10/4" +#define OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8 "LMS_SHA256_H10_W8_H10_W8" //"10/8, 10/8" + +#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8 "LMS_SHA256_H15_W8_H5_W8" //"15/8, 5/8" +#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8 "LMS_SHA256_H15_W8_H10_W8" //"15/8, 10/8" +#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8 "LMS_SHA256_H15_W8_H15_W8" //"15/8, 15/8" + +#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8 "LMS_SHA256_H20_W8_H5_W8" //"20/8, 5/8" +#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8 "LMS_SHA256_H20_W8_H10_W8" //"20/8, 10/8" +#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8 "LMS_SHA256_H20_W8_H15_W8" //"20/8, 15/8" +#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8 "LMS_SHA256_H20_W8_H20_W8" //"20/8, 20/8" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h10_w1 "LMS_SHA256_H10_W1" //"10/1" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h10_w2 "LMS_SHA256_H10_W2" //"10/2" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h10_w4 "LMS_SHA256_H10_W4" //"10/4" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h10_w8 "LMS_SHA256_H10_W8" //"10/8" - -#define OQS_SIG_STFL_alg_lms_sha256_n32_h15_w1 "LMS_SHA256_H15_W1" //"15/1" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h15_w2 "LMS_SHA256_H15_W2" //"15/2" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h15_w4 "LMS_SHA256_H15_W4" //"15/4" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h15_w8 "LMS_SHA256_H15_W8" //"15/8" - -#define OQS_SIG_STFL_alg_lms_sha256_n32_h20_w1 "LMS_SHA256_H20_W1" //"20/1" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h20_w2 "LMS_SHA256_H20_W2" //"20/2" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h20_w4 "LMS_SHA256_H20_W4" //"20/4" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h20_w8 "LMS_SHA256_H20_W8" //"20/8" - -#define OQS_SIG_STFL_alg_lms_sha256_n32_h25_w1 "LMS_SHA256_H25_W1" //"25/1" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h25_w2 "LMS_SHA256_H25_W2" //"25/2" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h25_w4 "LMS_SHA256_H25_W4" //"25/4" -#define OQS_SIG_STFL_alg_lms_sha256_n32_h25_w8 "LMS_SHA256_H25_W8" //"25/8" - -#define OQS_SIG_STFL_algs_length 48 - -/* Defined LM parameter identifiers */ -/* Algorithm identifier for LMS-SHA256_N32_H5 */ -#define OQS_SIG_STFL_alg_lms_sha256_n32_h5 "LMS-SHA256_N32_H5" //0x00000005 +/* + * Total number of stateful variants defined above, used to create the tracking array + */ +#define OQS_SIG_STFL_algs_length 61 typedef struct OQS_SIG_STFL_SECRET_KEY OQS_SIG_STFL_SECRET_KEY; @@ -110,7 +129,7 @@ typedef struct OQS_SIG_STFL_SECRET_KEY OQS_SIG_STFL_SECRET_KEY; * Application provided function to securely store data * @param[in] sk_buf pointer to the data to be saved * @param[in] buf_len length of the data to be stored - * @param[out] context pointer to application relevant data. + * @param[out] context pass back application data related to secret key data storage. * return OQS_SUCCESS if successful, otherwise OQS_ERROR */ typedef OQS_STATUS (*secure_store_sk)(uint8_t *sk_buf, size_t buf_len, void *context); @@ -200,7 +219,7 @@ typedef struct OQS_SIG_STFL { * compile-time macros `OQS_SIG_STFL_*_length_*`. * * @param[out] public_key The public key is represented as a byte string. - * @param[out] secret_key The secret key is represented as a byte string + * @param[out] secret_key The secret key object * @return OQS_SUCCESS or OQS_ERROR */ OQS_STATUS (*keypair)(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -216,7 +235,7 @@ typedef struct OQS_SIG_STFL { * @param[out] signature_len The length of the signature. * @param[in] message The message to sign is represented as a byte string. * @param[in] message_len The length of the message to sign. - * @param[in] secret_key The secret key is represented as a byte string. + * @param[in] secret_key The secret key object pointer. * @return OQS_SUCCESS or OQS_ERROR */ OQS_STATUS (*sign)(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -237,7 +256,7 @@ typedef struct OQS_SIG_STFL { * Query number of remaining signatures * * @param[out] remain The number of remaining signatures - * @param[in] secret_key The secret key is represented as a byte string. + * @param[in] secret_key The secret key object pointer. * @return OQS_SUCCESS or OQS_ERROR */ OQS_STATUS (*sigs_remaining)(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -246,7 +265,7 @@ typedef struct OQS_SIG_STFL { * Total number of signatures * * @param[out] total The total number of signatures - * @param[in] secret_key The secret key is represented as a byte string. + * @param[in] secret_key The secret key key object pointer. * @return OQS_SUCCESS or OQS_ERROR */ OQS_STATUS (*sigs_total)(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -271,7 +290,7 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { /* mutual exclusion struct */ void *mutex; - /* file storage handle */ + /* Application managed data related to secure storage of secret key data */ void *context; /** @@ -292,6 +311,8 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { * @param[in] key_len length of the returned byte string * @param[in] sk_buf The secret key data to populate the key object * @param[in] context application-specific data + * used to keep track of this secret key stored in a secure manner. + * The application manages this memory. * @returns status of the operation populated with key material none zero length. * Caller is responsible to **unallocate** the buffer `sk_buf`. */ @@ -315,10 +336,12 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { /** * Store Secret Key Function - * Callback function used to securely store key data + * Callback function used to securely store key data after a signature generation. + * When populated, this pointer points to the application supplied secure storage function. * @param[in] sk_buf The serialized secret key data to secure store * @param[in] buf_len length of data to secure - * @param[in] context aids the secure writing of data + * @param[in] context application supplied data used to locate where this secret key + * is stored (passed in at the time the function pointer was set). * * @return OQS_SUCCESS or OQS_ERROR * Ideally written to secure device @@ -333,12 +356,22 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { */ void (*free_key)(OQS_SIG_STFL_SECRET_KEY *sk); + /* + * Secure storage for private keys used in stateful signature schemes is outside the scope of the OQS library. + * This is the responsibility of any adopting application. The application must supply + * a function to for this purpose. A callback function and context data must be set in-order + * to perform stateful signature generation. + * The context var may contain, for example an HSM context, a filename or other such data that + * is used to store the private key. This var is passed into the OQS lib when the application sets + * the callback function use to save/update the private key. + */ /** * Set Secret Key store callback Function * * @param[in] sk secret key pointer to be updated * @param[in] store_cb callback pointer - * @param[in] context secret key specific data/identifier + * @param[in] context application data related to secret key data/identifier storage. + * Provided when OQS_SIG_STFL_SECRET_KEY_SET_store_cb() is called. */ void (*set_scrt_key_store_cb)(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); } OQS_SIG_STFL_SECRET_KEY; @@ -364,7 +397,7 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name); * * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. * @param[out] public_key The public key is represented as a byte string. - * @param[out] secret_key The secret key is represented as a byte string. + * @param[out] secret_key The secret key object pointer. * @return OQS_SUCCESS or OQS_ERROR */ OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -381,7 +414,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public * @param[out] signature_len The length of the signature. * @param[in] message The message to sign is represented as a byte string. * @param[in] message_len The length of the message to sign. - * @param[in] secret_key The secret key is represented as a byte string. + * @param[in] secret_key The secret key object pointer. * @return OQS_SUCCESS or OQS_ERROR */ OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -403,7 +436,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m * Query number of remaining signatures * * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. - * @param[in] secret_key The secret key is represented as a byte string. + * @param[in] secret_key The secret key object. * @return OQS_SUCCESS or OQS_ERROR */ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -413,7 +446,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned * * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. * @param[out] max The number of remaining signatures - * @param[in] secret_key The secret key is represented as a byte string. + * @param[in] secret_key The secret key object. * @return OQS_SUCCESS or OQS_ERROR */ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned long long *max, const OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -506,15 +539,36 @@ OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk); * * @param[in] sk secret key pointer to be updated * @param[in] store_cb callback pointer - * @param[in] context secret key specific data/identifier + * @param[in] context application data related to where/how secret key data storage. + * Applications allocates, tracks, deallocates this. Signature generation fails without this set. * */ void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); -/* Serialize stateful secret key data into a byte string, and return an allocated buffer. Users are responsible for deallocating the buffer `sk_buf`. */ +/** + * OQS_SECRET_KEY_STFL_serialize_key . + * + * Serialize stateful secret key data into a byte string, and + * return an allocated buffer. Users are responsible for deallocating + * the buffer `sk_buf_ptr`. + * + * @param[out] sk_buf_ptr secret key buffer returned. Caller deletes. + * @param[out] sk_len size of the buffer returned + * @param[in] sk secret key pointer to be serialize + */ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); -/* Insert stateful byte string into a secret key object. Users are responsible for deallocating buffer `sk_buf`. */ +/** + * OQS_SECRET_KEY_STFL_deserialize_key . + * + * Insert stateful byte string into a secret key object. + * Users are responsible for deallocating buffer `sk_buf`. + * + * @param[in] sk secret key pointer to be populated + * @param[in] sk_len size of the supplied buffer + * @param[in] sk_buf secret key buffer. Caller deletes. + * @param[in] context application managed data related to where/how secret key data is stored. + */ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf, void *context); #if defined(__cplusplus) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 22c26a053a..c59657f646 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -88,6 +88,10 @@ set(KEM_TESTS example_kem kat_kem test_kem test_kem_mem speed_kem vectors_kem) add_executable(example_sig example_sig.c) target_link_libraries(example_sig PRIVATE ${TEST_DEPS}) +# Stateful SIG API tests +add_executable(example_sig_stfl example_sig_stfl.c) +target_link_libraries(example_sig_stfl PRIVATE ${TEST_DEPS}) + add_executable(kat_sig kat_sig.c test_helpers.c) target_link_libraries(kat_sig PRIVATE ${TEST_DEPS}) if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND BUILD_SHARED_LIBS) diff --git a/tests/KATs/sig_stfl/kats.json b/tests/KATs/sig_stfl/kats.json index 7ed8350ad1..592008ce84 100644 --- a/tests/KATs/sig_stfl/kats.json +++ b/tests/KATs/sig_stfl/kats.json @@ -26,5 +26,7 @@ "XMSSMT-SHAKE_40/8_256" : "cf301b7d978d5c0afcdf3300ba97d829e2e5f737cb449968b19b45f05b987591", "XMSSMT-SHAKE_60/3_256" : "09d26df5e911e98e71ef73a1ab6f224964d4a7beacd8071b4c7f7d1930a537bd", "XMSSMT-SHAKE_60/6_256" : "0692a32e318d5c3ac8631120910b783edfed4cb7ed69e3ffa29f83aaa34e27d5", - "XMSSMT-SHAKE_60/12_256" : "1a05ff4a4fea850a5fe5c9e976006577335eab0494e1759fe217c2f33f5a84e6" + "XMSSMT-SHAKE_60/12_256" : "1a05ff4a4fea850a5fe5c9e976006577335eab0494e1759fe217c2f33f5a84e6", + "LMS_SHA256_H5_W8_H5_W8": "fa6f9a0948626c1e078ad442ea2fccdf456b529413eba441c175cbb681f9bc32", + "LMS_SHA256_H10_W4_H5_W8": "2485c56164bbfa4bdc8604195bf397bfe8f54e2ebe925423e4e70fce173c0fff" } \ No newline at end of file diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4_H5_W8.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4_H5_W8.rsp new file mode 100644 index 0000000000..d5b66c3f7d --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4_H5_W8.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H10_W4_H5_W8 + +msg = 54686520656e756d65726174696f6e20696e2074686520436f6e737469747574696f6e2c206f66206365727461696e207269676874732c207368616c6c206e6f7420626520636f6e73747275656420746f2064656e79206f7220646973706172616765206f74686572732072657461696e6564206279207468652070656f706c652e0a + +sm = 0000000100000003000000033d46bee8660f8f215d3f96408a7a64cf1c4da02b63a55f62c666ef5707a914ce0674e8cb7a55f0c48d484f31f3aa4af9719a74f22cf823b94431d01c926e2a76bb71226d279700ec81c9e95fb11a0d10d065279a5796e265ae17737c44eb8c594508e126a9a7870bf4360820bdeb9a01d9693779e416828e75bddd7d8c70d50a0ac8ba39810909d445f44cb5bb58de737e60cb4345302786ef2c6b14af212ca19edeaa3bfcfe8baa6621ce88480df2371dd37add732c9de4ea2ce0dffa53c92649a18d39a50788f4652987f226a1d48168205df6ae7c58e049a25d4907edc1aa90da8aa5e5f7671773e941d8055360215c6b60dd35463cf2240a9c06d694e9cb54e7b1e1bf494d0d1a28c0d31acc75161f4f485dfd3cb9578e836ec2dc722f37ed30872e07f2b8bd0374eb57d22c614e09150f6c0d8774a39a6e168211035dc52988ab46eaca9ec597fb18b4936e66ef2f0df26e8d1e34da28cbb3af752313720c7b345434f72d65314328bbb030d0f0f6d5e47b28ea91008fb11b05017705a8be3b2adb83c60a54f9d1d1b2f476f9e393eb5695203d2ba6ad815e6a111ea293dcc21033f9453d49c8e5a6387f588b1ea4f706217c151e05f55a6eb7997be09d56a326a32f9cba1fbe1c07bb49fa04cecf9df1a1b815483c75d7a27cc88ad1b1238e5ea986b53e087045723ce16187eda22e33b2c70709e53251025abde8939645fc8c0693e97763928f00b2e3c75af3942d8ddaee81b59a6f1f67efda0ef81d11873b59137f67800b35e81b01563d187c4a1575a1acb92d087b517a8833383f05d357ef4678de0c57ff9f1b2da61dfde5d88318bcdde4d9061cc75c2de3cd4740dd7739ca3ef66f1930026f47d9ebaa713b07176f76f953e1c2e7f8f271a6ca375dbfb83d719b1635a7d8a13891957944b1c29bb101913e166e11bd5f34186fa6c0a555c9026b256a6860f4866bd6d0b5bf90627086c6149133f8282ce6c9b3622442443d5eca959d6c14ca8389d12c4068b503e4e3c39b635bea245d9d05a2558f249c9661c0427d2e489ca5b5dde220a90333f4862aec793223c781997da98266c12c50ea28b2c438e7a379eb106eca0c7fd6006e9bf612f3ea0a454ba3bdb76e8027992e60de01e9094fddeb3349883914fb17a9621ab929d970d101e45f8278c14b032bcab02bd15692d21b6c5c204abbf077d465553bd6eda645e6c3065d33b10d518a61e15ed0f092c32226281a29c8a0f50cde0a8c66236e29c2f310a375cebda1dc6bb9a1a01dae6c7aba8ebedc6371a7d52aacb955f83bd6e4f84d2949dcc198fb77c7e5cdf6040b0f84faf82808bf985577f0a2acf2ec7ed7c0b0ae8a270e951743ff23e0b2dd12e9c3c828fb5598a22461af94d568f29240ba2820c4591f71c088f96e095dd98beae456579ebbba36f6d9ca2613d1c26eee4d8c73217ac5962b5f3147b492e8831597fd89b64aa7fde82e1974d2f6779504dc21435eb3109350756b9fdabe1c6f368081bd40b27ebcb9819a75d7df8bb07bb05db1bab705a4b7e37125186339464ad8faaa4f052cc1272919fde3e025bb64aa8e0eb1fcbfcc25acb5f718ce4f7c2182fb393a1814b0e942490e52d3bca817b2b26e90d4c9b0cc38608a6cef5eb153af0858acc867c9922aed43bb67d7b33acc519313d28d41a5c6fe6cf3595dd5ee63f0a4c4065a083590b275788bee7ad875a7f88dd73720708c6c6c0ecf1f43bbaadae6f208557fdc07bd4ed91f88ce4c0de842761c70c186bfdafafc444834bd3418be4253a71eaf41d718753ad07754ca3effd5960b0336981795721426803599ed5b2b7516920efcbe32ada4bcf6c73bd29e3fa152d9adeca36020fdeeee1b739521d3ea8c0da497003df1513897b0f54794a873670b8d93bcca2ae47e64424b7423e1f078d9554bb5232cc6de8aae9b83fa5b9510beb39ccf4b4e1d9c0f19d5e17f58e5b8705d9a6837a7d9bf99cd13387af256a8491671f1f2f22af253bcff54b673199bdb7d05d81064ef05f80f0153d0be7919684b23da8d42ff3effdb7ca0985033f389181f47659138003d712b5ec0a614d31cc7487f52de8664916af79c98456b2c94a8038083db55391e3475862250274a1de2584fec975fb09536792cfbfcf6192856cc76eb5b13dc4709e2f7301ddff26ec1b23de2d188c999166c74e1e14bbc15f457cf4e471ae13dcbdd9c50f4d646fc6278e8fe7eb6cb5c94100fa870187380b777ed19d7868fd8ca7ceb7fa7d5cc861c5bdac98e7495eb0a2ceec1924ae979f44c5390ebedddc65d6ec11287d978b8df064219bc5679f7d7b264a76ff272b2ac9f2f7cfc9fdcfb6a51428240027afd9d52a79b647c90c2709e060ed70f87299dd798d68f4fadd3da6c51d839f851f98f67840b964ebe73f8cec41572538ec6bc131034ca2894eb736b3bda93d9f5f6fa6f6c0f03ce43362b8414940355fb54d3dfdd03633ae108f3de3ebc85a3ff51efeea3bc2cf27e1658f1789ee612c83d0f5fd56f7cd071930e2946beeecaa04dccea9f97786001475e0294bc2852f62eb5d39bb9fbeef75916efe44a662ecae37ede27e9d6eadfdeb8f8b2b2dbccbf96fa6dbaf7321fb0e701f4d429c2f4dcd153a2742574126e5eaccc77686acf6e3ee48f423766e0fc466810a905ff5453ec99897b56bc55dd49b991142f65043f2d744eeb935ba7f4ef23cf80cc5a8a335d3619d781e7454826df720eec82e06034c44699b5f0c44a8787752e057fa3419b5bb0e25d30981e41cb1361322dba8f69931cf42fad3f3bce6ded5b8bfc3d20a2148861b2afc14562ddd27f12897abf0685288dcc5c4982f826026846a24bf77e383c7aacab1ab692b29ed8c018a65f3dc2b87ff619a633c41b4fadb1c78725c1f8f922f6009787b1964247df0136b1bc614ab575c59a16d089917bd4a8b6f04d95c581279a139be09fcf6e98a470a0bceca191fce476f9370021cbc05518a7efd35d89d8577c990a5e19961ba16203c959c91829ba7497cffcbb4b294546454fa5388a23a22e805a5ca35f956598848bda678615fec28afd5da61a00000006b326493313053ced3876db9d237148181b7173bc7d042cefb4dbe94d2e58cd21a769db4657a103279ba8ef3a629ca84ee836172a9c50e51f45581741cf8083150b491cb4ecbbabec128e7c81a46e62a67b57640a0a78be1cbf7dd9d419a10cd8686d16621a80816bfdb5bdc56211d72ca70b81f1117d129529a7570cf79cf52a7028a48538ecdd3b38d3d5d62d26246595c4fb73a525a5ed2c30524ebb1d8cc82e0c19bc4977c6898ff95fd3d310b0bae71696cef93c6a552456bf96e9d075e383bb7543c675842bafbfc7cdb88483b3276c29d4f0a341c2d406e40d4653b7e4d045851acf6a0a0ea9c710b805cced4635ee8c107362f0fc8d80c14d0ac49c516703d26d14752f34c1c0d2c4247581c18c2cf4de48e9ce949be7c888e9caebe4a415e291fd107d21dc1f084b1158208249f28f4f7c7e931ba7b3bd0d824a45700000000500000004215f83b7ccb9acbcd08db97b0d04dc2ba1cd035833e0e90059603f26e07ad2aad152338e7a5e5984bcd5f7bb4eba40b700000004000000040eb1ed54a2460d512388cad533138d240534e97b1e82d33bd927d201dfc24ebb11b3649023696f85150b189e50c00e98850ac343a77b3638319c347d7310269d3b7714fa406b8c35b021d54d4fdada7b9ce5d4ba5b06719e72aaf58c5aae7aca057aa0e2e74e7dcfd17a0823429db62965b7d563c57b4cec942cc865e29c1dad83cac8b4d61aacc457f336e6a10b66323f5887bf3523dfcadee158503bfaa89dc6bf59daa82afd2b5ebb2a9ca6572a6067cee7c327e9039b3b6ea6a1edc7fdc3df927aade10c1c9f2d5ff446450d2a3998d0f9f6202b5e07c3f97d2458c69d3c8190643978d7a7f4d64e97e3f1c4a08a7c5bc03fd55682c017e2907eab07e5bb2f190143475a6043d5e6d5263471f4eecf6e2575fbc6ff37edfa249d6cda1a09f797fd5a3cd53a066700f45863f04b6c8a58cfd341241e002d0d2c0217472bf18b636ae547c1771368d9f317835c9b0ef430b3df4034f6af00d0da44f4af7800bc7a5cf8a5abdb12dc718b559b74cab9090e33cc58a955300981c420c4da8ffd67df540890a062fe40dba8b2c1c548ced22473219c534911d48ccaabfb71bc71862f4a24ebd376d288fd4e6fb06ed8705787c5fedc813cd2697e5b1aac1ced45767b14ce88409eaebb601a93559aae893e143d1c395bc326da821d79a9ed41dcfbe549147f71c092f4f3ac522b5cc57290706650487bae9bb5671ecc9ccc2ce51ead87ac01985268521222fb9057df7ed41810b5ef0d4f7cc67368c90f573b1ac2ce956c365ed38e893ce7b2fae15d3685a3df2fa3d4cc098fa57dd60d2c9754a8ade980ad0f93f6787075c3f680a2ba1936a8c61d1af52ab7e21f416be09d2a8d64c3d3d8582968c2839902229f85aee297e717c094c8df4a23bb5db658dd377bf0f4ff3ffd8fba5e383a48574802ed545bbe7a6b4753533353d73706067640135a7ce517279cd683039747d218647c86e097b0daa2872d54b8f3e5085987629547b830d8118161b65079fe7bc59a99e9c3c7380e3e70b7138fe5d9be2551502b698d09ae193972f27d40f38dea264a0126e637d74ae4c92a6249fa103436d3eb0d4029ac712bfc7a5eacbdd7518d6d4fe903a5ae65527cd65bb0d4e9925ca24fd7214dc617c150544e423f450c99ce51ac8005d33acd74f1bed3b17b7266a4a3bb86da7eba80b101e15cb79de9a207852cf91249ef480619ff2af8cabca83125d1faa94cbb0a03a906f683b3f47a97c871fd513e510a7a25f283b196075778496152a91c2bf9da76ebe089f4654877f2d586ae7149c406e663eadeb2b5c7e82429b9e8cb4834c83464f079995332e4b3c8f5a72bb4b8c6f74b0d45dc6c1f79952c0b7420df525e37c15377b5f0984319c3993921e5ccd97e097592064530d33de3afad5733cbe7703c5296263f77342efbf5a04755b0b3c997c4328463e84caa2de3ffdcd297baaaacd7ae646e44b5c0f16044df38fabd296a47b3a838a913982fb2e370c078edb042c84db34ce36b46ccb76460a690cc86c302457dd1cde197ec8075e82b393d542075134e2a17ee70a5e187075d03ae3c853cff60729ba4000000054de1f6965bdabc676c5a4dc7c35f97f82cb0e31c68d04f1dad96314ff09e6b3de96aeee300d1f68bf1bca9fc58e4032336cd819aaf578744e50d1357a0e4286704d341aa0a337b19fe4bc43c2e79964d4f351089f2e0e41c7c43ae0d49e7f404b0f75be80ea3af098c9752420a8ac0ea2bbb1f4eeba05238aef0d8ce63f0c6e5e4041d95398a6f7f3e0ee97cc1591849d4ed236338b147abde9f51ef9fd4e1c1 + +pk = 000000020000000600000003d08fabd4a2091ff0a8cb4ed834e7453432a58885cd9ba0431235466bff9651c6c92124404d45fa53cf161c28f1ad5a8e + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8_H5_W8.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8_H5_W8.rsp new file mode 100644 index 0000000000..7e8dc7bd21 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8_H5_W8.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H5_W8_H5_W8 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e0a + +sm = 000000010000000500000004d32b56671d7eb98833c49b433c272586bc4a1c8a8970528ffa04b966f9426eb9965a25bfd37f196b9073f3d4a232feb69128ec45146f86292f9dff9610a7bf95a64c7f60f6261a62043f86c70324b7707f5b4a8a6e19c114c7be866d488778a0e05fd5c6509a6e61d559cf1a77a970de927d60c70d3de31a7fa0100994e162a2582e8ff1b10cd99d4e8e413ef469559f7d7ed12c838342f9b9c96b83a4943d1681d84b15357ff48ca579f19f5e71f18466f2bbef4bf660c2518eb20de2f66e3b14784269d7d876f5d35d3fbfc7039a462c716bb9f6891a7f41ad133e9e1f6d9560b960e7777c52f060492f2d7c660e1471e07e72655562035abc9a701b473ecbc3943c6b9c4f2405a3cb8bf8a691ca51d3f6ad2f428bab6f3a30f55dd9625563f0a75ee390e385e3ae0b906961ecf41ae073a0590c2eb6204f44831c26dd768c35b167b28ce8dc988a3748255230cef99ebf14e730632f27414489808afab1d1e783ed04516de012498682212b07810579b250365941bcc98142da13609e9768aaf65de7620dabec29eb82a17fde35af15ad238c73f81bdb8dec2fc0e7f932701099762b37f43c4a3c20010a3d72e2f606be108d310e639f09ce7286800d9ef8a1a40281cc5a7ea98d2adc7c7400c2fe5a101552df4e3cccfd0cbf2ddf5dc6779cbbc68fee0c3efe4ec22b83a2caa3e48e0809a0a750b73ccdcf3c79e6580c154f8a58f7f24335eec5c5eb5e0cf01dcf4439424095fceb077f66ded5bec73b27c5b9f64a2a9af2f07c05e99e5cf80f00252e39db32f6c19674f190c9fbc506d826857713afd2ca6bb85cd8c107347552f30575a5417816ab4db3f603f2df56fbc413e7d0acd8bdd81352b2471fc1bc4f1ef296fea1220403466b1afe78b94f7ecf7cc62fb92be14f18c2192384ebceaf8801afdf947f698ce9c6ceb696ed70e9e87b0144417e8d7baf25eb5f70f09f016fc925b4db048ab8d8cb2a661ce3b57ada67571f5dd546fc22cb1f97e0ebd1a65926b1234fd04f171cf469c76b884cf3115cce6f792cc84e36da58960c5f1d760f32c12faef477e94c92eb75625b6a371efc72d60ca5e908b3a7dd69fef0249150e3eebdfed39cbdc3ce9704882a2072c75e13527b7a581a556168783dc1e97545e31865ddc46b3c957835da252bb7328d3ee2062445dfb85ef8c35f8e1f3371af34023cef626e0af1e0bc017351aae2ab8f5c612ead0b729a1d059d02bfe18efa971b7300e882360a93b025ff97e9e0eec0f3f3f13039a17f88b0cf808f488431606cb13f9241f40f44e537d302c64a4f1f4ab949b9feefadcb71ab50ef27d6d6ca8510f150c85fb525bf25703df7209b6066f09c37280d59128d2f0f637c7d7d7fad4ed1c1ea04e628d221e3d8db77b7c878c9411cafc5071a34a00f4cf07738912753dfce48f07576f0d4f94f42c6d76f7ce973e9367095ba7e9a3649b7f461d9f9ac1332a4d1044c96aefee67676401b64457c54d65fef6500c59cdfb69af7b6dddfcb0f086278dd8ad0686078dfb0f3f79cd893d314168648499898fbc0ced5f95b74e8ff14d735cdea968bee7400000005d8b8112f9200a5e50c4a262165bd342cd800b8496810bc716277435ac376728d129ac6eda839a6f357b5a04387c5ce97382a78f2a4372917eefcbf93f63bb59112f5dbe400bd49e4501e859f885bf0736e90a509b30a26bfac8c17b5991c157eb5971115aa39efd8d564a6b90282c3168af2d30ef89d51bf14654510a12b8a144cca1848cf7da59cc2b3d9d0692dd2a20ba3863480e25b1b85ee860c62bf51360000000500000004d2f14ff6346af964569f7d6cb880a1b66c5004917da6eafe4d9ef6c6407b3db0e5485b122d9ebe15cda93cfec582d7ab0000000a000000040703c491e7558b35011ece3592eaa5da4d918786771233e8353bc4f62323185c95cae05b899e35dffd717054706209988ebfdf6e37960bb5c38d7657e8bffeef9bc042da4b4525650485c66d0ce19b317587c6ba4bffcc428e25d08931e72dfb6a120c5612344258b85efdb7db1db9e1865a73caf96557eb39ed3e3f426933ac9eeddb03a1d2374af7bf77185577456237f9de2d60113c23f846df26fa942008a698994c0827d90e86d43e0df7f4bfcdb09b86a373b98288b7094ad81a0185ac100e4f2c5fc38c003c1ab6fea479eb2f5ebe48f584d7159b8ada03586e65ad9c969f6aecbfe44cf356888a7b15a3ff074f771760b26f9c04884ee1faa329fbf4e61af23aee7fa5d4d9a5dfcf43c4c26ce8aea2ce8a2990d7ba7b57108b47dabfbeadb2b25b3cacc1ac0cef346cbb90fb044beee4fac2603a442bdf7e507243b7319c9944b1586e899d431c7f91bcccc8690dbf59b28386b2315f3d36ef2eaa3cf30b2b51f48b71b003dfb08249484201043f65f5a3ef6bbd61ddfee81aca9ce60081262a00000480dcbc9a3da6fbef5c1c0a55e48a0e729f9184fcb1407c31529db268f6fe50032a363c9801306837fafabdf957fd97eafc80dbd165e435d0e2dfd836a28b354023924b6fb7e48bc0b3ed95eea64c2d402f4d734c8dc26f3ac591825daef01eae3c38e3328d00a77dc657034f287ccb0f0e1c9a7cbdc828f627205e4737b84b58376551d44c12c3c215c812a0970789c83de51d6ad787271963327f0a5fbb6b5907dec02c9a90934af5a1c63b72c82653605d1dcce51596b3c2b45696689f2eb382007497557692caac4d57b5de9f5569bc2ad0137fd47fb47e664fcb6db4971f5b3e07aceda9ac130e9f38182de994cff192ec0e82fd6d4cb7f3fe00812589b7a7ce515440456433016b84a59bec6619a1c6c0b37dd1450ed4f2d8b584410ceda8025f5d2d8dd0d2176fc1cf2cc06fa8c82bed4d944e71339ece780fd025bd41ec34ebff9d4270a3224e019fcb444474d482fd2dbe75efb20389cc10cd600abb54c47ede93e08c114edb04117d714dc1d525e11bed8756192f929d15462b939ff3f52f2252da2ed64d8fae88818b1efa2c7b08c8794fb1b214aa233db3162833141ea4383f1a6f120be1db82ce3630b3429114463157a64e91234d475e2f79cbf05e4db6a9407d72c6bff7d1198b5c4d6aad2831db61274993715a0182c7dc8089e32c8531deed4f7431c07c02195eba2ef91efb5613c37af7ae0c066babc69369700e1dd26eddc0d216c781d56e4ce47e3303fa73007ff7b949ef23be2aa4dbf25206fe45c20dd888395b2526391a724996a44156beac808212858792bf8e74cba49dee5e8812e019da87454bff9e847ed83db07af313743082f880a278f682c2bd0ad6887cb59f652e155987d61bbf6a88d36ee93b6072e6656d9ccbaae3d655852e38deb3a2dcf8058dc9fb6f2ab3d3b3539eb77b248a661091d05eb6e2f297774fe6053598457cc61908318de4b826f0fc86d4bb117d33e865aa805009cc2918d9c2f840c4da43a703ad9f5b5806163d7161696b5a0adc00000005d5c0d1bebb06048ed6fe2ef2c6cef305b3ed633941ebc8b3bec9738754cddd60e1920ada52f43d055b5031cee6192520d6a5115514851ce7fd448d4a39fae2ab2335b525f484e9b40d6a4a969394843bdcf6d14c48e8015e08ab92662c05c6e9f90b65a7a6201689999f32bfd368e5e3ec9cb70ac7b8399003f175c40885081a09ab3034911fe125631051df0408b3946b0bde790911e8978ba07dd56c73e7ee + +pk = 00000002000000050000000461a5d57d37f5e46bfb7520806b07a1b850650e3b31fe4a773ea29a07f09cf2ea30e579f0df58ef8e298da0434cb2b878 + diff --git a/tests/example_sig_stfl.c b/tests/example_sig_stfl.c new file mode 100644 index 0000000000..b332d8479b --- /dev/null +++ b/tests/example_sig_stfl.c @@ -0,0 +1,133 @@ +/* + * example_sig_stfl.c + * + * Minimal example of using a post-quantum stateful signature implemented in liboqs. + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include + +#include + +#define MESSAGE_LEN 50 + +static OQS_STATUS do_nothing_save(uint8_t *key_buf, size_t buf_len, void *context) { + (void)(context); + (void)(buf_len); + return key_buf != NULL ? OQS_SUCCESS : OQS_ERROR; +} + +/* This function gives an example of the signing operations, + * allocating variables dynamically on the heap and calling the + * OQS_SIG_STFL and OQS_SIG_STFL_SECRET_KEY objects. + * + * This does not require the use of compile-time macros to check if the + * algorithm in question was enabled at compile-time; instead, the caller + * must check that the OQS_SIG object returned is not NULL. + */ +static OQS_STATUS stfl_example(char *method_name) { + + OQS_SIG_STFL *sig = NULL; + uint8_t *public_key = NULL; + OQS_SIG_STFL_SECRET_KEY *secret_key = NULL; + uint8_t *message = NULL; + uint8_t *signature = NULL; + size_t message_len = MESSAGE_LEN; + size_t signature_len; + char *sk_fname = NULL; + OQS_STATUS rc = OQS_ERROR; + + /* + * Steps + * 1. create stateful signature object + * 2. create secret key object + * 3. set key storage callback function + * set mutex if necessary + * 4. Generate key-pair + * 5. Signature generation + * 6. verify signature + */ + sig = OQS_SIG_STFL_new(method_name); + if (sig == NULL) { + printf("[Stateful sig] %s new failed.\n", method_name); + return OQS_ERROR; + } + + secret_key = OQS_SIG_STFL_SECRET_KEY_new(method_name); + if (secret_key == NULL) { + printf("[Stateful secret key] %s new failed.\n", method_name); + goto err; + } + + /* + * Allocate storage for public key, secret key filename, message and signature + */ + public_key = malloc(sig->length_public_key); + sk_fname = malloc(strlen(method_name) + strlen(".sk")); + message = malloc(message_len); + signature = malloc(sig->length_signature); + if ((public_key == NULL) || (message == NULL) || (signature == NULL) || (sk_fname == NULL)) { + fprintf(stderr, "ERROR: malloc failed!\n"); + goto err; + } + + strcpy(sk_fname, method_name); + strcat(sk_fname, ".sk"); + /* + * set callback to securely store the secret key + * secret keys are one time use only. So after a signature gen + * the secret key most be advanced to the next + */ + OQS_SIG_STFL_SECRET_KEY_SET_store_cb(secret_key, do_nothing_save, (void *)sk_fname); + + /* + * Generate key pair + */ + rc = OQS_SIG_STFL_keypair(sig, public_key, secret_key); + if (rc != OQS_SUCCESS) { + printf("[Stateful key pair generation] %s new failed.\n", method_name); + goto err; + } + + // let's create a random test message to sign + OQS_randombytes(message, message_len); + + rc = OQS_SIG_STFL_sign(sig, signature, &signature_len, message, message_len, secret_key); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "ERROR: OQS_SIG_STFL_sign failed %s!\n", method_name); + goto err; + } + rc = OQS_SIG_STFL_verify(sig, message, message_len, signature, signature_len, public_key); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "ERROR: OQS_SIG_STFL_verify failed %s!\n", method_name); + goto err; + } + + printf("[Stateful signature] %s operations completed.\n", method_name); +err: +//cleanup + OQS_MEM_insecure_free(public_key); + OQS_MEM_insecure_free(sk_fname); + OQS_MEM_insecure_free(message); + OQS_MEM_insecure_free(signature); + OQS_SIG_STFL_free(sig); + OQS_SIG_STFL_SECRET_KEY_free(secret_key); + + return rc; +} + +int main(void) { + OQS_init(); + if (stfl_example("XMSS-SHA2_10_256") == OQS_SUCCESS && stfl_example("LMS_SHA256_H10_W4") == OQS_SUCCESS) { + OQS_destroy(); + return EXIT_SUCCESS; + } else { + OQS_destroy(); + return EXIT_FAILURE; + } +} + diff --git a/tests/helpers.py b/tests/helpers.py index 781df5e45a..b911f5d9bd 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -114,8 +114,8 @@ def available_sig_stfls_by_name(): with open(os.path.join('src', 'sig_stfl', 'sig_stfl.h')) as fh: for line in fh: if line.startswith("#define OQS_SIG_STFL_alg_"): - sig_stfl_name = line.split(' ')[2] - sig_stfl_name = sig_stfl_name[1:-2] + sig_stfl_name = line.split(' ')[2].strip() + sig_stfl_name = sig_stfl_name[1:-1] available_names.append(sig_stfl_name) return available_names @@ -126,8 +126,8 @@ def is_sig_stfl_enabled_by_name(name): if line.startswith("#define OQS_SIG_STFL_alg_"): sig_stfl_symbol = line.split(' ')[1] sig_stfl_symbol = sig_stfl_symbol[len("OQS_SIG_STFL_alg_"):] - sig_stfl_name = line.split(' ')[2] - sig_stfl_name = sig_stfl_name[1:-2] + sig_stfl_name = line.split(' ')[2].strip() + sig_stfl_name = sig_stfl_name[1:-1] if sig_stfl_name == name: symbol = sig_stfl_symbol break @@ -202,8 +202,10 @@ def get_katfile(t: str, sig_stfl_name: str) -> str: algo_dir = '' if "XMSS" in sig_stfl_name: algo_dir = 'xmss' - if not algo_dir: - return '' + if "LMS" in sig_stfl_name: + algo_dir = 'lms' + if algo_dir == '': + return '' # Replace the "/" to "-" in XMSSMT parameters clean_sig_stfl_name = sig_stfl_name.replace("/", "-", 1) kat_filename = f"{clean_sig_stfl_name}.rsp" diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index 4607977065..457a5c3778 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -71,11 +71,29 @@ int FindMarker(FILE *infile, const char *marker) { // // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) // -int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, const char *str) { +size_t ReadHex(FILE *infile, unsigned char *a, unsigned long Length, const char *str) { int ch, started; unsigned long i; unsigned char ich; + /* + * Caller is just trying to get the length target data + */ + if ((Length == 0) && (a == NULL)) { + i = 0; + if (FindMarker(infile, str)) { + while ((ch = fgetc(infile)) != EOF) { + if (!isxdigit(ch)) { + if (ch == '\n') { + break; + } + } + i += 1; + } + } + return (i / 2); + } + if (Length == 0) { a[0] = 0x00; return 1; @@ -118,6 +136,18 @@ int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, const char *st return 1; } +void fprint_l_str(FILE *fp, const char *S, const uint8_t *A, size_t L) { + size_t i; + fprintf(fp, "%s", S); + for (i = 0; i < L; i++) { + fprintf(fp, "%02x", A[i]); + } + if (L == 0) { + fprintf(fp, "00"); + } + fprintf(fp, "\n"); +} + OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { uint8_t seed[48]; @@ -283,7 +313,112 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { return ret; } +/* + * LMS Test Vector + */ +static OQS_STATUS test_lms_kat(const char *method_name, const char *katfile) { + OQS_STATUS rc = OQS_ERROR; + OQS_SIG_STFL *sig = NULL; + uint8_t *public_key = NULL; + uint8_t *msg = NULL; + size_t msg_len = 0; + uint8_t *sm = NULL; + FILE *fp_rsp = NULL; + FILE *fh = NULL; + + if ((fp_rsp = fopen(katfile, "r")) == NULL) { + fprintf(stderr, "Couldn't open <%s> for read\n", katfile); + goto err; + } + + //Allocate a OQS stateful signature struct + sig = OQS_SIG_STFL_new(method_name); + if (sig == NULL) { + fprintf(stderr, "ERROR: Failed to create signature object for %s\n", method_name); + goto err; + } + + /* + * Get the message length + * Zero length means no KAT is currently available, so skip this method + * and return success + */ + msg_len = ReadHex(fp_rsp, 0, 0, "msg = "); + if (!(msg_len > 0)) { + fprintf(stderr, "No msg present\n"); + goto err; + } + + fclose(fp_rsp); + if ((fp_rsp = fopen(katfile, "r")) == NULL) { + fprintf(stderr, "Couldn't open <%s> for read\n", katfile); + goto err; + } + + public_key = malloc(sig->length_public_key); + sm = malloc(sig->length_signature); + msg = malloc((unsigned long)msg_len); + + if ((!msg || !sm || !public_key)) { + fprintf(stderr, "ERROR: unable to allocate memory.\n"); + goto err; + } + + /* + * Read signature and public key, msg and signature data from KAT file + */ + if (!ReadHex(fp_rsp, public_key, sig->length_public_key, "pk = ")) { + fprintf(stderr, "ERROR: unable to read 'pk' from <%s>\n", katfile); + goto err; + } + fclose(fp_rsp); + if ((fp_rsp = fopen(katfile, "r")) == NULL) { + fprintf(stderr, "Couldn't open <%s> for read\n", katfile); + goto err; + } + + if (!ReadHex(fp_rsp, msg, msg_len, "msg = ")) { + fprintf(stderr, "ERROR: unable to read 'msg' from <%s>\n", katfile); + goto err; + } + fclose(fp_rsp); + if ((fp_rsp = fopen(katfile, "r")) == NULL) { + fprintf(stderr, "Couldn't open <%s> for read\n", katfile); + goto err; + } + + if (!ReadHex(fp_rsp, sm, sig->length_signature, "sm = ")) { + fprintf(stderr, "ERROR: unable to read 'sm' from <%s>\n", katfile); + goto err; + } + + //Verify KAT + rc = OQS_SIG_STFL_verify(sig, msg, msg_len, sm, sig->length_signature, public_key); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "ERROR: Verify test vector failed: %s\n", method_name); + } else { + fh = stdout; + fprintf(fh, "# %s\n\n", sig->method_name); + fprint_l_str(fh, "msg = ", msg, msg_len); + fprintf(fh, "\n"); + fprint_l_str(fh, "sm = ", sm, sig->length_signature); + fprintf(fh, "\n"); + fprint_l_str(fh, "pk = ", public_key, sig->length_public_key); + fprintf(fh, "\n"); + } +err: + OQS_SIG_STFL_free(sig); + OQS_MEM_insecure_free(sm); + OQS_MEM_insecure_free(public_key); + OQS_MEM_insecure_free(msg); + if (fp_rsp) { + fclose(fp_rsp); + } + return rc; +} + int main(int argc, char **argv) { + OQS_STATUS rc; OQS_init(); if (argc != 3) { @@ -304,7 +439,11 @@ int main(int argc, char **argv) { char *alg_name = argv[1]; char *katfile = argv[2]; - OQS_STATUS rc = sig_stfl_kat(alg_name, katfile); + if (strncmp(alg_name, "LMS", 3) != 0) { + rc = sig_stfl_kat(alg_name, katfile); + } else { + rc = test_lms_kat(alg_name, katfile); + } if (rc != OQS_SUCCESS) { OQS_destroy(); return EXIT_FAILURE; diff --git a/tests/test_hash.c b/tests/test_hash.c index 3fea2f00ad..788f41ffb2 100644 --- a/tests/test_hash.c +++ b/tests/test_hash.c @@ -62,11 +62,12 @@ static int do_sha256(void) { OQS_SHA2_sha256_inc_init(&state); // clone state - OQS_SHA2_sha256_ctx state2, state3, state4, state5; + OQS_SHA2_sha256_ctx state2, state3, state4, state5, state6; OQS_SHA2_sha256_inc_ctx_clone(&state2, &state); OQS_SHA2_sha256_inc_ctx_clone(&state3, &state); OQS_SHA2_sha256_inc_ctx_clone(&state4, &state); OQS_SHA2_sha256_inc_ctx_clone(&state5, &state); + OQS_SHA2_sha256_inc_ctx_clone(&state6, &state); // hash with first state if (msg_len > 64) { @@ -94,7 +95,7 @@ static int do_sha256(void) { return -3; } - // hash with increment API less than block size + // hash with increment 1 byte at a time size_t i = 0; for (i = 0; i < msg_len; i++) { OQS_SHA2_sha256_inc(&state3, &msg[i], 1); @@ -106,6 +107,15 @@ static int do_sha256(void) { return -4; } + // hash increment with the entire msg len + OQS_SHA2_sha256_inc(&state6, msg, msg_len); + OQS_SHA2_sha256_inc_finalize(output_inc, &state6, NULL, 0); + if (memcmp(output, output_inc, 32) != 0) { + fprintf(stderr, "ERROR: Incremental API with the entire msg.\n"); + free(msg); + return -3; + } + // hash with combination of block-size increments and non block-size increments [64 bytes] + [n < 64 bytes] if (msg_len > 64) { OQS_SHA2_sha256_inc_blocks(&state4, msg, 1); diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index dd75b8a916..55ba104d56 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -1001,6 +1001,7 @@ int main(int argc, char **argv) { const char *alg_name = argv[1]; const char *katfile = argv[2]; + if (!OQS_SIG_STFL_alg_is_enabled(alg_name)) { printf("Stateful signature algorithm %s not enabled!\n", alg_name); OQS_destroy(); From 982b44061b575ad573f81bb668325ef4dedb8014 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Tue, 19 Dec 2023 10:46:19 -0500 Subject: [PATCH 23/68] Fix Build Errors (#1635) * Fix build err when built with no thread * Enable KAT * Add Generated test * Fix typo * update formatting * Fix typo * Fix build issues * Fix undefined error * Fixed SA issue * Fixed warnings * Skip variant that exceeds timeout * Fix style format * Fix various build issues --- .CMake/alg_support.cmake | 20 +++ src/common/sha2/sha2_armv8.c | 32 ++--- src/oqsconfig.h.cmake | 13 ++ src/sig_stfl/lms/external/endian.c | 2 +- src/sig_stfl/lms/external/hss_alloc.c | 10 +- src/sig_stfl/lms/external/hss_aux.c | 2 +- src/sig_stfl/lms/external/hss_compute.c | 2 +- src/sig_stfl/lms/external/hss_generate.c | 2 +- src/sig_stfl/lms/external/hss_keygen.c | 2 +- src/sig_stfl/lms/external/hss_sign.c | 6 +- src/sig_stfl/lms/external/hss_sign_inc.c | 2 +- src/sig_stfl/lms/external/hss_verify.c | 16 +-- src/sig_stfl/lms/external/hss_verify_inc.c | 16 +-- src/sig_stfl/lms/external/lm_common.c | 2 +- src/sig_stfl/lms/external/lm_ots_verify.c | 2 +- src/sig_stfl/lms/external/lm_verify.c | 8 +- src/sig_stfl/lms/sig_stfl_lms.h | 136 +++++++++--------- tests/KATs/sig_stfl/kats.json | 16 +++ tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W1.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W2.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W8.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W1.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W2.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W4.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W8.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W1.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W2.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W4.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W8.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W1.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W2.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W4.rsp | 8 ++ tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8.rsp | 8 ++ tests/example_sig_stfl.c | 2 +- tests/test_sig_stfl.c | 121 ++++++++++------ 36 files changed, 374 insertions(+), 166 deletions(-) create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W1.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W2.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W8.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W1.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W2.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W4.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W8.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W1.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W2.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W4.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W8.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W1.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W2.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W4.rsp create mode 100644 tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8.rsp diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index 27ce29c1da..119ee52f3f 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -529,6 +529,26 @@ cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 "" ON "OQS_ENA option(OQS_ENABLE_SIG_STFL_LMS "Enable LMS algorithm family" ON) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h5_w1 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h5_w2 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h5_w4 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h10_w1 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h10_w2 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h15_w1 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h15_w2 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h15_w4 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w1 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w2 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w4 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h25_w1 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h25_w2 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h25_w4 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h25_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) diff --git a/src/common/sha2/sha2_armv8.c b/src/common/sha2/sha2_armv8.c index 71d2cebb59..9f5a96bd97 100644 --- a/src/common/sha2/sha2_armv8.c +++ b/src/common/sha2/sha2_armv8.c @@ -290,27 +290,27 @@ void oqs_sha2_sha256_inc_armv8(sha256ctx *state, const uint8_t *in, size_t len) incr = len; } - for (size_t i = 0; i < incr; ++i, state->data_len++, in_index++)) { - state->data[state->data_len] = in[in_index++)]; + for (size_t i = 0; i < incr; ++i, state->data_len++, in_index++) { + state->data[state->data_len] = in[in_index++]; } if (state->data_len < 64) { - break; - } + break; + } - /* - * Process a complete block now - */ - bytes = load_bigendian_64(state->ctx + 32) + 64; - crypto_hashblocks_sha256_armv8(state->ctx, state->data, 64); - store_bigendian_64(state->ctx + 32, bytes); + /* + * Process a complete block now + */ + bytes = load_bigendian_64(state->ctx + 32) + 64; + crypto_hashblocks_sha256_armv8(state->ctx, state->data, 64); + store_bigendian_64(state->ctx + 32, bytes); - /* - * update the remaining input - */ - len -= incr; - state->data_len = 0; -} + /* + * update the remaining input + */ + len -= incr; + state->data_len = 0; + } } void oqs_sha2_sha224_inc_blocks_armv8(sha224ctx *state, const uint8_t *in, size_t inblocks) { diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index c2de65c545..9fce48b769 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -222,5 +222,18 @@ #cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 1 #cmakedefine OQS_ENABLE_SIG_STFL_LMS 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w1 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w2 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w4 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w1 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w2 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h15_w1 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h15_w2 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h15_w4 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8 1 +#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h20_w1 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 1 diff --git a/src/sig_stfl/lms/external/endian.c b/src/sig_stfl/lms/external/endian.c index 709dc7bf98..0c3c55b0fe 100644 --- a/src/sig_stfl/lms/external/endian.c +++ b/src/sig_stfl/lms/external/endian.c @@ -4,7 +4,7 @@ void put_bigendian( void *target, unsigned long long value, size_t bytes ) { unsigned char *b = target; int i; - for (i = bytes-1; i >= 0; i--) { + for (i = (int)(bytes-1); i >= 0; i--) { b[i] = value & 0xff; value >>= 8; } diff --git a/src/sig_stfl/lms/external/hss_alloc.c b/src/sig_stfl/lms/external/hss_alloc.c index 8f7cf6054b..3907d8764b 100644 --- a/src/sig_stfl/lms/external/hss_alloc.c +++ b/src/sig_stfl/lms/external/hss_alloc.c @@ -167,7 +167,7 @@ struct hss_working_key *allocate_working_key( if (memory_target > LONG_MAX) { mem_target = LONG_MAX; } else { - mem_target = memory_target; + mem_target = (unsigned long)memory_target; } #if 0 signed long initial_mem_target = mem_target; /* DEBUG HACK */ @@ -178,7 +178,7 @@ signed long initial_mem_target = mem_target; /* DEBUG HACK */ info->error_code = hss_error_out_of_memory; return NULL; } - mem_target -= sizeof(*w) + MALLOC_OVERHEAD; + mem_target -= (unsigned long)sizeof(*w) + MALLOC_OVERHEAD; unsigned i; w->levels = levels; w->status = hss_error_key_uninitialized; /* Not usable until we see a */ @@ -220,13 +220,13 @@ signed long initial_mem_target = mem_target; /* DEBUG HACK */ info->error_code = hss_error_out_of_memory; return 0; } - mem_target -= w->signed_pk_len[i] + MALLOC_OVERHEAD; + mem_target -= (unsigned long)w->signed_pk_len[i] + MALLOC_OVERHEAD; } w->signature_len = signature_len; /* Also account for the overhead for the stack allocation (the memory */ /* used by the stack will be accounted as a part of the tree level size */ - mem_target -= MALLOC_OVERHEAD; + mem_target -= (unsigned long)MALLOC_OVERHEAD; /* * Plot out how many subtree sizes we have at each level. We start by @@ -305,7 +305,7 @@ signed long initial_mem_target = mem_target; /* DEBUG HACK */ level_height[i], hash_size[i], &subtree_levels[i], &stack_used ); - mem_target -= mem; + mem_target -= (unsigned long)mem; stack_usage += stack_used; } diff --git a/src/sig_stfl/lms/external/hss_aux.c b/src/sig_stfl/lms/external/hss_aux.c index 5817b76c81..0d8777386f 100644 --- a/src/sig_stfl/lms/external/hss_aux.c +++ b/src/sig_stfl/lms/external/hss_aux.c @@ -133,7 +133,7 @@ struct expanded_aux_data *hss_expand_aux_data( const unsigned char *aux_data, if (!aux_data || aux_data[AUX_DATA_MARKER] == NO_AUX_DATA) return 0; const unsigned char *orig_aux_data = aux_data; - unsigned long aux_level = get_bigendian( aux_data, 4 ); + unsigned long aux_level = (unsigned long)get_bigendian( aux_data, 4 ); aux_data += 4; aux_level &= 0x7ffffffffL; /* Turn off the 'used' marker */ diff --git a/src/sig_stfl/lms/external/hss_compute.c b/src/sig_stfl/lms/external/hss_compute.c index 353ec939fb..752a7e2868 100644 --- a/src/sig_stfl/lms/external/hss_compute.c +++ b/src/sig_stfl/lms/external/hss_compute.c @@ -51,7 +51,7 @@ static enum hss_error_code hss_compute_internal_node( unsigned char *dest, merkle_index_t q = r - tree_size; merkle_index_t i; - unsigned ots_len = lm_ots_get_public_key_len(lm_ots_type); + unsigned ots_len = (unsigned)lm_ots_get_public_key_len(lm_ots_type); unsigned char pub_key[ LEAF_MAX_LEN ]; memcpy( pub_key + LEAF_I, I, I_LEN ); SET_D( pub_key + LEAF_D, D_LEAF ); diff --git a/src/sig_stfl/lms/external/hss_generate.c b/src/sig_stfl/lms/external/hss_generate.c index b604ab3593..5d6880c267 100644 --- a/src/sig_stfl/lms/external/hss_generate.c +++ b/src/sig_stfl/lms/external/hss_generate.c @@ -695,7 +695,7 @@ bool hss_generate_working_key( if (ratio > 1000) { core_target = 1; } else { - core_target = core_target / ratio; + core_target = (unsigned)(core_target / ratio); if (core_target == 0) core_target = 1; } prev_cost = p_order->cost; diff --git a/src/sig_stfl/lms/external/hss_keygen.c b/src/sig_stfl/lms/external/hss_keygen.c index 743604f170..7a364b3f04 100644 --- a/src/sig_stfl/lms/external/hss_keygen.c +++ b/src/sig_stfl/lms/external/hss_keygen.c @@ -101,7 +101,7 @@ bool hss_generate_private_key( return false; } - unsigned len_ots_pub = lm_ots_get_public_key_len(lm_ots_type[0]); + unsigned len_ots_pub = (unsigned)lm_ots_get_public_key_len(lm_ots_type[0]); if (len_ots_pub == 0) { info->error_code = hss_error_bad_param_set; return false; diff --git a/src/sig_stfl/lms/external/hss_sign.c b/src/sig_stfl/lms/external/hss_sign.c index 359e59df7b..3ce7159fbf 100644 --- a/src/sig_stfl/lms/external/hss_sign.c +++ b/src/sig_stfl/lms/external/hss_sign.c @@ -41,7 +41,7 @@ static enum subtree_build_status subtree_add_next_node( /* Compute the leaf node */ merkle_index_t i; - unsigned ots_len = lm_ots_get_public_key_len(tree->lm_ots_type); + unsigned ots_len = (unsigned int)lm_ots_get_public_key_len(tree->lm_ots_type); unsigned char pub_key[ LEAF_MAX_LEN ]; const unsigned char *I = (next_tree ? tree->I_next : tree->I); memcpy( pub_key + LEAF_I, I, I_LEN ); @@ -253,7 +253,7 @@ bool hss_create_signed_public_key(unsigned char *signed_key, unsigned len_public_key = 8 + I_LEN + hash_size; /* Now, generate the signature */ - if (!generate_merkle_signature( signed_key, len_signature, + if (!(unsigned int)generate_merkle_signature( signed_key, len_signature, parent, w, public_key, len_public_key)) { return false; } @@ -303,7 +303,7 @@ static void do_gen_sig( const void *detail, struct thread_collection *col) { const unsigned char *message = d->message; size_t message_len = d->message_len; - if (!generate_merkle_signature(signature, signature_len, + if (!(unsigned int)generate_merkle_signature(signature, signature_len, w->tree[ levels-1 ], w, message, message_len)) { goto failed; } diff --git a/src/sig_stfl/lms/external/hss_sign_inc.c b/src/sig_stfl/lms/external/hss_sign_inc.c index e455b5cd2b..6890a4a621 100644 --- a/src/sig_stfl/lms/external/hss_sign_inc.c +++ b/src/sig_stfl/lms/external/hss_sign_inc.c @@ -159,7 +159,7 @@ bool hss_sign_finalize( int i; for (i=0; i working_key->tree[i]->max_index) { hss_zeroize( seed_buff, sizeof seed_buff ); return 0; diff --git a/src/sig_stfl/lms/external/hss_verify.c b/src/sig_stfl/lms/external/hss_verify.c index 089bdbd1ef..b7f0f8b489 100644 --- a/src/sig_stfl/lms/external/hss_verify.c +++ b/src/sig_stfl/lms/external/hss_verify.c @@ -68,17 +68,17 @@ bool hss_validate_signature( info->error_code = hss_error_bad_signature; return false; } - uint_fast32_t levels = get_bigendian( signature, 4 ) + 1; + uint_fast32_t levels = (uint_fast32_t)get_bigendian( signature, 4 ) + 1; /* +1 because what's in the signature is levels-1 */ signature += 4; signature_len -= 4; if (levels < MIN_HSS_LEVELS || levels > MAX_HSS_LEVELS || - levels != get_bigendian( public_key, 4 )) { + levels != (uint_fast32_t)get_bigendian( public_key, 4 )) { info->error_code = hss_error_bad_signature; return false; } /* Compare that to what the public key says */ - uint_fast32_t pub_levels = get_bigendian( public_key, 4 ); + uint_fast32_t pub_levels = (uint_fast32_t)get_bigendian( public_key, 4 ); if (levels != pub_levels) { /* Signature and public key don't agree */ info->error_code = hss_error_bad_signature; @@ -109,9 +109,9 @@ bool hss_validate_signature( */ /* Get the length of Signature A */ - param_set_t lm_type = get_bigendian( public_key, 4 ); - param_set_t lm_ots_type = get_bigendian( public_key+4, 4 ); - unsigned l_siglen = lm_get_signature_len(lm_type, lm_ots_type); + param_set_t lm_type = (param_set_t)get_bigendian( public_key, 4 ); + param_set_t lm_ots_type = (param_set_t)get_bigendian( public_key+4, 4 ); + unsigned l_siglen = (unsigned)lm_get_signature_len(lm_type, lm_ots_type); if (l_siglen == 0 || l_siglen > signature_len) { info->error_code = hss_error_bad_signature; goto failed; @@ -134,8 +134,8 @@ bool hss_validate_signature( * someone other than the valid signer modified it), then * Signature A will not validate, and so we'll catch that */ - lm_type = get_bigendian( signature, 4 ); - unsigned l_pubkeylen = lm_get_public_key_len(lm_type); + lm_type = (param_set_t)get_bigendian( signature, 4 ); + unsigned l_pubkeylen = (unsigned)lm_get_public_key_len(lm_type); if (l_pubkeylen == 0 || l_pubkeylen > signature_len) { info->error_code = hss_error_bad_signature; goto failed; diff --git a/src/sig_stfl/lms/external/hss_verify_inc.c b/src/sig_stfl/lms/external/hss_verify_inc.c index 451082f8de..bb8da66db1 100644 --- a/src/sig_stfl/lms/external/hss_verify_inc.c +++ b/src/sig_stfl/lms/external/hss_verify_inc.c @@ -44,15 +44,15 @@ bool hss_validate_signature_init( ctx->status = info->error_code = hss_error_bad_signature; return false; } - uint_fast32_t levels = get_bigendian( signature, 4 ) + 1; + uint_fast32_t levels = (uint_fast32_t)get_bigendian( signature, 4 ) + 1; /* +1 because what's in the signature is levels-1 */ signature += 4; signature_len -= 4; if (levels < MIN_HSS_LEVELS || levels > MAX_HSS_LEVELS || - levels != get_bigendian( public_key, 4 )) { + levels != (uint_fast32_t)get_bigendian( public_key, 4 )) { ctx->status = info->error_code = hss_error_bad_signature; return false; } - uint_fast32_t pub_levels = get_bigendian( public_key, 4 ); + uint_fast32_t pub_levels = (uint_fast32_t)get_bigendian( public_key, 4 ); if (levels != pub_levels) { /* Signature and public key don't agree */ ctx->status = info->error_code = hss_error_bad_signature; @@ -72,9 +72,9 @@ bool hss_validate_signature_init( /* as we go. Note that we don't validate the bottom level yet */ for (i=0; i signature_len) goto failed; const unsigned char *l_sig = signature; signature += l_siglen; signature_len -= l_siglen; @@ -82,7 +82,7 @@ bool hss_validate_signature_init( /* The next thing is the next level public key (which we need */ /* to validate) */ if (signature_len < 4) goto failed; - lm_type = get_bigendian( signature, 4 ); + lm_type = (param_set_t)get_bigendian( signature, 4 ); unsigned l_pubkeylen = lm_get_public_key_len(lm_type); if (l_pubkeylen == 0 || l_pubkeylen > signature_len) goto failed; const unsigned char *l_pubkey = signature; @@ -122,7 +122,7 @@ bool hss_validate_signature_init( memcpy( ctx->final_public_key, public_key, 8 + I_LEN + MAX_HASH ); /* Now, initialize the context */ - param_set_t ots_type = get_bigendian( public_key+4, 4 ); + param_set_t ots_type = (param_set_t)get_bigendian( public_key+4, 4 ); unsigned h, n; if (!lm_ots_look_up_parameter_set(ots_type, &h, &n, NULL, NULL, NULL)) { diff --git a/src/sig_stfl/lms/external/lm_common.c b/src/sig_stfl/lms/external/lm_common.c index e3eb56f0f0..5976f4b589 100644 --- a/src/sig_stfl/lms/external/lm_common.c +++ b/src/sig_stfl/lms/external/lm_common.c @@ -66,7 +66,7 @@ size_t lm_get_signature_len(param_set_t lm_type, if (!lm_look_up_parameter_set( lm_type, 0, &n, &height )) return 0; - int ots_sig_len = lm_ots_get_signature_len(lm_ots_type); + int ots_sig_len = (int)lm_ots_get_signature_len(lm_ots_type); if (ots_sig_len == 0) return 0; diff --git a/src/sig_stfl/lms/external/lm_ots_verify.c b/src/sig_stfl/lms/external/lm_ots_verify.c index 91576474b5..478f5ffe8d 100644 --- a/src/sig_stfl/lms/external/lm_ots_verify.c +++ b/src/sig_stfl/lms/external/lm_ots_verify.c @@ -38,7 +38,7 @@ bool lm_ots_validate_signature_compute( if (signature_len < 4) return false; /* Ha, ha, very funny... */ /* We don't trust the parameter set that's in the signature; verify it */ - param_set_t parameter_set = get_bigendian( signature, 4 ); + param_set_t parameter_set = (param_set_t)get_bigendian( signature, 4 ); if (parameter_set != expected_parameter_set) { return false; } diff --git a/src/sig_stfl/lms/external/lm_verify.c b/src/sig_stfl/lms/external/lm_verify.c index 46b3627885..3ec4cb6599 100644 --- a/src/sig_stfl/lms/external/lm_verify.c +++ b/src/sig_stfl/lms/external/lm_verify.c @@ -36,8 +36,8 @@ bool lm_validate_signature( const unsigned char *signature, size_t signature_len) { union hash_context ctx; - param_set_t lm_type = get_bigendian( public_key + LM_PUB_PARM_SET, 4 ); - param_set_t ots_type = get_bigendian( public_key + LM_PUB_OTS_PARM_SET, 4 ); + param_set_t lm_type = (param_set_t)get_bigendian( public_key + LM_PUB_PARM_SET, 4 ); + param_set_t ots_type = (param_set_t)get_bigendian( public_key + LM_PUB_OTS_PARM_SET, 4 ); unsigned h, n, height; if (!lm_look_up_parameter_set(lm_type, &h, &n, &height)) return false; @@ -47,7 +47,7 @@ bool lm_validate_signature( const unsigned char *I = public_key + LM_PUB_I; if (signature_len < 8) return false; - merkle_index_t count = get_bigendian( signature, 4 ); + merkle_index_t count = (param_set_t)get_bigendian( signature, 4 ); signature += 4; signature_len -= 4; /* 4 bytes, rather then 8 */ /* the OTS type is expected to be a part of the OTS signature, */ /* which lm_ots_validate_signature_compute will expect */ @@ -67,7 +67,7 @@ bool lm_validate_signature( /* Get the parameter set declared in the sigature; make sure it matches */ /* what we expect */ if (signature_len < 4) return false; - param_set_t parameter_set = get_bigendian( signature, 4 ); + param_set_t parameter_set = (param_set_t)get_bigendian( signature, 4 ); if (parameter_set != lm_type) return false; signature += 4; signature_len -= 4; diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h index 8380656eb0..b583782e64 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.h +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -94,29 +94,29 @@ #define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_signature 8688 #define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_sk 64 -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); #define OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_signature 4464 #define OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_sk 64 -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w2_new(void); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W2_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w2_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W2_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); #define OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_signature 2352 #define OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_sk 64 -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w4_new(void); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W4_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w4_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W4_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); #define OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_signature 1296 #define OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_sk 64 -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w8_new(void); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); //H10 @@ -128,29 +128,29 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_keypair(uint8_t *public_key #define OQS_SIG_STFL_alg_lms_sha256_h10_w1_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h10_w1_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W1_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w1_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W1_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w1_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_signature 4624 #define OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W2_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w2_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W2_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w2_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_signature 2512 #define OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_signature 1456 #define OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_new(void); //H15 // H15 W1 60 9008 64 @@ -161,29 +161,29 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h15_w1_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h15_w1_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W1_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w1_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W1_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w1_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_signature 4784 #define OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W2_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w2_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W2_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w2_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_signature 2672 #define OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W4_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w4_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W4_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w4_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_signature 1616 #define OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_new(void); //H20 // H20 W1 60 9168 64 @@ -194,29 +194,29 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h20_w1_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h20_w1_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W1_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w1_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W1_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w1_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_signature 4944 #define OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W2_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w2_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W2_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w2_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_signature 2832 #define OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W4_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w4_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W4_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w4_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_signature 1776 #define OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_new(void); //H25 // H25 W1 60 9328 64 @@ -227,32 +227,32 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h25_w1_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h25_w1_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W1_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w1_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W1_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w1_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_signature 5104 #define OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W2_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w2_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W2_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w2_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_signature 2992 #define OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W4_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w4_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W4_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w4_new(void); #define OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_signature 1936 #define OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_sk 64 -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *totaln, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *totaln, const OQS_SIG_STFL_SECRET_KEY *secret_key); void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk); @@ -280,56 +280,56 @@ void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk); #define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_length_signature 3604 OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W8_H5_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W8_H5_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_H5_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_H5_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_H5_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_H5_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W2_H10_W2_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W2_H10_W2_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_H10_W4_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_H10_W4_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_H10_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_H10_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H5_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H5_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H10_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H10_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H15_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H15_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H5_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H5_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H10_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H10_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H15_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H15_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_new(void); OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H20_W8_new(void); -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_new(void); +OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H20_W8_new(void); +OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_new(void); // ----------------------------------- WRAPPER FUNCTIONS ------------------------------------------------ int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uint32_t oid); diff --git a/tests/KATs/sig_stfl/kats.json b/tests/KATs/sig_stfl/kats.json index 592008ce84..59bda4d7e2 100644 --- a/tests/KATs/sig_stfl/kats.json +++ b/tests/KATs/sig_stfl/kats.json @@ -27,6 +27,22 @@ "XMSSMT-SHAKE_60/3_256" : "09d26df5e911e98e71ef73a1ab6f224964d4a7beacd8071b4c7f7d1930a537bd", "XMSSMT-SHAKE_60/6_256" : "0692a32e318d5c3ac8631120910b783edfed4cb7ed69e3ffa29f83aaa34e27d5", "XMSSMT-SHAKE_60/12_256" : "1a05ff4a4fea850a5fe5c9e976006577335eab0494e1759fe217c2f33f5a84e6", + "LMS_SHA256_H5_W1" : "6b5ffc953ee90b32ee4f1972de5bbb8f055073e831009fc3004e1ead32ecf64e", + "LMS_SHA256_H5_W2" : "68f4412a902595e6debe7da1af714ba3179e2ea21053d8fa25acc1bddad7232c", + "LMS_SHA256_H5_W4" : "01c828a559c5b91b3347c4a1ff5040a50371b7056b4248cba6b8d35080240e37", + "LMS_SHA256_H5_W8" : "f8bc9145732676a2017a3cd065cca68d224cef1671487e3cbd921bd9c772c745", + "LMS_SHA256_H10_W1" : "276a037406ce9f1df6a8ff87f6b892d45bd42af5724a2ebd3fdb1d64b3d94d5f", + "LMS_SHA256_H10_W2" : "c59da910cf06a8de9f0c5fd4b55895ce1996a55983f4c8d9be328c5d83831041", + "LMS_SHA256_H10_W4" : "2ae301108ed8c9eb363e423a483925dcfc089720cd5b9cf8eee62bd1869c8182", + "LMS_SHA256_H10_W8" : "3eac8278b3f9eaea6361ced30149d2d3136c153c6e45d59899af4322e5df7941", + "LMS_SHA256_H15_W1" : "a68af38d6c955fda6c6deabb6925a686ad768ffaa0f6a93d8649e5985dbc6be1", + "LMS_SHA256_H15_W2" : "3ce54ed403203c996c50bf50c69492acb7cadbb41521c2b7d49baed65fe2bda4", + "LMS_SHA256_H15_W4" : "38cce574c163e6a7167ae328dc6bdd44c60d4e9be08408eaa6c239d8625d5a07", + "LMS_SHA256_H15_W8" : "a2e16430224b3caeebd63397e9780be087efcf672421ffc5008f852af2597692", + "LMS_SHA256_H20_W1" : "b31f8b45eee9ec551178cb260cc431256ed7ddd233e69de1587579f0b8ff0128", + "LMS_SHA256_H20_W2" : "0d9ced22271ab0bf90968ec4934a4a44211ef25df11e562bc32767a42cd3a9b2", + "LMS_SHA256_H20_W4" : "7f52315a8fe04caee69874e87bc0f7f4ce38a250f95a0ed39baecc0cb55cad54", + "LMS_SHA256_H20_W8" : "1f5d5a149830ad72a9709659d5968997ffe4a43e034a5c72550032ce6dbb53c2", "LMS_SHA256_H5_W8_H5_W8": "fa6f9a0948626c1e078ad442ea2fccdf456b529413eba441c175cbb681f9bc32", "LMS_SHA256_H10_W4_H5_W8": "2485c56164bbfa4bdc8604195bf397bfe8f54e2ebe925423e4e70fce173c0fff" } \ No newline at end of file diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W1.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W1.rsp new file mode 100644 index 0000000000..206c2dd284 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W1.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H10_W1 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 000000000000000000000001c044f6230d8e90854489e823101a65fd2f0ef7ee9c0d49fcf5a354076f3aee868880df42fe232b55bde5016e05e454850883a80d3570cf9ecd0c960b9701fa0617c2e0b4a730c7e1fe228ac702e0f68c0ea9b3985e0704db86f1bf0305addfd7b7db7617bc50db44b28dec65d4727393a6362cbaac5d368ed18e0f4b06d77088d97fe31a2276fc39885891915bd7a738aa81c360177de403ec91338f2c3d6097c7afbf153370a416161c03a4977ae1eed6ad61eea2d0dcd081d2533499c213cef6585a0210e8f806a064f739e1d3e630ecd4e422fa3967895ddda5621b176e1e4b3f20c11f875e45d7ea0f765875376cece2acd7ade36c52f3511aeb23624fa0b3a4bb554cf8abfe8adf0e5129a821fe71b0420ed90ef0c670e68ee81897a3665aa40bdc6e86614b91e042854b71fb1372db99872bdfd7979e8552a2633e8d123150f06c6ec2316aae6bf64ac2a2db5349b7d08a7b9a97152193747a69081fd3b57cd666cd28555e531bb870483a0144cc13075dafae36993b1aa3fb7ddc6dbf095a7c2142ecfcab40830a293ea6303b5666518692f468bdf82c0e802624621c5cbad8056aebf836506ecbd4992ced3e8c8e5ba2633591f3b0ab3f0fd61ee396a7fea0f0661d8271d56796a48cc88bb555c74c2b500d512622149b13a49550597cf1b17e140cfb3738ec36a386f1d9aa92caf1e75e7c9c819419a69e1711e4fd461dd1e00059e8172f0c5f8550c0a95b1eaf9f2796df7bbd8d0e08ab1a240a6049678f481a0097e3fd05359c78dd6fa3d9d53bba7fa3083f041820561703c5a5f071f3b3d33024657840d72156daa207a8c6308af5bf0b50e476292d95d6786092622c109d9fd388dd8f9f2bdfc31a95bedf6deead4760a6e76b363932246c8437294566da6f372dd61b1a0d957f7393c7b3dc43d26c4b413380d1a3e9fcb70c8c2028932b913fdd0e81b360b76b27662cc1e8119db1d00e35999196918fdc1763aca80c861bf8563cff7f62fd5c4713a5a44e9f6fe9ca3855183e1aaa120d72d27bac94aaf7f2216c9b1287c05e60da13799ebc3f8fd2ed9cd873707d0f093a1a57e169d88dbee305c7e08cbefa8bcf2e643dda0f464b7450e57cab132101e0da4612941c50f809c2a592e6c15f791cfa91d4dee9aacd064a4e1a147a52ad353710f15db8159e283ae8399620b58401373fc093d91303a9bda436a23390023897bf3747c55a103c18a4f40dea1029b2ae1c6404d0387a7c5c7f1202ba8cd49c451d9bcabd23489ab3a5e82cef30712c95d02bb804ab01993c9e765474cfc9cdf9b7b68d6e6228f1481e73ca03138ff76d92d37dcb5ba9047b9ca8cddc7427b1d01f33114a2262df1ce69711920fe7ac428b2a92f0df08f3059be97e404b34d1ad3c04a837d76b3ad7966335568247f386bd5fa9de5cbafe53000ee3559eb6c06a3a3c85fa8ecd68e2ab30cc02db71aa9cfaaeae95dde704b353945198f75874dc746b3c169bf2edd15cb24f7414a070643b882a39720804e8f845dcfcd4254fb717d0748a9c9186eeae81b8066533b1dfed213886fb579e660bb2b9660b6878b02b514bc9ae3026a161b23bd3f1e0ad57bad5a4861e8930c20731e6dba31a6de742820384611cd2ff2e392a37402ff7016ee68d2ea04e00f7eed62a5c1fff05c2e32326b37f19ab7b36b57f43ac4ed784ade45dc2a7b69c5b93fadf362920e23bc000b2700c8b3fa81f43149d2a1300638af7c780813c11bc9eec1cfb3e719a02eec19c0205581d371f2d4892e1725f286ea62fb92bcf002b4ff2cd03c4ce8de4bba8cab2b3d060ec504f51de9858e4ebd87700192d06062fc19b75709215d080e04f2d1bf1330336c70d21d996f5597c971e6a91aaef92fb712908d1dd6338be54fe6b433752e92f4d841844f63bb42fe25eba83978664ceb75229b9406acca437b627b262b4f73d2e6221695f8f8e23cfde9c4933b6d22705536eb66f9a6bb8892c5fd47b014bfd81bdba6bd53e2cc5c8e4af2a275735fb974d675ec1abf6a4b46ccbd7eb9853252055143d054dc22114fd12a74ea3672952f6796dbfee528e744ae8808fb94f44aa289465805bac2446e1e2652bef7a411d12f8f28bece67c3d71723aa4c345e91077230e93eefcd19933b2ad7ce6f2a4e716b22201509a797531856920a3ad3d0b256eef648414b1ce56193994035de4f755927324300b0187571683905acae0ed98a6c9cc5487aeb006a4e8b20077ec6749ed8e8d6c1ba74746f47580d6fd834ff19076a1a53d4f627d83c8eeb54383071eecd277531a1f17b078a57875464d069f7de6ba87ebed03b6133b70807989aa1d887e875a0dd6caa1fb7577ac7db6196040473c5116c19ad0f78add6041d3790b8b124fb87d3290e14ed4437a040b557f6a57bbe35df9ab0b593998ea6002a7d33ea0053bf07ac82842d8bccf0f8f6366e0a496e4470825c00d5f88c4726f4e6bffe39aaa127d868b71ede4fa178501888a985241ead8d21145d0e78200ffab22b38708220a6313b507e3282dd575f070868790efaf886dfb4d18144488fb992d8e8e9983151310ddcac4a6a10af0708a10b9e74f46c972a852d1352538849d53f23887bff6ad1d56cec8ee77097b50184f27efd6ff5643bd8f9a7438bfb00937a13a6a65ea4cf70c2287a80c2de433878a504433fd2244c59d8f65e907a15ffefe7b7ba487e1d39749aa3503dcddf071c6e904d98b070c2c226da31fc17c649dc494263009abdbcd2bfce0c96d2e53ab169cee718c4809b3e1f49d43d60369b79af9c0dac15799576c58163b513db329729fd391a4ee5adc3df2f6cffd927187c2714f2f0ef52796550d71c93982e1406b37221cdde3da3675638f5c9ea2c4fab3ffc03519616a09138be036a33ab7f3b025608b3cbc263d44729a02d3af7f7aa587ad2661067cb88d3aac03f3efb3f3eb7da876ed42a7b8292406a965bc3da2fe2f5d815183e291b0a667e442ff907127e48a6e7aa70ce6b893720eb4fe104935fbda3ce1ddc4f0c2cc8ba6ab0e66d1850ecb32ed50f3767763593e8223304ff768ced4e03816526b6d3958477fe2ff57f77a2a1c80745a3737883196aa7aeb090655626a3d3682c9aab46fa0090cb09c398dc14be9a16a52281df2a875a2e7690923a8d63be691e6c519ae41cc550c8618af002ad5b826badc763762046e4ebcc474b3618b56fe2deed72425252390c20fda469d4ea19ba8746aaf06b10e7dc822c0ef872ec1b85e39c3b2944d1680964c11f5eee844bb6b9d97952e29b946c9c71fa0f7c94dbb6cac5b701d03690b5ffa669089118af04e42e5a12ab0b7199bcdfa41933a7de4de50239ab0f82ba223fea923c2ac4bb37534aeeb0abe8883cb458a8388fb94e0e1c7cae58689d297d8ef2bfb356993f761754ac1ffa5670b69a43e61362a3e71f99d0f1d95ab0789d8a831efa30a388d3b3f191237026a541f556b44d67d131c29a9329634bdf7deef48ddfb1636b9094ddee01261e135c7fc782faccf9489de8ca1b2790af3d8b77ab92a9dd992139a6fc0f369e2031bb9df07ad67bbb7ed9366f214ff9efb115c9510b219afbc7decf1de3c0e471adf5897189745dabd7525c760bc49739f1a45ef64f126de0dde44e95a44801a617191e960b72a6a3d362e84b7f8c0a852fae3191a8be19e4fdef968586b20dc51b78029722d7f44eeac63e50a3e19f9b49e2a47495d708e59091e78f57e4e17cb8cd37971aa83ead384da8fab871aa3a90a506fb7ef2cf316b626bf0e34a4f6718af6df12dc38ea7b382cc5bb5fe15ee5c5fa54a54824e31faaed6ced9364cd7e0692d76979d95b0ca7c1e912c9a6a6e882e2df0e143562b17e33c81a5d7e5c0a44cced6bc961d11fe6d7a7ceae323f8e136842982ee764f9b7622dcc43639bbbd55207165aa6525415af15813260e9b7735fc68ebcc7cd8346cd8fb661aec511e5a17d11892a5c8cf84d3cacc9971edf88f979be7f891aff54de818486d03f51581e10e12bbb8ac43587d0b0e87aa0c1302346ae31aaacb290968a56b88b7e06c99591b5e096f638f540d6627a0ec9c0be8a71426c7581baac231b8cbbbd8b1d4a8e6332782aba68c61c274fd39b2c04fed27ff8c6afffdc285f652fcc3e4f81fe2667f04f0aaa043162ab7fc0fa2e5dace3ee139bd7a2a7c4137b786e8e631d39313ffe4d6359be064b97f87a43ea52b59830a791399b60e567e3ab072ccbc85ee731cb0e3eec8eb588dd38b9128b948f9faafd1afbcd1c22808746306085763bb36cdac3ebf03c78c73522e7f9b048450afcf26aa4e6ba5c0b9d67a4f23a1737206e5a455fccaf939616dffb2a37bc4f0f8b07d50b6f165013fb8b19b7fdbe5fc963bf4ca5eed1cac12dc25f0bdbd7dfd155d92d7a67f5996684558c2391f7491e01777c8b870de45587195883ef84879185646833b305ff883b67700a2bdbad3cecc2c72c29f31afe69ea90d62b07d77985c6b66c98536abee2fb469beca6231a7b18e9e2f15d2b5cb1413ac0cac4306fab163abbc7825882f4469c819eb34e090980a7855289858967d68bce082629d1a284e128bc05d8aa3b20d3bc1cae265a279cdcabd582b3fb52afbd72f57402289946f9abe07b2e4a6e4be45996d7555eaa95c9964254f8a97f0d4f8dec47b451ad63b79b463c6ba27e81775edf8eda9d6109ee75534c7eca0bf0922cfa1764cae631535daa56d9db9af3ff7ca7294b6c8b94c416970bb5465dac9b437810ed393724d8f4b9aee0dfdb76c80634c512182ca3a61041f3a9ebd9b0ed13fe80ec347c60efffdf259f39c87cb87a107ae7b66f847fb30d62ac3fb3c4e364cce8a2d1c1b68da478e3cb18966510e3133f47be63f2247d95acef4959506ed21c4ee3a4dc2a6775feb0c317d6c96c58975901fd22a3cff32618b01d027ec5548ee82e7c6cad1401ec0de200d4ffa816a5c54ac344173a22145883c657d6b10bdcc522e9ddeb13d8c7cec932ef28dff74703f4a74fc75f75290227d11efd2909721b3f70a01db8b5a87c9e0bc63b30b2de13de8c0e25a91b6bd047148060f03783e6626252c8b278217d10df42db3b0fd1f7313270c141fadd1217972f3f78ee16607d3bb726dbe289355e1e277338bc60feedcff08f900d289db8a1e1670cae7a5ad5e4fd30aa367fc74854ba9dfb4084aec45bfdeba68ae85e9bf938b55b2db19d7d8b6f875bb2c74c2613edc3394d0e5bf3e71d01c2ee71d983083867efa32cae1c5cefa3089ea96500fe21f19920c8e182034fd3c009f9e48b6e49f6e691743c4066b478f73853f04485df6f3dfed6f307820c293ea8a7adf48a14e081b228136a74a51d59c14edd09decbe2903c4da0436e54b83626b678e75e91ac2e75e4180d6e1807110ba68576e59f80115926a352e8bc2d69e99b12f79537bf1264408fea3f0b6851d82557228291a39cbbe590f66b530fb022a7a3322b6a507fdb48f128c465ab1f98fee8ea442d957d14e3d060eed76cfa6f0d1cd1de93ec216bd5fcd9889afb0ca02c9ffc52fb92d76675dd30a4d2c2f937b7dad5044731a269b80c73f52db035474b6bb7f2124f50793a85818c0a1778ccae570002c695dc47641791eb89d7aab7370644fa9ec2f69c5349570cb0bfc9af395ec61589313121ae1a111028e0797845902fef6f2c2caf061d56674543b455acbf078378af10083adb7b29f9c347605c5d39287a5c94d6d512be0bb131ce06df64f2a5bf6e072b8d374afcc7a1eddfdb1d4ff98f0e2e015867e623f124a821d38c553ff4b899ea2e99fdba5b88ad921eb3c9a5bf42bd534972dac661eca5deb47c47bfe4af8bcf042d9f111613b11cace3332438cf10ad67b0e8c12faa1e60b460057cb36a719bef0fe9fd6dd672b30ccd61ae5d559e83b62bcae72db42da2b95217a7249fa8bc6878b9fc7f59c2988a27e1706bc84b47600ea42a45c3830752f00e33fa3318b2cdab84d44c9b7156bac88247dfaa5b3b7734aef4e12ffe77fcf399ef3916725ccd1214647339bee28b78c7bdd490ae7e8aa68e50f610ce12687e0c2faf91a2a84492067e17a7878a70d08f1f66c14aa556a2b9898273d4b7fbe5166baa52e9fee4daf24c9bdca63d543da430cb15318b5aadb721153dc6f3756c2f26d22780026e0e340246a5892787d6caf45dc3417d27c093d974edc3de8eaa34ae760081076389a050fd3b78f2e2c8c75250443f526361999f23d1a803c72246142e0203cba42c9fa4791623f7ffdb0fc9ae339ae92bcc66fda3e7d343ac701422dcdf4c89a2f2044d44093d225addaae2c3848a9e55c1643abb64e1222a33edfe62d44a3c146b48ff57c54408be6ccf605c5f4d97a1a4932d5bbdcebed5c6f8edcc35415c3be2cbd09166c03b5796417938ec7102943a9174ef3c377db5eba123b79830bf9aa9d6ba7094dd691400c1849fd987dfb94da5bc76537bd38504f7625d53f7adc60517e0b6420ab8d407293c1aaacafb9a73ce02436648c1343a24210a26fed2f6c73afada4d38da06231bbb8b7ccc1a9c045bba93f46abca2b691a0fbba1223274a9ce0e3221e4c606934ecbcfd5b1e6ff4bdb6c1fe1cdbc1b1a9fd3a4588a685ca786ab503767ba620d878f84d7b5338f0d9b6b07043453f53505e9d7e26f85ad8001aabdf661e92c06a8fac95590527aaffaa9502e689dceceee7322e63bbdd6dedf6c022c4d2fbe4cb68cab932a213a7dbb78e1c3d2dd8b147244faf11333f857311d3fc060816bd08b9bced8fd5c44ca9b4ec37355762caae31c0d3ed6b54ea06b46f6bec414e8ce70cf5e5ee2ba4d6e61aa7bf61d8fdc790d3f7e8d83df50000c9a3b627b5a79a974bc49ca887d5c81c4908d8a7b483f1cc8984bedcc346096ad8114722d23fedd319dcc95d3cda9f8a4af2d888751bbbd7138ab8d2d7dbc3a1505ac7675a7abd99c46f1d33a1b5e743be3cf002e7116eccd515cce11a46e198fd532bc0efb696fe871371c422486f5b0469a82869333a57df8a917b15f91960411743166c93ccd551bc48a779812a66550f4c4e395747ae09d35b28c466e5e61dc9f30ac2124a745bd3607b74021064bca34fe7fc99b5993ca0c35f8c7c751d35de70c25b2ca1e8e72e91841b9d9d436e115791ceb4a8e5ebf8bc232dfd3703975f0e5f50de5bc684232fff7a3a9da09cdb17c719e004d3354d90356bbe97624df21295cb372ad491b92d5b3487ccc27d4b65f0452a944d1f1e46a95c2d2195162f7fc76de43524104b6493dce02a8158a07504b37edab79c6cdfd4c849ff31d1b62e62516e7b306a8de7edf39ca6065cedced468e04a99585acc782bfa5e82372eaf284e5af5e9e5711d1188afeb3f5f4daaaeda0f018a6f69bb0eb5b9e759b846884889122a3cb2619788a7abcaa15a9a6296924cdb9e83df9761c0fbdc993a5d93a01f46d165d6bc9ba409ba6f16e4948849e9f03b3e14404df153f3fe4f10bc67bfd188897f0adef44428508733f11f49f10497e78f6070917d5b93c425ea628ac5c9fcce0f782132d74cb0347d90b3aabe395be584f497023984fccebc79d6634390080042567c4828ec7176ba8da4e05aa15d0e3c68f07caf5e373b8187c33de7387adb464d5e90378aaa5223d1360961f315c53c8cf6313c9fd48645f21c3fa7c3c1a685b93de4453bc09fc3b0ebdf6d52cc521818f1ba0c2e88fcb07a1a3f4e8cd33b9f0eb6fa811100169c6d4cbfb068bb22c618edb5c3d2cae01810151ebc960254284477ee68cf13c2e96f7aa5fb2666019d8abba36cfe9687658c378003e4e0d43d3771a850274d63d05686277ba10fe9fc134530f671344f77d5b9195fabaf5559399896222aecfe8d8bc4b1013429716ac93e676cb4a6326a0a7be15e917627ef9bfdef640579adc8e7aadd16f5c3352806ba9d380c65f927e1bab8fa0c1077490875890bf814256147ad951c5fe2d07f895946aae7ee5a24374255455d5aabf6104be3e3f4a4b36dc466a68486f1ae586e4db46da74dd3e195207c0f1fe34066871e9d7b28513d6b31f4f17a4a8a7a2e81b93c9c760c2a93ef24fc1d0321b64dd65845d1acf2d4dcc2fc3917935c59334d0e3268af83ccd350162d8e8930f04dd31c26bf2ba9d17168ba0f77451771bdcce1ab6205f2a8cf4df2f583a2ff43a049baf2beddd7d82e3239f8cbcfd50538656ffac80253e419a25b93bc931de0a24c9a37444a56a62d00ceb02664ab597719082f78ad463bf6d999f8c2e3cd0340dd1a5fa44c78196af816230ba3559c1c3bedae23a913b3d5b65a77e2a8bc6b39ef371cb82500e0124cc8179d26f8d9b21d82b1b81b323f42ff02584d16b020ff0319cd886a2b2492b4ed1c27b3f5b51ff759650bbb17643a18cdcd9f56b5e3e40c6762e20b147e55d56ee9773743db41a296fcc40b326d3e17062ebcc9720171cd8872001a9e5ee6135d1b9cd16e538ff8ba2a2d8ec3f931cd971b4757f4c92f840b0d985fac936ae6ab492b09ceb63ac80b13d5d9c5fc4508dc0cedb5bca1e2398dbb90c371696d93ec80a8cf2b6b9e5ee1a73b031da2709b4a6987af3bdf44fe2800502d10622884c562540d20c2c823eb92677d3accda6408b9ac3167adf889472c93405ffc37e2acfd8e2495725eef98b1b2c066af0e11a287e0313e63f79262e22921265614dac795912ac60ce6b626d5c2ad79420f136a9db58d2536d3525ebe30a00a88e81a787700ed2a077f6b4c1b6019115283c1d8a3a27dd4349fe0e77cb4b864c680dcc96410e00f5c1a09e6aace2ed201a8a0140c3156bd9d3ef2b08312cd22f04c2c7d08d7a298b7819d5f3a30877ad88b35aa5efd00cd7b5f01f0a5b491a6a1c7032fd19ce2e8a6e04693bd7d9481ccd22b57a0b8c749d975ecfc07e9c5205ecf4fa993ba866f5ae6eb45ad4518e3c94644fa5911141acc37ac2bf123ca70e627e604656c3615d38971e571019793e535a9ddc756dace6e1ba5a5d0135b7347d85d29adf6cbf17c6177346e4904353d5c8b44b2a0dedf4a039a9d945370697deeae5a850db0e8be9a003ad36ed3fb675ef5f6e386da850d3223549b1b6305159bcef54b3ddc39ada9d74d97ba4e7cd78d326c39eb9a9d5caaec9ac7ab7cd30181a9410a98b15a69c168c78b9b03d723f57b8be73b3698f7fceb5ccd92cb495a547ff2706805d97819a6f43d3423917f877dae750ebde6f81fe200b59c6dbc8565ccc5c96c55125e851783f3b60502df961e971fba37fbc592c05222bc1185763a5864479471ee97f05b1a953af6faca1f7669cda1f1bd7a4ca35d286cf1c699e4f74177f1a9feb71708c0404fcab769fe49fc0ec8ec2a8e310b69913f07ee69ece421379e0acd2381c7bdf9d877d847419181a9f27500b1750ee6f714beec530ce962829bdb9f1d1d6ff5ed7e28533abc4d3f31ca467627e34a89bfad4a50ce5b7c7409432c31319d98a0f986d4992a7709a949349b2caca79eb0fbb6c481f6e4b2cbf4eb89581694814ec968514915e92be777900564f99efb85d872bcf740cdd8f90b4c983f8677e43fd30f622ca502680f9f85e707c74f94e18e3fd9fa935f662004dd4af3d7e8cadc5bdd119806e2f630fea565dabdd51907035c8c8c4e5d94e37fe5efdab61ce8e459f5dea5a8582e3104741db18933907ca05c3fc93688fd75f60b4464a46a44356e78e8dcc8704eebc2c8c12b89ae7f3d64a9028cfb9b6284833695f565f8d6db30a2e597683c17e0529f653d6d90f290489cdd84b1b5f01a130c85b6ccdeb3ef3ff7ef8d8a8c2627aabab2b43e6cc957eb8165d6debcccb225f4d8d49ded27d1b5f9afbacc317fc289b951c22f390b91746c06d11e4c133318e24a62067873ca1147ac0f7b8b572ff4287fabd48d587f976d2b5eae6eef4d2acb924281891fc95304d5f99b3d0adfb3badf173b7ed56b3dc85fef93f917dfa4a45ce34ea61661e772e480c5bab1c09a07e3d4f5713f47f4a97f476a8188413479e6c0320db6b9a7ea2a05e130bb79eaf350b60d1d8936b29835d5fa873f70ed264dbfdc8172706ce713d7b52815bc458ca41f114b0897ee65dd59351db4fc4a069b344a1b95c53df6763f0e498958cbd3499c26fd8856cdfce17e8f8ced0f50a9afd62bbc2b1955bdc2c25b0a806f69e237cc2609182ce2d0916fe200027e038cb6d8e704b34ae7eb5b6408b42bed2f0ff03e3fd0e42b510cf1b0f9ff73c57120edf67f8742d75f5d7b8576049ce9ea5bb2cd8f3ad06e57b3155ef85f7539102c94bcc6fdd0a9faca161315c77906c5dcd6e0278498ceb2807fee87a6cfd387dea4605ff778449a000dfb7d79cfc194bb70e3e9f0a9c63faceeceebd47faff72f42493a18ede63f2cd06fd217d5772479d362055e27837157c047c5ef0a77bf5884ea78c9c618b571ac7dc2c24a81eab1a5d0c027ad5e1f9944d8200160c1a37ea44524fee0dadeca457cd259ac8766732acb7608ded63195a125221fb3d90b16f19cfef20953632dee7af848c75276e95ea9d34449e17465c91f2dc289c724d5179b7d2f83008d994e911a5d739c989dbf63d05dcefbb5a851045ae969787c167c8098bf14e473cd13848ce7ca4e16a440e0ec3dfae770d15201a41cf90b87d0e87ae78c0176b274a3b2c3fd9cb12e7eb4765dda7ed7eea3639b0cd11c862d7e2c65c1c6b0d1606595e9359bd6f94e20b12cdcb039cca934ee01f7f957c343cec9547592b180f6720cf2454b8fc526522c8c3071445d6ca95b47289862021855d9a2b38dd9d39a8fd633db4761a17969f941db403a7c0e260f0c8de4a1e45751aff151e33612dbefaad6809217023844e12f6a8b90be585c948c12a571b30ff0a69aa5bdb4c3c9b5018b77c57980c07dfbcf7667ebd7030406d3110d5406718b8e95d5d035a86dcf2c78fe575ac316d7c44407aa6c68087008433eada0e7bbf670b718830db42f668d203519d294ceb910edd4abeadc3af44cee24e0cbe6c436f3a523e60d0627129e9ea4ce01c5c45e0377c1655e8ed4b8f79ae0b8bef8a914f6326a0477d9f17e59ea6096d6a5ba75d64a94e68c8ce11e8f28eb80d07efac85c64a6c3c493516c7d929859307b33dda16c271cb21f4400f3156337ba02143f38f677b89b7907342fc16cc14bcf00ac312e0a0f9af6e0be926f345f556693d730e667f7f25098277efa691ef155fd65b8289c1e92d67dadb608902cbd4b567198cc776168a2c7543e58041a3f09989994a7aff610f9b35fe7aae6a8d43b676778dd7a8dc97475ace615e09e101de1a8f5f95ba082f296715aebb3d4ccd5f8d000ff8e3dd452a79f4b9ba75b7ec71545bad1c2ac91898d4564db141e42290a37390e0f4058274ffaed8ecba88a976761d716096babf3909bd37b873f1cd98cfbc3fed8978928c69211365519d30dc68598addf3f5ea2d0de53c4650d9b183834bd89b2fd55e1ae9ec2123e0fb66b8abb36b6ba62da3cc205f24edd14d68d355133de0aa26dae7c5d7b8b60bdbe4b6daa43aeeeeef410234d6b179557a39186022394615629430f783c8fc1efcfb23df92267cb81bdd20bce73f2e825d31c52d99d27b77a4cfe821d5f9b4d77c403e0640b0d53e04bba350228aac6a36fc7ec513cae4b832fb7de3b1938fc9aa35efe1df21ac41905fa9141cbe5719c3c3b73bc5b3d1a49d4c7e8e8f31f653634d8494b18c439e1f65751ecef9d95911370ec9c6ee74f632990aeb6ae3d04a429308177b6a7703b471a5335e2d356534c92768cf92e168e07d971a7abf08ab722622215982c97eccdf381f95c490f3596fd03c8465cdba4f9512767855dcc5a082f947e8f308f584d0971469fdf742dbdde2dbe79e97420f9f61076fc0dab44902f324f644ab22dac6374cc20f01e787da093ac0025e737fb2fd795cdd4f1da73018da1b992fab997189ea359c2cefa0465963c6505d0830ccc13c010295a61f69875e13dbf596a5e4320a648f07a9ef5d29c92babdf2757ebac1113dd761b2f5fa1fae5365aaea3ca3d0c3ae1de09f78ba8ece95e200000006a3761dc5d71c1cd0c210c04f7d6a2e64411150e168d7a5e83d532feee580087a78cd5fc4e68e3c9a2b34f4f5bf46a6773102f940d108e236c1830219c1ef88b8fd4846cc3f5f980b5aec0fc2a29d4408ad375735ce8803c9fad7b38c9e98dfe1dfeea1a3e57316f52addc5b501d133bcd1ca2e6a855f1705b6e946b2ee206446e1d400c943f425fc82ebaa069233b625195ab5bfbf9692d9607200c7442e33afc6cba48d00dfae2198d3c8a9d13f8b87774e41640ab9d7c2c66b778eb122e9b5298c717b3b4c58a2748ed811aa75154724454d8672a7cf49c0f9521993031e7cdb863bae7bfdd3d4d91ce8f61ffed3f8951b810594152fee76a4dd1c998f52b071f56a1e40a0b2963fb7ecf2a71952249fd9dd8ff29029d30a381dc6e1818224b2234904a8e50aa4e9df193b12c9d8a6f32b6c43c233889597e57abab57dcfaf + +pk = 00000001000000060000000116dc020cfd4abfd4d0423565aba4d66f585c5f38861af8c7c2626cc33b043c12db72c2210f1578c00a1e6d087eb37c8e + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W2.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W2.rsp new file mode 100644 index 0000000000..4a8296a3b8 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W2.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H10_W2 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 000000000000000000000002fbe373f21f0131199ae1967db9e8c8e5e91b55b41c1a30b1074b4aae40788dcb1fe11bc5b99ce8c08bb612b75649e5e7966836669e5b4fafad1766c736e99d66c47d7cdfdb318def37933fecbdd392174e6bf3d476122609c175052b0b03e8ea63aa156096b3b23472ba6f1252285802ad7272a4174c69b255cc64583b543e13668beb8581ca27a10023757560b6f5273a56d5c2dd4adf9ede64a7eab5cdc189a64d91bd7ca4e2d3ea559981ad535e2425911b9d8ab94cb81416326d851aa8d81ddae453fc4cb231a58cf405c0ddeb06f5c67e611a411add275d9567d3f625cfa26384586c435609da22f62ee8f14af17ef86c10f72d2e15fc00d6563e113ff96347e550bda84502167c62a9520d7c7bceb772866f422e8410d62418f7508e2192f7cf28d6192e93bae26533bec0139ebf6869464ed0f62a2b5d10bcbfc78923747fac8f0102dce0f60252b1160406849180a70befa6f56d11daf1ea4a02d4f85e3e653c7eb3b6db7a705d499e51ed477c305d92ccec35198f2bec53133c147ecd694689a5b636f935c0fa08407298328207df0f38a3ebf7dde9985cb71a1129442e03eb414881d63be98361c244a4cc92cad855521da2345eb24b52963f55aa7c7fb13b11b06d6acf8c2108a9090e35e75b10b177351f196002198c7b3e7126df03d1e625aba220bcef06c885a041ef5f33340d2104509595140b64b8f0222474141d0371995fd6461764e87f3d94f6e1a7bf06e350cfa5982de3bcb4c2eee90e884be8c78bf1ecd60d466fb01a33431536dc9106e989f9af03517c78e89f855727c8590567e91193ec3e646f3f7bc99dd55cb889c4751e9209198b55f27e82a14d55bb62324bb1e65a4ec65244c90b755d729bc13cd81f15aace49b1de09ad58f052258db141a8051990edf33c38cab95978dea6b507191251f09f22c9c53300883928c5ad361039751088eadea38ba65b9abff4ca94ec4f5cf5e64189bf9630c7019a48701288a9d01ad1cadba3a6df888e3bbd91d28685f02aac6fe1ce4fd79ddc577dd08b3b3909877694f1482bf0e1011a5953a035f6c78d94d5f18260108205badeb37e6f6bed44f3a7c8fb72e7258c9c23c4ed8463959463f60e2cb71dbb51d0c78be4f817fbc6f1c0287af42b9c889081da7c4ad849dd1ef36b41561322585aa7c12b0affecdb282298b2e3f1dba120a450919631ec0542e1d4923351818be85ddb0d9af8a86b40750ddd65308bed9fd789c6bb127f5e0dd7e5b7954be351411c16985e651e9117bf620e57761ee1e08bd79ff50ecb09a7b9b8e27802c991930472712a6475367bbf60de34e586ad178093245f47dfd068600267945783c61d3afcb030ba3a10d349daec3bd62832260561b621e9638f9123948880bc448e4503822afb4765aa8829a4a41501abe11bacb790793e2baf52306be0fda5f2ad39ccf950ea5101c99fd3f360f6c9310ddf112109106c33ec95a56bf18e6675e365eb50913b08e5e0ed6a8a4eb51e62f2999b50c4e7f933d325bea4e27c629c91fc41cdd0831a9d1173ad4dfeda232668acd172595c9a22164db2e21b15119b45742615cfab51ae7ae500d0617f8a47e3cd38e7e216a3307ad7f6bd675b44db9fff1c6dc7334558a122708045d03dd082fcac0ff210181435bd77d5b3da9a95eec42721c264823bbf73cb747c00101e654f7308e00d35ec90af819cd83e1695dca689625daf70a46b0f1a6849b75020216f5cdfd7638eca97e798a11efcae371b79779d96b68b3bee2da785b1b7be96202428de97877e08b38b634453aedf262d063d057e2a088bf52da274ea8a85085492724e99bb939cb2f2ae8e32aeb6e457f5e25a0f32844518d1333497f015a95e77066748731b92ea75855eb4a091279f775292045e6759259b31411d301ea0b3aeb797e9057bf66ea26ecf3f2c5fdfba8e59bb571eb27870251c830dbbde7992c5900a638034c4fddc2f32c10d680043ae528046f0f9418b19a423ec2b1ef1c9cf2f8823897a25582e4874244560797ab6883b47f31df1929b37938d81d71934fb2a3642587428dc3b050aac515b5c0d5b51e671f4ba3ab4f1f4e50cb854e0a8df162672c61d009a1ce84536eaf81644f790f582072bdc68902c1e100bcd21a4d349b24d860b9ac73b0ffd83af5c371a2d7c164912a9a7e397ca69704cbf831b07d702520628869f89549e641331ca8137f5ba478f08f3323807313fe5ae54898a2dd0f9c8a76fdb9920e5a9077bb9b4a0825889244c59e9cfd81cb1c219ef6649cfb0ca0ae7548f11e109ad2ef4f1083f23c6fa57fdbfdf4fa6544f7422eae4c8d0c3b6dc9d3566eff5568698fb4f65155a17b6ee202c4478dccfc3563ad3736856f750860c38ef414eb57bf007423f67d47f4a2b72372089e1c906b0cb3f495ce37180049a7b1839cfbb4e1c943e54cc026829322fda4a13d7cacc2466e1b3a74c6095fac5c37393616621e8885182c992ebc040cdb2d3cd17dff9d7f761a793c8a7272adb4a6f3b6a945a6476590f3f0c5291b7d367e896824d51e0c9a8cac943ab86a4dad31b13299e5c05375b4a69e1cd1a5c1f0db8221cc1e64a7f2d940a1c3ab2884b121ed8a02f379cafb47ecd0d07df41df903486f88b1564be398a3694817e6d00b6a9d704259bcf368c36b612ff131b136f620af09bf9757cddc741d04a48fecf8944f848f8f84d16f8475d726538e600b9666904fe8154e641fc79377455dfeeec84297e5220a0c8bae196e1b4f7afa7c513dac1c27d9e55d5cd942737685134ad28156e295c89e8377fc2eefb1b6f78002e9207fe4e6b490e03621e15cd8db3379d78bee769fa505f0939ae07e24e0a29612acc2f2b5fc9c7797b111096b1120ebf2e9e44bec5f7fd9bfb20e8d39aa922d0c781c2c79ecdb3cd97c5476d7d22648c718b088e24ad01759dbd5e38d81cbf5007649807e737509b8f89da5f9ad3471d136b50685504e1a2b8b9167d91020a4c8648dbfe1af14074e9ef4ccb66e34304d41f35b1fc9672dc4430fbaa1c654643bd7fc5012df2ac7818dbb0b739986ea1a8360e710a69a2b3acaf683c62320b1c5184a6ed97af06413244bc73a0dcaa3a023bf8ef4048083df122d4f8616ffb648116fb959f044277c9ff7ccc634d1d64955fc9dea925e2c87a1c5244b47e06f3a7350b7269f37adc5b4b6d13fc8bcde6c0b1a895077780074a66563ac9871976167c3b8cb588a2c3646d22605d74b429b39ed28f90c358e37d05ebc8ea55012e14e3140ef33037169baa700df3a26b81b65276058c0c7da75d555ae9930edae33610dc005e12b5ca33b4fc0bdd827b6732ef531c5fd12974a0d6346a05fce10e5bfd39501ab27752a7f1d93e8c1ad30df412a654096d5ddf91ca7cde9fdb93a4c594eebd12438c0a9caba13a7f054bab27d0d3710bffb80fc9d27da1c80cc1adc1f1f74d39f1b87c55b4b8401fee6f03be85cadaa9f0599db12371abbec87f401c4247199b2448165fc309e8f03530cfa94a929f61cd90caa6a715f75e9f8f8eeb3c889f4368bc2d04bea1babe2d6681c85a7c3767e11da601e346a63363694aa5c9bbae69b33246d383d17a964bc3cd92a9e866158d8ece3359c119ad05a6bae1b76797a20381683bfa209acd00c8e9395eda6c309368d7e11e8b1bcb8197b0e5ab033dc76044a22a96a15b1b5d329d692b67a6365aeb6f41c0628a436f5aacdf400aad71f1ba89aee43c442d17c172bf7fae4f26d755152fad7e4b9a3c76ed365d6e6c3852584cdf7ffd3784d5473f75e126d5678dff50f0b3add401019d00c3d843bb7dbff67c6a80ef95a257dc46dd80a900b731b768c88e1550a4705a07a9acad0dee22ea92ef4fbccad11d805ce0b74d42f009e0e1db5808f230488d7ca36f9f41648a69ec6e9f82bff6fccf1a029c1b4133c8eede4cea8faec69ec3368acfeac3f503b0b8b39d8cfb4ba0cb558a9dfcb26bfa88071585f06d51c45f5dc69a898a422cfc93a28bfbb351c8bfd820d2af034d6b8873701396fe37d80691fbef22c81d2b59e2528900401fd52c92a01168bbfb0f38accf304432fdee1059aa76071635abbe552a297915a6b0e32617f945fc2a17c00312e771ba75b92471309d0868ee4be35feb6122cf644e3625e0f2b45622e096d23303c50d26dbc75134658bbd2cbcec849a969a6e32da2198dd6bbebd859dbd9559b5263b68a6236acaf67c1a24ffcf0396f7d6cb0a67f7d147f6636b111ffeacc86a5200c8fee40d03f2ab4cffb3ab8d0347621b1c812afba8b50099c06d3f39222708218c4481b1b03dc2afd0f528aabc5bd917d2da2c6f9be60b84c07e86c84cc2cb54041254013f60523948aa48ff6936d19f6658b6ebb043df00a3f67e1f5769145d5b2c9fbfcfad4718f2555dae7345ec3460a2d006410619c0ababf3af5fd24ae0c6f0a6afba83b467ebcad8f4bf975d12cd5fd3c4aa81eafdf65b7cbeb0a40c23e2a9646b459369681b9390436096b0363d96bb941669e247d541e6bfd082614bb880c922e56afb2e061b5836852530ed2d56fabfe3cd88d035561574215999a1a309dd8696a63452f44c73c17675316137ca4eb59638f83c5e751642164e7b3e8d6cb6b55e2da2bb413d16c5bb46ba7bb887bd42ef2c7e7172d744f96ee8a6e42caf7e1a608aa353ad9bf541820c1bb37895ff2b7a3bf60b261c28c36ce1f08a979b51c2ebabd3870c1ecc05256344c21f72367f0d10eacdd169d074dc48418c7e996ec9bee750dbed649202a2c6f30cdec8eab58c4b42aca7cf52e4e3c49674f8e64512dc429156830438794a3f3d787926d1c1e1c321becc09ef7958b2af3a3be4dfcdfb1fbf725e7d3712a875e2fd665a2077a60c2dfc818d9dd11a31d4f237c21d65f07f16c894401df1cac95f5f8086156e39bf7cb2e9a5bb17c775d6b76dcff9ecfb81f511041ac6bdc97719842333ee30c11484b4045f0111d56f40c913686c812bd7700896d77996ee2caea8b5429d8b4bb469b516ea65aea4675e4a8a15017a56da3242e11322fe9ed0112fd521af63aeed89769c51b2db665776a75e8e6049c548fa59c83b59df8fbb3e1042b56debe1639d66750fc2ccb8ab379fea3ec1730ac865d8f93df792f2f6eeb1ab52660942457a83077cf1cde57150806b12fcdb2491afd1f9350579cb8c094dff941b0b72867b4b7abe3e522930460cb4459401bd9183d504b19cc23b8d0b25ba8253568a8991cdfd0502c964c8ca9b76da74e2fc343afd1c1d2ac0ebd9e5f582b527de90b2ef53435a4ab5106f6fc724e3eaa7c24cc2de651e784221e0a698f22a1cb64362c3ced006a7031ec875ea4ecde9e901d6f094db57e53b617876ef3f5eca499dd6a43cd0da463a1c74d89e071d9ed265fcf3cd691f4de004d82ccfa54889c9885d1de8a5f0cd1adaac04cfd586963760c36e59882b5619707a31220c7ef13ba47fb5c4efd887e6aa417f4bbabe089a385f1115e1189976854b53e4d6a45db155689ef525287b5f853bb71d065243e696441564980f94b2d33d8976993904e9f5ab06d6807def08e6a37a6c554aca37698225d8eb0345899e1a6d06ae26c6e50c791338097081eb58ee2b019f295a482272f24047d429fee6e8b783498db27684d5d591a66a63f3ca4f9649b73abd1bc4ec55b928ede769e54f08aa8160a1ad68b41a12ab7d7585088c61db423d41e1693edefa536606722aece9f8552e7ec0ed4dcd2b322794d808acf0911490ba37db7dbe9a1bb6c0a93db328d71457acc4ea6585a1323b613265b50b13a5ed68376cea8cfbdd4d44ceba37edf4941d3e8dec0d1acb6b93ff3fb965710c36b8d7417bf0cc32519c1f0dae8320914faccbadf2f572dba4027e3746a685c8ddffd7f3667f7495223378f0c73aca0db3999f51ab4e46f8e3c27b033de2475d73e758f1409ac8be14a788f552bf3116ecd76948e8cecd03ed9f057064387939f471c03ad1769b63d300ca960c7130a279c92d1a1aac12d9d021f045fdbcc91bd81b1dd970311d9427121b8f2bdfae35bc08b31cae8f95e92c000000069001b4ba886086ca8ae0e5b1d7b99491d7a5f93012a9a8fe4b8b38f49bd6ef107a0679dffea4a8993d4eb8dbc65ddf29f7df08ef81aa69c396230d5372a659391db0a224dffcc1a3b11b8cd29a29542687ed6f23741cde1d38d4620024ed4c6d3ba55af8762dcd8b31774c61a2eb5ddf60e0d06cb3557d13b44b675409306e639b41850b005ad91ace703d12e2532881289e340274ec561b21efce4b68e8f5bcc3b6a261cce940316dce317f0facb914822afb9050378c9f9f35f95991e1266f9d95d9680464bd717ed6dd0b54a06e39a57813ff9dde406d418f2cc925a7c2f1ad134818ed84d0475bbf35d761fc3ed4905a08779d52002835bc5702b54df36957a49173b48261407ee35c3c8eadb59a407b38d9c83c0dc2e959c89d380998486fa5a2cf960ea54f743ef0e3c1851b0297e1bb2e0292ee3b47956d598fe202cf + +pk = 000000010000000600000002f669d58a91971ac07f6a5944eb3559d47589156c855b69b744ce85da0ff511a6a353f52748de5549c1c7c6cd4236564d + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4.rsp new file mode 100644 index 0000000000..ed69d34822 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H10_W4 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 000000000000000100000003584a33ceb2d50a9af04409357774dbaf8b8ea517370e62c4dc06882c1407baca174157ebbde27d8e255d5c522c78617f3cfa03b811e32593ca965f771f8d88fb3059a272c3b9af8e445b37650f3616b9a06d2a79e74e847dceddcb6f854fbae8e6790d241e5e496a66244ae738bca8482630b5369e2c45e27c7ed919fa298c1d5ca5efdde0a12b258a584c9f44799b5c40f3889b1e8f3c274a355e24c088bcdb5288a47bf40a4677062662f4feef135493ea4498640c8efca349dbedbf5525af5425a8aabbfb671de5f71072eb07867e15c383a06f39ca2a09ae0d53c4db18370011d4ab6842a35c3bab93e642bee89310ac457e68869f4289f9e93ba553e39892b2969578ca5a02ae8a0272f1b2d6c8a022dac6a397d84bd2ea56136ea45aaccc1122aca34bd4ba6a7a06b2cfede81ce193ff878368f9f2181b8116185558cee1cac048f61109ae5c7b3973241919d9974f8b44dde66f1a8b2830abebf3ba1a115f4563453fe20f7ac023f6a02544d24b38e661a25a68ccb44c287f28d3fb0769048eee6d8f41046423d77e56344f7d5771f8ebacda4a4b5069f0c4746a74e77aa8b5615257b2dbac9863937e6d9c905217341a825c0460dce7a13845db6449d1e1f86d42731df8eb6f4381d71dff4defc11fa5d6bc9a0309a47e298dcf55e559c750f3c5d0fc1a1fedc8c8c0248a7babf6390fbcf70ad7b51259b336a2a39e1306968abb7f39a94a36374910ffa96a436a225436f7753eb7a28198750c3b5deffa1092eeec7857244b4a4d13d1eec3adf0efcce3ea75507f376a6c7effcd9e904ef2bd7b3c8c092066d46955c7ca38ed79ca8a7ffb1617d1619026c8fcb3cdc23c7403cc3f90e3c3d88123b20d40e8763c0aeccaadf79c41a69667cdbdfb73b33642f1d1e3b021cf2400e6252526d3fe62edc9d022e88ef111b6b5b668d2b20e23baccd9746668fb63f3916630506d0b696d850dcc60eec42504398f4d25e2eb6f36a417bd71c20c780f1a5075f86e953302ef0b7a6a9b909857d0ee6fd4c1ade224cf667067d9df328433b19e136bed536e364f82ac05705439967560c8606cd1c26b7146b82e825a233dca703ce03ab7df5c5345b5285be16d542a47a1fb4af74e786cbfd01c0456b8f86fd0e685137617224ff627b5f3dfbb75c9258484d9347ad6282e170c2657f5721e24d5643a4705d6f9aa335294278421da783d44ac38cfc7676740a399f9002ecac9a78b41c70c3188298dca26452b72a8d582d167c3c965d5f5c8c8f57022f417b0941f7828721951978d568a3d2ee0b7a843e5c697b0c7fc0975f0f09fd18856a16fc63db04e0f3ce3a357e4d3208546460814c270629d7810e452454927f29666a919fc8fb104f3c9c1fd38c19c6574d4dddb5c18683a8973cd061faf5f5c18b66734bf8c08766612897d0d9025e380c6317d88791d0861484e51f205c14e0bd83d2d61c394df3645eb0d66c80ded707429fe5e1fa77f3c3389ac59b353ca657e6aa88dcf6498479e76bbba01e75e9d992e6d3181eccd53e122c0c3ed428d809eef91934ee657364151bf711f0c922b6490fa2a9ea9ef02a9fad3a655cd305a2ccff01f60b9ca0b3e8381cd83960c08c066a30a9f46585e7ba143da7700216cb5234406301beb66a0cecd7d8122429992f8eab74cebaa1e7c8ce4d54587056bdad8636c46326e484c63b5aef8b6560e289acc20b953e8bac254da2f22751d83845be6132c6595cbf91b0d2ff7402fd789c92249af031afc1076bc99b9e9cd6e42a1a2dcf8baa42a0c34dc343508e70bb0760e5f9d8ec6390995bbca810dff3a0474c59cf9fafd9d09bf190bbafe003c7576960a6dcfa0226f874a084b4a50d6a680f88f1f3f352c71eb26df521e5ac9c2c6cc410c51ecbfcd090d7c09541810c80cafa5710c849ed324ee734a8ec0610a1a0ccda429f86b28ca0d0cfdc7d29ec03ea1b97021dbb00a7837d5ec8f6e6ae198ae31c9b4365aec42e83e92e879fb641915ca129324176444171873a75b3df1322cc74796b5e6cac0f950d92c322a8a3c6c0a824f8f92ae30aa110c8a415687ce6dae5135b4121b67fe4e5bff65fda4e0cde3372a0937488d22211c92192eebb9c0b38770356fc65533a86efb75a759fcb02c62aff2f61d3af079ce09d6b01ec9d6fd3fa6f5e2f60273f4b9c3de7bed546311557c197dd2c5398853a5b768db5d45b64d2860137c1c1e9bf3bbaf8f44cda1ba1c88798bf91c962195a11d1d43b937801243ad3483d951ce3c250de463aa136273c9fb9404ea92a204ad15a161852182d271e6dccce0c1385eb8a192d063b0a018cfa36d8357d89f1257aef5be8be3f26051dcd238e4977324204029f2d70a4dd2a9e9cdef1831c7163276bcfff2f2530f29dff5dac9a7026f3ebf9ee0449465a61db572b18434dcbd30fb0843ed81560473f8529191b25abb086d5ee06022b10a64b3a1ff18aeeccf277c4b33c9ecf4097bd5097e6bd0a30ad4d52cf5db089d15f4627a44e0689781a6c6a8ce08d744123f6364b1e7428aea701b20985f2ef76cdb3023297c894c7f14892a3e891f396a3edc2507892034a142556e78deba31ee286f0e2752eea28a0322789fecdeec35306d87105ca2c19f977597bdce1de1f8cc1f00c45ab2ecc7dd6f2d8e8e7f625be39a2348e77688819ed541d2c12ed74688d201fa307d958ebc4b8ce08a6b0e9a3116b89a038807e587bceb9cc98cb91d69f884c67e88e30c7c8d72b208dca96f6af60a73c4444d5e7f5b472fd2ca3b36cfa2b4bcb767acea4d8085b080e57f76ccc0dce2c2943b6c806ce20c88300bed34a383e5bbcdfad496910b9198bd43364da92d1fec89b90b53ba54ac634d5ac1f7faf0385358b6b0b5f5d06e31df6d3b17eb9181cfa131897dacbde42ae3c66010b978ea391944db2b52e52e47ff7312b1600e569b46859bfb6af8c4402ccaa3632eb293ced20d61552c75f0068b5a0a7d71f276367f0061f01e7fe71985ecd70fea79d406217f42260791f554b1a1b943e5312ee65251ac228d78c90f517949f6460dd3664f09b092f483d6ef2c00000006ecf1ce60192137cb466675f2310292d462477d811c672cb1890ffff4979ded0aa791c87c602307be68e7e3ed69e59b7c22458d9d49f353679f1f89cba91cd886900b1eb3666e5f0e78dec37a110c5cf09c1571f66e5862d48f6f4dc01812fb600ab2b3ddb1c5585cb2127e4a5e5faf00636beeeafb3b18f2481de5a4dbb9182e93a5cad39c43bab87f66eefd1428d0a426e0ee8c41fab4baf40bb982b9b5f1ce9eb65ad914744b45a4f00c11dc8fb012844cde05816d91fd387be9a2087c3758634e4ae3658a035e9b9e2d50a98ecb21489779c538aac7fde32b293e4f809494a800bb16c5ad2e8d4f22d61fadd2cf82bcc9ac210bada1a203f90f67b115cca1f9c109cc955776335779e6d9153a9880c91c9af9eac9e88b7a5e5bceb3bba9ec9432fe015b672ce4c04cc49ec42b865038b7166de32c1f745c27ee919bc25d0a + +pk = 0000000100000006000000031fc1a45b518c620d9ecff3b054dc2104f35f80dffa2515819e569eaf3594081dd7029a581ae1e818b181368d1cabd76e + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W8.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W8.rsp new file mode 100644 index 0000000000..500754baef --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W8.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H10_W8 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 000000000000000000000004e8005f5e66764d13c1a66c4b0919b51b818e23767f813cd64ce8f961e189ad2287a30c45cb69478d54db906e55516483dc65862e24ef059bafa11845aba072ee4302a1e4c22243cd893f12b053529942bf1d3c97de2c317a317c9d2fe5dd7e3cdab428bcb8935db5f3efbd2757261b50431c9ef1cf49256a37355bbc2931ff7478acce22a47dcf7c0662d7b21a8727b0d1ae54473d2c761cdfddefcf10f050821345b78d6a1fb6399a0233d8cb0062792bd3e944951a9d1bc85922fd5bad206242800aa6070d1968d1738f2837039f1d8023543302c075ae3b7e490b4e49b1c2f52f7604f94d455d49c08695f4536d027374838fb11e1c32de758434c1b95aff54b3a949c2249eade7486bbd5a600060d1d925da6cf66ec882558813bc3c35c7b461b013f847c3fcde510affdbb548f0cb16d4151341ecbf521090d6d94062d4c06316a0c932a260cc3a93fe75a6e56e642238902fe1d064b43390e71c95ab901dffaa506aa89fb5e4620fd9b71718a8e4516b791c0ca899addd197172f26fecfb6905ef031679b85fc32b98bebf54c172d294d749e041d4b8e11dcca56c70a181c55d1fac4acc936efa857eca994ef6b4bdbea24881ca38607babb2bfa9635d824119d87c78aa919b9ed71d4708f044222f5c80590638981ed8b46a099c5162982665ed2c1bbe1a6f1a91ebb2c07dd5d577713bac16964eb5bbc763b7600c08a13e02bfa253caac622d038961fac0d45f3e3ffa998d13f80f78f454ec7593bcf47214584f4f32dd02350a0175f646c7a80685f2d5d2bfa3ec8f09bf45869d077a6fd43b777c95bf8f848445709acaac75e82fb479a578a16ae5724084b3bab6d8bb5006d246545dabe8a27bc7419f2cbb71beaf7d30d2213d053e3d75d3e785d7d76347b45f0ae31e1d4138da2836b401424213e08863e87760d3cee7caee7e5c9d576ddd3cd0a827960c2697751b855fdfbb1ae63a87317fcabcbe251a305340172bbf0d907ca57d4d01fc10abdd4d7191fcd9400cac13ab3c949f2ff0b1559cf6336f2cac59b97c45faa702b1212b341490bb0905b0598b8d76d95cec3ee6fc37d4096b625c84c2ce3a4bfd1e541661eb57bd4ca0a5d1a55578d0018bf0183cc2684fe61d8376ed35fc6c9715e03d20c3c103f29f8eb4d19bfbfe71a81cd587ec0a2302789bdc9b6741fa811e0b7dd4e66abf7287fa282d039f9c98cba1e46594ba3d2fd2b994794c7afc627f3dbb29900f42aeb0d7aad125634fc281e9c37047a1c7aa7cf9d78c3100e3d1395df86e785970f3e107bf12ffcf7ee3fa8c1169192c61dd9f3bebdc08d4290e36e8b135d6596b70c91c281b766b0ff8ecc82d2355f33d1077d7f0a5bfd05e19210b78408175b1e7c9330a8f4ab4ceeee202b3667694277169bd0403db497b57d9974a3c1ee438a0339908736e1f97ccb1ea3f324682f0786e218c59751f8231ab20d9bf2648e06e32018f3822d66a2d180fe5203484401e5471b925cf05aa64f287571b0645d05c438f61c14660c316dce2d8aaf22a64430f69d7c3bb14721ce16569863b7e65dbb6192b581751a903fa2de500000006979941fe2a0034185d9aeb8f6eb51ef6767f2e0218f9f1a20c604fb41592503e1efd6c941c7e3056ad0b47b3afc6954a6354791967c9274a43f835fc370099fe0d26a4850bd75228166c06d23d16cb07326be16f454269d1648fa58b6ce4738a8fb926d2a61b5aa66c4a3d4417b0ab7ba7fec2f7bcc1d1d179b7d7a90bc316975c81d903b29345a3ccb9309534aeeb6647dc5662a5a64e9b2c622bd394339b9963ac9e6c3479a5d6180400620115b6b09af77ad82c7a39e278ced784702d1ca621705827bce972d17fe501ad892d4de6f94e748cc7ebaf600ef73037d41a4719cb7a96ef86d89b0eb0e7da8668c85e52407b2b14c232ae6df56bed6d1ab6d7e5bd2448f15e0acdb7792f62cdc3e7ff1db99db034524e0e2b77749ef0b624dc6e2937e289954069c33fe4d0328672caceb377112bbdaa844bdef5bfdedc1950aa + +pk = 000000010000000600000004d1436ef5c39f769b4c9b61659c603f4a29be7b4a06700654e65fcce588dab0b2478e6b0bfb4e74880afac2a1a2d2fb66 + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W1.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W1.rsp new file mode 100644 index 0000000000..138da7ff33 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W1.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H15_W1 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 0000000000000000000000017d1442b03e3d2c279b85ed284445fa421587601ebc1015f9b49ea82e29ae7fa09c61209ca5af037ba2779cd5e9ae813a491892562b8f737a6334445e63c739bd3ee3725b06f7b9a26316a6997f143db039f38134e35669d9dddf12e75dbcfc9cd0641d9281215a820882047fec3d52854c3285eb61b25c9b5db59d0fb4f38acf5a3bb2a14fa03e2e03a4df7570cdd167cbdddfa44973bcd3ebcf3501aa80a748b70fac5ae3735bbf1a8937d6b8621d837cf7c5edb65ffd08e830cd17bd6753cdc98df5a09fbbed909e812c50f80f71315e2ec337ea1ccd0f203c9932e889056e19144c0b17144bdcd0c50bb51e8f39ef8ba2d787fcf9536e55e59be8b5b5f55f15cb186678c41210466eb6843957f69f85fc0e1e789ac26c2a0744b076c971bd364cb121c87e2e08491734e51f9be2a3698373473761bdf54529fc40e2cfa865442f320e3045ca046ad2646f6a2e2e91f054a9c4ad449bdf7a35ac9b29e6b8385d342b49c15fb0077aa4a41c0d67dbbff3329c7f3a32f183b47affb5292af90082c6446999b1316c46f79716ff2c4a5a8d510977af1e86bae7cd578f43f4e8a85d8ab33541431499cfbbe66473f1d7653a3882ead0dae56f7e010fd17987361d5c48a2835f25ec9c70b7671dc53c950c27e4ebcce2b6d5b8332792afdf1a4ae1501af44799f9337edaf1933ad5b679b8291be1589190ace128670e5b3bc230925b78ae34a175c5d1dd7856812011da166d5d8ffaf33f60bf82223fa88bc25696fc21033c7ef5c47f6b0ae0ef47e2119b58882a379ff38b89cd6895cf84770abc68bdaf5309bb070a194f29f3aef69ad6731a741710951fbed65e82d259a73efd6cef99d642695651e1b0ca4dcbe39ae8fdb6ec4b1c44d9386125cac42335da4ca99610d0924473da7d1a85dd527999d363062bba6c919272cc529062120705fe39b11cf43003c851056cb858649da4a0b8eb53c056467163de4d3da8bfd370879c834f78553ad0921d5dde65855d47380121316e8e774adc1576ad529be5c7e465b77dc36e2b28cd88ea44574a8998e477911073fe4ead79e6ca304783ee4817cf1442d311ff17d949ad643f2abc4d71ee5332a62ce8be26623304e68ce1743acb9a25eac59d5ec657673278c28252a3dac364a232730eac4c0d03ea39ac7e954f1b551d8dfd5d429f944a357148f9ab5e74d05d4e2e3dc96c1f5d086e2e313e4ff986cae049445589de4be46e2360e311ddf0592f1c74224aecbf2dbfc72e8c9111fde1f64b7028702e8653f2f6a7823629e174b01c44bc33907709fd0e3673c5d087d730017ef2e61544ebe71ef69d23e0292afe1a7ebb41326cf530d1076b3cc863426d204c8e8b548640e62e1bb236a5d22f61bd1c769d70bace9e813f4ad7fcfa90167fe4c4c78648512185496e942331f0bf35f6bed5be20f9f7d77ca900871055eb9e84fd6c95e7e7bc72c0a92fac0c788841329921423e152c95efadbf31721a36194370bcb0d77738f3b1a4963056d220bc399276e7a0fdd3a1953bde9e2983fc2b045a5c6d5cec1bd6d8251184b93c7bbe06f2606a913f602bb7e2aa42264b25d8eb7d4aa9ec8bb6e90841e52e93b005539d3aa42e953c00a89289fbb75baecd04ba4fc13cb0e17989257cedaae0e52aaff6b06db21d4ab5fd45db385a1e978b91fe6c4aa9473ff6687a80b1f96bfb822f1314a2e097804602c81a1655b71ed74efbe23696e51310edf39b58091d791fd62d17432392e79cfc0c70b9da67f621bcc7fa93b9ee56d340450022f2b3ce5f01f3325c4a7851d7e64646241b394a65486829a794b82593d0579bf4a2203e673fcdc87411de87e157a1fabd7b137da30d632953460d76d48f461180c86cf77392265193906453ec36401340770fcd33a4a278d5c82059a089eb45fa784f5f5dca852f6cbf0ddfad9b8210d472be700e66efb8dc4fa66233a524daf2631be8e39f25119f6388c3d03ff75980d390c99392777ee8dbcc29ed93e9481dc4901d4d26ca5abbbc45a066b5318736967083f3abd97aa8ececf19822b22b3372a76095d5581c7e7a852438f937837cb7a9812234e93af88c465b201aedce324c2af3d7f75adad90e01b67e3e3fae8d8ea18b45506c00cb130312e3805ec4c38e4bc5264f4cee3ec1d1450752b4fb6c6466e3281527385c41e134945b80ba041a8b903a8e08124c9a3fe29bd9722cbd20f1f5f9a0b9cc67a118a504c89d4eceb7bdc87195930b1fa2c29c31abee9a0877f64dc02290871f204629b88a857bf2dc01ff1eeb80af9f44fe70d6f441edf54f72e8d96b0dcecdf7f2961aed57eadf36e40da8142f082cb118534fa7294cea8d741c8450075957f094eb170b6508cb504ee685dcc890d591f460a89c0c3cc08c4010d748c1b7bf32dabe1116dc0781bfded8d98c1c579d4b4f522c273f20255300e7e0b39123a1ba87f9dd4c8a6d435f6d6b4ad1c9580c7aaf5d0c5b4b4ecc1c201fb3fae9b76d14a6f64c1cdb101688909a4207176eeeeeaaa3f2abef9202d051b8042866b09db501adc7f6dd6ce283451f2b247ce89b1c177caf840865ab5cdb619928e92ac4a315eca917a52ab0af747c45c9d4f3977b96b84bf5b46e323ca4a0031ce21fb80021148b84218a420a9430bd23fca1bed37e84cec725b87d7b8e2a7a47d3d016cc434965ae6f6d106f46c8c4565fc467d8dfd24aed77db85834995f9f21c38f405c16d3212220415b3d0b5f97729ed438254a7aad03c8c555364b80885fe75f003b1cac833a4fa1cc3ec7af43e328e5498499836b830b310e46ddaa447c6e8db7d3eb0ee5523ccb52d05d84a4a51288bf73edaaac052fcf5130083937cac1d09e98a70f6f2610789476a30f8b9206448b448c36dd6874f9e5418ad11b7d790276140287f849b441409d2c7bb7b037bd15b5d52fc0190a02562734ac0349d5482b494c05321f0c484e5adc20d9b9d175491dbb05e7220996710d641449207d8d408e3bf4e5dab294381d72766a31038e02d08b007e30f21b79c655ca313a7fe1b893763f2b923dcaa23658d5cad13cd7818e3fab3ef2752b638bb6b5162578a74aa388628ff35e487d7754c4b7b18414973914fe4f075c63e81a7ffd474febf313edf64eff44d542afc40d5d90b7618b6577108523528d1d603535511f890e426da5cdc150d4c50b047a7159d48b7abfffe824cb176a8a6e5cf613bcce956a012b83b7d2b916f0b2db5d2e68b8255b6b3dd930fd8cd8eebc3fc0665865835dc0db816ef635275ec5f463b8edb99bec830746ec86bcf87cfc7cf3d6ce98528181d9f4c75bfdae6981e539ee06b97d48e1807eb4cbca3847debc05ca002b2f726018475de66e9ffc92adc1280774faf20162f9270fc6179ebca7ef612fef2dd253d637f51cf8c76fd1c831e4449091ff3aee820e8a545bfcf9a7c16d080c73aee97384618f24793cd6c37293c2c23d13ad0d7d03c38992215be779e73b6cb979908b2290d051297cc2591b5d7894da71f6c2dc255c9f01eb548c05b5fc5cfb4f9bdb6c007a03b173ec25970fe6b841754bbc529ca32486654556eb20a311f94983c77e118642d5de4d6eb2f4fc95f8b37c90a9825c56a2295e5dd166c9d0a1e3f94023738ae46fd4c99ba60c06d8d42cac8568e7547500a12d02c64a2d73bf075caa8218cab2ae30b0d2d45cc7c69fc44d21dc2cf17453eca38048e58f18980bb5c4c608f1e8f4c264f0683ae0229b8283c93a48eb1182857474a484f473b69aab94ab76ec62f9de834012c91f237d0fec778996482e04c58858bca4dc60573ab69628bb6b73e0fc51bdb3fdc684ebd00006210cce6ab04914001661c8d5b36260a0645053431ca8c29494efceafb20019ab9351225a20a513a8b2321f2c5a6e3c54424b4e9485e504701146812c051cd42fa482ac1c00ee2b227b978d7b0465114636cf1bc04c39840efdd33d033ff4067e850126acaa8b60005f61d69ad38613d3446bcb5e421371104c584711512f65d9131dc08a39291b910482438c6d459353d12d0d7ce4a06c3ac24facf80cf6d1b89b743467140a7d05a36b2eb970d38d914970b65eb6b6dec1b52f1e973b99d4a170bf31ca7908f4a4fb3cb62bc64aaf557b9e4c1511b0daed60f88bdf7aaa4f9b9a849758a6237467144b2aa2b0f24b16590bc151340235133827024fa8cb4e291fac6daa96e18afd121e076c12617d64a34139b1470fe7f7defe9653a6e416fec220656bbd1cf83adca819b7b415085bb746af4b0ff3ce65b5f8252f30ab100b46bff20c047ef76079e0061ac365a2a54d1020928c31d778e19676512d4bc359630b165534b7b6b50197d5146979336f33e9289a120dee4450a0a60394eb2e32a4b2a770a40f81fc98a02865833044f79ed73174118b2b201ce0c4d1a8a0ad9b44cbab004001c5d69734302f0d845cbefe6afa47342bf7924d8e8d231e7cb0e2e1af58938ee32bb08610864384c022f415876746454f427c0fd485d51707ef3227e0628076a14c0580dbd09fb05aab40bb307f290502b03b7d25d4c6259311255998c43be15f25c9f5a340a3cf1d2a6fe722689db45e283529a3c1237b9ecc84d76952a86c7461a73c7bb26aacffcf0a33f9cb21ad93e42e23c25090d7272c4721e48d73c752350a243a0d568b3d6da99ad1a5e31f1946ef130ebebfccaef41a28edcfb0bc3c7f76ac279d92979608f735ab4d5606ff04b21d67f4e44e3e152d871b3eb329612e8881a9e91e4ae037d7da1515397e8a99446ca0efdb889345db20c627b4b583e7d609c0bff453f7df98d3bda21c70187a14f8502699b4d55aa71b569a3f66b04c4b1791d830faec2fc9ab29c33b64165c9ac08377c475c2877e473b3d89018f734c1497bb7143b8e6386f474801403372f8acc43a7188c4fd67eafeb1f0637b9842dfccfb74468199bd90cb52fba0b556b8c32a5ef2ce65cbfdcc0bad3102861415405636a43c75f54b2844325cf7544a22d5c56f2d98c9fe6155c984ce23439440366a21a8ea24ce6846a7bfe40459039c0d7c1f3112a9d5ca8548f8f20d884086e907f9385a15493ebefbd509e7aa19691029741dbdabc15da65fb42f2816c633fbc1d5b42488466795a902ea4ccdfe4d70a50b6bb594f614e111f57527496a1901bb290c3c59f21aef0c68a877732de2774fd3823e2271ef0083bb35530158e9378fc050f0fe5df440a2e63fcab3e6b58a5ef185946f2f9fc780b329dff4fa5b29be55c1868812b71bebb26588c08b97878b7118412caf4ffe183efea366b626391a67f6d0ea2e00e28be4ecc261b397bd76cb9da3c99be84cf7ba4938622c3e7eb3965de2e1ae07e4e811811cdba640c9cc13c6fda6340df33e87ae23ae8edba372fd154b63e3851360380bda2b4856428f14f99d008357e45cef52b500cd84e6e07607d8b058fc2765ca7be87c3595d1455a05e984aac50f432145cdad0a98f2776b70c63ec6137754361d778a413fa657d0ca945682a179420c5ecec5d11d4088979bcf2a823c14fb3548108cc520560ed0e6842fe1a49268bcd69bc20e31136126f80084afc99444ff0b35824d3699c143a91eaf3e97ac4c01ea5c983c10cb910c0301d6ff257956789705be6445c56b260ce10dc8d8f165ce4619a8c56051a7fc4d62be54dffd06c3f95817c144282f33fbb7ecdf495dd44f2a4590137d3bf89b729ecd102e43e72b6f71a059baab8c54ade2d90f61a2dfa819443ccac6d3473a9fb6532820a3168e2a7870a07dc077fe3bffad4c9cd53dfa02a345b19115d89236fc843993c6a336d19bf666d67fb50b54e7001237137ea8c1ab4d35e9f330d322687e5b7653fbb72f14cebfa405dcb978eced6f313c3c6b2ed02892cf051ab489154a18ad86f59aa9e5af5c42b0cd85cd41d2e0294f5aa3989437535e4e362bcd92f6d7a74977590f1086e877ad1e291895a9913f24a44a5ee056b9e1624734c09d8ee02ec4da4a0327e5c3ec3d8441c1da8532214006b316ff404cda80d6595507676404ba8f3bab7a8b7459ec54e0acaa9b98263041d1e81b70bb48b24839cfc1737ff4116168f51dc5c9f84c91a3bbb4f7190da7271659f98286f11650a28c8bf8847810f7d286f3d28c5b86f2869e1d532e77f62ed0c24d4ee3c722038821736acfad959f763fc0b8d348f724d0a0a95371a6c4752f120eaddb080d73ca064751dcc3364fe950643a1f242be28d9b8a55a1a3d6bbb87b04eec17569011f19ae74ba249a12327d7f008442289d1c4324bc2f14d86283e195e76b47a9b599cad0a8ef23a952f85eb0610dc4a3cc2f77297c2a446ea43ea7839a0771c6b88b131ab2e2f2b39d031f39bad2c7336874db3f0b3b78274410321c61990498b16c68c1ca17e3f25c3ab283abb2938cc4e383dcb81432058abd8c7a298d0c892f482d77187fd25174b12b1194a50b29d90e7da3ec2388f75f85777bd2cbf224bf65ade3057561a0b37c6ff1c0ee59703fb7bff8ad9c58cd6d643b9a8da7116318c3cf737001af6a343104cfbacfff57fc82dcaadd13fd1ad6a8dff9506e1c3dff33832291e9174e8afd4c447164796d8daad8735922ec139a3bbc0721ed51e1ba85c5c9fb5cb0f4b23707cf32f7af4e61cd53775c4cd346dd09b8fa075adb9c311f3c4ecd79e9fa6bd3002651ea513765f847ce08ce5a0256501dde7804e320b1fa6528b88afa3f5094d326325d02ccddcf56a9be83afa5df7b69d83842e714f3cf18518f4145df769f7ae73856708aa90770496eb3e969e1f21aafbec05af7368e1bc31a668170a368bad96244a7cd42ac576f4d4b53324133fb0cfc849972781eabc2dc6d5361f9b5cfacd6d7f3a2cc69e1bcd6ca6515ac5d704ec53fa68f8422e7437a1df7db7fee7b0277b6ea71bb5c9c9f4f310faff9a0ccd118c0a463313ce4b0b9d61f72f48bd1ee8991f0e1120ece2255ca63e3a10750eec286b0d50ed7774206d0c268c9f5b29618547bf2bbaff0eccce72883b21dcad1b5bf47ab5a943da9823211684517ebf71745a2a0e627f15c8ebdfa104883b60693d4c3938dd6d6e5e170dcbafd9f15dbca23a4aef76c260d7f6394de91badda5ebc56e2fc19f7d5c663012a3be507a2f0648c31131128f6c0889fd65b323cb3d9a5d45a9e5a363dad6e450625bd5b227c37326789eb214725be108660cb30fa0de03637764156e72e1e545135698a561ff16d40ab264c2aab89494dd43afdd8ada1373e0c9dc703b2dd3af759d58fca6da57bea537ff54c8bfb7e8bf90d22fd7653b2695219136294bdcd68fce4fb19f53ee98bc6a677aca85bb74cf9a653996258bdf00b9f2d174163b330ecd55c86706e7d18983785e8bac6e2b3f96be025aa892bb4e02623d95f981d30d60f8583fb6f14bbfccafde70886d032c491df8e5d07dfced834e01a64b83fbf744a4c1c40afc38d6557f9258ab9fa49f52db50e3b261d367663f49bda16ef5e6c73635312b507132a1178cc8aa8b4befbcf1c595f966a36491ac23deb941e63b20f2d17d9e575043eeb3a2804cb6b509e731a54b718234c226c8efa217323924a0e09d73eabfc89399a49947e93c3d3ac6f65309fd70c09192d315dab37d2815077f684aaa9eaef4ce77b6d0653bc4d8bd77b0c5bd10174aeb5ad0dd7aa7af7fb79c8af3aff371f0a4c625e584a0b9c75c10187b009a6cf1bf7d92a44fa489aa1ffe90e00c1a5ee0a3ad9256c77be81f8adaa14311ea934bdbd9e1cdd0c31d9f7ed8004aa5343d28416e9e888a46be875bb8110d03b048a7de74b868b124b59a9f38d6f6164c263ad8d0fdc3728ae3aa7d103945faf106aa62db4401c3394ecde71b3e966aa4100efe8c2a233d97ddb3a376e0c5fcc2ea88fd35e8db7e391d9e5d6aba6d06137b725b7fe7d961773ffba819fb498185fc64399f7a45369cbd1138a67f2c8c8cf4aa112aae89e125b74adbf76b3e02bd1ae10670c57e3e87bcc2250682f34f7f41dcfc8a140b176a0e7254d8cbb9357e1daa642dfb72130649d1b9c680d7103ef60aa2cda3b661ccd41b310e6bb24f51531ee0ddf4255b50276199c01fa2b36b0b139b6fc245232371ca7239721a4d7ac080dc7dacfc12144f8e5186e7bbf89d4959351161be25407cf903290c1fbff1c52accb445e5aaeae4b49d35a3c4e4f2b6ce02947da170848a2e337c6f3cce5a3a32a3162b84b3e76e2b43be5600beeac09d2450f14dd7000d157f073b41ade05fec31e148dafe7a603cf9702e7b066418925c2182126d41a252c9f989f3d09483c5d036dabd5c00f0533a3691f834c88631f40b51d69356ff8310ca646ac1cb343866e6a721e118fa2ba83e18a00f0dbcc748feb16896908c4bb0607c02e235ff3d2376a8544f06322d27d88ea777e4bfa1473c855b9d42143cc7195eb796c5e5d1608aeab8806974c314b22e08eff7ce9547041c4fbd33858d5c2b6b56da4d64079745c02354ed18966a27548517aa255cdfc3e4cc7447e246d867eff4fb828a8d66e44c321bdc78bd34f6519a4d03a14b54727e6619e47a0d328b817ecfb44b7696de948aa382a0b9ef40201191aea8771aad83a7a854351942c7f1275667d0d55306a1484edea1f0c496ec3f73eb5c512a30de2fd3fb75bb9d438e328f18746309eacaba3e022a37d9e6a7ecd52565951609934bf206c9e3b547b56cbfdbaa1fb20c2cec67010180edaddf35613fbaab373895c3c0ed63ebdcb381a731690a96a2f3f7374dbfa74692bcf046c7dc093963f985501a8d3163e8deffc88b8af1492becb0246bae65cfc6270ac59b7cf6f89a75e2553427560343dd30da6e9cf9d286c7366f7612d33e123c759da9c77d86710463a6a4b940bbffa67834d471fe6fa1dd0d6a6eea669cea7dc2bfe265456e37e91caecb427900e3fe81e2ab3d89619b8887fdf07a1cfdf724a6ad7d3b64cdf6af69769f8baf3d6ec9b4cdd28dc255825d85a4e675b091cdd38074d81170e12820f2b87eb6bb9c28a6a810e867631930cb02283c3d7addcd7024a25199f1601f2afae5c41593c92d670ba4baaaaec69c472070205568dc084a2d11cf1d862c4ef31066031809990ba8abe27ad644559b2368c5495fb24bce089c6d84c539402a3a6da60477b032f4655b3f9750633f10527a1b9c08815bcef973d1c60e1c077b06dc0456288ff4cee7482215e2cd131875d19a46e88618a263e6fdd09ebdba9288ce359efbe18cb994eb5a532a52d6af1159fa0779be5faaa86f312c972516d4e752aedd501219f11f2f1ed0e646432bbf1220008007550b2ac59332728726f0e78774e16e085224c56da67b2da89a66c21233e14ebac292bc710a4e3420f821bbe79f3ecd76e6f27bea09604d7b9762b45147773742e7a98219708316e0d211a7829f179c038241f8289173a99c319702381f20aa96232da4d072dee8b587a1f1392939c9c0d2cdd0b2fd734b43cf5b742d5a11384503bbdfcccbb33c43795192e1f2e4c1309d4de9671d4e90a460159defc8f3d6fd7aee2ee2c07800d43d5a1a57c0d8a8f29ea1706bbb9d1c69cdbae5c27ddaed71b5483be5905037904ee19d2f126ee252dd7b769005b45428fc82447134b8c0a49759374ee62a1780b8797beef9e50acaee70c4cbda59eb615692f1c5f0de4e5b5f7468cfe5cebecf2d4fb33dc95b10627df81584dba001fcfdb1bdfed8b11022277f859fdb2bbe2083c124d15a260cf2160fdb8718258c0b10080a99e6e40f59b07f504b8cd526157f371c503e9e67c52ffcda238c3042d80d30f897a0ad481ac6771cf2556b07ccdcdcfe85c292e6b59c201889984758604e918b07270e38a182de814fc756763b10ab59cf832556c1813823ea2a276accae7b7e9e18a4cbcfcecb32f4745afa48305869fccd3d21a3c5d31105d64cc985cd9dd2d3fcefa6d6b397154dc219392dd7527ff4b0a3d62c3005bd770cbd00b4e15f6b85508e14c687ba63a167782a8392703f2f16010e1ef120e936efadc099a0e9e904e662f51f7f46951215773fc0eda8ae1f0f9411c799280cc2d2827e226ee1a7f7e225999aa49d47401b44a74dac13f16fcbe6709445addbd2005f390084d52e4a0c86d8a713ca5febf4f58ac66720f2f6d8382884a3c416b6e4c2f66ae865ac28f2a31d9ccf3bd7bfcad84d80116ce3c217b9f4ddb00db4dd8835b5ea1ed439c258ad054c8621d8842d95060e368be065f7b5c7f701f50d09c5d1c1c9ec085226894bb708bfc705fd7d63554c0a47742b0daf29de184b1bc96f7272449289054d6e8d35a27895b6f23ef2361ffc8a5ea338381bf39c63b4337c0779389f34e4ba8acc79fdffceddebc7999ec83d058e5f335f0962533aa8aed74d09dc2e21769e624b116ecefe4612f4c2552864e648b8c9f541469925d7f6601d778872515f675a446e908eadc235c9bcc6f84feea5e8b2ec7d437af884ccb619632959dd2ea272f38fc3c9ecd11d14857a499f8f98a358b5096b4f8565c3a72bca57dcce68f168c6bf092fe27a80084e5f803162f58ad7a0a5cb86e3ce57d2f5d4c3cbdfdb6d239e4d3ba25053127e2a5a668b7f955169135921ddb43839fe464dd2efb8a8c9fd93d62edcd0e2a949b69f398b0fe2f84b6e5aab4672a19d7454c9fbf9732da4252a1dd759a2d91aff5bbbd8a49b007087ac2c7663ce2f6801cb5668621c466fb273ed2584dcb3a7fd352156d4a9581ad007b1b5d072e8c2ff7ef003faad178c0fb2fe847c2991fbe952d59287e50d049b9745185ec9a64bb3bb9f9590fd890b3dfa2a415077322d308c84b3dbe1beea254cb583c87c88b22fd5e6e3ae819266cb777649519e839c52cf458a2ee5a1a4b2142baac0ebff7ff55e6fee2e362932ec9e58c5f106faebfe5079950a0d24ae615a8dd60e6611a9fd13bdc0b6de2f3e4b7cf355959e2803a430776d211aa97fa7f759ac4f8aa0bce11d9bab5ff2299bbc093a33d40054ca49f364e2afdb98b94ce7acb2f13e11dcfc7c9e16887df27f09c16dad202975d1683851d5bc410c1e1ddbc802f7493ea504076970f4b4c6d22ee0f1619e851238c3d056a6400ec0d27a9a20f41d238a2ee396bba4783fdadb71c266d110367bd9c64eb72dbd5a609f2ba414fb7f8f67b2b4da3339c43193df2c3d0942d3c3b30db2ab59b14a3fd30878a48c95ec161cccd572ea241ee4adc190b89560133475f5b99ac247b56c2488a8132c2f024472b45691223fdb9a46aeefb0df73e6ba3685dc2d19c909383d108fba300fdcb4a46cb8268cf6f19939c2cf789d009549d187d9b895e12034db35fd3a17e862795e50484dc071164bf2415eac1b0177e5677f20778ec4ed2cef56773b2f0227d355ed61804210ea7a136d6a0593b484c5ccfe733faf8244e5761225732a2aa1f6ad2f6a5263a4822a624ab308e590183af5663cf82f7043565edc1870c53f4d173189fd0e146925574e8e04b63d56d1eb9c3c67df7bd165ba2e089a7069a0678254cad9d15057c367de62b8e839128bb428dcbc3591443a5bb5afd147e1baae525cff0a7cda95587cedd15b67699b1378744b8143a0a112c5c467cfe26821a616107f9548e9418fb7e96cbaff23654cf029fe172a38fd830022ef2c05a8972593f6740fca55d68b924bda7ff73712f02288f195cfa6d9dcb66e5be19474aa7a584a282858fdb6341436140d7d11ec428e01d16cbf7a638dfbe9e18da8763fe2ec4f5987bcfce15e988a411da4b6e54f373f63fc6512a839a4840a37bcd845c4305e3723980647b038a7d298b67d94219b31a84ec3d4df4bb81aaa07a8a358736412bd5b761789dcff2d182a3ffd22ae05845af001f7f028fb3f46e461e4533db88b9fa11cfd12dd2d34ea11bc8c74b1843e8f28a5b845a8bb3c7277fd1c49ba1dd17acd340b1f63086fb9329c774c54c036798d5b5184de7097a71a4484bebb858a11428491669d4b41b652fb5848c8725938743aa03bff8d1bd5576155d77979cbe76fd5aa75875f395fbdb5d03af750dcbcf1afa0ffee9c7cfb1722b533c87f84a57b53b000000074390c608ff3cce57b78d6e566cfea91c5194e61fa3b921d8bf843acfcc90a14707eeb6d1583937420c247cff52d53f4400e90287ebb3ff64e2dd5b4455b39e56b4765ae3b1dac860e281ece98ddc4209d4e31c1ef61c01a8fe8027911f131d120b391b97b20915840e0e5cb9d727eed75623fa38673e6cb3a094e508d9a9983bde1bc386ee4d584347f341ea70358d9f35b1f64fbe08c8edfc4e4e1d79a44d2af06bc484d5a19d448adda5d1a5af9b7fbd5f9599c5e05a0f576cc3568cabf31541b650611d2793675d3edf1140b65f310f98be6af7618bb8735d7043d73df3409d37749582429085738936562f603720fa713f2df9e95fa47cf35f9b3bfa82618dd955d746010aab36d9d6e826e39eef5d682b87281b2ec40a1f03d9d1139361e15c12276ab4f1ef62e944538751e2a585118eb91581a2291d500075b7ad514cc840cd07a77accf69cb3b3ff7dd8d1c6eae293d702373647a8e215e7c386dbb9698ddbd84792d57c041ec08ae5b1e034f4bd6dda80c35d968397ee84afd6f533c90813a67f525faa2f5ff5bfda87c936fdbcc443b1f4e1ec87258484fbd36d3a708bdf805c5b8b287b352241df3f5ead4eb730276d5d7915cf5c6a8fcb357ae35b124439a5ae68d9425b3d476ec7de45d79e31a5732af9712d5844a7cc26889d + +pk = 000000010000000700000001ae5630e18184f7991499298f672208ddbc2277f012b38faec33bcdd80ef1b5f3577e649214e41db2724dfd194e3258d2 + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W2.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W2.rsp new file mode 100644 index 0000000000..e478aa9d33 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W2.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H15_W2 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 000000000000000000000002f08b5ed856f80451558c031cbeda91f6d5f610e6980ee56751444e2aa676356757ad620d1fd857d154c6c42ea5f4e169b4d9e71c8cc801cc32f9f5c675c6ed6b65ddfb0d0b3058e195d1abaf2db1c182a814453ff0bca5f67a5b7990aac2be11264c00cbe443510f9e7dc92b874fb03ba51f6841569f84c7be828662be715f3805e80ad07144ba1f74bcbdeacb4f487a04b4dfb873568eeea19da257507086c23e0e1c757ff97e4a3fddbf56caafde716eb678ccb9e70b097955d01a7354c32bb762af1aa18bba060580a9aa515507008ab99f0180f76d9d1548a85cb0c567129dfa7bcd632be21b545f0aaad3832ceab7dde6117f4f5cc65fe6e5d63b110badfee7d3233ac43d55717e721e5de68dcf99a13463823de42f488ac70d88fb04b50e2e4b8f9c3cfc57330ca0b84d33b8ec0842fabd160088e62dc64770aa3ee02e8840a7698183fb484c897fc7de9efd597347924921544fbb545ba4bb3ad3f95a05fa55e21a827f78d44d8ea96dde96a6d9bdce75491fd2e9c7edb3a0c155576cd083fdbf706d6c54ca1abed0e9ef069438779cf2fb20318b47db116c1fee2972617306a6bceb64bb910c11baacd8fcc0a63596d328dcab0f41bcdd1f5d4b17f3ec2a8b2726d2071d9257adf8fbfc52c620ca411c1a3d9afa3c224745f8601e28ef0e3351ca8593f119079b3ec16ae4009f78299eac494e5b4a4ed920dab2e2e9912856d586ff7d037f49f25dc5bcef30d0755f4949312cfc9a3673cbd4f636cf81350f5adc050c323ab9633bad880690cbc13f7cf0dd93922ea92688ef1fba968b903725c6ea09170f4d26bacd62132856b6972665b466f6688e37a6e8a8c938a72e1fccad2bc8c1fa7a246e1361ae543892f23c3637ddd20b3d8a3b0aeb68ccb5edff07be9e9169d93c6e4c0e5dd7adbb3384eb679b4b8c14c23e3679a6ff721678be639d3684375e9a01f14d29f310c8460fea41de9dc5289a784080c090d23da1ff5aad37caf80a920c82962f966f0a8f00cf4972752b44c4bf2af44e18cd373a6b5afc281055a71dc9d39d65233f1c397dcf8ffc0a32a07905f2007798979ef0123d65eb1033eb98be9481286b233875ca0e0e6a7734956c6120733ef49ffcadac9986e902a24aa00a5facebe20c8a90e899ef14cc4fb536cb2fd272849f448bdc30943fa027b697177dcd9dcb135c78d4e000230ba274754d5dc7591b0b818e8b2ec5eeb216e02415ffaddd6e10e42a2cb55c122bbe2dd7c19a70bb33b52e1450db1d49a30c1dda1673015cd7944b35efeda84a821134085193f70030a1e375fe43e89fe5e84a14283f78ab2a5985403b45f8da9ee082a1c773acc7c8b0faffdd433c840f5519a1945c622642548dfe4128a01bc15ddb3a4defdcc9fdeac62c27f8ea27e939966471ceb011e0a116b43b100050cb6c2d74c71156e48ad869c18b54d08196101f845ca21c89b647543fc38e05ce47fa3c21c3fd65401747ec0076fd74ba27e1c2d70db3c05bb1c08e2a392a8d548f428dcb572c7cfa49e709ef62305ac06ee9e705bb5c5c440ad92f8d72313dd0d35d244613b6df9a325e6b7670ed0838af40bd48bf42c239ba12408adbcfb492b9d2fc0eb523dfb419bf9eaebca4fa4305e622088a4482ca4735e14c0d8bb26305882c254e87f60d5039a1857b0d6d2a9dcbad8a10c802ab9a9ec8a6f5caf05a4dcfea0bff82b6830201978c145611a3eb060d08fb70e6d9a6eb85c6f779c7b50bf2c38f9631003a1d8c5943d24a987eddd3a9a27c694c6def4b3cb938515239a3e35452acefc29165e8c5cb3d8e8b5da9423debd3ce1ccce82d1279af8253c21e8dbf743fb80d8cb1f51d3d9afab06da2d11d99ebf26f69e93bf726d9d33a8f06ca228602692a7ba44ef95990ed181ca9acc62954f8a1af3b873b2a07faf575f387b3a3fdbd9ce68afcb2094f39713d2cdd430c85e534af140adf30d99167597d2b05ef7d7fb4a636bb8c94c4892484a00b987cb203ef3b038fd6034850015a0f3ee971896b9c76df5ff2d724ba2c5eaccf86f19e83bcf968774106d7fb42614cfcb5c1da672d5ca1bb41877bb3835ef3ad680f3c14ed7fb0e2839bde1a8d70ec318b1005ff0385f8cca6febb52294f4caa3b284349466d3fb2c65ba2df6fccbeed18187b24a65801304d1e09b56befbc5fa3ff1ef44d73e0f3e1dfb9b86f85f2f3a99c2541808071d20b9248e100e7813fe18d553b63ce520e3e60612aea4f076e65f53d23f122a9bf435eadf13e5053d8b509ca895844b7b36c284e6be757407d202c447355174634cee9c90a1c0c2d29628d9ac6e9c4996d6924f9f6b99adff788cb99e3a4ff46e257db3a9ce2b25e71dd783d59ac36f28d48e0d6271a1ddf1b4c5deaf1e97421031bf6d8e86579ffc1eef966e502b695878bfb514cb4524b28ce202d38e7d4545f14b4f4709f7b23de5a0b5695e9e1ccbd16bf8fc89b960da883667d256b08428f8b5874630213007a24d23c086e3b171ac61ea4a042f8129b22c1adc85de8d68f534116493980c28054f8a4887b7fb8d53bf0149927c5504956284f4105500c9b8170d2ec6746030ca343ad1224c836b4538fa9bedf2d2ee97ff85d6ea7290a1aa3df9e47550947c35a3b7c74e0969e6a3999deeaed57c9ce705fbf859f700a197f73ccceb5399a028c781aa42a4216500ac3a1592d7c3f58474986b0ae7f2685c6ede892b6098cbd6c9743fd974dc39d45d732f392617dabb33e12df59d4252bed5d19f36b77b67d45d56b9ffc26219fd9988646649742ee364f483aaccc9ef8c7aa16e19cf045a46dffb27863cbe8637403638826fcc79e79929f49dc315fe802301072b5fc9b26a91664e6b69ca897f4c5ff753e3be247a0adc3fe5e3d779f0da3c7f4be1340b6c38f596afafefd951760f4f25611f689aba3319dfe54044a1d6cc4aa9d6e3f1c21c35c6bc1dfeabff882eaa624fed9f50bac1fca9d53378629c1da9013c21750c820a860dd5a97ed04b3aaa771ed8135bb4ccb9bd3815fa925e464db27b96d4582c105c8a1f471dd5fd0c512a3e5f596856e3ca297e7b78bf654d078cdd2a46eea45ae7febd39f127351f2beeffa29d967417935dd98467d0f1766dadeac80f999d517902dc869fe13dbf186d7e871141e5e04f68a238140933a1e5b215666eb1c7499f28dbe2b3407f3bd2ce6a7088718768a6d71a24d3fa16e62d7d57e2643274029b5f87dd5e04d887012bab0eecab3c9b5f3391c713ed718e30b968d65e342f0b4a61baa381fc9c3d2aa398706a2ff9e6a7c5fb964cba0a1d58fcd6a133008245ad9788482e153effd601ac217568ff7a35675b0af3623df1ecb784f2e7b690a059870654057950a49cf7f037915baf02886badd23fcb2e61274482e7ba856d7203c620f81be9d22f24557c11126c79cbb45026e21c43638d059144c6a2dc7c161d87963b3185641d97bc8e2ffc9bf11e78d27b2bd62b1fd13f872c454d7354b92613436cce8a1333b59ef75409581c76fbfb76b2dfb157aa6a0fd85ef1cb38006c9ca2676b83ac624932175bd04f72b8ecca8b23a86bf440c9a8f9b874ad1508d515d18b5f097c7e182b63787d1acc78defed914cbd33ad0d07ffd9cfa73eaa956297281fe3e0310902b2dfa8fbbf21ac1ff387b1d8fb202a3be3b157bbd113c4db44e86329bc86080ee38593773f614ea7b7841583340fce41b7345607d84e877f8b715f5575fb57201572bf775c960cb17f976504a00a98b0057b664ecce394e3d117d62bf9b653b76ed6fb4e2436a22deb7f72b399154d151f85a224862c6bbe564c3ffae36a6732e528f84b15fd617e383663c3ee28cd442bd7ed4c38228fea64e543d684f6e613982bf8a9934e4f81db467ee1b5da2b8a2231eb5c2dac2795a478bfd91beeba8f3c731381c98593a4699a520437659a8dc297c561cfc66986e886b0f2a79899324af9029466f6593bf4dc5191f3ac0e2d0b7d6afa2764942987bcea3c0404de1942f0e058f5b1457a7713d987e408d54ac05bbc5322181fc30934d3fe516f1678f91ba1733b4b31fa1c968ab5bbc6567a436ad88b328b31194e7f3274ea9e14dfb2af9fd137dcf6bcb31ae8723d3d2b035cf062e614ddff037f3e636fba860ca70540dbb704fcf1886bd5453b028e7d50020973aef05155215b044ca7eff50cc74f1cb2cb6dd447f43d42ce8d3c69295aaac5433e72deea922afb0853b27bf5347d205eb121eefadd31fc337c4e67ecc1df4e36c125b77fe5dea89104a52a58b36e76a57cc5a5f61fbdd7ea04e7bfb0895a790724e9ea93eafe01d20d2f3a4db460fbd9728c0e954984851a48c3806fde2930b98274109201c57fe8d0ccffa2cceb7d7f1bac2264235676df2253d65de551b6112f0a617f9b16d64953c646b84137185e63018cbfd28643d4dc96c782a8ca43809426bb905a7d872fecfad0814fafdc0f6079aa80e1b7236e33f3ca28ac02fc32d4fc4e751fc053b5b31b38b76068dd443fbb9b37ac9ee779da0d90bd9b4fc80f1cb71675c243ad4f2c2f03e9cc58263da9bf5aed282b1ab905474bf3a37225f7bf7952c930b7135479f9fffdd2cf85f2c3d5664f696bd32832db043f6b39ff627448042f7248253ef8b9e3d577f824c5100230a35a3581eed96308693407fdfa960266f8e338a70e2a8206886467bdb5d7ef7e6695eb0145e52a370727cdc55f437469c56a52a69a667cac0f057caea787700c5ef454600574dc27784d9b6d4b91296d776752d12d0ba6b5569f79121bb1bcd3a11535c5badc7daa72362a23099aaa10d2e45c081423afa48d28203d18d16529610965e28af87ae97a73b7d5ae048dcd9f352381ac26b96ca3269da6dbf88e96c795650904e479b72b7dd6b9bf46ea10d24d88213a002d0655918cd9217d02750d396a44c653a71e2d9125a133542a5462756b0cfcd1e1d9e7be3b919a65042e69e3d3e293f1fc34974eb6a148700c7f74c5497351be1ded9060f95a103b5f1243db2acc218b30fe27697f5fa3bc7a43fe28174bf916e985750f3647b53479f1ebe74806322b64659ee49d3a754f5b1c22fd39f8b6f36aab9512b4371323a3d939b97aedd726303d91f804731ed921f70dab7c2475af8cdcd54bcb6747faf7e7b6a1aa579cedabf8447358d23aec2cc4b75a547e0b59de77984b33bf04557210150718f53f94dac4e80eff9e20c61bc457dcbfffb69c61d5df812ac70ed8600a2d8d9081e46c34ad9ce6a0f1aef9b25277b8600e3dc9a001ab305f732f5d01a1cd9096ae813c53731490e5af8018ea3a15618e365e12861340e7ca7f8afe683be65a508d8f8ca5dc701c2708ec1c2d70a80362a217cccbaec9bf6e1a201d70025701759121a5bced89d618a1fdd8b9456f23d7b3c105395f9397fb80ad8ca754c132f7d0e9f95ae2f956b18e313520da33dccf03e3ca0b37cc6a4034aa7d50489054970da47fc22f385a4ce208613fb347f74f02c0e17eaf381797362acbf78294609c343eb3035e42fe71ce86b9e0dad4f1777f29457e7ada88d3c0c3f8be6d59076bc2fcd9c52debe5fdfcc280b567bb7622c2012eed6cfefa3533d9a2606aef17ae20d9869f02f83606c93778529e20d2252ff239c4252b7944ed439f443c1b1394a1c1df5b386bf5f9a3a839d7b1f30aa6d04ae2f1348bc926c65c55880918a4ea278c141afc3229eb756e8f16402ad40ec7d30c8ee56317d6ff3023b58e468cbe0404decc7e2f548d41f4669c5ee79da45a3d30cfa9466ca9bc34474d1b3a3beede79ed5c177b2bb48edff3a8c3c71284a3bd1c29eef2bd1defb2d40c1c70f5fc02ff899dcd3e7c73d88602e7ff66b25b71537437eb0e349c4d62a306c97131f0cd5affde1e9938d86602df061f6837bd542d68600324f9f8120ee567c9ffc87fd0a9507b1034789055b932528d618959ae2c43778051824c117d884b3315a3c0fabe2ae16284ea6ac01712006d222f9874d7871777255b46cfb44b72b3048f1a43f7e9d72ae996ae791d2f17ad97c26ef23692126df47840f7219e414e4994ac281328000000071f0adb73b4cd33823d14c463983567475f253c2723200371379ddd88255aaa21bd9434e4366d569655f38c8f6f2d25c66fdf7450ae9aaac284e91d433870308864e3f2568c460cfe515027b525228a27f154ca0161e0c3571ad85e38b2b5e622871da013c0ce035df5cb59508775198d3b69dc52a7cbb459d10ca900172c9c46a44efaee553817d7fdc7f7f1e3f2f6714d101c8555756b1d5b8d13342d7fffe8f1a37aaa0cffb53ef5cd6c83bb78b450a026edfa8e34d18fc68743dceaba69ebc6b26d18d63a9b80f6dfcf9293b7cad5523e0b215539cfd6dd858471d7fd725e030265518140575ab772b858152f41844ef97e54b685e81745c47e9b7f0b9d375e65a2214ffb0fa163b8df334d1495b44b8232ce3dd8c5e2a760cd92eb59c80080c841d0150fed836cd7ac390ee1b17ff670869b98dc3ec29c5f42c4381a3866764e0754fb5f4b73050993e1445fccad4d346a2dc6b61476cf0cc8658b3ff406bb1ed89df047dcd49f2583911ca3a7c4bf17fe0dbf5ba32440f253f12f9f791b9bb80d413204c41b4e9689cd72b5b8bf73272fc005c6a9f230997310d49dddd68df985bba18ce58c1dc63d5c62c8f150b29e077892d148e1c6ebf342277990b51c26762bd0da452a6c88bc50de214cb59918583839641b67df417828fc2b9f08 + +pk = 000000010000000700000002e8de95cb58a8b0aa8ad47f68af1c98524fd0f190b5205f40ed55507653ae7fda835c910eea1f29d7716330c27dc4f835 + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W4.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W4.rsp new file mode 100644 index 0000000000..b63cadafb9 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W4.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H15_W4 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 000000000000000000000003b15d44eb5dec79430945738b499d2beebb5302eafc1318028103aab6469c2cc9f7701919bad01498c915de8d56a9e221413bc8191bbb0a6e538298c49f46213ec9b6f27b26d85c13541b2dca4fde3fcb5c6cd830ba044c8e6478011c13a10e79d5ab11157d952166ca5e5cf7f36c675af016a4476d97b79bed46cc06d261e82ee8eceae9031cdf85e0afabb71aee45054e90534ea22e32987f6bdad1d82e5753c3d49b70a2da50e715598dc45e37ce67404f50d6f068ea9f053f89a25f3167b778f670834a4247dbf2f3463772f1af1fe98def960bad75531503874a8ba1679b0eaacfa0532017d7f12587180a0cadd20abd54e206f9482ff3d24be9efb41e6fe749facd7312927a81857f0810d14610528c4ea6b3fe3e8efb75f3c100ace31d91b273790534851f0ba37977178b38df4319405c8ad6c9a657c536836c6362f41fe67884198d8ec5366bc788c43b8f7c1689c47d4f3d1c33727937fcab453fccb7dfd4f1932caad1ad5ac45d51e4c4fec014ea796b3b9e70781a541e9bebdb309ebde3a30918b63d6d076c4ca22387e0b7a17a42e300ec1f9b750511d989c443edf89d9f24bcfe96767aca712ee08583a70fc80b6d7b7f3d7883c02491bcc02e37e267d9f14ac003fe002a669a8ff5ffb37e55a8c002bc1ed3743745119eb0ec227ff38eec5956f1a36390fa086f98ab4d9200e7c17a48ecd8f8b5bf38341ecbf8a5a0f5f3fe4b2a0f813df19df6277b014126d1c0d42e093d1bbc4e2cbae00422a78c1e70b2203ea18591b22d2015f8d4d000fa484e879d44ceb86e7ef89e11f3ea786f3b6d204e4ba13466bad37b1cfb4cdbe0f7bf26623d787681441e6a64d3d783bdeae7fceb6fad18c8b011c2f14b3660951a8cf87b75d292489dc87cfdfed0610cbc7b727b780400b8ddf7a1c5d5fc265a7f0d2356a7e39862dca4ceb0b07efbea59bfa5c8d27ca1c04857b5c033322dfa8bb5f0aad504c246f17d97e306c55cf17f0724d5201ef283f8e0191ddb9b5ffb5f2e86586a1ec2243dfe17b61e6c5b48204717a3de944a26082b396d016a3f689fec52354321d08722f2141e53063305f988a720a91cd326bd7ec72071ea45e314ad505c66a85ac4478fa2fbb7abfe83e890779f607de7bef9b852e1b72ca511cb49b5495884f04a6c6252dae87ad6154f0934c44ffd9f9b7e78ff32163f414fb1ae01d703b53afd5400178ebdfefaaff149de556b474d507cc4f83a2b6bc8d8aba86d55f32dd6c59f90376480d195ccb157201150438b93432b26cb6a437be4bc84b5239b89bc477ce4ad981c7c6ff38cee53091aa3489a095e72b582ccfcfe783554b3dedb32af18f136cbe0c83ace70cc09164debd2b67fc5aa9a9320024dec45a74be1793e3850062849860596cdc36b9ea154cada6ea752049b391082ba0107e4658e6efd741fc5899fb5ddb7549cae174fb9e08d0b42d75f15b1743d06f107045ec931f8ffcc67fe70779cfb6c3e3f58fa230c951cc6278571796cd0f83249ec93f7ba62868782e431c177a691fdf617e9af2221feab9ee09684365d0a8a5e1948de7a01b6e390d18651f26655d994c1363efb93e6dc196b64e65b8ce1150b7d020b280760e0354d561d08228611e2fe9f483ab574f93cbd709fb3b4b07af72d27f3960f6c6579ecc02ceaae745a3939112e883e9dca7856d5803dd5b21f889c145d3c54b2a5fc117c341e2109b935cde6c7959ef33e3c2a9aaf32cbe003c14aff7f36cabdf25f37467e7fcc58155eb0a354313057f30898370ecdc5b75eb2a74388197adfb36439ecf97a7f9302a2f4d7be079abb824db22f7e962136df36dad41cd5816f4e8deb434b59b4f308818a12963dcc0168f20a15017f941f129dbced6e41fadd87f91655655b7001170188fe9545fa93424f939464c7af32a5f282d999e5f93523ac2090041cb087f6be7e8cf2aeb95e05afba361e973c4a69eca8bf7c1f22bd98e94dd71e604561ccd316f6579a82c75b58f731282f658ed2de278ec4c627bd7e89b4f7c4a8ea68a48cf8744be232981218ca4ed83db5dce7719b3237236632e9679516271015ec8db512d517f03e038910cdac47ab895d8a8a17dc43fdb7c27273cb830372edc94e9188fc8eb0b95bbd6f10ea1d593a7aaccf302b6ceea1f6f3b71d7d4bff16abefdc5c065922e1eb3527af393186b963b15b3a5c0c7626e68b69de1df88dd9d5430d8919548b1dd21fc65f4e602b6a0e1fed96e931ad8953b30f84eaf86b630a104d5f296afd9196c865134e9f93ccafd17abcb2b2fad3d7c379cd4b7f2382b30af940474665eef0e0817e322cbaed4ff5607e7970a8b5292313a9594e5ad6878cfb8cd74e9c498dcc63510e7c28d931ff70253c602ab5cd2d600580ff642f68aabf7a3643f1c7af8a41e65310311ea43c75e95f8370ba5a6ac3cb0065d599d79e4d44f0591135a87245eaa7866f49046e764facfaddff76c5759fb7e58c215dd446f8a81ff4b8e48154e6840c38cd961b9b9dfcd55fd605880bdb8816d877fe1a53237b7a3e056f60476ef3ae607725eab95cf03290fda825d9db7ae0262ecfda3370e5799ea77dce227ed43316cbaca2bf61217151d703ad6801add7891d374353de6bedbf63c69bf33eff12c937df5300f52bfe07f7dc12f197e7aa071a76e0d2e3eba64f99737a8fc0f413b143c8a068e64fd7c0767094b46945ccb76ca3591c0f7cf02caf00254eec04585a8b9e38d3125283c3932fa6ea02999cde821a534272b267df5be0aa822a18edbd174bba9262d0f43a6870b2a5e95e8e673a00b7de8a0acaa0f38d78523564b7dd045c151e5c072f6e8d4b179eb36d7775d3f55523331527c1af2b623b4c894da1847a3bf9ace1eff733eb1dd0a04c09d8b378e9abbd00ffdb9d9bc8d73fd4977b8271240d1ddcda20bf41e2402e2f3085dd9ccd4ac881455a22d46cf9637ab93fcb3e4bdea1facb4f10fcbcd96fa21ec295837c56148dcad04c34a15db5aa2a9b0b4098493682e9d536acce9150cdbcfa62015c43473d58e5fb1f30adb8905b90a4426c81abdb345696f21da4bd210000000775500fe3a11d75bbd8a575414493dd05e9089d78918012e60f09610f1d957fc6724bc66eb0f0ecaaf9d040e31cd61531b5b950991637d97ec4aebbdd68efef4fa42b984809bf91e21b1b767d8550f0ed2d957fc61db16b5bcb2965436e5e15b76bc299f66f30d459eca6642eba5b5068cbdb38aa87def567852f1adce0d08175390ad6b1e9db4eaf8a07c11fdc7e68bbeb66afa3916aca2b7e9366cea55c60d643ddae869ef53e95a5e24866168c106f6ed019c0b120417c64b479bd973077c1543ca6242a05abc1d48e778eaaa3b3bd5e45bc9d569f372189309aa91a927ab31f67daf8b45a5947db1149a9ff29a4972ea03b0b238bde23599b4068f4075f02bce308631ad3b4a00babb5fef7a03a6a335a543e10e360824272d7d17b9f169f1a9d39e941c61da753842870f3d058192ba9b808376e08a5879c077ee8fca7228f96cbb6d694d6bc10be0cf5b718389378115e38943a57716e5d98041c4a6b93f40e2a781728d98d9965784f7404dc2fc7b63e3c8af12992afe5322284fed577a9e9c866a590332436b08fb783891cf1cc7c7b4753d24e23feb7046f90aa3bb9ec1e30ed1dfcc1f22e78ee63e648ed3bf949bc04e47f410a3441d614b912a8e7aa21ffbb15fa2f3261cddac3758c6f5a54fecf3153d7e168c0aeed75c91cbef8 + +pk = 000000010000000700000003a61d708a980acafcb08bf59ee41d84fbac8fb29c8713a2d9ca6f42c2df089c931619b265671140e35027c6428e2cc18a + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W8.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W8.rsp new file mode 100644 index 0000000000..cc7ddaa6d2 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W8.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H15_W8 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 0000000000000000000000047af430445b89d9b8c82509c6d6e14559a7e26488764d076cb6428ec25a95afb01d0fa6b245bcd544909ca29bf1787ea02eb45ad125a5aff76f43fcf8d58c8c92559e4a1f99339a26f66a75296eaef6d9c087606dd3df5987808521b95905e0a6c7119faa2e57df8e1ec02be9d1ce346f32d465eb404e928080dbbbc6f9994bdf9ef72a44948a0f69794401fedab887ba9a8dcf117650c5cb45b239d08b9247dcde09b238a5cfa5fc26aa00f2060e7eda5bd7d5ce5b6037475185b0b2561d8851626b2beebe8f12b1efb24bdb9a86b657893ccbadbee0d04efb421fa494aa1dc926a3666a959313d08358dce4d7ce16b23e36cad0c26e56e2d5b32afa744ed53310fceea855092a45fcd7058568cbe4508d511b8bab52cd30a75d3c97cd1a42e7cc2f16a6242e8e10fb498606556d6e65e2f7d55294560856f706cddaaea7f3d495d4d0c6b655cba91b211b7d79dd9e4cb4e8c44f187ee7de6312c39a99c34590a8f50141c31be1efd6083a8aaf36f5da7eca4f66fdff1d984e764b720bdc830ee4f6c7406c2b0cf0889a00ed51d435f0b31c7b9a10eb8484c64d3d24cac953d38b11c02047d919da39782db070571a9a10658eac751c19eca9df0b0a0f68916ae4830f56d28eec5f18341542bbf2c8652b44ac354326a9b2a854f6326ae920f4f201f5f71a1c698ce69e9964fe7aca73f9080c420fffc8fa3838194ce479c87e6ed5619eab0bd317b84485755a2390ab4b8220d74b73d14087ea334c14f61bb06da084eaa77aa99f13b62758e6a83f9665999b0f86f92c854a1e44b45e5cb5209193025d78bc7e5fd8300c91740b444ae3cd3880bf22927f777d2833eae0d4792b917fae8dda163cf4be2928e8c881d0fbab323a4925657335a5964f2cf295de1d4c1817be9a78e89712accb11e4b02bb02ef55e42832f94b293c732e1164e1254c6597053620fd88b78d884106d98c88f87756656ab1fab40175542c4f716340d485441e9af121860e971eb8c2b26d8f5d262d09376e04c8cbfd79f5c45261cfb6c290563b4ea0b62c6464d40d1ef036a2cbc3e8e9e227c91798fc2018c393ad54a6709a8b13caa03e2c0c8cace8253baef126a4e2900ec69bd79e2a99faf088795b894b09f002e8c33ac189346003372543b186e145f322630883a283b9c31d8f0679b9fddf0b3a551c451bce5f9d6e47cd113894d723accf6ff6a28e37452884244456f55cc89514dc24585b458725595890c809a6e034e69135ce605bba18d813a3f68f0a91595b3c301e955a283620e88425d3ce747e68d081dcaca159d269adfdd8901920916ac8dc652fd2b019d86342d1b92e3e8dacae938fc14bc775021a8faac81f5722446c8e9715e23ce5c68a114ad1611a6e146dc80488d4f359537de3b44bd3f1b7ea74d045f6846931bfcf1747e089c75a5ffd2b7cc7adf693a282966d414ce7715fae6064938f7db7006bbd98c70b661f2b82bfe5dc4d30a9d7763e4be9bfefbc63bb7c5d4c8da6c9adf6a9e1f20025bef2564fa87886feed6789d555ebee11bc812660b5e5b4b54c196eea96f693324ff20646e1e4dba9400000007f656672dea662ec5bcc26a23487368222eade00324f8f5f72c9111c474af6995e54f45a1ea3ede6d95a73d863b1491982f23f2ecada075a63512600c7661590ea4097241a052c5bcad87ba7858e9d5458a9a7627c06ffb3a7351aa34e7654ea893deced8e5736374ad7a3efae2331d3f4ccfa90ba46871258a920ad200f575b755e977555f8480b3b59e1e5aca7300654b78a56befe6cbc8f7194ef7b451e09644d4220ddb8c52ddb9029d220bc3794a26581e2e1dab769184b502f32141242b0f73f608ecea7f3915e7e4730a99dca80a672cd4ee902b64e15ab4292e265431012040373192b3579d916b8cb20f746c512c065eed493dc15d7af1a7836caa481a3a0369373debf8061bc276f8fe6cdf6062c607457bb08653baad184ce8dc6262114e566eb3e6917a12977028a252d27b4d20f88a0157dd5bcda24fb14d9b55a4663782d6ba567f424acfcdaa1ef74e3b4467f42f78cb1a75e5df72d2f3f1f8b027252d2598fa3cfe6cb30db132eee876479f7de10a3988bf5f9f828bb34cd497307f92d16d14ea5041dcb7223099850a79f6411dd01eae4d04a5a029c6c32f728f778728492ff47cd2867a830a0c68db065021b163470ec315ac84d0f1086b841651ed5101170aa822dc63cd76d198a44d50ca755cc39d0cc421b9923ff4e2 + +pk = 000000010000000700000004ee75d92a6e0f472dfff23ae76e330d6175dc24edee5b25641c195c2c60ddbfd9382942405a37f4bb4b3bac9806603507 + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W1.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W1.rsp new file mode 100644 index 0000000000..b9d272dd0d --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W1.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H20_W1 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 000000000000000000000001c0228b6816e9c280638c69e725851f996df55bfaa61141788b213464e517bcfae1e2e52bccdd49fb616c682c3feff0257c25f758fb41e031b0de1999c68856c95de7f94489ff58f275cc6ae9084c0224c65f015b6a370965e4a16953f311b2cb2020f5d7fd649c2535d47409f7144817fcb8e3cc6e4faea1a4e49fe32af89087f7c992578df860af90f4e1357c3be9d05fc5b2dcd23840e708847d65433412df9f238afa72c6a7561b917f3e3313e44628daaed4663206a63a39d8e5eb2306857bb29f7667394937e7a9a7a1b3ab5e231046efb97028f0ac6bab86e2637c46bf164bcfe7d8613d9aeac631a3af401f562b7e6b24473e7c22d7030d27bed9ca721119e1b0ea2b195fe3f9b2abbb0ff03cd3fd666ce0d1cb94ade5a8b189be3bd888a21f41e5f9ade9ec1c377d047553185aad657609bd4356936c60ae1eb29ad56ff4de54b79a9027ab406e9ce8f4b5aae8fc4ee3a401950df35b3376394869abfa8276328de1e2b4d17e8d3ffa1ccdfe80c808514401def95d73c87c9af8e301b03ee17ed3a6d3a6a82664ba846600b9b2482a009cd1aaa1dfc319ee98e98619c91785a6f404508748205992e12f115a0f35640598241a5c320151d3d7568385d79cd8e7fecfa570538ad82fb1a5aed8fb13310f1791b9b885d638c182f148b9a035cd4774f303828a534c33590d6aa4cac1a8f51717694662f0995912ff63856179479c35e93fdcc079c3a7ee4ad220417be72d2634d2768103b5c1c9c7af1cf957cc89720fdd004da77a1e2fe9cff04aedc64b13f5a509b8810167aa2014a4036a89f5b4e03f72348882adf6b9aade977b6a61b0cfa0a789812c4086b7c1d0ad78fb0ceb59e246e06caae90011cdda63af047d4eeca24d631f72cb83cdf52d41814101af0d0c6261b034a9a5588945f046616f35049093ea66ca788cf7cefa41de218915ef934ce4c2c883a1f44682bc450fe8e78c5616e4598443611de11394d463744e3896f9de8c63af0e6caa11f4c9f1668f31e43fc7b78803b089f05314f781cb9c60f29f65f03fedc199f0f953d8f120b189977d028160b15b0607898722709cba176df3441894959dde46c52cf78987bf102b1ca44290efd51ad37fe969b2177e24983c4bd7569723c4c13ddef10222fe9277346e67db8ea3c7eb11e598044d514faf74f34c25e3ea6891c0a1ba4b91f1f0ae79d5a36174c342bc58e5dbe8840b4aea026c4353445b1068b29dc6d42632c2742606615b3c94116694e5051ceb193c6d10446f3529e513c2ac81e3e69e56db86dd17672eea3e6a4bd35dd8be87919a853694b65f439003e4631ee6a2ecf1e783bca8e87c5fd232ebb068fbef64ed41eb2e0c1f6ee536c23010574a23d5265bafbe40e6cac639469432d926caf4b3c3f9e04a4cc232b595777353f00ab2efac0a3d1175c1eeb9d9b160f7af3d2859e17efbf7dd5a3a9de48e27533728161ecd5880e6ac0865b4e1f2a5c517c449e7f336546655ad546d51d77b98f65290b003a89fd7f187f72daabb36010898709f85b959600f8f92323788fbba6e4d8c10c352f13dab5f1ad2dc5bfb3753b4b7f22207a8a591f1e291c02ae53b3c5d593238686907792ffb6118d162f8e8a884b8bf091f5a788250231aa5660f87ade9aaf7e1e87dc2fffaea7afcf584e6fba8cc8674b405921d32722f34002a0ef915e0c313c36b1e3ee600155ccbb0c09536256d83662896c4dde681747289dec9c9bada62312df7e69f6140b036a45801405163a7aafce19c642ff9bbdd807189fbbe5c4cd7490cf291010d4d3e7ff0713c611a3427a28782456c09faf1c40f76157a39adf0b805ea40070b08403821e416444f904e12d243cd2d92f026dc6cb4b9bdb6227ffd4e97ed1de4f7c23e1670a51710b60478ccadca849aba66871020d799f3a5ea4087fa0246ddaad1d4e7e6355076bd59a1c02822aaf12d1fb63a5648cbe597d839c142cb14b0f1998ef266a35ba5eec1f26e7f6587425cb3ffc0be475d56446a45bcfc45b781c1a8c32c98eecf271242a0c69ae67f01e6ec4df033b574ab143782ce393de71bcc0db84bb72c0319cf089f8707c3926eb0202ce01f08c548f579269e9f32254a6d2f8a83ae6ace7d80ca4aca63e08ad5169997c05b6a809f243f5c1e3dbd9d5fe0dcd3cf77cb17578f09a731d2a3891c8a4496ee62f87d93afbc9ba68039403234cb1e552133a88ae9c644c6d8504becbc5f457072cf07ba6a02cf49b22592d1963e01359326e476da37a439fe9c52c001519de2e4228e34c10e99f897749156769512ccb6efff3dea10fada8e1d49924f3c4b0e9f8360f0fc9c680e721f292d2744370674b1780eedc8e7e106024c5ed240dca97b0bc91de1d4e39a3921866785fec13e325ee3042b09e40b804b195eca06b488e53f0ce7dfec718004a5a3f2256b6044e8635cf8642949ea9550c9ed9ddecedca7bf886fff103c674ba334aed47c3734e7c0c8cb50f4fb197502886ec02017c18dd94d5df6e404e6312bad153abc8ac5d8c860f3b6d35c8ca1837ff40a35d55b210ee7ff6e9e9efc5617398727cca27768abeb372a19a79db130a5aa7e17dd53805d8c9b5ecf3b33bcabd89ca491c8b0dca65c218f03006c29ab6e145b7f4ce12df7575712a93ae7ab746ecac67358fda8b96b43bb144d15f15206636cc6d5404eb14bbfaafbb9c967a5849b1472a1829dc41e9277ffe2a1252d3346be797fdd6be25a203006fbeb5d4c44e2ac95e9066838d199f2c5fce7d6ed825851b6ba51d319eb50d7379edcf054d1620ac4d9c74f0a9c3339f69627ff961be41a603423fd5b23c8fd42120ff6ef745d72a8b82528edd42e0ab00a1bef3440bd671312a4c134f5d1e25314043c48296910cc4084dafdb0b392526b68d79c7a3cebc01300243e5de21a317e53f09e4b65872d769c19b1aa72768b3298496d5ab64bfc993c4ad21a25f5864d53d8ebd1d7cfaaa7ac12fa517af42c4e1d874ca356bb4d40a55a3276fe42ff468bd45618342baf4bdabff943b76a9822104207987d9278fde73e031e848183e11a85580aa99538ba1f69fe18f7a36e38caa69982bf62c67991c37632fa6522352776fec155f55e134b64e6b688a3b0734634a99b545aec48641ffc243ca9e6d83b203f6bd529010b99790779f5463c7ae521324cfb004d2df83881552215168efb59ec495d425f5d51f6c25eb4a4eb066f45fb754e7e1d869981d4ccb46b54554ff41f3a7228c07bd8ac2b4cc7f21a7b59007eab643581e89340910dc1e966c93e2b16f6b42d6638a95ccb1456225c4e1f16e9b81c6ad1c681a7dba004f60f312b15a34958b00198e19b351760ef7f54137096af6ee388cd3431e184f3fec8527fe3a9dffbe70f4bdf688ac845699c652f6c70c588d4ca1599e8274a15843d77f82b34c6f85571b565d485017b35e05da22b8428278e97dd2ea96ae4961ffe02dded0f1026af739484eb97a259c7a95c367e5408d527ed08f7e1d485ab7b6e806a6687c7bb4bcdb5ee6815fe38e83ba6380905902bf2a19f26e3811168544b68476dd6402a2ca14f625b0150ca18fce52444a93ed0004cd60f013e68f5d01335eccf3be61ac5cff0b67f876db0368a779f98d81d0f451bc353cbbe57d6d54dc450582f47c3fc626eadefb971f6b570ab943d02ccb016e90ac926ba73afb1d4c03f55b355143aa9356ac9821c53e2b6552369c5607b05cc2ecbf3a522cf2c442cf1341c42e06517f7191a7195f2e80f93d78b4e6ec0d65ccaf946b2e95d1e58e19d4601b85a8630a5d44cef2439eaa4437a99e743d5fcefe8f204fe3a02d080b1146423d08cbaa1eb46ca0ee414db14e9aa81028ab1ad4f760089c84e83ab5bf786ac9d8343de08a7f419b2f27bdec69c4dd36c905880b13c90edec09a4dc10cdcf7e045a7700c538837895383bfad6fa0f3820cc147dfcb0c649ad62cf79f97447b2e8001f68e0c59639f2c5e5ccdc7c8c8028cc528cd979a55eb3ae4aa9716ae9b8629574c37bfd9790f6027bc7e3053aa580e5af824199d14bd0c0f00dfcab665bd255c6eb367e6072b4eafbb68e1310eabb0be06493a542bd394c106a52741030e20d25ac1956485e4967fb8d5cd21a4e9165273beb2853d8c85de85a68771e87f57232eb2e600cd912a41da7c56ea0ebedf12db3b160e456f584ea870f13f973d7ceb8069a96dea7fb355d3ea077ef5949ff71a8f33b1e2d2b71d7f6b671da32ca60fd100e1261319bcc54eff8e9602ba4a5e5df945203b3112764baefd20154e662f8e0738ce867e4e8c13ecde81750981ab29c366a9709df04f5e3a425801125ece6029637d0dc7a15a180eaa22bd6105b6a774e306111ccbb4631316965aa61b9b51821c0d1bf77ab7f8227f60b9209e418fc90263536b5f616bfa23285a4054a9302aec6073d4eedd896415a4a6afb20b406e51914ed1f04fe83fed971e977c89cd01beb90e449ed1270e61a1dbd13e2b111d232e337d5d0813f1a89950db909b3bc3991cc65c54ad51c07197f3a6887a2d6c3343c7e708d3723037e1a3dcb5c921500224100aa6aef3d877993632cd3cf53702844d22249336cd3bbbf3a75b14958fe79850476ff9a142787484b134cf2689f48b3f3ae9f847f6f3682604fb7b58577093f39e65a2f9bbc4cb041194e62e9909b2104ff2d9520b541780c60cfdbc039758fd3e822648e0aa0de4507834a790a57b7dd3651b337e7757768547d92b9f3a41441f29dccc3d32321e445a3466604a0fd9779202918a172005bfff0e3d3604335de16185023dae0e5b06ee6dd24d5232149b5a2c36619479dc5d24f56a014e73431fa5562f8b4952d132ca77328b94c121fd63dfb071a881a349ddf00689b35066822e35d79203eb8544cca9f46dc860d6931b41e9cfdd0d68befa32ed018a4e40e989d22eaa9cc2b6bdd076a698e555e0ad7eb8d18b559e3bc1f6325a416c4f20c45e91f3537839889255c24498abfdfc62e31a58bb3c4adac6fc06c02ea797181d25a471788606d0b6cfc86ce9c3b648041be48238a76e48d21bc01c6089499d0ad702ee3a8db82c0b07e17801db880477bf51b9b5c5fa042aabc45322c5f2b480f291d77cba252b1b807e317851382bb4b9fbdc818baf23a84bb3e68daca17d0679b3310c70d261a541681d8ae3868aa4c82b35c7f7d341aaba00e23c39721692b4fe9f4b370ed737ba1a1425f1cc7966d06497ab9fc3454d51251c582d2f58ede07cc6ee4f5afed06014a1565b4db5c3291e05ef6724cd426cfcc351abb31791bf23fd02f9d0a94adfce6a5ffd0649dd731b716b650a81aacfbbc0f321e423df0399197f0117987726bbc5066befdf298a2626cdbc9bdfbc8fb4ca1019e10ae713e553689cfd262b0785f89c387223d414083456b14bac872b9d10d244585ae64c247bd49f89bf931b716439d6b62f25934f8115c5bb171878f9f7d8c2cc313ad461be60698074adf388ced446609d8ec6df763711d7c0a6b84f39a1df7b7b91dba55b2836a471c6f4b1fc71c63f2c7a902664931af1d533c28642fe6e1e7213f896b96445a66c02a2d18cab936298e49c7475cad39727ed018ec06abcd7f127899d6eb3c04fae1ecb4d898e31587cbca97c5ccaf072aa3b6687ec73049a838d39fc0eb23c9fb4e7f3cb9bc8ff59035948ba51e1b6227616e07ec238bf73e62778ade666ebaaf9ca1fc8f75061a274f05a81b453a82919626a5b4806bc90fa9e67759c393b2dd01e4355256f675726d0b427efaf9249d8a65597d84ca5202a2b25099750c5caecd998b6cc4f096663f2a22408a3c30a01a1a55576dfea2248ce9fe192d14d2c7847f331ffc55facc83ae63de3f06ed4da61a680f5398ef17de35f839c00561430d6d5f954045fe73cf4e4d5b5f7a6da31bebc22e7efdc09d2365e16fdf4005657132986a8b00a3e42803a0e7c5536b1e676969d710f1edae0bb10886410939aff6cfe873103c170178b3767c82c7bd517c2a4c9ef780b407c4d793bd37cd30841bd4bf92cad75c92d42b523f274ba5a5e70d73a7fcf4fac4096cc33f5c1fd414d98592f1dda66038dd43e279c4cfe53a7491151e534fcf9a0dffe6d8ab9816b71909d31172133a8688e7f6c686ba9cac6c3b5c3b97349c6d1d35159e065f8eec03ea00dc13b8a3aca6a214e0dd84784d8ca3bd7ba82f3e8b72fe9e795eddb1e40b892d22e678b821bfca547e39cac1d0ec79f41cfc838e12246a0d4afd25310cd8978511fd1350fb537985f8492dba75192395364f6139b1e6920ba5f798e4f856e4f43f1befd17efffe5e53e31c7ff03cc78dce7b262e939b8bc37a8c364272806d3c726c0b30db4d3604bf5511771b4c14cd17a15afa7a25c85427d3aed70b1f54dd6227ab2d134a5118decf9dd63f31f20f19c82bef4dcade144de5caa366ee7fd56d77850e6f49a302f4f3e4daea513985c2c6a56b9ef68b1150da5445fc7ed014f2630193640b0c54cf30e6db14c229639650e90131d8c2074551d9bffeeff5005293add6166581651bae5db6d0ece72d6393cc3216128b5161598e170093245a1e068b5b3b0e87991eb06622fc52796c79970ff7b813b952ebea86373377a7decb8de35fee87e00d7ae758165f2b244ec85aa96eceae5e37021958afbb50e81a9553b6358003f042936d15536ecb57d15846413cbedbc124c01777f0973954c7d93af230716526eba5bd84f0e35050c74b075023759b71074bc09a77dc1f9715cbd8858bd64068b376fca1b28e12f9644d314a31ba2a54f0a9119a04bd3ac40beff7d79d110a9861b5362b157dd5364fe9b778ba940aa1bfbfd88e9eca65b6f9cb6ae2823a056897b6fcfa402490801e3dcdca784bde34ca6e02ad1e3c33a2a21e8d4990d52ebb363119c30de6c6e882bdeabcec6b3e9fe55b5c2acbcd1ee39c4800d33266723b7fbfe3b2714d6f5de746fef266d692f0748906caedda4e7366dc8e515bfbe033044ef6694731f1fdac5f732498469033fb0e89e6a6003ba11eb2e75d131542c4ea9ce728282db5dd20254d9814e91dc8efeb3f11467c9410134a7d8f10201c6d6a6dd76909524a24138da4afade14c662ccd901f076c92321e2c55375900668eaca39aed979f25ecc0f646d5ecf7d276369b9c400c64abb86a086f8a7fbc87c9862ddbfa8e752c125927d52ddcb177488ea6dd486c9f4cff3979cd2a7ce422a1ab0cc5f50d9b04ec03c3aaad923c97dba8702fa573f66c3cfe48dd162b329ef8176f254292dd48197b67bfa3c2d4762d1bbad6b713b5da53425d2fc2ae192a5936692927c4d8b4528a6cadf4db389aa541c5dd217709b5be86d8d680bb408d7bfc3b4b6d74d66a07e7ae19aa4f4ab4977980741f026d79543460856e14c0be10fc7cdc8fb757b4d52072942693ade204e245f6cb7689a8a2ed626d73efea6d52c5f1fb8ee532ad72b069bfada33221785796186303a90620a809c07c051701b7b77882b00e243461bec75f00b82a009f91d26a602157f9199889c54be8e4cfb88488ce52e8ecec906d658228954699a533016e61e6dc2baf01373591945bf42fda64287cda318628e5b1d50f23cc7ddeabb49137d915621d47e8d8674ea4d28d66ca97d92b5a8766701fbe0e456c3c96cb981ad8fefbf7e2bec0e0c6e8416b6b16b92093dbfa70b1f22e5134b437870ebce5105c919ae78bbe11cfbc9f67b9b3a3f32bb7c4b377aa7240d7cb57986a69a7b09af890df89aa302b02dfb1c1890bb12ce2867548c1f82759e48809163b4dbef99b25a0530a379e4a6e9c34323aac76d6d0e2402d9fb5913f69b5a22bf963dd213009b2816f0f9aa40d1a53dcf55bcd4335cb3e4946eb692a997857d3fee5ccd3477f2c10eb7350940394ade01f1a0d4d91be111413b2e3439881a1b79f65b9293b743c9dcd4b125ba5a832b4a40bb0ba3db4f386272c7c197a0e61c33ae0faabe1e77f7be21be7a7c76545d0072d3ec5de25dfba72fea931b527e2753b0dface81fda30a6a2aa7a82508cd0f26c6b2618fe5f79ff649dcfd5c7aae489061d848f49fe3c3c8ba76cd140fa02a83db417fc6c5dbdfbf34b841318f86c7d3a7ffef5d3bb10d33aab4c6b37919bcef9c8b799f9c4ea1d26017a391bdf6b45d5eb1a9996b6236b8ab3296efa5e70b6a13e4fc22b9c0e6b51ffd13c079f05dc91168dd9c745452a57c16b68a138212946f1f70b4ed0334e6001c23bb8304ad95191870f5ee2b25e16c20250446f4c6aac9032f467705beb550c5493abbb9a84d245c4c80f5c6be3f40d8a3067c10a4f647e63ccc8047b1c48a904b2eb4c78755df457d5e09a12236e09097692dc0f5b87c9738fde4a863ff925380b62c5545b326403cf0d0f00a417a4f0e59a1d637833ba1d763427a5df1f291b94890b115cad736b387f106776c5c68258587960663d5bb985b1d13e35bab772046d79d6eecb8bb0417bf1faf6f76ada12f0c9a9a3a1ba15a376d0475a3a4bbe33fd1bee878a112bf7281bdc5b60b126e2e6c1c8ccc8731d0bb924099af1ea3b555fefa367bc9854f804363925c1c497011bc2b47bf938d48220e0e8a916b075cb52b24e4233d688c33eee9b6c00eb6f1c4f78d2dc8d59f759746891a05cd990016a7b9aae3392b23ad4568a0f727f9f73de9bcf66574b381e470d757eee50c9e0a208804da1ce8fb5fc2633723595c89dea8ab17b19f3489b1cc43c4be2d9762fe7f3233ab35bf82a91a097dce2957cb3ed7d2417fd5164919b8f3a9e9ba064a194c1b69d999e9334cd6715a5ff1d5f653d2389e1f10f9c2841bdbb5d1241489dafba462b0aee76eac30dea6f20625bcf7958245009e839c325774023e8da431c3863fda3667836678be1c2297c2e41d2620109299dcb1d5b1dc2e5b4c45dbcba88cccdb33b962f5fcf19f54b6a41349f2e6725be606bc89aef7ff6a8e19d01459e007658d5d9a1576b22edefcbfa1d3a58fd654f17d9737108db5851f7bc3712414df1490ef7956ef109138214bc1f167522949c33b7138a9df39cabcba58701be56a2f9faf9b00c1d8c20fcc3e5188580a4cc3b1c175e2ef9ccff2fc1feaf3fced006502e732102d4f466e3c67b2deb7de46d02b098bf633306f08b78726c420f8d2a879f9ef7fe28fd09b4933a21e51b9264caffaf819f90dfe7f8b08698429833628bbde882f6efb266858ac67c297eb3c7dcd4a129f40714dfde897b996846c578c3515fb5f1a6047bddab51f6c3bb65bb4a7dd8176795a23309a3c79755138db59c4d102446114146b209103586d007292e8ff01eeae492283470fb8ce36a9862b476107e96c66f4422afdfdc1d9a9c5bd43fb29d20ab2b883d02713e7732dd58c729fe46b006718b69b264c13dc4096797a846e2c9e5fd4db0237801d9fed1ea104f46f978c6b040f627ba5cdd9e175d158bda4540eb9b775c17feeb5e2b43776ef351b649209ebc8d7e24caced0b68f6c83492405732c36538a706343f562c2a773d9045f6d809257f5a622772a104ab91b9819feb06a9c7c7689b046dfb6531bc46ca59af211eab34fc3a5abb0e97107178e33bbb9a5a763288a0eef707d6a450d399175f3df009efb17a10dfa99c96cbf5220546d280c43ee2bfab372e33fc7963bc9ba34fb9f249af84e10052e2a1fb3938f47fd464c6bc23b484ee240046841062b66141e9f791e5f4b7296abfd557947dd40c19404b03edf37e3574b2daaff918848f8e6e42fe167968a15c422dfc357d25825dae7d85921fe6235b64b2287df01686e469f11908eca1c79b0c0bf7dd852d959a89e33d83ecc227303eb6cb96d01e42aac20700f5b6772fbd03d838787c8124da272dbaf483ca6f74292a2b94c412a3fbeed8b027d4b49dd4eefc3c552bbcba74dd849622eb2c97340335dae7c58867e7f5b6f53a5baa4b5b27828916d74e1ef4a5cb0b571a52122c442fbffb76be605470c08cbbd06db2c829500bad3942b366108e2669a803ab88463702591ac552d6b20ff3ed8ae44c8d72bae401a2e4891ba6f68fa9ebc5e1c9ca0dea44a605da9a8977a5ef9453cc9a07b022726c8c87072fff9b5589a223f0c74707ec7e963e0487883a535d811cd8329fca2c8b536bb404761da5eecd4c6cfc8d4feab27340c29ae44b15114fcaf02a6bc8271383e697a1c8680b21ce4e22a961572da213dca40db8bfe68469afeb109ce524a0b906799dbaf4bc98cb41d5ce14e38320a9a3289f37e15dcab9dd07767b43447c6c04c65004ab47b4a03e652287325d313cf8ae129a40ff473bb472719feb37255707599d8b5b0e52d5ef56e0f4858c15fd7cd53aca5a36e77c3523e4c4f8028541770058b5d446091e6e67f6054fc11bc0b67ff07c2e8b3eee1953c70cf379a4344d1ff0277d0c3cddc749b6d92217d0eeea38c669d27ed521028e342daff82a5efb66b74c4fc65ff31c517236f9294b91ab8d08525ceb6f4f7a2ff6f812d75218337a5ce550131fb4bcf00a600f2e3e5c09709f6c801cb93af2da05601dcc73e47b6e46cfb011562132567a6c91362bf9db2710bcfbad097e81a3e35e3c53efcfed080760d93b3e0dffa96c4b16cf72ddc0d62ca91a4116a69536a22afeffcb7b1dbd79757f340fe7ff7e721044153e4e5f353a259d8e1546a98b7da7a039332c4118e0196a31c03077adb6b764fe9b34eb31b35f983248556fb5744d40e090a955759709df56a1e469431a510351f74c30a638c82b37b5555746ca1eb4176b1ac8ea8d6fa8f9cf5441d670d3e0347976be0d524b2b04c6657978c5eac4f14bd7520434e7082cb17edf5df97810497fd1ac5992824c8c52be2dc2ff130f3de8788a6a2aaa843a040592e268cac01a1f9bccfe30d7906af9ddef9c35435b1f18446c6a1221f88c904150694cfb01764ffb020e3a76efbf9cc178264b4ac5fb532594278e67daaa06e5f968f177a4a546a4d424dd4092d1635e9220c60d608dbfd55baadc6864a519ef31641bccc870a5bbc8430c779911b171e1e445f25f2bf79f14eda57235e2bf857d301ede525c8b5927b05f9a745e4ebcfe85c0a69af2a6639cda72c75fb1080c24cf602b16f7ac7c39f5c62900b5a7c3e3c864d6ab7d0acf6c03c16c75db3fd9064b67de88ebbd335b051ada9c5fd1c96d907c58adfc3a9e18d7e5e5ed50ac942d140d418c3697731a505e53923ca12caf0b9323d12df0f2bfd4b1f1d6f1534e55b6d0dbb94f3e74b710f6bf1cdfff0cbd6af49de716d89da6b136c88d8ea2ae82f908ff679aaa2c294dbdf5ee5ac73d0abf22a040238314eac35aedfebd49cc52f6f54c9ebe8299627ec1058cd82b99a0cb269852ddc8d9c520bfef9a339322be240fdc58d8b7eb2fd38206729255e2d5174e3acc3c88e144d039f25b6da38255a587d16be6929c9cfc2ddd08a6bd41a6a3e54bc3571a1ab1b2e2797fbfe4e3d469383de2cc4de2e0e6bfae99d97a936e1d354c92f93be90131397f35384f2889db4e949709a00e5703d80361c88321233e2eee03fdff19d012967351fd7610d0b0b38f21116ebc46abc56d7181e7dcbbb10de6479981ad536d9d9b8a817511f949b4322c20f0b40600bef17fc572653a1a14787a2042bf1453bfc0d9aa878ee7e1e5842be2d51803740e203d3530791b0ff6578904f90f094d06d9077d6488995cb37f075779b3c3425f3bb8fdd2be06ef877a730faf45d4af78e1c5b537f089ddfa9b19d17ec8a3051a1165f77029f2b03634723b24f7dd4cadb229f59c6a5fe15e1d07c582909d460f34ffa275838b0bc5dea8bfd0b95ea75ddb1732179120877064a2b91deca0163b96059a66467262e0544344681f547dfb6ea22828a8e18def5527ef4603f3641954da0d7554a58aac51b4898505413f84e2d0a387d86781370642ceb069a9451f35590fe6cc5edb02df40a11fb494c0c5e9c6d9690f699e1486ea14e053b6f2fea5b44bfe1488ed8ccf51614780880d22cca18494983f8012669a829d565a5652bbe2132d1954815c038e9a34abedc940aa10e3088a659300000008c8f1e9392a53c8ce2ea53d83626ee04031d76b225f2defb2dc8e3d78893e9a6613e02d1d2a36e2d9a8bed878ed678d74890868b489e5d9d1304036211350bb64ed0c11784af90af64dbf003dc210e2976fbaf867a9a2cfcdcabac0e9c4ae2a48e086855d5b3d6b28639f43a483bb27d17e883a1150b9ae2fdf1be6a31059182847f5d1e4c099750b3c7f3c2dd28d85ef383124d035129b83bfa588a507ce81514671f67958d1647240fb164997ca028b0630d6468898803d914c64376b22d1cb957c7b0d872930fb4a1820ce0a9928dc8896dad09e8f7266c4567426a909e1c54e39cb9cbf3a4fb612681e5e263e3350dad995fac91f22730d7d57bdedc09f1521b807f4e51f306b9c7af27c55db874f9b95a7c816b954d169ee4982963c0c7f3459510e311bad9381889f3b0a8b61172cfb8f5e787b8a956fcb9717aade60376547e8cf44e0e8d6e661078f63d5708ce36800ac3579d6dbfeeaa70c95e2a92b2e59e8ad96a2535054bb72cd58882fdafa350cf342d73e0e39a449e97849c61d3367cf7bdd18b0e7632f7d00a12ebc44c449f5941bd4f5751f429c578173dde171efdffc750a4bcc9cbe1e038a8b613a77c22ed876333e69b8e39742d11da0fdc014058741156912771c9b6687f6f1d37b2265b49ce914950fda134a5e90f7ad4677b0b5f75536837cdb8871383065333f6b7417487a99179280b413a7636917fac9b0300fbeab9d50243ab02cd3c45432fdffb348abc206e83b3bd85da6f8280c488909e487df8fbb592bfd1850ff2b06d1e520d4b460b5815d1dda2ae095f694881f6a8b49f2284d50c2a4d035331d1e9bdf5d3e7bbc4839aba234453462ad4b8b00b463419fac10612f07dbf2e6d036cdc4fca84f089055ad4c734ec411e4 + +pk = 000000010000000800000001f8142f2273c3495dc1e4bced0300a27839572bc36123d71f3bc6b847841ba4c377bd240deb05ec3ed15ee30f7fca56d3 + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W2.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W2.rsp new file mode 100644 index 0000000000..46b9405c33 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W2.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H20_W2 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 00000000000000000000000270cbc93eaef8347f7c263187859d5aa45969e78fd83aa3da69ea10802942af0cb7d0a433a5b0e39993a0200f7da84e434d0111941b43ea8819da913e0a955d7dd4c05fd2f719ebc987363dbac1f0db8bec4daf210f9aca23e68e5419ba0a0683c96965703529950ec0b563dc7616e7ad0feb9c9098c41ac82352f8f23b49f9c063fee47599a88d2580f3618f95b221998ece2324d10f5c9aca92d0b9b065d29051e41cf8242a5a6ce2562d28e3e8fa29823fb6ed5df3da56195bb01f5fdd7c62a07a3234e280cfb7e855890d7cc6423b1214155683b6a30f7a85dc2eecd4ccdf230899c31e819559786b81b1f7ab30e8a288b971eaa3c483ea0a13e5447fa0c0de47efba3e67e5759608702b094980b13d9a53852c8de6991101310fbaaba8c7b74ded0d53f47005dcf6dcdfe1d154e13308543bcee4e5f91197d9ceb9ffc763016b2a683f5b180990c126dbed2ab5d45c391a152bc7f3fefd088f76777dd6f24b12f3b9283d7108ce1b1d1ca1fa540f7100b62bce0cbfccd71f64f34d540a1d35056887ac069b4f07bde01f07eb2d2603884e396735e91aec35c93bef29fd5201db70e047e938e3ffa307dde005b7803f0699bcff5c0f9b56da1f13f77b6a239c7dca93be5ca1b5eff0534da3a6d22dcbfa312a95769c9b6894a32b5308f559a51e0eb6287d6ba51820b1b2c57fb75b9c073830735a173f3449356d11f4090b6f67c471200430a7a1c6d05158397c413be214ca194880484eef3d8e6072dab6a3e649194979b90e39e1cf243958b614a401ec578b1b6a2c0542a91b06021491c7524d9648dc9d4ff4e8590a2c1cbed9c8be58b29576625488f0caefaffef05f9b47fd9ca320d5338ae59391b24b981c492614861ed5a05c3dc23731d363b5d0a4efa8cee7f6b809ba89d6c3bcce1ef5b23b47dbec62d76cc30e7402b93954aa3ce710413a45b810274fb7a7ce5044fd4afb87706616997ad853c5bb0a2bc202e4b1f252cd2e5ae72742906bc36c2a8d129718678535b0bc9ffb269e1e74d5f2a37931d49add7bf397f4d62013fc7cd0e5af68d3df77eb74128119ca903f6ac8222d0492c1ec7f11f4220eaa3f1164b7322951ac2983397b11de0fe0b915a236b70f317c28e9ec458956cc7d62157f7fc7ad179cee31a6e0c07d09d99f65a8d2b1bf84a9b55d085f84aa94086d80f4045c11a67f8df1646df47735ad026b6db5ff769fb946caeb02829e3e11aeb0ed3e1a16be21cafdc66fb5d3bb8b133830209db4ad5b2c2e9935af16618001a714a098472d291f9dcb8949254a7529d654fb4460c14c88e55b966540ec4b22a19513665f02f00d560f586d08242a63a0f192832cf897e4a1587569de114ae85ce9263ab308a3a8fa2a62a0de24efed2193953c53c69d710e340acde7c1851dbe371954a59da03543f854a84f7aae5a3d50e2be068d0584199bdd81047d7adbc975d021202f97032217a3e4dc8398245b2c0b203845565c4f025df5eaa6347608a09462c81a134e32d5a0ef7cb4c464f8ce2ad0aa5cdb0d26a86ccae4bb1960b71eaf7075a402addbff18d3da51390f28f088fc3b0e8b625cf2bd082177ca20d7421fc38b44bdf73eaba440fb272850ed0461d544022807e79a45de86accbc3695d23d118a43439afe3e4f116bb306deee09ff7206e85352aa70b5cc8eba70f259b22c90d3084722ee4fabc67c92808140d1892439691f9a0afe9c5f3a2dedaf6ab211c5b29ef0e4fa9825ce11568549823d0ebbd36a4ca2d88f9344b2d20f7112f836768ad31ffe694419dbb35ce1a304944ea05ddfbb33f118290313a9847031e6f8a2b51ec3379b66fc4573ed1b2f6091d24156b44220d5fabe5b7389d7f8777a51c74fcb314c8a9dced4ddb0a551628647bf1d1a0ed665abe77dde46976e101cd7802b803035175ea7d4b57c1511f258b1878d4329d7530a9db0014d35d3b03339947a529ec16da327f61bb22994a50f1e274217c606f55dd959893cce0f0c471e535c2376437c72192dd783ea73cd7aed94a3120bfd0f315d61891a716fe67dcf44c5a50d8f82dd4edbd21c0fd5fc3e4a9ae32ee3cf138a2b9646eca7ba7fb5b1814a0162ecdcfd4b93d8d4d3316dd99db0df390050423b100edd5dc4f478fb930bb9e1ce7e85b62794e99b5f46ba96b9b734397777f1274998ec77817d704abbc6195283165b961d730e55c2c44306a6753bc42bfaf25939d22b3a4ac307c16ca28e260ec83615b934eba5a17a58bfd1be8cb4e336a68613b56ea8fceaade54afc2f87b2658a7b3a8e0c9e9bc76a8a012f2e15ab6ca59c9df0463fe2bbc594bd756f2516bacd04a423d219b22cd88144c0a4e4bca914a5c4e575a049dea608411afcaeae51f680743610b5d6d05d8fba39e5126ca1f0aa3a0bf7283b46099cd4f9337f354ac730f020ccaf0e33644807d72898b726ebdb20eb5078288800b3204dc58679b4658106fbe45b9324fe1da13239189e7aa068bbafaf36f6bfedcb6846464939ff03d0eea29f1464b90502bd4325d49c643ad5a4d51e7892dcc00d0f7d43e57511d2556424adebac0e2a0d6a053d0aba09bd7351638a05555c6fb7f91a5262ec8a326bf0b7b4392e06e479a87662b7b3b2bc5066e689aa2917509a07f74983714731e785104b81e9c5ccc734f3e47c0980001e1befca30e4a447ab317c7b139cb88f3e4c1819600713b4a45d3c292d2982a46be517dc3029a739e65dd107bdcdca86a6962f8fa7e5de507e4352938942ab99b19fbd95fadbfdad169807be9f8d9c9dc1c1ac4a530965a6abac63baec409b6d834ada0fcc58be2d3ec519d649b13502a98705535b5f841f4011bebd87237b2ade344a2dc63142e5390fb620e24b1f9504ca78fee0d2432e186e9efb7dbc3aeec617e3af88492492f6a70ff4bc2006e0ffa9020fdb386dc30a576f3a06b46cb43f8d5b4d6e2f691b7a7c471ec7c6f5c047595a8c5acd8d6194bf5fa500e362697266ccf0ab2621983013dd2984e8d7ef562a77cef437c1d68b22a522eb887fc39874d3579a262baad48a69a54f5523180d46da0a5c30ac87d79fed8a3bb1392cec27eec881192c63fd62f3624145a69ef54ff95979037c0bc9dfb70cce5b73ae6da2db0411d140c244d148532f02eebe97f4b5259dab9c01bd84bd9660d854a3bb7cb613725ce9e8224b14c1dd2325e8f44d30929700f0c95af1ba875336dea67471f650fc77922f3c8c49be00669506dc94a968c1f6ae58f5f2e61fad22760eadaf1bc70fc78fc82221ed6d6dd029563713daf4cc64f978fbceeed2d31113399922c48fa071297e44659484b2ccb98e0ad94735dfcd5b4acf7a80953b41b6c0d9c865cec6c5decb3669eeb8611b24b806ba7578074cce2299eab8fca8254841188fb9f06d0326009f13694552c34e9e54d79550362fe49ba7761385d3a4d092b77e20ba3bf1d1413c2fe0ffb29693b60f97643efd05a8a9e5165e13a9caed226a3a14ea37c7c54c37eb0197da7aca429da04a62cf4832702937d447c1a32fdbf3bab57727ad87bd8352f6ee1ed94b0808aa9de1feb8ed3325c53e1a440674dc7ee3ba523645a605d484a3909f83ab6651eabb5a5196ee9e9e1350af9370325d11a4f9c6a4cff9821435a7fb6be95dfcd6ec25294ba847cebead8d3cae3c388d58c04adcf545db68b983061962d2865bc9217f4c3b4890e02ecbe4300c55672c3f31ab3ab86175908914f852570d84dcacd03beba7eb379727dea0e117a5e6b33f760bd219e1cefa584a96931c873d21db1b529960d631dddbcfb799775d411f2c81f83368844557405e4da95a849eaa73da7b1f433a117ced5880abaf8f3b37e36e245ada21af768a4598572d729dda11aa62eb4af07cf1b467b954cbbe7fa1b0d0d92e1ca25e169189a144a9aebf1e1d13278fcb0ab4023c7b086acb5aa8aa3a948c189564a7ba8e3d4409fdb2f4610e9d16c44e4fcdc06d1a66dc96c645698bcaf4a1d2da65c5bbfa47d05f6e5234154f53c38db9af4828c6310e6d72469b746443bae8c5c37374b1626b842c46399508839e6b1b208e47e749ce6722e0dc966783944ecd8ae9bc4f959a704252b05caa70d4076de26f1648badacab530ad2920b5627fe558c9cbbdc4d583900ea33afdb995444adb283ef80979ef6dbfca07fb39b965a4c6aee65250d43460acad5547dbc62693993e9d28c91b0267d9df93e1cf375b0807b1f61d538c1ec089532f873c3dfb723300b8d3c2ce9189208bff8b0776a61625e639486503b3bb850a950ddb940c6161f67f904c482b423f5e63f5f9fa5de88204b2eff2d719a880bec7c882765918b33393f4bd3222010ebc37fd1b7c0c674ef850653b22f205d2a9005ba6bf5d9a33ca3fe0d6eab3e19d3bf4eb28ec5c55e7e9ea7c4e1b036deb668fa4a352b5f9ff0ab8f42ab110dc006b6c75249e3fd2f089b10423d592e8959cf275f2fba0f6dda4838526b81320e49bad5dbdce9541beee5e70377e03b54eab41fa04d65a2141d763f3bc3d2dacfe013b36940979d82070e4f3c5e6fdcdf4af93939f9af71224d3a3283dd21634a2062f98f4c5522ae34aacf773a5611fdad906e30598f51e27c052411e6ce1c7a755fde2dd530251c1f4de1164ab285658bb5a674951767e5bab6eefbed65de00ba4a5d88a2d30234215e73035f2a84d4468d827d3dff51aab1bc7e85e974b36268d139a0b9ceccf8e91c3301ac1fc31843b0edbf62f31306dc2e4c5104bcd6b7243d6578cec97f8c60e922a45e9f1a4ba06b20a0f2c49f8e7a3638ba6f6618c3f56d3425eaa8f14f76bcd6f7212a141aab63a3af49da3dd81f16b247ad36aeb7f4deb928c7804d1be0cd1721c0e0451dbf1449a52f82a0adb64e8f350117bf1204820c99d1046a8967034730cd3fce7302916a945b5bb6f373e713465130fa3ae1a233f0a412b890a47fa6c75d960894064bdc92cc570344eeda7176a238972a24e0297d7176d6f37e5878355cc151e9f8be423b3ca74be8b46cbdef22aa205c40d03e1d75380a32db764ec8feda089134ca7ae016c92d63565af09b66dd235c0d9148303b5924d44b8b854943093497224c350b112c7a786b4e085a9d7109ac33dc89a6c4d5bd9c9df514c69cae7cf226fca6de7eccf075521f1c929e3416f0ec19a93089d6888b2647415d8cba864ae643ea11402e0f685d1f047dcd43ff8d42e19430c6859aa812c477111e96521f427db2cd8c99c47d1d5c1de91f54219881bfc6e4cea3b4a844fc6180ca622dfcce3dfbaf4c775e3b27b2aaa021dcb99a7e6bb48bc14f969794d08656f7650091a6c15ed9880170328421bb4735205bc20267669fa89ea2301f508c81bc47104d320ea8d754d55f08d88ddff81edd342b7430a54c3406bbf843712137f13f78a1a951d6f4e4277ec4e9c66434f4ff0bcd4095a9ce744d969f7d73336847abf76dcd1023f2e5d92580ea275dc25df9a98165ba863ac31908d3466b03386e5abceab01b64dadac6237e1fab22c59e887ed71716c58e5ca8e88f1fd9f1cbdca0822c9dfb0101ee45fc64744f5a8f3e2c12abe7057e20121eb0141ec4f82a9a917242d4556a59348001243e8df4d272c1d455d05b4e792f8f522f8e5bedc5999bd0f0b79561e85617feba1af0875ae7fdd4f3f9761d279b34b9bc378c1c8d2df99aab19829201a3fa2f13b2d5516a8a3e8104021244fad1f5c13b6ce010b47410542fa9229bb4f7505806419f14764691b42ebc0ba569d3eda081a1f9ba3a6dc9bbedf66f85738eb574fadc183d5c6ac554bde82915193744fd332728779ae0f9ccdb6f9d43fed0b3bba36ab60027f8c29c035b2b50b01768183a288de3caef3e5087660bd1d10eceb17f0daeeb8778f234a57491fa439e646871ebabbb008886105d3ed601b5dca431167c03ee66b5622c9a28e9b415c4d03be006b0f7733a57380ba346c50c8370180eaa179339275c7147afd3884f029af75689ab5a1a7ef98ebf1aeb9fa612f5cacc1530eab1cf4de29cedbf12a1b21cfec2aaa453ef302066f05bc3ab318e23d9654cb86a00000008fbacba04e2608ce5de88939ed3cc5f92631b7a435f695253dbf8e35f0e92dc089d295724a3753e2a821aa454712d3739dcdbad73af25d7e4ac14cce109ee1510d75628951cbed855c82448eed4846e440f7cc824f0960f9eb6452fa955225b2ca657acc7cde4fa0b5057d407b37335492fb69444d00b89eca2d042bd0f839a7de3f0d236ce0fc52bd2ee6e7a10ee1018f47e3f3b8e7fea48886ae18144e5395f16528b67f3d3393ef6390d85c857fc497da24331e8ad8d11ccea2bb1fb7dbcbeda700058268bb61db029ba43f1602c90890222d07c6475102520466dadf30a1955898bab32c91f557534de0c7954b3f4effea63d64d16d2ab75532b1b8010c717106219f38b04fbe7c083e1f764ee72063154cb0042661f48c385eb9d5b0e3f20e002f0757655039feeb3add3517fd32b40833e81466a61d1270297f03ed65906667e0b19f862b37e2d02d98cb563aebadb65e967a26fec2d873b467f16c142b5c4301a935aa25a2011d7c2660b6cabb9940a681d1718944337472a9fed2f24f62009e568d3d7f6dbf2869e8e16b13dd36eddaaa4a7d198d1458351bed134d69c60bf516dfd21783a5025260fae43097e57f2054739763fa9dde8f4f088764facbb54b3547717f8c43fca90ee96b53a6af1fdd143e69031da0d2f76b2b0c6a356f5c15c1c8189c1fe397ece30ab2ab9d68509a234fe2a93f200436275164e0d4ece03dfaa8a3f0fd476f44f52f34990b938a86c07b93950c98d041f3fc68fbd4cca7026e213febc5cbea40f01ceb4e8c6be31f1741c3f708125b19ef3a2df2194e8eeb7d443c19b0731e44c05316f86f0b573378f7cbb30e8766598cf472175425d874b3967453dda75c4f795d8342bde0fd7bb97525a65ce0d7bcff9cb86182 + +pk = 0000000100000008000000027298009a2dad468224314c20395b436b6cd9955b10abbc17538e96f1cd6d55ee948288bf22a0602760b00231a8d71ba0 + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W4.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W4.rsp new file mode 100644 index 0000000000..0d461a43e6 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W4.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H20_W4 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 0000000000000000000000037c43ee18a5df8fbfd9e917f1c48edfdf3bba8def38735c8467489c1392881b827fa292e35aa39f67ca2a2ceb9301d7a592458d8bb115f78241ae487783e50926c43c04ae72ef85993a9a2d8db2139ae7cc95eb1d1cc04840713e0e867f0aa3644179e4411498d0f50c3e149c8849e03979ab92e726ffc2e3be442cbd4d1c9eb8605678e51e613417f33479ea18e3ac3e864c8219554629568da7f5b8ba9d4f3dfdd7f63b4fcaf606467d1f5b326e20c36e45c9f251c08b0116bcb01e3e5cbaa1d5e154ac2ce0e11ec42e81e105244a020773ed094262ee3d609d668b2948a0682e96ec77532d85e899d5f7e07e48b99b7416f27f05408e8704d36251bb5df5568c53df8c3aa7a0b14a7e311f0cb63752610127d73ac0b80733144c93d6de013fdfda6ff4693fbd19e6c7ecead046f1e2c937875f74f1428e3f1f54996b3b47fde49a07b34298b678d0753b9e363ac9e8a777148cf816ecffb458d829a440d983ab9b0d435bf8d98ae71a81a37b7d10f5e001fd0c6a3ff033530f0eb1f155fe96e21637dfc82c9e802070b1c4e008998206e9c04cf3a38f89108b275b5afed4d58b9c34cf4b7d94df20ae5a516e7da4557d53750ead4f760ba82a8e7e217c048acd6ba2ba877825522cdb72e152b31993cfc0fc1df21934cdb80fa088011c62e127b3799a498860108e5f4f8cd6e9fbaeab60b7ea46e84942e354e4065391a6c7039125eaab29dc08cc5bb695ee950bf37cd1d3d83030ba994f280b00d22d48269f05c56ffc54e43c45311bc6dbfb4b53a1df6ee4920a370c894c17fe90e521175bb5ed8bf39987d343e59fafe785e9389daef38de6e863035a3fb630cc2755b58f0d4952cdaa83040c84775faf0314a7d84008ff79239b7f77e3627afd2e868aaf5a73cb3d92f697eb4b880557cfa589fdde3feac0336c7814cd0bb962d96ab5a9a3737cc465e605ccdaf5162c21de0feebd23b6cf9cb0fccce7a1645a66341b7314df7cbf24ac1256ae53d5ac9952de184c1b026b9b2f227591694939f95d1480243488e5a26ed84a628dce33aa884460c0cc3535b73be0dbf4b01608866ac032c19fc1ddf288ee7e2b955c1fc80c1761cd6ce0ed9d6fa3a66723c1f4bfc67b5c2b36269035661a8f10d20dbee8712322d93f6d70c329b5ca914ccc91373f2b809686a5a68ed5bce241112ff1274350219cd10208c51f1b1ba415b61a1bab437e6a75d422f635584a83633ccac0040215df734c6d5e654874f8059a26893183a3d1357e01f2f5522351f945957a0d14c263d5da7602b2168c786c66bc419eb941c1b029ac4ae53b89fecfadfb58ee1aaea9e71287152c180952de7f553599aed4adaf6a6741fd358f2ae0968c027a1f5f175acd951303059cea84a98b70b7ca986709bc2ea405159ac9d50665f25eaba56e0ce2fbc5439df6e5cd08d10d4167030fdbade6eafac433d37eebffc185c9333411d3abe34f5254f1451191c7541352f7daafca626b26716663fb25726e77aee9c1c6ea2de33c1f28c2b6d15cb7addca5bc422d6b06c0e4db832b9ab0f08da4530218d082116a1a0ff9f4563992302b2ba889d04c1375bc15fda2510aa034963121af0cb9be12a68c99d76390c126f6fd7df89f8a38982e7edff991e8d9318a9429dfdab46a54aa9a04018b634079d23a511350e4b0162e628605ad852f0e589730d0f8e09222716bdae6151aed4a62dc3d50e417e9a8817fac017ddb0da99ce08723bf420b6a70d25abcb2914c3997361b5be31e485b4c621ae493729c7f9efb00e5e445f4828629d61d532459f08654531b4bd5da5867745b58a9e608a753e568c931afa3909da2a5dbede3ac7cd52cbf954e9fa26f510476cdaca57fb014b4d9f46cbf4d2450e2c5ad020d189e5d32eb49aec0782de2556403f51ed8ce5f519c2cbd451233f1adb9702918dfad4031ff5604376384a200fd64bc0bd80371cfb896dc56f379b8f3c964d2e57998bf67fc2fe12c88d23ed3bbb267e0b54d1603f833a5588a0458a04521b86d90a56c7e9ed3a8beff5f13a49517a79f270d245fb24fc3dafb1ce0f01f6f15b8e230291d5f6d6f394572a49f9f85d1847b990cb2060b09dcdbff555eaf9961fd5acfbacc64556b77139c177438b8e7a86112c60293eb1c583afbc17de5261eca46b76de8160d5068764c194fcb6a9243396ac5a7a6db9602b3421f8f4f425495d91d5da88eb9aa3036b5749a670d0fc8b40af82515f296057210751d49269d6e86e7cede47534b7b307b39c6ab21fecc37048f4c911112f38ae2cb01a5fe9a2379d37bdb4986a0e40c2db67f529cd3903d41a9157224224661414a9092f906e6fc7b6d60a68d311159107d22d2a15d757f0b4aee8d1a453676f26ba90ba8862b9ae5ea403e6ebee935407d468bd84107c8913592539adc3c65609f859f57770f72d202a903a63ee0778a321e402e036fdcfe4b62d78a67e3330b71efadf9bf2678fb024c75d9ec9591f2c58c08e6543b5fb5427177cda74ac3c0c641308c0562938e30455799bc555f9c0cbbbf12b9b1b7ad907ddf838c86634d3ae4f3b9f9d5d4dea929c75c5af465d17fa96fe88233fa8996cdff1e1cbe21cd5ee75fb3ffbee0f0f15817923588737a6b1647324b9cad29c33414b5f87c7db0b0280bc27dab78b4c8cf137752169d65fa5b9d374fceece83acbfca612847a147a66642d2b25bc19c4e7e86118efef57ef08eba9fd9bd36854f96ae47ec1b7ba8d4e53f97553386d1a117fd6d11eead3d10e58cda7258ab8d530c47d33321247690dddaa770c9dd6b5295e164e2a0b9b815dedbb9654517be6691b3dfc739c9d470cfee8ea2117ab7a2c2876a21e3513911486e00649f98aaf9ef1a32b63000dea1ecfecb9d433b51333781262053f1096c884fbcbb3187b09489fe1da7ef9d3eb14ec1cd91fa1e09bdc2a6f05ba95bbcc583a86fc73daeb18ffaa7802e671e0641331813bded68bfc6f284cf44ed3cf810caa5e6103208bd4c56ea670269e04f96a5627ce77b364b50b21b38eeebbaabed9b311bdf49f46310be5d19aba8b76b5ff276f90a784850000000863db9401ef22c5a1bc3ef9a0894c875e66109f097575f50f8feb4e2c18ef1b3804d41ae1c38fb1dc4d3306ab4cdc3a0912ea0d70983212a10c7fd15f9eabe503251cd8e12103dbb3d5520a22bb4f758ace010741d5eca7d2fb972e70abc782243b7639d486656e9c0bef7a89c6e64ecc0bdfee8af27e24349e9cbf37ea13c9533fac0b57d5ad9ed89b7af20991dd140b9c23a01f53eb3f1e649d8b2d6d941948ae30c64cdec7cf05e17ef2b74d24445ff0c108a240168aa5694336f1ebc3f9577ecf4aba3fe7494eed663a8fc01b85498206a6e87a435e30a3bfa64558126e79e440369683bba29269d86d8c08150286a1ff69fc0a4eec0067e88542a2dc03fbef3d11681fa55c18d9ce1ed722755012df301ad7082256925a5fd0b50d675913a929f7cb289ef8abfc5514815a88397a1be657ac0f5a3a343e18d56a8264d0d52596c561a22a72d18a7d6551b001af0ffc60576f54829d36515e4b9a5c4069306d2c3511f176d2d74c092c7e261d9fe4b8ef9b1d2f1dea9663795afbc7058c147f1fcb977f80f98fda75a7c8821fa226af50fe8d02b9f8b9a9ab58d6f498544e4c8414938f106891bbf87d215e42a3b3dd82462c9ee5007edbe45379f89bde29d86b485af81942fc8a71123b51971ecbb49ebce70a85298ef1eef2226ded1b68a16f525be1f074364084b9aa50a2f215e9824727ecdfb536c3e2f8254b2e37aa81bdd106ed7669e5085774e49ebeb7683554c867c6aa891d6f02ba298fb5bd75e2af2163e211cf09873ce061f20badfd14743a9088c2fcf756c37ebb41d3a437857a85abafd33d57765e8619429abeef65b6a532f5b2a8ed9892316f3ed951eb32a10f51edd95d7a5a0e5eda591a481d081e124831d297cbc44c233522ea9f26 + +pk = 000000010000000800000003bf90b647b42dad7ba89ff319a8b70dc30f41f24161c1b6d1935257ae4b0bfa5ce168fddedee56ad0931604f868f9d5b2 + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W8.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W8.rsp new file mode 100644 index 0000000000..dae33fafca --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W8.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H20_W8 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 000000000000000000000004c77901fbdf3723a0e739e33dad60d6438b3a33adfc72c33f3e1a3e13791a362aa3a1cf96aefb864bcab9cf5714de25794d8d59428eb4585ba22ccb719b12dd7301bb456156130d9c8d34e1624025b402dca6c4d2d5462ef59c5842a9aa242c72cdf29daa26527f5f529c01af89066ed129477f2796f7a2bbf91233f4bd3a9f658e995fcf6221a40547c442f3f5dad46aecff3a4b061bd72c2bd725af87940805954d9b9cef4395fe8e914c736cff67cb8f481c5e9842ddfb95a4c7f9f1310c3bdf951acc06337ca482b677992f207e11fc3520c923d69fcf8b863bf113531e0266246adbd818300bce8ab72b081d453f109bb298e72bd499614f9e609a12bd1e7171187b65e70e9f175b7f03eec038f2faeea0a6c13058264f3b21ef4cfd27c3502eccaf94c68060a468353f1e3c111226bf3baae1af78d783c91c32a344ea5b1e3875f1571cf381e4a142f154c749a572ee587395b1bc49df8c979623dd8b4b09bf1622d7bd1846bf5f65d7be5f28f69a40eb9cb0f25cb30b1090205f85b067870d2abebc20f7bb67a35afe9eb9e1c8f9d90d32b18728b313e055c22671682ae85de2277aebfa94380bbc7ca11c090430cc519695f3af0c5667a3595bf565e7b1114e069d9343132d36adc42043cf0ff1d075f82147d4f8baa9e38e68ba8aa9170c855f3c6e3be4840dc92f65cb5f2e1e24730bbf6d4f73349c3d85e4507b8c4f39bc8b07eeee8f2fff240b07858d391a9e24d34d7f219bad1688546106ecdc177589ea3cda62c02b3c862d7ec1e995e6555beb0d2fecb6d6d86c232dc76f063fb90b1bb4f20116bafdd7436825a53fcd26d1544e71a1feeb0b154ea298948c3ba9ba0adeacdd46860c6d28da3630b36acc8913ecfbc1288417513b8988d977613b93fe7c5c883a4df6096ca35875f24b4e2f7c6c5cf715aa9428069b365e1a121323556113a0ed9a2b8c1cbb944eba56e4917ae1dd6dca34dbb4098a52651af8a8b32a0416b85a9ec8c3e305268c518f713edb977fd6b17cac7fe85d574003bc5133b590d117e5b471a0abe73f96a069b0162bafd492a01900cb3c9bf6ffa6c30f11e9d1ce0eb5385187990f54387a1f66be91b8e9cc09acc5cf0545da67470ffbe95b856f90335573b14cb487787a1440166a4b5249c8108b7d7e07f340f2a30f986cbc2b1e3055cf425dde138deb3fb12a9bb2cfae7020b2503ff50840ad2f026282bb9725e82e310cb2c32a1fc1e7291817f7539055d8b61335643d2a6754033df4326da389ed5f83a6a1c88125975548fb213a2fd7287d98e8d815f42524e10ad9117cdbf88464a8354a96e6c1127167f7cf00088440501d660e670bf98e174cbb5bef986899bd2ed23f0051d1d776e6f4eaf6a8b4c973f12fc85b218c17d346dc8e8f820f71716219165fecc90ac1101a58d0325a586e9a2fed1a2ca2a96b86c94892551712aa032e2a474315ef6e0aeabb2d92356a65e55ccdd371f79a5e6f59e902667731512f1faf7bbbc3ed307927323b1a51f52268d696be32066cdb859662fdb69f8e2a718462537a612987377552f3e34919ff9e044ebfef0f000000088688c398c528e063a27c2654d8ef6fcf86cccf6111384367569f78e0c5544ac0c32f502398b9fb43c94ce6b0c2fdff387ca058d8b3d70edf444567347c32180e5f579935bee605d8d59580c7092b374ce27758f3fabbdc1210c52e7cdea694281ba308427afff30f71588a9280f7ebc56fe9b80c84ea65867cbe443ce760d0dfa3c7889846873ca76dcf464c7ac41ce082605d115f02ac350289557bf7afa58157cbed69a0dee6991af022ce6cd54867c1a05e71949fef85c941fca240e0cb67ea053725b7fa8de0ef248b9203f3de202fad5415112aa621ffaa5504fe4d20929b4f761d9b8621a63726e079b36c2e04bff0782374e2cb103c54842768c164ee77668753efebca2f6f075f47002f7dfb3689e27f1096236cd904645108e7ee25a0f6f3a24ca2db67b53a13a5e9c39601d526b5bf1658c9e9ce2b80f0a6eda7ddeb8811c6458dcea902dad8c1e0da485459d01a9349bebc7e03c7da4366fd53ed29b30c7bb9d28d758c5574f7347cc02e1becabc07964ef20bb27950f4352c92382eba52126a33d4fbe947a1a70dcc622115e4a1e61d283cb7e21a26d43f5ef2317acba85a2aafd6fcdc6fd902bf7821de2b21f252d73efb0f632e46097ed8b9d7c859175c8b4c54d7509ed221131702fef73ca28d9f25f7e1e915be840ff3e56b8d09323f93da0a6a041b5fe66a1910707f5a06c805efe8cbbbcef36a20680cfbbc4d793bf7ba9be868e290e4fe99c1f44eff6f1444775ce1f2c2bf2479b38db8029024f7cca496cc0c1d4013f96a1791e73b72d4220d649d7333761aad155a45e23e00b83bf3c80848c4c3bef451b33102338b11e4fa27c0e63800f1fb10c72029c3034e04d606bed563c0a001f5ad8c718d4056acce6076a1a652b28699928 + +pk = 0000000100000008000000042fd1d7b686c84cbe1eaaf415f6095268787d809d3b8d9cd021a0967b3972c847cfdc0935346b1ce9f3f6e21a2fcde0cd + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W1.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W1.rsp new file mode 100644 index 0000000000..a3527abf11 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W1.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H5_W1 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 000000000000000000000001a5b1fcba390b752269e52f24ac609acf4e5f1cd5c45f46b26f6177ff23e3502f959bb3e4a9995e7337dda0dcfaf464974ca49ebf852abca2643fc8670b9428dea973c569cf1b6efb10b7aec60643882bbb57b84111901de9df43ff8b84941b85aae106b431995a6cbf103758a727cb4234cbf8b6e3f659aaa7d72286174708859e0e153c5101dac9615e1b9a43426433ff250df739bb9bc3e8e19723199f93564690801de8699bfbc5c966286a1d58936a50d2346635e4da1047576f1e97f97056975d2ff57baf59d88ba3459050f049b3a74c6fb82e7a8cc70c121ce1c633afc86093af3426c5bb2096dae2f40d68024928c28aa3b371d204194d22616413bf304548fb1c93821e16aa0005ec8d14cdf300de7a841b925731319c19b413594e3b2db5e74a913e70a1cb89b0bce8175c8856b1e221d5a07bd2d3a2d106f9acabef321cc2ef36e5ec9e60240956d5b9533f45e11bace27017bcf6d74eab81e3a55e10025e954b510b1b7909956f6d0b2188bc62dc05251114b8e878dba723f8cb9aedcb5c1bc2fc47b3f1663070a23ad908adb9abaffa2fb3c4fa3b8ef5305d979852e1306f3b88bf826ea086e9d6229de20cac880aaa32a0426fe9e0e5e283d055a298d3749721235ffaffb1561bbec3321d96c68140371ef7a20cce5987a9a37e9a3dddd45707e181a855df4bd29a22e63995c92b22db1919c7c1882d8e91c6764506dfbab529319e49dfe6c32a9dccafdcb387a05704938a20c786a9d413bcab3dd020ab8f8bd5a8b6821902c028e19b3ef75726dd5c6f546f25a820976f3d6c6d30ef4d42b06a0133d8ae43b97e639863f50310e822c568e4ee523f354feda584bf549294140674e5756c248afa342eb60b9e0873a1db661b1184371f752ad23026cef236855d3e707eef88b5f7b72f607c1a47db31cfb51bc346f20526f4f5b696ba7171a65d94e536a361863b67287b040860ea3ed4d25af0051581e135ff422243e4346896eb58ad50517b3b63df6d104176b02bdb5e2a6e8af0ef52ac4284c35b2561212a2d1b0b9f16d0f08378ba0368f0e5cd031cd898d21d0d7df5c81241861623896903b1115a0a61e4aed71abafcb609344eaf227af41a0ae4c3017c8dc7f8dc99aa679fe0605a800d6443bc27f18f4de198f93c4553836cede5f24de328319ec49bd203e322e4c1b57c2504e087b042824e11dbc6ea13207cffe3b0fa1fb595052e80cdfa8fe7ecf4be060b8d049bf52da0bf09a24b5297c2d7720ba7f9cf8264cf1397a5550a39206dd98bc5488cb7f5429f6327f643d3eb49c31cb66e281bfb7488777dc0ef8c18f9670e29c1f03d08cf405c263dbba87f5fcd1f1d365abe7dcdb087449618d3f0ad10b3b663757f8a496f24d857a61ad952984e13e181c31a7c39440f37ef23ca77e1a95264fc784cc53a779ae92cd3833967a8a7bd8baa57cf98be69d67f0d540592fbac6990d1b11b01facc7c570d267480f94ef5bdcbe6558c70b5e23d4fe14625e45439784601d0cad002b2f541f65880d286cc279f0ffbb0bac3a1bda18f3f8dcb3210300c843ebcc349cd59f48eb8763d901575158c77f6b1494ad63b2118f78461e773383a0ea685008d1bcca28f6dfebb445d2e82a90ea8f4856d1a3343bd00cfc8a73c0d496dba865a7b0c232f0a79bb0be78263ecab7d273db90219abde2deaed1e82c1ef3efe5d0a2fc826a396fb4121abca045898814c8b63bf70f584cbd75481eac9dbe9b13f5e50c95871bfb5facf07deb4873c2d8ad81b3a212195de3110be065dc1694a84fee5b4bc80b143a81e6055e3bd26fd4b487c7c27b73079449fe59393ca2ee06d51bd9902f5bff9c5bd6d0793a2ab21333009cd9efa6f64fb67f97d5775110be4356c20600188458faa739ca149796f5a598b05f46da225b969a297947b75185d0e9c8c32221414ac4ea886209b8e4dcaee07af50bc1a995fff0d5b0ae01a6a36c540f65642ed3be1d1b6808df18f575df9c01e1d2150e1ab268355d3fee33eeb7fd6dfac9adb0d9c99aada56e299e9e13a4c37e4c902738bc92b684d5ebde5284944a95cbbf2f5119040e3f8471b6d572f108415034f574f13dc417686a3a92306f0ff22bc9e253c5f04b9a96b9105c397da197ee587bacf961c71d8787cacc05d12bd14f8ec2eca4d8b11de8810d7d31cd0c172dfda21f732eb6a53088d11db3aa4b9080eda3230e2b55bb339b4aedc9624c32d5e6eed1110bb61373fa10d98255ecd9c073f374ddd197c4b9c208771d963e93beeb263c7be992ad8bb9930725303c9e5b8b2eb40fe7266e3c1f26f6150da42668021c9bb2ef8f91c76a1726efd58244f0aabac9d958f320fccab4e4f32898be68a83dbfc15f1dddf63fef8b3ce05d8f8d1765ed7b2d3aa6a8941c94600c4e177d3f0a0d606dc2a55b4c46be43dab0380fc96784b5dd0ed9dcb590083682aa3a7e6b32c90612be44d1082e3738cf5ca4ef581497c3ce6d7eed774561c86177901cd67cb7fdce4ccd81586a5a3d0587d8099fa7678a43f095eead13c98976481ed4040529ce29145436157b0228241634faa5a43c0d0185ed9f2e07eec3ee3aa95a62b127e45ea2902f97d024ff810968fdae1c1fc6c851b51b8829dd1280d2cc3b6029f0097326d34f3c350d6501a05d7a333323d23839931e947f5a7df7274098025a0041e4d5e719a0ad3480b3a16c76486d119a1a4ba0542fce25777e0cbaa44936b540c5ff91c013351e0ccc93d3413f9b145c551c2c4d302f000f2c5b3c3dfe5642ffb9e5e5978c323eea9ee7e012dac29f62af9d57f0b5dc106ba751900604c76573eedce79c4c06c8c055daec35e2534ef7c2eb6aad9c9c4cba215ae520cd87752ed32a4dd3916ce38c302a13c3e1dc613e754480bece4994b28e900a9be004a0aab63eddc3e06fd05bd744fc43f76487407b6999d9fa65d15550a1cce8478e55860f614a2f13d0667e98763788802a95c2fadab792928d397dd8e2e3a2691c88681574e1169642e9a1d637bd3ee8e0494629692ec9b1d0560df3374c53b33ef8a1c13c105daeb538b7fd65de27e2223255e3dedb08bcb8d3d18447a61948731d30a9358c3aa61169bf679ff24aaf7d0ed19a82add52a6ad496baf24934c3d991274d70380c8a9fe2a520272106e2d67d5a136b9588c0dad681d7b11fbce6d835caaad3dd9179c594be9e4c58a9d294b85353974fdecc6075f7dfe1ffd1cbfbba7b6f0d99f1f9b3eb3cd22f0a75e4ee9361025890de6556c2b450748dde7c200092a0a52ad85ea5e1d9c6eedd274c05e55cf42624a3a2477ac162061803eb176ba5747559b1460008b9f55eb5a3c55a575342addb5fcf0be3334aac1e0ed0f22c457a2c1f4b1dc0afc8485905ff537360060b895681acc58cd5f23eb587edd60b2e33c2aa77b1b07bd4090a3f8ea627dd1351fc68aeddc50d51bf5323ef3055f6a16bf2a6d1d97f124ffa7c27faac2a0e765a75f363faf715b0452e2719cf3e13b2b10d890a7c66aa3202760ba41874d14ca98709005166f7bf5f93de9054f31ab4d9eaf5c97e2db07c9b6376eeed1048dfb6c26242e5de8a46bd308b37edc9a9acd3a4beb04b084ec9e1325aa02ad58af47f264cdbe5fb49d4d79cefb6badb8e2afb4c2ee7db16606f0166be7b2acc848dcf51ae6603d72ac4c1be1b8e4cd54de4a2fccb53a42b83e8750c825b4e1b0052a5faf2f5bdd4581a557834c6571cae4e05d47e71efa27b792ce9596d2605fa89306942699d126f842746190a36c5605d5b83cc9fbf3133ae752ba0a4c42b474d30e6fd9127b306854f92d0f0e29c8a734c468e0837b073bd622319c05b00db874b63c2e6cc152bd0fd7e5107f168c897d80efc7d943f3bfb2a64a108d84506c2895d1a0cc6206ac92f9d274757e91defc3612b2c6868937fc02d45b0441cddc7969fa0dbf0df711a35b6c43ebf8b12a3ae77b941367175fa8795241002cfb3262cd4bc9857e1fc6420c9f7deff319bcad70047cc9a24dd13b19ee95a96df562d36c5eb010f45b0e0fe353f95fab81a722dffbaeeaecf1e169e8ed774048b34f9f35df7757438e57f157f83507382ad7bc169c50186cfea182a6e402cec92b4915f8447ba1b96a6e2fb16634241efb103f1de9184a62e3c32ac1fc4e3c5c7142d9895ebd5b80954cd141856dd2242a42d760712a895aa52c74c52a0c0544ea85ced655e74725944f87b9c1522806e0a6c9b8dd7a1f0f92ba06c9fb002de559cf637fc139abd90d0a836360be6fa4c0bb8eb6b797d4e64af3d4316e402c59e432f25d54220c50b04ba0f6a6e4b7f349090d5eaf205800cd6feb6f5459554f03cd8e3557f6132889f3d33b91a8a56190d9b552bfe99b0b3b3f260948ddb14e106a22b96ada2e7459adad648117dbc0c4944bf46db8d557fb3a1a997d963debf89e542f43e6695140eeef90f93b06a378b2f4466eceae8ba6d81e5019ebd2baa6d28a11a8824fb17fb808b612e36225d7c1ac798dc49faba3210f40fb230f9ba0d24549ba5eacfd9f8a470b83cedcc895347d50bee5fb5d4602d0294a5d73332b03d2800ed5eb21c6f7288e01a917da98e6c9214372d9139fa2bcf82912df4c6e9b4537f3ca9a57fbc55f20483b99acbba555f9ef4c6e6bc943e24919215854b902fb2e5497b22e6aaf0f5b0d4f3cb338f94c24ca9d53f87b98ecf391e27df19ce311598ccdb09f5581111d77c1caf8aa8d163a485c74db922355924ed67db075c2bc0dd29b4efb130e7869aaed5f20ba740cf5ad4f47c64c93fcc9e964bb0aabea679d4e17150658a3d97da9be89ade5ee42d52c36379d5bc2520b344bb269b0cad9e2e0087de976e121cf0f0975ed9051ff8fc0c7eca3341399f14b8e62fe5e0cbd3f15b8f3a18b10473a1b253d645815b0205841a9c4d7c493d4eeb4e982a4b5ea723d29c8ec06083dbd252846f119aebc07fc9d568b2eda28db5ad905123dad39d02c012186d854e561443b0fb73b139d632f2a102e33b52ab2b94c3993aa8d8713b141379c62193d3464a96529c75676fce6451482875c33a4d699bdafab582b543399764102820ef92837d3bce37938b6ffa46bc7a0ba4ad3cc8e7e196b12df2ef03748b8bbe1541613c693d4a02e54cff8b72438fc9cd36706422e327b5f60ecc0e7285c2cb3ae37a818fd9310da196ea7bc87ce42f358570032a1ff791a471fea3f5dededff0439d98ea5e49958e3521c646bba4f1494c9734b05f2758b81b8cc590cecf09ede5d69d29a388cfb04dd0d20d2b0e4bf6616aeccd45df4682ba6a93acb83f33d17ed8740bb26f6676519d29a96827af74882140a88603c0bc1cd98f0466f8a9952de5c9f8e58869a2783d4e35778fa2407522005c5666f70273d55f8901a5459c2e2c53f484ee811516a5a235b5575787acd073a944b29d5ee4f8a3f9936e0dde8570c357a990c49c05eeef2dd604c8ead74541d7593dea66125d19d2c65da11bcb7aeee7fbb35ecdd7f7a17520f46e17ad0c3e68bfde0d459d8aa9da2ef6cc2ca2c90c9349501312778adaf1948624ce0250e1254b443a11a0a1f5532a0576123d2bdac0be59e9111bf7dfae21859ca219760dc4f6dc5ad73782138084a48abee1a8d2476d44fc22aea93b99f3e4b94da17282cd2bb8f624a92ecc5d24f5c0096434e4a6ca1ce474ea3abe8d658cbf3ec5a9c9ab563bc68043c55d92267cd9dfc5bb086a0dc9b800849c675d5179e60bb6f38385118ec7b2aca937d54e8ea99bc9736fe94e614f2e584f203892ac14cd2ed24067680ec94d0c1d8dfb9cd0cbedea7efd865c32fa1e2e6c8f0f7e86dbca875dc0d0e83f1edb9ff190f463fd57b89ccac14b9142d513e6c60ce226cbac592a3aa47b4b062844b6aaf3976acb6714f9d4080dde568c29de2d710816693a31e2f0e4fe61608395f67c0b4f0000fc4d3eb46bac57251d99188969116864fe0593bc60f3e5f7c9f9ad0964194b37b897431acc14effaaeff4802753093027caaf6ad88e20cdf6ceeaceaf681a2edc951e4b6e4d49239797c54d87e591ac324a5718fb62338074330b1febd106ee389b727346b581e4b0ac8a7c40d7b56574ed506fca456838abf7ed3f789e55de37051c07ac02b610f0a8d656add1fe9104b0243a29ca46093f6292e0ae152e4976e7c5c8eb6c18e04cfeb11a3163a14cbaee778e0967936fcf76ddbbadbe93794a98ed8befffd0d182b3a96a8a0217ff1be9fe8377e93a2c5f4d75f83df93eaa3e2d55574851dc3e0d096685a3b3c575d6c703a41807888ee4222461e1753ebf1862e39f29a5bb321bcf111a0dbe748fe337e301ee9ffd1b7de24b90f815bbcff5ab6d1d730f4795446a5c5655fa4e99554fc9e461d9d88c26492b28d94c7bb32e5f99ca567705536b7c3530f3bd4c0db0eb984d15a110417247caadce1afd28cfa5cf9f7998459ae4461637aa5db978db1bb15187bd7606276d720be8a4a421f0b4fe049c0decf60c5cfaf3afecefc431ed8498ced36c88b20f417e4ff5a5b871df26e7918ddd44edfd04caff5870e0591cad7d085102dba0a880fc0b456535211cfba89a5b45fcc58d6d996a32e39488821b7834ca4ed81e4fa77b37a9fde7f4309531fae3988e0fe2c2c5cd390acb4232480b20896bb5a136b66b95c2728474d91acde95dc61b86f18d719f183aa1b47aaea4f9d7ab9ca0099f3496c79b203edc277b76a00e99d287aff8ee2cccf5da4725643f97f0aa6c9658c4a2deef1c5e09278080e035343632e3212f72d82e09d672463a3471af578c7da9aef1c727238626c8c76aac5544626fdab7fb15b620865db86cdbf3718c076dad60779186f13f334a0546ba457e5b33b96c575aadd2455139b911c3e69a14dcfd8c85ac63f1f9159c2825cd8ec8ce9c7eca54c3dbc8c37128867508e0b410030444cc0d6acc1e9ffdcf3288889710dbd95524333be72257d2dc79af0eefc4d0961ac720640af06e1d15f5da49664ab3eb1ba68c5767794e9a79f595f70626365a47f4e53d31229158270ff4b9a3ba2611a4a53fb739c87c7e4f9ef88b6d5ed6eed8d11d345756c867e37e342b48170236f9fdb11c4aa49d534daec9cba8bbf1b0a7fee6c1673175ac2677c4cf1604a8adc2c6d37df26f102ecb2b9f9b7a493767f81eea07fb60e319a5d2c5c239994952e56974900798cc2335de0790dcf706e18a563942aa04f32d869a97f9a6a30904a71164ede9a33f75e5d47b94e49ab6931092e982fc2635b83ed8e085cdaabe697bc26ef3611f894c97dd410ddd45d41f5144360c1a96b332a583f47e75ad4afb74ac27ae97bc0a1f05a1a780d0a0041f9416a1c5631562c34e0859d5e973400c9d5acfaed302364f11e65c47448bae7271dbc36c00c494614218f04585fff089d0914b3840939817972bf6740b7e6e53be78ba98d50aa469a965f0e8fd33857f5aa2ab731a7ca7a8eb4f000443eb6e436057debed8441c8dce197de6e9e32c646fda78feebcd0fb5d0ea4471f5dacda99f20e89657a6af993a5320979ab45b807b9f756197850d419b5c816662519ebae7fbd17c3893e753cc8eec9d7fc3910b8ee0277b78ae08eaa4dce23a64139dd9800a173e047d447664ff81f5689b164590af784e6e4859993683b747602a816d49b34405487ff12ceff7fe7ac0990ba49130295177d1678f783867ddb593e55fb3f49dbd7d7092078296852fa9c9f02d1d399250fae993c1eb51d32df789e75590657d25ae633ec882c896829f861375a8139b824775b8bbeafe72ce20a7b55a8d187cca8a8554b4a8c314c8c4d8cbe8124a7ff4d63a0ae11ad6806e9cbdc4b8c2c824579960b7c49a4b6bb3cbe18b28c9e64909ce50fd5d9d1744a44e016b0433b66ebb5eaeff9fac286d71d80f04c8e78b898b818cab7dbd2b701045d2cdcee907e3171408318fe0a4a5f86fda1fce6398b78854598e287bc0594402fa56773ad8cf53b839c84bdce861a20efa67aa3ea38ed601687f9a9050818b3aee87e22355e62bc5978979c98df3a7418e468d7ff33b15114e838db3b39b0f5e6bc83a774b84210a2642b9c56c8691e2796f7d0bd72c72035ba327ff33f220380d6a39cc1a0322e8c2bb5a843f6411652f4792f7c15f4c0d4cf87c484a89fe45eead455cd2dbc792a2c840e3be5278feb93a988c6426ff56529b0185520443f2c21aa5f6dc4c03f96d6d30d778fb9dcd685ee6e3ca5eeb0c05d300806dfd7ac94fda5118e115d2df3f8bb8bdf3e198a06d5e876b202d391ebe92a633fcfe2f8315d6ebb2c27a9cb7de232ee7cb12069ace3f58fac8a7ad8c628ce28a757151b9b690fe70ca8fbec03c0212c91e96a1efed549d46e379edc255b66e097acc473662d079c393f00177c80c0528240eb19e74378526eabab965d5e2f433191d0fb7eb3e3bb8c1ae32c8ed2ceb8ddbda24f8f06a8e64a2cf1fde2c1044a7f6d55d5cddbc8208a39f08f9d712aa40aa1d8223e3a42d866d8bb8925fe37291285d4aa71b83dc4072bdaaaf9f02fe833310014c050808a24e70830b6d0014fe3750dfe78515bf135bdd47af71258ecaf59cbb3dc147f55cc13274e8c959bc594a8394b690dcc1d98f564058f2ecf0097beada116507d9062394eb45164dcbec53137ca226043809bc44b9477137c99e79d483a523e60d29e35134cca5f589b5b1f1d5e49c971fc2e5ff224b53e0f19745d39c93f212447ef0fd0fa70856c1fcf86dec2c4583ec2943566353fdcc139ad4b87e4b4942f87f74f353bac1c9097818dc6796feaf1829bfadaa7dd07cf6b2ec95c0acd49f26a03616caf2a8ec2b1d44d8891b6846965cf0d7e6b08012c4d2b98ef86ad9c30380d023ee096fc749b94712ead24e2fa2e78600b3ad4ff5bf3451604c9a9c44513a1c18c665da883a5adfa8ac42d445c6572e30bf63324b94052342c671c1702e9ccd0da5abd1c77017414832ef16f636015a653268507f0e8fd186b83e4aeec1da71280b31393ce0f5a776cd8ac1d221ecae60617fcc3a36c53839043df0d5d94391f96c567b9659e94415f7c229518ff2f675eec0c97090146355e02f67ff5c42ed2b29dfc541b3e6fefed4d124031706b319a36999afb787740af4cdaa1da253bc3cd2e463d603b059dff4b5c6310a876b0260fa40d65300ca194bb590d599391a7e049e76b10e62b21b5ce6a83b4e92682b25dc6ec68f7ecf1e69d8e1db07d3837d45df27452cf4d6c26903450b352718f4d3ed7adad608c377c1f53e6414a3282d43f78b348c496d8603e762b909fcaefbc8193cf277041082cb9dd36b8810ff8221d956de5e0ced5635bfd261bc4c32de67fe1648f2b5d1e01784a288df133c2f8a803718bea3160b207f9b11c5dfa9981dbedf7fbdecaf5117b65760708045f8fc1e54d54f53c37995a367e3a578c876086c96bda438c9a8daad35ce5e8def882bfdf0a0d65cda63a7a9e3ea7fc91a45dd02ca9614263e6ac1f62d28c70922b81fcd98a5a966ea56beadf4ecd25aa5a2edc6f8a92ded720d8e062077db026fb845b08bbbfc9da7f6ac48eac5118b654cea44262e53db291d0cf4b7d4925e7115372aaf4164bb86d1fc5e52690984c74b055b384a91405ef626e79532917f8e26c63a4e8882372bd6c27eb747a2a3d1c17845b7ed826d2984947e8a299d718cc274e6c1bd530f14853656220b508c0dfe96e4cee284a60d183fea3b5c8d39eb0615e067633376acd5852fd447781aa5a288a5ae2347152a1830d72c5ce1f267157166cc33fc0ac5150b00db8f030ea63e51e1ca1cc1fbdef61fda793f29394d3a8053f04bfb2f182aa9060273b76a129e232687f2d42d00a3b9dc67c28c10d1c561c428aaf2e21bb290d66f7d73add81ff98cedd69f34875c84f30d4eb48dc3b882be8965db6c23b246cefa9c94c36c52c4979b464bb4592e422b121bc84f904acc48a04870d42e6894a12eb78b849b6ad26c4d637b8f870b25360542e143563efbb2adf39e8001c1b958ab1a04ec186a1c5748fab6d3bbbdd15bfd36300bb986044caded761067f841a31a4e95ffe9caccc1fbf0d51b83945a29ff1daa8d2d57630c7976e9ee730c5b2441330513e5fd21b234a5e9b65e36b256c3939d1de2730fc4c2a273d702e13dd3f8584d47ed692a730c82f5ccfaa8acf077b722ba2fdaa5c246b2209e897da9972c4a54b7a49e3a14eaa592a2ddcc9e70a8a7a8121a1ceb33d22dd0ffcfb7cfd76688b1ffdf6ee63abd623d30854266cb534fcd420a578437282a37a1deb3ab51f63c4c600f011be09f4ab3840caad041f87a033cb958cd4fa0307c8e33ae224fc85d8d332051324d2fb277874e1e17998ad1338843bc0160c31fcaf90c4fe87df89a48f14882f797e54c9a62702c8750d5051b631810ff0c01a05867c02346adcfe2c446db28c0d07e5dec99dbb508bfa0838d914ba1bf69b79c9b5eaaf46db732b57f315cedb1a050059c2e94a1b337bf7c64fd07df43ca7933827b6dc9fde538b53c3e8b8f579db106a743deaf31592b4697222f6b64d19210bd832207002690366c68291e641fb7c9f0877601de2d1590290ec3bfd8bb2e433f3c94416890e5bbff624c8e256d636994b5a3d1813e4334eb8f4f221333b1772dd15d280554c188fdd75063581362107d59d470dea5f3616be025b41ae8d00130f3b3357d6e7d5d9571cd6b801982fbdbc12b2f29aab5b9b7085a223629767c97e0f21d1040ada264f0c6a6e4cbe9690d2dfa58a52dbeba0db545a8a023adfc720923cd1b616bd0f60e7e3a9c3d08cd070faae9e7fbf5d7b8bfe0fd8c3212367db7fdfc9b635e986cf138900acf395188292be5dc88e6bd158eb637d8473ce8e750e49a4cabb6635d31da466a3b253192f633bd7125210d1fbd266c6c3d93701f888152ee1645481177d9981fe4b404f977004f6771c92049755d9d629eab760421137ddb63b778157924930bd5d239c2ae90fb5fdb8c8015a788cc45dc61a207ed4605d28a7cbd00caa8b97cd3b62a0e2278a76ea2b3d5bd41a774f659e196130fd4539ae8ff20fecc5b24a20bbd39ed7cdd08348116446ddaae9acdc320de58f63397b29c77199fc60f42f31ea467522ed446f4596b9917e27135bb7b73d1c5851aec57f763568d86b1f1340ff6acab7a45bb9c746a7f2a2f3faae60e4a598d37f45088d9d1250599fb0fbf68e45d2cfb28eb02215879ff74cec3b38f3741f64f03611ff7fc17b1c49c02ccfea56f2dbd13185c8d77f42a943ff5ee2fabe4e616d722ccf66314e8da191b67cd16c04aa94d19eae82c40d0c3f2e13ead51245e9fa9447380c597ea4bf26e90ed235e59ac2f783c681d21fe057b79e4bb3899fa72182892431c3c66dd3207b178d0d3a973123da3b69bbb2e73da6bb8d71a86fd501cd58ad5c72cf56e9c26387ec3271306cae768e920dd88eae06049d360015dc9719a0b91132bc0f55a005320fde40505bf18912817346ada67f36424907d7b6d950958bec05944a9b55bc93908a3cf1a9ae8d709ac366def39d29657c959d6a72b2cd1c57277d3b8340fcb9bb9745a0f003278ac104346eb655e60591b0e341d57828343b3fb6b8ba2ae24153cbdac528861fa30bd9b54c7d1035ddb4b280fce1a8a069d9224753cc449decb3148c111ea658601b59165f6374b010dbd343703e4a6cc5c8efba4ac7f420511b9150d13af80184bd1f371b64bc15e289268faef39b5eb7825dcda6326897dbdd9c6f37a3d5653b6613a37af51e5b74d27ae8b344baf8f47347227f201af58403ad59f68aeed8c9e3e1662a2bf2d0bb567fa22814cbe36b533ec64cb055122962d8725cf132aefda54f8ee290a51e53922e39abbf1df0439acedaec5031ecae048cbbe4a291044911f5b7097f98891f08ab729086e6fc4f9142dba686732db6f2b3044e4fa327284a1845fece6f59ef2ecca89b8d5000b2b1b21cfc690b557a54c6f1514d85fbccf269e8eeae79c4c2fa9d33965f46934324a1cc97c648cba1d5f6befe5dd06b45538689f146e28543b41c5c9b2de6000000005a83e68d4f50adec31a352dde617fa8ff70e9028362d2f20a9b1e9ba99a4ef0e0a8d6edbf3799ce086584ec56e2c3d9f8819e40bd62d4fe38e0295f2761f8e55d4da91ea2d2130a4b5b88ec92108b8b02b2967b1c68e4c467c8e3b65880f1dfc3b4fa3c1883401b6bd771d0147874f16d3635ec192c5990486ab3604f9b754229c837a959aa1847e50c6e05332d252e8f8b92e3db1d8b43a71a61c01e485ba1c7 + +pk = 000000010000000500000001b36459ada3fda491d658ab3eb3746402365eff2d5dc9a06584f35229d860137b855cf7759157d382db8a687384089567 + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W2.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W2.rsp new file mode 100644 index 0000000000..488997fed8 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W2.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H5_W2 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 000000000000000000000002150417e62d167e4676733e92d1394e814545ed6b9b5bcdb5abfe12ef0d5e14f418017877e0ae217554001f178e1fbb78c6517a7b91a4768e2133c5c0ffc3541c1c957502a004405cb29dc9f86b37da393939e10c6050fc178853f99a31f96dee2893a203398e3cb632d761c2552e0f181eb568ce5984b89658da394dd4138df820dc6974ab9baae3253756c4c90e329464b5663e5b4cd00ec4efd4e3d4224b2fd0d0c6e0241fa222e9ca3057d903c958a9e3bba381d3b3e91406f34f368be3f40f09a4d7ae479944113e69709ea4a8eb3a0dc3c02b49822f35deaa94bf1d98335bb0a10966eaa9fc19167d9d07956f1e2cb1eeaa6ce5ef1d1860824911d8d151aa133eaa0974823d9b0ebc6218b5f1d3d39560832c303c99fa3a73f4a5c983cf80937cc18788a162e025515213225f357dcd2e2d8a9411fd4abb915892461db7d02e15c4b7f774837ca87d764d2f07e8c437465c53152691e39c65e7c6649e83ddb3568e2e31c661c649ba174f9829351817456b4e527ef6e2db153033becc31af7ffb1ec040d7f4f6ccfad654a34d7041a854cddcb8ab905356d37e4332f5632aef346eae7a49d6d3f465d3a918a532e4efe3f458bc3c2a17200e18e71bd05730f44d1d3b9490fec0e4a52d532bc987c7f29b0c4d1a1375b302a48476645f6f9d938ed7c4b9d874b496488439a299e9108be95b2c695e5049e739a9a3d14684d88b064884ea5438f2e009c0126509541457c87a3f06af3c75da61373ecda9a693b980113b22c34ba15c95696388c2e66d90b2fbb800a97a1b96b31a954e411229bbd86cac0fe668990a9c15c6181f847f2a1db288e995257b2c525e049609ee143555eb36649e119c0f427c998ffb45592ea6faffeff2a9e498428b09b6f1d3fc3a0c8b62a749c51b279be712be38f7b323455b50ac4e325703cf564025e2aa1e5876dd56a7be2ccb920dd22e475be7db8b3ff442711e9d0f3b392eda27da8a34cae12cd4f99fa17d8364d5a2a1303e996621b649a6d7105343b0a5af6dd65f2b1f13d8f36545eb65b99b8b6db5f022bc702e8bd2a1ddbc99b64a291affd1e2adcf8a01e9dd9c117e80e32f874beea046b56b44ee8cc2240d03de68c90d9f4d67e5f3aea949cf6f47d5356a6232e979329c10422193f206c74cbe2d06d290d40fb0ffcf2bafbca374a7c327006cb1b21608af282955d3259a4f4b845ac2d9b386be83e96eeda3a84a64810ae3c81b709fef15078424298917b2697d2bdd3e7f4d365b9a84bbab07c0be4d0929be663a06345d1a67360141c03c3f37891f09c24776177e34a9093fa62005187511268fb2fa80740cb751f5e9fd0d74b0f61b643d139f8ccd040c9a9a32cc740b825a2e6a5beb28a8915fbbb1bcd41c9694fcc72ed570b1e96cafaedde8adf8d5028f80eead64f9407e57ff5465da3e5e341e587cbf091f2f5bab89e95666a3fb7158718afcf685df10ea4a22ae7fe55c8f70d5d5a5973f3dde9c80f2a9eb13d58ca3485268f6e380464892f4c3c3598c81fc3d77d1ce0d3d9f50c78be78b88f6a9e17d6ec4ad9e6a86edbd5a4e5e17219fde097f422498c171ec1d0f6dbb6a2a49d34a66ae854e2650fa4a6c2833af5106472e7c787ef2da06f28f84f0f1197c7b4c4cff6ab3ceaac5ee819809ef20ee9b535252c23117da43e31ce778abfd84bf647875573217cc79c088f91ab07adc4c930a4819b936a98834ba2f9b034996d26bff2cc901317536b5481431656c083780d774b686ac5b0abd7ae2e05981c39726e6efb4ea2507b20e85cffecac815d6d9f84fa86240e6ded4dcaa67a2e2f944ac6d38f986b7268f2c240d8f5eafc0b2b67dfc11992e305e64264e19e021fd29b72dea8be8c315e3aa5f02c49fb9e77a34c48c58a28c4340ffaa7fb5b5d0c8a4aa4abd7bbf3955a0b71cbff160c5dd9a6a4ddefdf00367f414dad1c7ec0f77c1a777ec1c726a1049a2c4bc01554b95665496584cb13b28dafd7c668baa7d0c1e425e5c8cef9f75f21819a5708db01e5a5918df096424abcea2d758d4a8c5fbd96e10ba91bef727bcc47930bd45bc7d6851b21c7daf94c016e8cd10498f18ea44c6474d865a8841800dd19fe3d57611660c3729b5c2a2f1d1765a1237db7b97bcb6af56f79f275677bfee3c37fb1a0d7c2b453feea1f7adc60892a95a7e00421b4fa320ea25119fbd6af73d9049c8e109e2b1b683f5bf83933d63bd552f65fbfb806f346db3592e244acc0878c450962956f4e47bb0bced88d1ee0d18f93acdaf6bff6e6d9b451db35755c1bbb547dc4e098012823874546757f5aa94cd0bd294709da538e8c8675e96d47269451bb63d35b6f027d68aa0871b23114553e883463512890d489286886a93227ad5ba80c53f0bb4d383f15f607091a3ddf07cb199a7d8abee54097371c8ae59b354a8f86765288dc635e4f5a3f1bed2f0998f0562755035f39a4fb0f69618ebdbc3427f1fec8d1040aef11da99c0d3f0864615b1283fb2f9e66b957cf666ae08b2e11fc9153dd32b5fc43736758f65d896d253dbe16d7b16db56130851b7a0935d92d33fa75affb9d509ee73c40c9b61359ff814267e962d4aa80f6fb0ddb76dd4cbaf49fe65ad51b406a2f33bbf698a6dde309a7d7ce95f7c68ee5bccd1631f1443f0b1e823af31b2245095afdf073708fa9afa0c3b1c4606d5428cfbe3799003437b74b136b1d0d2f80848a1e5ab14fe7e9ffe02a09e21bd5d9c4eb0607bb5549f0399c2336cbc76a6e55c7f80fc0ee968c696beaa803fb020438a9ca6c89ef1e8823801e91c1cd7cbacf09c79f128f22f29c9d49355ecfe470b8df5edf9a47bdc781a3ff0ae8e5596e13bc06c610bab6121f85d54ef764e6a82a290a4ac3db0f76820d986ffeb5f19460db6246b59aa659afe6753093998876cb961b07fac8b0c0896d0931bc5843c4f545263a950523b7ad8520654564e27d0661f1cbe60812ad232b458ca36c6439750ed12df2f5d89b12f584e0023a2b8fa39c2a13da2b7497a968189f183f65bb37c5999fd6187f9979f39ec459271d67676ae157271b24ac7b3d3876840c48296096ee2730e14adb8af5ae11666d02e441f83c859aad9657c1216a9c8116d660abfb5e061f2face2f11088e661ab2046b969e72c3d23c6410c951ad210572e3cbddba77c5fb81c7594e60e1a4784d3d606b254a49f05521a0289dd14687cf8efb78a2eef2211e6021aa14f2a3d2a5a0d5013282591239e7df7991e3f44442b544e14ae382181f0790d4901b30f659f0cf9b3080a113d2bf869e44149667438b194bca40f1ce542ef7021222e0d6b7bcf40b8631e9a23b87dc1b97cd6eea407d3f7149e250c70a021b3614b5f68c065eccba5ac481fc4435f2da541a1e368d69259bc179338e641b9b14e77abe6762ae8db9a980061c85f49aa161aa92851f6f1e6a38152edac3f121326e517215cfab5746db3e026ffa2b5b4ea41d297bc4bf91f1d07c866b21425e022f0081c7284fa81c0b6b43bea2ce4d61b910aaa539b5485b79f0f766bc704eba870b33855a589ddf7525cbc07c828cf51e687f6d804e4d43535820171d38a67a8025486f0594872c996768b56177a916b13bdf622ea4d05ac608bd1f9220420733fabcbee129a4e89b243bfb4cb7cafebdbd37b1b505014ac3b9419bb51e274f8aa81f82725693341424df75c08ff6acdf622fea4988d0925ffb33466489331b00dc3432d19dddf30fd64194d4523dd3cafef94bacaf6c72b68665d1731edc8c2e9933d9302c61d576160c3c98a9fa393aa60a843238acc975f5af75532b5088a06299dfe395bf4ffdd4ba2c96ca3c7536c6986d34bdf61e01004e537748f427a7cff650918ec3c0916cdc7ba3037d078c1f96d1d77ec7560d1fa3a55443a8b2876c882a7ae2ddfeb611af3806be2f02e39a82e734728348bd90394b732da8798ea1552925e36a8ae92697bca66ec1cc4f6c2d0d60348f81f74ddae919516cb53455e4642f0782acd678e0f2daf973f866ff0f5576517038ffc52301bc53624eee8cacd1d9fdc4c74bf2afd75bd3d0c7a8010ab8d082e6edba64106cff64b5a9ac166f02b906b9b84539361a68703e43c74439306382964d3f2245a1cb9699b9aafe48922dcfec3515cf9d737d72888562b4830e5a80594ea437556ca1c7921629438c620a439196d194a862dba078524bbfd801d2cb33cd500957b84719352baae64d8163ff85cf8236c509ba495633d4972ba8094d1e293b07f7693bc939ffcf4e3979c1f077e48b6a7b2666360759b82adffc811635b860062fe55d70b1397d6dbebe2f73e722fcb90af4d98a55d4043edea799954e8950e7f6744a1e3a98b2fd48f2ff685208c8ad85becaac5ae51e187e75beaf6589773d23367379a6b46082761f247d79341d9498d210a206424d07bb88fe5018a302f4bbdb2d0ceafd4b25603fce716eddbd18ba669fd0a18c93112082b2941924ba80c5a50efaf1f391e6e0d7d6e27cc991c29f4065d75be997762e4032b62bba80be85d4c8ec05ebf54354ebed5c32ffc47caf0e7c703c38559f125521ba736225d9284e33fbab9d32ad54e3ddce4a79a6a0adb2fcd15c57281a9f150a38d8fc96a27c751a888daa65c4461b54efaf2dd2e0d3b5a6ac12027e3b9721f6bb1a32239824faf8574574845a4d649820b1a003cbe2b3e6466f47062356432d3280edc53b1c4fffc63de4fac290e4525c151ce05314c8a8b0c744acd5768936f93a7421eea8e69522ad6d188f71f4b285a535d84ca72c965bc4e40f03b09703d534b6de536b2da8bb36704ee930f1252fbaab91d5974a9d89e1411c5662d65328334a3982c31d4d0588000204acb1f5fc359302d931d8844dbf24201483041dde064ac06dc020768f40039ab61e8a4b893a1a782a49632e38d5a70120aa4ae391d69c9fe11aff5c3f4fc55153ecf9bab047e130e4585e5de2fb875ae4841d21abc580a945e4738674ee2423a237e9f03edd0bf5e395760d5ffffa1645846019fac8a58ca6741a221ea52c0c3020ca6590a7633388da3daed3ea8425ad3671f235420b00ccdaa006a0cee192855a6d8f6cc17794c4bb1da3c6d1b3b2269572bc2f9d93ba886fe30cdcdd2f105536472a580d0e9ccbaf9d2bd091cd33a2243c816da0fd4a3e8f1c01657dc236ea26cb83e05f1c6c184d9c0391535307cb945f80f9329800b39dcbb10e1ba5d13185a3050772d694429e17426136db817cffe563a77703666f1dc827d81790bcc4e9ceba15c34a28c420b6cc7df34cea563d48e9fd20a208497e0cb5a02eb25c3f67095f3f3a63d62d06ad7953ebfddbfddbb613c676394ed866622ba3323d6b1ae1b1324aa41e99170ee1e66560fa78b74051fb172f9b82e53a02be5859ca2d59a133551b7f1cfde0ec524b4fb4aefa69df632a385db308044922dce6258d71b36b14cb481e82928fafc56111ebd5969a3588ecab557b8c15654cbd559f0792b6caed5413d750867d00ef53aa597949fdb837c468c41bdeb081aae58040a50172cbf3d075a9263f4ad7da16062e80e5fe39da2e05366b79a148ae181c465aae82ecec18e98f696649bca24931a702c338f25bb2d135b95bddea4f9f92a2f925f31ee784f195d29eb4003a5b9a21cda79c6a35a579a470bdfa05ce3ed9c2a693ec92ac559691cdf22e5b074c479f58ef2395781369738f7de2c13de64090dc6575920c28a2c5164c8266e9dee906ef55c69c73fc932a64549470fcfe4da13bda91672870957d0cc002998510826d6452f7b400d09c47925eb3e4bb8f53bbd3f657d2afcd7eecc992966bb1ea7774ed15d22d931dacd5bd45993151ce89e173548d0d9324ef74be4c0cb89a1d824f1eb164821249116274a536b1b760846a4f6d1426f946d338ef04f06494a8ad0e3a59fc2269cbd411b0106e8b1245dcc3814ccf330790dd352e68a675736119d839155378f573524f5071487329e2b30405d2b0f07ad82cf2a7a3514821356f126349668f35350f3f3b71045bf60f1f608da2ebb1b067f0e9b673a1e6bf221eee8aaaae8000000051c142d7004cafdc21431a71b81e6ddc44a8ab75a3a2c8fa3a9a8cc4a781d9079063f7a97bf683473a44e5ec3877cb60d400f6a6d8a3e4fdcb02f51160f6d828ea4358ff1f2fdeb78042387d9cf0452ad8653f511d53435401a55c32b0c03a76b0edfec3b1fcb0b864da0ef3663930feab4e318cb7c271ac7b0ee8f7fa2c67838b293d94a7bddb92e05b5810f88ac6eea3182bbe37704a0190fd4658e268be368 + +pk = 000000010000000500000002ad412ccdb2962114e64225d1add892b4adf8f6b43057169755d96b6ebc59eaa37904fb719e358e6759f598593ea69f7f + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W4.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W4.rsp new file mode 100644 index 0000000000..7e4ae977d5 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W4.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H5_W4 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 000000000000000000000003aeb14a03f55d830d64ab4981809d932f48f8371887e4b52188d67e9e77d296b7699c4267b07320535a32b9fda668fe4d64e126e1190851de8400a1eb29b6251778dbf3fb6e6c2d4ed9cd306501ff53e4b3e2e6338d8107537ba3bfd14ce795cf8f939e9ea6add97df60ae591800014cac041bb38857d29a479ece3289240b926b02e7079af6ce0bd239fd9c9c55880c7c68d527abc9210cba38903c561130e1cf88e75ac230a1ba6591edf39142739e8cd16d5c744d49c6dc9318927b3f6a2f44139131b5a29635a80e5e4ebde27570727e9fcd9aa18c7e45293f67c0a179a7a159574908c1a43de083e69aead0dfe6ae356367da1de7bc4007b45483f3863b045a047ccad8a88c16ebf45aa2e76a40a5806225bfefcfce1687602b204efd87385308a2a4d4e0378714ce5bd12341b1a71e8d155b2cb2e08616d5280c418d355987cffad11b65e2032371a211269943baa66907285e4968fb4bfb271230809365dbcb8fece0e66a6c23ae94a4a91ad6cebea8c2ed848ac76fd43935db8382731ad2188f556519b87efad901b656f8c5b533a772cdb1f59b2afadf46ea3cacb9eff1eff51ef73cb414da18f188880a67d6a2dc70c4aafda7d2d65ccb3e870033c3ccd2e16116b4f685ee45194cb8ff4415768a22ae5189ebd2f5d2a0bb796890b85a01979536d5ca3ea77994cfd530bf95a039a7ce635a6db922baa997a6c26ef45e12018b58cd2cbc7b3b3d0d2938b28ae7d0779369e0f8889c36ad3a20e6cac70268428eb43fc660d6a2a293762aef9df55e5873304141ec87a96ce4d6a7e20fe69d66a70e872c4f037f32b5317f51a602196c8e443ed0cf80bc2b7104b2b5211cffd650cba2de1777268b1e015556e55f3e4400e61abcff383541594947f4ca2394ad26c43d3301264d05cae9a38d4c70b7b6edf50368f2e30842bd619387961c258abf34181b0e662af0db9ddd8e444116e28d1959c4e56f5e32322d51b772f6f994e971c49869ced203936f76731787fa6e8d13dfc533103ca0c3cea5d8c27d8b3b05f9ac81b30b9ec947cf39299972214b6e058f3fcf58ed982efb02bd1cdb6199264183c82853ae04cac67f6d2baa37f725dc77f08534273e8cf070e9383d8f4ebdc44bb2f4a48a8aa9ad9b8c6ccd1a718fd9ad8716aece437630a5294ae83898d44392444bd7d26fa0705fc37f384b9b09b94ef0ffab639b9d01758d286a8ae14c933e746459c64dc31d609716e928469e38b36e563ef68e3644a7200a262b1688fd8e4363b57d42a64d0866e19501ec91d83707067fd37e1a3b42453e75afa9739e73030180ad38b687230b6bc8ba02ec2bc300a87828a1de3a8cab63fb26d30099f960dd82b7cc65923b0dc380d3513cf0c74e671e50ba668b8b0497919e260cd8c2755de8ae3455ab3dc3c378a789b8c84dd6ee8641a4feb06ac3d8dd80093e744ca7f44e1a3bd0e1d05870841e13a6744530cf89b887085cf8031c1c713d9167d9e1ad5d5e7c5d6ecce0830863f846d423dd76a91be60aff65a72f16e71173609a46f3bbd33f46d8d1928fe620a646bba75325dda0e8dbf1f95ca9bc02e891889e6b3009cbc944b9aab65fa30cce224ec1856abf23556ac570f43396c61cab7f458d5ff1fe7f83c0764e78fa0f9f9d75fa9e0c518379a3ca746205fe03751231ba269e19b579b90b1da30d8b6315ed7a4e54ae88fbcdb15a8fbf24fee6d9f7b95dceb99d330b449f05a53974118989ca9ac1bcdddad5a43b882db01cd27d72236c0d060b2b6120ecd7053820a5cfa84dc672fc2c310067cffd3f5a8c3bca13077fc1d44e99c111d4f95cd68d74bf827849277ccd7245166950beb19f33297a00838ca21b896073878f2b509bedc6d6ae8295dbe1a059cf3ebcf40e7790e0530dcb66159a8c0e0fdde36f1b6374e42eb331b92bfa9061c6f480bb64e73c539eda7ef879730904d5843ea1c5616798adbe21d6c5fc4efebb60c45ccb30b7b1fbe673e754717ac71f5ca272dfffd2aca2eb8cb885c8a8395800f70c90271aba676239abb86c0708301bbf643028e55b9dfcbd338f2e22f5cee5c4d0fa163488a06fab8f15337dc219292f53325f98a4ce0f3f931b2961483d165a97e19d9d1408a156c7d35eab47fa5edf71dcf862e68a37787a1203c35383047398b3f305e1d4fe19d8dddbeb07990c507e8d80b6992c5c996c14b7cd31f65006585dd6bdc7fe43a893e96e06daecbcde583759f8138b3461341ec115ff29f1ed2eb72ff45d29e674dbc27165c9c2ba212455264936a9b8615ec5fd6cc26390dc45e1bfdb9815c8026ab9744af6eedfef8d2b2e73adcc50c52593ae3750dbc880c19dd627f215a49b044f87f866098c14e2716a055819ed0314ce687193cddc15773a220c1204b81dbf11087019ef723f0e14131f638cce5224bc1c73626a2811fec0becf91b6e39674c16c31407289222bb02eeca5ccb6a195c8c594d5ec984ac7fa1cc266f40dc4c6ca0724a94da0e1c8ac89ae52ab5c35ab2dfab88d9899336b19b099a71d0564f31ecfce6c582446a37e4acd62c62902afe83d01b977d61b31e4d03efeef17e381891c5e96a1043da0421eafacb98358ec2e98986762add3036aa1a1dd9f3235dd9a6f991e935d44337a265755aec34e819175e140b51079662ab5905073e588c785647444c4a3484c7f5643056b49e4fd0927cbfdab1b4c3101484c20a673b5322fafba8525d8c76f05e2cf522f1bd9955b86ebff690c02bbe96f73247396f50829f12ab26d21f082af26fb68cf7c4edd47602955a72eb29fe18a22131a8ec9b33936e816da6ecbc78b83e7656796dd756eb408a462df7830a67371d088b4e3aa15d4f56412cc1147338ca3fbd759ec61c2069d58ef9e84fd436eadaf2f8a955bf86c1d336830e9e8e8ae5374827cd801f0fd92dfe10043e8e1776c6ecd0cb7b9e0bfb6e326e8eb0224203575ec16007008dd284836dc7b4425fd39048d3cd2df1ef4fe18d6499abcd55d38d44c70852557ce09c3e3f45234cfa94f417600886b9b8a946a24ddeb19726c8b0a0b1a41be57b203c310f558daa000000050233c68da9d372a5a75790fd99589f6cb07f2c9cf97325a28c59bac5ec87e8eac10877a29091357b9b12611d2ad4b6ebb92f2a92cd0efd4a80eba5fec0eb6f95d1d9ddfe0b6e9eadb2420921ab517eba102bb8fa0402cf463d7b7d3122e161a5b18959390a8a38d08706f1ee4c2a7cdbbf95a642133e504791cb5516e1ccf2915cdc752a2a6cc023632112bf44115a1d97fce39359885b203307721151e4574c + +pk = 0000000100000005000000034cadc1a52afbdd1adb775d499fa9defb5f95bfa52fa746594f3311b8fb9c837b15412323da079146956b63e0a30c423c + diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8.rsp new file mode 100644 index 0000000000..57369ce635 --- /dev/null +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8.rsp @@ -0,0 +1,8 @@ +# LMS_SHA256_H5_W8 + +msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a + +sm = 000000000000000000000004c15445cdb0955e650d038fe369128bb41dec49c85cd58208337d27a63c4c4c613fa669e360606b31f1bcbcef9540a8babe0fb27755ca9e444cc7e3b2de51f4f63b9fad23b7a334003a45ce9919f223efa24d1e24ccd6b7d46f645834ae72cdd32484d1db569f8ed1b784ee2aaca9645e3fb7b0c68c1c8d22812b6903176e4475f307e0fad497f2134462d94f51c63e1e29defaad7bdaf03e49da1ea7086c064b3e536c01c4cc435d5be073cea199da5e6d1c3fd3a9f6d5b32f5ae2d974f07dfef21994f9e33999dfc0d3074aa8bf41c73d1b2f106ec5624badbb6521a3d21bb59fa5c28e8f02788975290248ad126ccec0639da4b0eb2e1a09be522dbadac2fdf2643c4cf2f905a55e7181542ce391f9ec6e3023fb3f015a52358be92385d6fb2c5ea84ed630622c872fcfcfab61e90b94b0307b31fab6df36c43c3d8907ff7842573d998b4e66f629d37681700c8f8d0c4da8ff8ab6e20348e817ba9e818de076ebd99d0b8ce672c12459b5955dd714b40a93210050bf54c8bbaf22840c2d007cd1f40a000cc55c745cfd3316205731818b93cfb51045369a4ee88cbce94b77544e64861d62dd10e711795d6fe3d4ad1517ead72967403c1a6a308bf834d224da53c2f89528c480bf294ca41e9018f129c0ba6316ea18fdd6e9d80e0593333c668432cf8a9505659fb63fe309b5ef348bef9e19fbecc33af91790b1c4531a85cad51af236ce5efdcbd77212fc0b642dcb91f7719e49a38ddd5afad688ed9ce5fb48d98f5e2c08f06d743d92b005e4d013e4474703f8c8f5b085f4f479896191f8fc9e9d6fd8b9c529ce2a7e8d1fcf614078366943deb263455843a31d16be42aa8551185315c705e90afaf25a06e93a7c7ea6696cf6f3cb496c674e3366e1fd6c1280a83900d5e62de9757e3383feb324728b32a496b97f6356f30ab160611ea04abc38b21cc7553901599ea4c590f9a4082e6341a9c323ea5dbf0f93180ef5bec182694c44e3360cc4ba3be21aed6958da7a6d8a75bbd84e24b40d88a2cd477e319933ad193b3072a987915edd7404e67d67759b31bfca09c6863e3230ff1e8731d1d8611bcdf31d5c5e272f674eff68b25933555feb2356b7639b7147961e3d8405e42f01bd6710bf64e896658d3532a78f67dd99d047060e107e084141ab06ba38124224861d6ff5e356bb43f90ca37b7b119ee2a06665b1c9f5d913853cc27f20b539727957ff17c07de0b9754d49f3ea1ea6da022112015e82a477e719aebb35e4c7e680dce407e3919832143ae3898ee14cf91ceb150341ebf5f767d2e1581c41751b8ddee365491e69d4c3c9ac548d60b8105b6b6afef80be691f1a766c59ad94ddee2ac824e26a3341b4409050486fbc94a1d95488446fd58595465204a0b7baeb3654c85ad124a6a42d6bb134e2bb9231a9f073afdfdb9fc6f114a99d08a685587475567cc68df54376fd13acab6b83b06628715e5ebc69938154c9e7c14c7cae80f78ccd41a8d07f2a65c09f5be027cd8fae674059b48d9d720250fc35160dfbcf520f89cce57af12415ea14996e85c6eaecef30319642839d4ce000000052c26f6dbb703f8711854e896635d51cec418c2c01df5fa5067c3a3ec08b30d042f4a08bb5dd156f17039c6eb9cbea8cdfbf46e64c6e345edc8aff2dcc7ad2ad911f2fca9853978b696cab99a0d633873e5f36f7e3faae37e24f8a27451604e9aca4a6d3549035e7a4e4527fead4920e658bd66d06509eda1841f843720016117ef0a66c52e26a12b719480cdb6055127a1601bb7110772341f1202e54ac90824 + +pk = 00000001000000050000000467bf07c0d0e24981d1b189ccad1efab150d6409b74d36699f982f537969d785c7bc406d1803ccca5905e8e9c0aca1113 + diff --git a/tests/example_sig_stfl.c b/tests/example_sig_stfl.c index b332d8479b..cbabee8b14 100644 --- a/tests/example_sig_stfl.c +++ b/tests/example_sig_stfl.c @@ -122,7 +122,7 @@ static OQS_STATUS stfl_example(char *method_name) { int main(void) { OQS_init(); - if (stfl_example("XMSS-SHA2_10_256") == OQS_SUCCESS && stfl_example("LMS_SHA256_H10_W4") == OQS_SUCCESS) { + if (stfl_example((char *)"XMSS-SHA2_10_256") == OQS_SUCCESS && stfl_example((char *)"LMS_SHA256_H10_W4") == OQS_SUCCESS) { OQS_destroy(); return EXIT_SUCCESS; } else { diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 55ba104d56..973a16692a 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -32,6 +32,12 @@ static pthread_mutex_t *sk_lock = NULL; #define OQS_TEST_CT_DECLASSIFY(addr, len) #endif +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif + /* * For stateful signature, we skip key generation because it can takes hours to complete. * So the ReadHex and and FindMarker serve the purpose of reading pre-generate keypair from KATs. @@ -46,6 +52,7 @@ int FindMarker(FILE *infile, const char *marker) { unsigned long i, len; int curr_line; + memset(line, 0, MAX_MARKER_LEN); len = strlen(marker); if (len > MAX_MARKER_LEN - 1) { len = MAX_MARKER_LEN - 1; @@ -130,16 +137,16 @@ int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, char *str) { return 1; } -static OQS_SIG_STFL_SECRET_KEY *lock_test_sk = NULL; -static OQS_SIG_STFL *lock_test_sig_obj = NULL; -static uint8_t *lock_test_public_key = NULL; -static char *lock_test_context = NULL; -static uint8_t *signature_1 = NULL; -static uint8_t *signature_2 = NULL; -static size_t signature_len_1; -static size_t signature_len_2; -static uint8_t message_1[] = "The quick brown fox ..."; -static uint8_t message_2[] = "The quick brown fox jumped from the tree."; +// static OQS_SIG_STFL_SECRET_KEY *lock_test_sk = NULL; +// static OQS_SIG_STFL *lock_test_sig_obj = NULL; +// static uint8_t *lock_test_public_key = NULL; +// static char *lock_test_context = NULL; +// static uint8_t *signature_1 = NULL; +// static uint8_t *signature_2 = NULL; +// static size_t signature_len_1; +// static size_t signature_len_2; +// static uint8_t message_1[] = "The quick brown fox ..."; +// static uint8_t message_2[] = "The quick brown fox jumped from the tree."; /* * Write stateful secret keys to disk. @@ -161,6 +168,18 @@ static OQS_STATUS save_secret_key(uint8_t *key_buf, size_t buf_len, void *contex } #if OQS_USE_PTHREADS_IN_TESTS + +static OQS_SIG_STFL_SECRET_KEY *lock_test_sk = NULL; +static OQS_SIG_STFL *lock_test_sig_obj = NULL; +static uint8_t *lock_test_public_key = NULL; +static char *lock_test_context = NULL; +static uint8_t *signature_1 = NULL; +static uint8_t *signature_2 = NULL; +static size_t signature_len_1; +static size_t signature_len_2; +static uint8_t message_1[] = "The quick brown fox ..."; +static uint8_t message_2[] = "The quick brown fox jumped from the tree."; + static OQS_STATUS lock_sk_key(void *mutex) { if (mutex == NULL) { return OQS_ERROR; @@ -183,11 +202,13 @@ static OQS_STATUS unlock_sk_key(void *mutex) { return OQS_SUCCESS; } #else -static OQS_STATUS lock_sk_key(void *mutex) { +static OQS_STATUS lock_sk_key(UNUSED void *mutex) { + // void(*mutex); return OQS_SUCCESS; } -static OQS_STATUS unlock_sk_key(void *mutex) { +static OQS_STATUS unlock_sk_key(UNUSED void *mutex) { + // void(mutex); return OQS_SUCCESS; } #endif @@ -213,12 +234,12 @@ OQS_STATUS sig_stfl_keypair_from_KATs(OQS_SIG_STFL *sig, uint8_t *public_key, OQ } // Grab the pk and sk from KAT file - if (!ReadHex(fp_rsp, public_key, sig->length_public_key, "pk = ")) { + if (!ReadHex(fp_rsp, public_key, sig->length_public_key, (char *)"pk = ")) { fprintf(stderr, "ERROR: unable to read 'pk' from <%s>\n", katfile); goto err; } - if (!ReadHex(fp_rsp, secret_key->secret_key_data, sig->length_secret_key, "sk = ")) { + if (!ReadHex(fp_rsp, secret_key->secret_key_data, sig->length_secret_key, (char *)"sk = ")) { fprintf(stderr, "ERROR: unable to read 'sk' from <%s>\n", katfile); goto err; } @@ -410,7 +431,7 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char file_store = convert_method_name_to_file_name(sig->method_name); if (file_store == NULL) { - fprintf(stderr, "%s: file_store is null\n", __FUNCTION__); + fprintf(stderr, "%s: file_store is null\n", __func__); goto err; } @@ -683,6 +704,23 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name, const char * return rc; } +#ifdef OQS_ENABLE_TEST_CONSTANT_TIME +static void TEST_SIG_STFL_randombytes(uint8_t *random_array, size_t bytes_to_read) { + // We can't make direct calls to the system randombytes on some platforms, + // so we have to swap out the OQS_randombytes provider. + + OQS_randombytes_switch_algorithm("system"); + OQS_randombytes(random_array, bytes_to_read); + OQS_randombytes_custom_algorithm(&TEST_SIG_STFL_randombytes); + + // OQS_TEST_CT_CLASSIFY tells Valgrind's memcheck tool to issue a warning if + // the program branches on any byte that depends on random_array. This helps us + // identify timing side-channels, as these bytes often contain secret data. + OQS_TEST_CT_CLASSIFY(random_array, bytes_to_read); +} +#endif + +#if OQS_USE_PTHREADS_IN_TESTS static OQS_STATUS sig_stfl_test_query_key(const char *method_name) { OQS_STATUS rc = OQS_SUCCESS; size_t message_len_1 = sizeof(message_1); @@ -883,9 +921,9 @@ static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name, const c OQS_SIG_STFL_SECRET_KEY_SET_lock(lock_test_sk, lock_sk_key); OQS_SIG_STFL_SECRET_KEY_SET_unlock(lock_test_sk, unlock_sk_key); -#if OQS_USE_PTHREADS_IN_TESTS +//#if OQS_USE_PTHREADS_IN_TESTS OQS_SIG_STFL_SECRET_KEY_SET_mutex(lock_test_sk, test_sk_lock); -#endif +//#endif printf("================================================================================\n"); printf("Generate keypair %s\n", method_name); @@ -915,23 +953,7 @@ static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name, const c return OQS_ERROR; } -#ifdef OQS_ENABLE_TEST_CONSTANT_TIME -static void TEST_SIG_STFL_randombytes(uint8_t *random_array, size_t bytes_to_read) { - // We can't make direct calls to the system randombytes on some platforms, - // so we have to swap out the OQS_randombytes provider. - - OQS_randombytes_switch_algorithm("system"); - OQS_randombytes(random_array, bytes_to_read); - OQS_randombytes_custom_algorithm(&TEST_SIG_STFL_randombytes); - // OQS_TEST_CT_CLASSIFY tells Valgrind's memcheck tool to issue a warning if - // the program branches on any byte that depends on random_array. This helps us - // identify timing side-channels, as these bytes often contain secret data. - OQS_TEST_CT_CLASSIFY(random_array, bytes_to_read); -} -#endif - -#if OQS_USE_PTHREADS_IN_TESTS typedef struct thread_data { const char *alg_name; const char *katfile; @@ -947,25 +969,25 @@ typedef struct lock_test_data { void *test_query_key(void *arg) { struct lock_test_data *td = arg; - printf("\n%s: Start Query Stateful Key info\n", __FUNCTION__); + printf("\n%s: Start Query Stateful Key info\n", __func__); td->rc = sig_stfl_test_query_key(td->alg_name); - printf("%s: End Query Stateful Key info\n\n", __FUNCTION__); + printf("%s: End Query Stateful Key info\n\n", __func__); return NULL; } void *test_sig_gen(void *arg) { struct lock_test_data *td = arg; - printf("\n%s: Start Generate Stateful Signature\n", __FUNCTION__); + printf("\n%s: Start Generate Stateful Signature\n", __func__); td->rc = sig_stfl_test_sig_gen(td->alg_name); - printf("%s: End Generate Stateful Signature\n\n", __FUNCTION__); + printf("%s: End Generate Stateful Signature\n\n", __func__); return NULL; } void *test_create_keys(void *arg) { struct lock_test_data *td = arg; - printf("\n%s: Start Generate Keys\n", __FUNCTION__); + printf("\n%s: Start Generate Keys\n", __func__); td->rc = sig_stfl_test_secret_key_lock(td->alg_name, td->katfile); - printf("%s: End Generate Stateful Keys\n\n", __FUNCTION__); + printf("%s: End Generate Stateful Keys\n\n", __func__); return NULL; } @@ -1086,10 +1108,6 @@ int main(int argc, char **argv) { if (sk_lock) { pthread_mutex_destroy(sk_lock); } -#else - rc = sig_stfl_test_correctness(alg_name, katfile); - rc1 = sig_stfl_test_secret_key(alg_name, katfile); -#endif OQS_SIG_STFL_SECRET_KEY_free(lock_test_sk); OQS_MEM_insecure_free(lock_test_public_key); @@ -1097,11 +1115,24 @@ int main(int argc, char **argv) { OQS_MEM_insecure_free(lock_test_context); OQS_MEM_insecure_free(signature_1); OQS_MEM_insecure_free(signature_2); - - OQS_destroy(); if (rc != OQS_SUCCESS || rc1 != OQS_SUCCESS || rc_create != OQS_SUCCESS || rc_sign != OQS_SUCCESS || rc_query != OQS_SUCCESS) { return EXIT_FAILURE; } return exit_status; +#else + rc = sig_stfl_test_correctness(alg_name, katfile); + rc1 = sig_stfl_test_secret_key(alg_name, katfile); +// OQS_MEM_insecure_free(signature_1); +// signature_1 = NULL; +// OQS_MEM_insecure_free(signature_2); +// signature_2 = NULL; + + OQS_destroy(); + + if (rc != OQS_SUCCESS || rc1 != OQS_SUCCESS) { + return EXIT_FAILURE; + } + return exit_status; +#endif } From ddae6444b424343e7623b010d3dc304adc101ce6 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Wed, 20 Dec 2023 01:22:18 -0500 Subject: [PATCH 24/68] Various fixes --- .CMake/alg_support.cmake | 12 + src/common/sha2/sha2_armv8.c | 2 +- src/oqsconfig.h.cmake | 2 - src/sig_stfl/lms/external/hss_alloc.c | 2 +- src/sig_stfl/lms/external/hss_sign.c | 6 +- src/sig_stfl/lms/external/hss_verify_inc.c | 2 +- src/sig_stfl/lms/sig_stfl_lms_functions.c | 4 +- src/sig_stfl/sig_stfl.c | 416 ++++++++++++++++++++- src/sig_stfl/sig_stfl.h | 8 - tests/test_sig_stfl.c | 19 - 10 files changed, 430 insertions(+), 43 deletions(-) diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index 119ee52f3f..d1f9e8daae 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -551,6 +551,18 @@ cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h25_w4 "" ON "OQS_ENABLE_S cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h25_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8_h5_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h10_w2_h10_w2 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h10_w4 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8_h10_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8_h5_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8_h10_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8_h15_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h5_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h10_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h15_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h20_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) + if((OQS_MINIMAL_BUILD STREQUAL "ON")) message(FATAL_ERROR "OQS_MINIMAL_BUILD option ${OQS_MINIMAL_BUILD} no longer supported") diff --git a/src/common/sha2/sha2_armv8.c b/src/common/sha2/sha2_armv8.c index 9f5a96bd97..b8f6b16cb3 100644 --- a/src/common/sha2/sha2_armv8.c +++ b/src/common/sha2/sha2_armv8.c @@ -291,7 +291,7 @@ void oqs_sha2_sha256_inc_armv8(sha256ctx *state, const uint8_t *in, size_t len) } for (size_t i = 0; i < incr; ++i, state->data_len++, in_index++) { - state->data[state->data_len] = in[in_index++]; + state->data[state->data_len] = in[in_index]; } if (state->data_len < 64) { diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index 9fce48b769..7fdfd7bdb9 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -233,7 +233,5 @@ #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h15_w1 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h15_w2 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h15_w4 1 -#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8 1 -#cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h20_w1 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 1 diff --git a/src/sig_stfl/lms/external/hss_alloc.c b/src/sig_stfl/lms/external/hss_alloc.c index 3907d8764b..9e6e7694c1 100644 --- a/src/sig_stfl/lms/external/hss_alloc.c +++ b/src/sig_stfl/lms/external/hss_alloc.c @@ -361,7 +361,7 @@ signed long initial_mem_target = mem_target; /* DEBUG HACK */ /* This is a signed type so that the comparison works as */ /* expected if mem_target is negative */ size_t stack_used; - unsigned long mem = compute_level_memory_usage(i, j, + unsigned long mem = (unsigned long)compute_level_memory_usage(i, j, level_height[i], hash_size[i], &subtree_levels[i], &stack_used ); /* # of sublevels this would have */ diff --git a/src/sig_stfl/lms/external/hss_sign.c b/src/sig_stfl/lms/external/hss_sign.c index 3ce7159fbf..9b452e7a83 100644 --- a/src/sig_stfl/lms/external/hss_sign.c +++ b/src/sig_stfl/lms/external/hss_sign.c @@ -197,7 +197,7 @@ static int generate_merkle_signature( hss_seed_derive_done(&derive); if (!success) return 0; } - signature += ots_sig_size; signature_len -= ots_sig_size; + signature += ots_sig_size; signature_len -= (unsigned)ots_sig_size; /* Write the LM parameter set */ if (signature_len < 4) return 0; @@ -253,7 +253,7 @@ bool hss_create_signed_public_key(unsigned char *signed_key, unsigned len_public_key = 8 + I_LEN + hash_size; /* Now, generate the signature */ - if (!(unsigned int)generate_merkle_signature( signed_key, len_signature, + if ((int)0 == generate_merkle_signature( signed_key, len_signature, parent, w, public_key, len_public_key)) { return false; } @@ -303,7 +303,7 @@ static void do_gen_sig( const void *detail, struct thread_collection *col) { const unsigned char *message = d->message; size_t message_len = d->message_len; - if (!(unsigned int)generate_merkle_signature(signature, signature_len, + if ((int)0 == generate_merkle_signature(signature, signature_len, w->tree[ levels-1 ], w, message, message_len)) { goto failed; } diff --git a/src/sig_stfl/lms/external/hss_verify_inc.c b/src/sig_stfl/lms/external/hss_verify_inc.c index bb8da66db1..4b5cf7e7a1 100644 --- a/src/sig_stfl/lms/external/hss_verify_inc.c +++ b/src/sig_stfl/lms/external/hss_verify_inc.c @@ -83,7 +83,7 @@ bool hss_validate_signature_init( /* to validate) */ if (signature_len < 4) goto failed; lm_type = (param_set_t)get_bigendian( signature, 4 ); - unsigned l_pubkeylen = lm_get_public_key_len(lm_type); + unsigned l_pubkeylen = (unsigned)lm_get_public_key_len(lm_type); if (l_pubkeylen == 0 || l_pubkeylen > signature_len) goto failed; const unsigned char *l_pubkey = signature; signature += l_pubkeylen; signature_len -= l_pubkeylen; diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index b05910d089..be709fc71c 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -707,8 +707,8 @@ OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_ oqs_lms_key_data *lms_key_data = NULL; uint8_t *lms_sk = NULL; uint8_t *lms_aux = NULL; - int aux_buf_len = 0; - uint8_t lms_sk_len = hss_get_private_key_len((unsigned )(1), NULL, NULL); + size_t aux_buf_len = 0; + size_t lms_sk_len = hss_get_private_key_len((unsigned )(1), NULL, NULL); if (sk == NULL || sk_buf == NULL || (sk_len == 0) || (sk_len < lms_sk_len )) { return OQS_ERROR; diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index dafbcd8aa5..6b63f8a73e 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -11,6 +11,14 @@ #include +#ifdef OQS_ENABLE_SIG_STFL_XMSS +#include +#endif // OQS_ENABLE_SIG_STFL_XMSS + +#ifdef OQS_ENABLE_SIG_STFL_LMS +#include +#endif // OQS_ENABLE_SIG_STFL_LMS + OQS_API const char *OQS_SIG_STFL_alg_identifier(size_t i) { const char *a[OQS_SIG_STFL_algs_length] = { @@ -273,83 +281,215 @@ OQS_API int OQS_SIG_STFL_alg_is_enabled(const char *method_name) { return 0; #endif } -#ifdef OQS_ENABLE_SIG_STFL_LMS +//#ifdef OQS_ENABLE_SIG_STFL_LMS else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w1 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w2 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w4 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w1 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w2 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w1 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w2 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w4 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w1 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w2 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w4 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h25_w1 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h25_w2 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h25_w4 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h25_w8 return 1; +#else + return 0; +#endif } //2-Level LMS else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8_h5_w8 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w2_h10_w2 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h10_w4 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8_h10_w8 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8_h5_w8 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8_h10_w8 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8_h15_w8 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h5_w8 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w1 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w1 return 1; +#else + return 0; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w1 return 1; +#else + return 0; +#endif } -#endif //OQS_ENABLE_SIG_STFL_LMS +//#endif //OQS_ENABLE_SIG_STFL_LMS else { return 0; } @@ -529,77 +669,209 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { return NULL; #endif } -#ifdef OQS_ENABLE_SIG_STFL_LMS +//#ifdef OQS_ENABLE_SIG_STFL_LMS else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w1 return OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w2 return OQS_SIG_STFL_alg_lms_sha256_h5_w2_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w4 return OQS_SIG_STFL_alg_lms_sha256_h5_w4_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8 return OQS_SIG_STFL_alg_lms_sha256_h5_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w1 return OQS_SIG_STFL_alg_lms_sha256_h10_w1_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w2 return OQS_SIG_STFL_alg_lms_sha256_h10_w2_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4 return OQS_SIG_STFL_alg_lms_sha256_h10_w4_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8 return OQS_SIG_STFL_alg_lms_sha256_h10_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w1 return OQS_SIG_STFL_alg_lms_sha256_h15_w1_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w2 return OQS_SIG_STFL_alg_lms_sha256_h15_w2_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w4 return OQS_SIG_STFL_alg_lms_sha256_h15_w4_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8 return OQS_SIG_STFL_alg_lms_sha256_h15_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w1 return OQS_SIG_STFL_alg_lms_sha256_h20_w1_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w2 return OQS_SIG_STFL_alg_lms_sha256_h20_w2_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w4 return OQS_SIG_STFL_alg_lms_sha256_h20_w4_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8 return OQS_SIG_STFL_alg_lms_sha256_h20_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h28_w1 return OQS_SIG_STFL_alg_lms_sha256_h25_w1_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h28_w2 return OQS_SIG_STFL_alg_lms_sha256_h25_w2_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h25_w4 return OQS_SIG_STFL_alg_lms_sha256_h25_w4_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h25_w8 return OQS_SIG_STFL_alg_lms_sha256_h25_w8_new(); +#else + return NULL; +#endif } //2-Level LMS else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 return OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 return OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8_h5_w8 return OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w2_h10_w2 return OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h10_w4 return OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8_h10_w8 return OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8_h5_w8 return OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8_h10_w8 return OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8_h15_w8 return OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h5_w8 return OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h10_w8 return OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h15_w8 return OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h20_w8 return OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_new(); +#else + return NULL; +#endif } -#endif //OQS_ENABLE_SIG_STFL_LMS +//#endif //OQS_ENABLE_SIG_STFL_LMS else { return NULL; } @@ -827,77 +1099,209 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_ return NULL; #endif } -#ifdef OQS_ENABLE_SIG_STFL_LMS +//#ifdef OQS_ENABLE_SIG_STFL_LMS else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w1 return OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w2 return OQS_SECRET_KEY_LMS_SHA256_H5_W2_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w4 return OQS_SECRET_KEY_LMS_SHA256_H5_W4_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8 return OQS_SECRET_KEY_LMS_SHA256_H5_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w1 return OQS_SECRET_KEY_LMS_SHA256_H10_W1_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w2 return OQS_SECRET_KEY_LMS_SHA256_H10_W2_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4 return OQS_SECRET_KEY_LMS_SHA256_H10_W4_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8 return OQS_SECRET_KEY_LMS_SHA256_H10_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w1 return OQS_SECRET_KEY_LMS_SHA256_H15_W1_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w2 return OQS_SECRET_KEY_LMS_SHA256_H15_W2_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w4 return OQS_SECRET_KEY_LMS_SHA256_H15_W4_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8 return OQS_SECRET_KEY_LMS_SHA256_H15_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w1 return OQS_SECRET_KEY_LMS_SHA256_H20_W1_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w2 return OQS_SECRET_KEY_LMS_SHA256_H20_W2_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w4 return OQS_SECRET_KEY_LMS_SHA256_H20_W4_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8 return OQS_SECRET_KEY_LMS_SHA256_H20_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w1)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h25_w1 return OQS_SECRET_KEY_LMS_SHA256_H25_W1_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h25_w2 return OQS_SECRET_KEY_LMS_SHA256_H25_W2_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h25_w4 return OQS_SECRET_KEY_LMS_SHA256_H25_W4_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h25_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h25_w4 return OQS_SECRET_KEY_LMS_SHA256_H25_W8_new(); +#else + return NULL; +#endif } //2-Level LMS else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 return OQS_SECRET_KEY_LMS_SHA256_H5_W8_H5_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8_h5_w8 return OQS_SECRET_KEY_LMS_SHA256_H10_W8_H5_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w2_h10_w2 return OQS_SECRET_KEY_LMS_SHA256_H10_W2_H10_W2_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h10_w4 return OQS_SECRET_KEY_LMS_SHA256_H10_W4_H10_W4_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 return OQS_SECRET_KEY_LMS_SHA256_H10_W4_H5_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8_h10_w8 return OQS_SECRET_KEY_LMS_SHA256_H10_W8_H10_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8_h5_w8 return OQS_SECRET_KEY_LMS_SHA256_H15_W8_H5_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h10_w8_h10_w8 return OQS_SECRET_KEY_LMS_SHA256_H15_W8_H10_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h15_w8_h15_w8 return OQS_SECRET_KEY_LMS_SHA256_H15_W8_H15_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h5_w8 return OQS_SECRET_KEY_LMS_SHA256_H20_W8_H5_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h10_w8 return OQS_SECRET_KEY_LMS_SHA256_H20_W8_H10_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h15_w8 return OQS_SECRET_KEY_LMS_SHA256_H20_W8_H15_W8_new(); +#else + return NULL; +#endif } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8)) { +#ifdef OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h20_w8 return OQS_SECRET_KEY_LMS_SHA256_H20_W8_H20_W8_new(); +#else + return NULL; +#endif } -#endif //OQS_ENABLE_SIG_STFL_LMS +//#endif //OQS_ENABLE_SIG_STFL_LMS else { return NULL; } diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index aa83e4c486..70797ee80a 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -575,12 +575,4 @@ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY * } // extern "C" #endif -#ifdef OQS_ENABLE_SIG_STFL_XMSS -#include -#endif // OQS_ENABLE_SIG_STFL_XMSS - -#ifdef OQS_ENABLE_SIG_STFL_LMS -#include -#endif // OQS_ENABLE_SIG_STFL_LMS - #endif /* OQS_SIG_STATEFUL_H */ diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 973a16692a..a3d4bfd3f5 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -137,17 +137,6 @@ int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, char *str) { return 1; } -// static OQS_SIG_STFL_SECRET_KEY *lock_test_sk = NULL; -// static OQS_SIG_STFL *lock_test_sig_obj = NULL; -// static uint8_t *lock_test_public_key = NULL; -// static char *lock_test_context = NULL; -// static uint8_t *signature_1 = NULL; -// static uint8_t *signature_2 = NULL; -// static size_t signature_len_1; -// static size_t signature_len_2; -// static uint8_t message_1[] = "The quick brown fox ..."; -// static uint8_t message_2[] = "The quick brown fox jumped from the tree."; - /* * Write stateful secret keys to disk. */ @@ -203,12 +192,10 @@ static OQS_STATUS unlock_sk_key(void *mutex) { } #else static OQS_STATUS lock_sk_key(UNUSED void *mutex) { - // void(*mutex); return OQS_SUCCESS; } static OQS_STATUS unlock_sk_key(UNUSED void *mutex) { - // void(mutex); return OQS_SUCCESS; } #endif @@ -921,9 +908,7 @@ static OQS_STATUS sig_stfl_test_secret_key_lock(const char *method_name, const c OQS_SIG_STFL_SECRET_KEY_SET_lock(lock_test_sk, lock_sk_key); OQS_SIG_STFL_SECRET_KEY_SET_unlock(lock_test_sk, unlock_sk_key); -//#if OQS_USE_PTHREADS_IN_TESTS OQS_SIG_STFL_SECRET_KEY_SET_mutex(lock_test_sk, test_sk_lock); -//#endif printf("================================================================================\n"); printf("Generate keypair %s\n", method_name); @@ -1123,10 +1108,6 @@ int main(int argc, char **argv) { #else rc = sig_stfl_test_correctness(alg_name, katfile); rc1 = sig_stfl_test_secret_key(alg_name, katfile); -// OQS_MEM_insecure_free(signature_1); -// signature_1 = NULL; -// OQS_MEM_insecure_free(signature_2); -// signature_2 = NULL; OQS_destroy(); From cc50ef00d14eef43e51c1b83ef32637a1f42f7af Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Thu, 21 Dec 2023 00:28:13 -0500 Subject: [PATCH 25/68] Fix warning --- src/sig_stfl/lms/external/hss_sign.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sig_stfl/lms/external/hss_sign.c b/src/sig_stfl/lms/external/hss_sign.c index 9b452e7a83..cbcbdf845b 100644 --- a/src/sig_stfl/lms/external/hss_sign.c +++ b/src/sig_stfl/lms/external/hss_sign.c @@ -253,7 +253,7 @@ bool hss_create_signed_public_key(unsigned char *signed_key, unsigned len_public_key = 8 + I_LEN + hash_size; /* Now, generate the signature */ - if ((int)0 == generate_merkle_signature( signed_key, len_signature, + if (!generate_merkle_signature( signed_key, (unsigned)len_signature, parent, w, public_key, len_public_key)) { return false; } @@ -303,7 +303,7 @@ static void do_gen_sig( const void *detail, struct thread_collection *col) { const unsigned char *message = d->message; size_t message_len = d->message_len; - if ((int)0 == generate_merkle_signature(signature, signature_len, + if (!generate_merkle_signature(signature, (unsigned)signature_len, w->tree[ levels-1 ], w, message, message_len)) { goto failed; } From 9610576db49c8ebb1c21a8a4bcde942d0ade53f9 Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Tue, 2 Jan 2024 16:17:08 -0500 Subject: [PATCH 26/68] Fix windows-x86 and arm compiling error. (#1634) * Fix windows-x86 and arm compiling error. --------- Co-authored-by: Norman Ashley --- CMakeLists.txt | 2 +- README.md | 2 +- .../copy_from_upstream/copy_from_upstream.py | 2 +- src/common/sha2/sha2_armv8.c | 110 +++++++++--------- src/oqsconfig.h.cmake | 2 + src/sig_stfl/lms/sig_stfl_lms.h | 4 +- src/sig_stfl/sig_stfl.h | 14 +-- src/sig_stfl/xmss/external/xmss_commons.c | 14 ++- src/sig_stfl/xmss/external/xmss_core_fast.c | 69 ++++++----- tests/helpers.py | 3 +- tests/test_sig_stfl.c | 17 ++- 11 files changed, 132 insertions(+), 107 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 16b09a6400..5881ea3f73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,13 +196,13 @@ endif() if(OQS_ENABLE_SIG_SPHINCS) set(PUBLIC_HEADERS ${PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/src/sig/sphincs/sig_sphincs.h) endif() +##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_INCLUDE_HEADERS_END if(OQS_ENABLE_SIG_STFL_XMSS) set(PUBLIC_HEADERS ${PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/src/sig_stfl/xmss/sig_stfl_xmss.h) endif() if(OQS_ENABLE_SIG_STFL_LMS) set(PUBLIC_HEADERS ${PUBLIC_HEADERS} ${PROJECT_SOURCE_DIR}/src/sig_stfl/lms/sig_stfl_lms.h) endif() -##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_INCLUDE_HEADERS_END execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/include/oqs) execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${PUBLIC_HEADERS} ${PROJECT_BINARY_DIR}/include/oqs) execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${INTERNAL_HEADERS} ${PROJECT_BINARY_DIR}/include/oqs) diff --git a/README.md b/README.md index f91e39dea0..926a8ce28a 100644 --- a/README.md +++ b/README.md @@ -68,9 +68,9 @@ All names other than `ML-KEM` and `ML-DSA` are subject to change. `liboqs` makes - **ML-DSA**: ML-DSA-44-ipd (alias: ML-DSA-44), ML-DSA-65-ipd (alias: ML-DSA-65), ML-DSA-87-ipd (alias: ML-DSA-87) - **SPHINCS+-SHA2**: SPHINCS+-SHA2-128f-simple, SPHINCS+-SHA2-128s-simple, SPHINCS+-SHA2-192f-simple, SPHINCS+-SHA2-192s-simple, SPHINCS+-SHA2-256f-simple, SPHINCS+-SHA2-256s-simple - **SPHINCS+-SHAKE**: SPHINCS+-SHAKE-128f-simple, SPHINCS+-SHAKE-128s-simple, SPHINCS+-SHAKE-192f-simple, SPHINCS+-SHAKE-192s-simple, SPHINCS+-SHAKE-256f-simple, SPHINCS+-SHAKE-256s-simple + - **XMSS**: XMSS-SHA2_10_256, XMSS-SHA2_16_256, XMSS-SHA2_20_256, XMSS-SHAKE_10_256, XMSS-SHAKE_16_256, XMSS-SHAKE_20_256, XMSS-SHA2_10_512, XMSS-SHA2_16_512, XMSS-SHA2_20_512, XMSS-SHAKE_10_512, XMSS-SHAKE_16_512, XMSS-SHAKE_20_512, XMSSMT-SHA2_20/2_256, XMSSMT-SHA2_20/4_256, XMSSMT-SHA2_40/2_256, XMSSMT-SHA2_40/4_256, XMSSMT-SHA2_40/8_256, XMSSMT-SHA2_60/3_256, XMSSMT-SHA2_60/6_256, XMSSMT-SHA2_60/12_256, XMSSMT-SHAKE_20/2_256, XMSSMT-SHAKE_20/4_256, XMSSMT-SHAKE_40/2_256, XMSSMT-SHAKE_40/4_256, XMSSMT-SHAKE_40/8_256, XMSSMT-SHAKE_60/3_256, XMSSMT-SHAKE_60/6_256, XMSSMT-SHAKE_60/12_256 - **LMS**: LMS_SHA256_H5_W1, LMS_SHA256_H5_W2, LMS_SHA256_H5_W4, LMS_SHA256_H5_W8, LMS_SHA256_H10_W1, LMS_SHA256_H10_W2, LMS_SHA256_H10_W4, LMS_SHA256_H10_W8, LMS_SHA256_H15_W1, LMS_SHA256_H15_W2, LMS_SHA256_H15_W4, LMS_SHA256_H15_W8, LMS_SHA256_H20_W1, LMS_SHA256_H20_W2, LMS_SHA256_H20_W4, LMS_SHA256_H20_W8, LMS_SHA256_H25_W1, LMS_SHA256_H25_W2, LMS_SHA256_H25_W4, LMS_SHA256_H25_W8, LMS_SHA256_H5_W8_H5_W8, LMS_SHA256_H10_W4_H5_W8, LMS_SHA256_H10_W8_H5_W8, LMS_SHA256_H10_W2_H10_W2, LMS_SHA256_H10_W4_H10_W4, LMS_SHA256_H10_W8_H10_W8, LMS_SHA256_H15_W8_H5_W8, LMS_SHA256_H15_W8_H10_W8, LMS_SHA256_H15_W8_H15_W8, LMS_SHA256_H20_W8_H5_W8, LMS_SHA256_H20_W8_H10_W8, LMS_SHA256_H20_W8_H15_W8, LMS_SHA256_H20_W8_H20_W8 - Note that for algorithms marked with a dagger (†), liboqs contains at least one implementation that uses a large amount of stack space; this may cause failures when run in threads or in constrained environments. For more information, consult the algorithm information sheets in the [docs/algorithms](https://github.com/open-quantum-safe/liboqs/tree/main/docs/algorithms) folder. diff --git a/scripts/copy_from_upstream/copy_from_upstream.py b/scripts/copy_from_upstream/copy_from_upstream.py index 0db38f54bf..9c4f8f2232 100755 --- a/scripts/copy_from_upstream/copy_from_upstream.py +++ b/scripts/copy_from_upstream/copy_from_upstream.py @@ -642,7 +642,7 @@ def verify_from_upstream(): '{}_{}_{}'.format(impl['upstream']['name'], scheme['pqclean_scheme'], impl)) verifydir = os.path.join(basedir, 'src', family['type'], family['name'], '{}_{}_{}'.format(impl['upstream']['name'], scheme['pqclean_scheme'], impl)) - if not os.path.isdir(oqsdir) and os.path.isdir(erifydir): + if not os.path.isdir(oqsdir) and os.path.isdir(verifydir): print('Available implementation in upstream that isn\'t integrated into LIBOQS: {}_{}_{}'.format(impl['upstream']['name'], scheme['pqclean_scheme'], impl)) else: diff --git a/src/common/sha2/sha2_armv8.c b/src/common/sha2/sha2_armv8.c index b8f6b16cb3..dc8661485b 100644 --- a/src/common/sha2/sha2_armv8.c +++ b/src/common/sha2/sha2_armv8.c @@ -15,7 +15,6 @@ * from http://bench.cr.yp.to/supercop.html * by D. J. Bernstein */ - static uint64_t load_bigendian_64(const uint8_t *x) { return (uint64_t)(x[7]) | (((uint64_t)(x[6])) << 8) | (((uint64_t)(x[5])) << 16) | (((uint64_t)(x[4])) << 24) | @@ -24,21 +23,21 @@ static uint64_t load_bigendian_64(const uint8_t *x) { } static void store_bigendian_64(uint8_t *x, uint64_t u) { - x[7] = (uint8_t) u; + x[7] = (uint8_t)u; u >>= 8; - x[6] = (uint8_t) u; + x[6] = (uint8_t)u; u >>= 8; - x[5] = (uint8_t) u; + x[5] = (uint8_t)u; u >>= 8; - x[4] = (uint8_t) u; + x[4] = (uint8_t)u; u >>= 8; - x[3] = (uint8_t) u; + x[3] = (uint8_t)u; u >>= 8; - x[2] = (uint8_t) u; + x[2] = (uint8_t)u; u >>= 8; - x[1] = (uint8_t) u; + x[1] = (uint8_t)u; u >>= 8; - x[0] = (uint8_t) u; + x[0] = (uint8_t)u; } static size_t crypto_hashblocks_sha256_armv8(uint8_t *statebytes, @@ -63,9 +62,9 @@ static size_t crypto_hashblocks_sha256_armv8(uint8_t *statebytes, }; unsigned long long pos = 0; /* load constants */ - uint32x4_t c0 = vld1q_u32(s256cst + 0); - uint32x4_t c1 = vld1q_u32(s256cst + 4); - uint32x4_t c2 = vld1q_u32(s256cst + 8); + uint32x4_t c0 = vld1q_u32(s256cst + 0); + uint32x4_t c1 = vld1q_u32(s256cst + 4); + uint32x4_t c2 = vld1q_u32(s256cst + 8); uint32x4_t c3 = vld1q_u32(s256cst + 12); uint32x4_t c4 = vld1q_u32(s256cst + 16); uint32x4_t c5 = vld1q_u32(s256cst + 20); @@ -80,13 +79,13 @@ static size_t crypto_hashblocks_sha256_armv8(uint8_t *statebytes, uint32x4_t ce = vld1q_u32(s256cst + 56); uint32x4_t cf = vld1q_u32(s256cst + 60); /* load state */ - uint32x4_t d0 = vld1q_u32((uint32_t *)(statebytes + 0)); + uint32x4_t d0 = vld1q_u32((uint32_t *)(statebytes + 0)); uint32x4_t d1 = vld1q_u32((uint32_t *)(statebytes + 16)); uint32x4_t s0, s1, h0, h1; /* make state big-endian */ d0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(d0))); d1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(d1))); - while (length >= 64) { + while (length >= 64) { /* load one block */ uint32x4_t i0 = vld1q_u32((const uint32_t *)(data + pos + 0)); uint32x4_t i1 = vld1q_u32((const uint32_t *)(data + pos + 16)); @@ -110,33 +109,33 @@ static size_t crypto_hashblocks_sha256_armv8(uint8_t *statebytes, * using 16 constants in c0..c3 * we need h0,h1,x0,x1 as scratch */ -#define DO16ROUNDS(i0, i1, i2, i3, c0, c1, c2, c3) \ - h0 = vaddq_u32(i0, c0); \ - x0 = vsha256hq_u32(s0, s1, h0); \ - x1 = vsha256h2q_u32(s1, s0, h0); \ - h1 = vaddq_u32(i1, c1); \ - s0 = vsha256hq_u32(x0, x1, h1); \ - s1 = vsha256h2q_u32(x1, x0, h1); \ - h0 = vaddq_u32(i2, c2); \ - x0 = vsha256hq_u32(s0, s1, h0); \ - x1 = vsha256h2q_u32(s1, s0, h0); \ - h1 = vaddq_u32(i3, c3); \ - s0 = vsha256hq_u32(x0, x1, h1); \ - s1 = vsha256h2q_u32(x1, x0, h1) +#define DO16ROUNDS(i0, i1, i2, i3, c0, c1, c2, c3) \ + h0 = vaddq_u32(i0, c0); \ + x0 = vsha256hq_u32(s0, s1, h0); \ + x1 = vsha256h2q_u32(s1, s0, h0); \ + h1 = vaddq_u32(i1, c1); \ + s0 = vsha256hq_u32(x0, x1, h1); \ + s1 = vsha256h2q_u32(x1, x0, h1); \ + h0 = vaddq_u32(i2, c2); \ + x0 = vsha256hq_u32(s0, s1, h0); \ + x1 = vsha256h2q_u32(s1, s0, h0); \ + h1 = vaddq_u32(i3, c3); \ + s0 = vsha256hq_u32(x0, x1, h1); \ + s1 = vsha256h2q_u32(x1, x0, h1) /* * this expands the block (or previously * expanded) in i0..i3 to j0..j3 */ #define DO16EXPANDS(i0, i1, i2, i3, j0, j1, j2, j3) \ - j0 = vsha256su0q_u32(i0, i1); \ - j0 = vsha256su1q_u32(j0, i2, i3); \ - j1 = vsha256su0q_u32(i1, i2); \ - j1 = vsha256su1q_u32(j1, i3, j0); \ - j2 = vsha256su0q_u32(i2, i3); \ - j2 = vsha256su1q_u32(j2, j0, j1); \ - j3 = vsha256su0q_u32(i3, j0); \ - j3 = vsha256su1q_u32(j3, j1, j2) + j0 = vsha256su0q_u32(i0, i1); \ + j0 = vsha256su1q_u32(j0, i2, i3); \ + j1 = vsha256su0q_u32(i1, i2); \ + j1 = vsha256su1q_u32(j1, i3, j0); \ + j2 = vsha256su0q_u32(i2, i3); \ + j2 = vsha256su1q_u32(j2, j0, j1); \ + j3 = vsha256su0q_u32(i3, j0); \ + j3 = vsha256su1q_u32(j3, j1, j2) DO16ROUNDS(i0, i1, i2, i3, c0, c1, c2, c3); @@ -163,11 +162,10 @@ static size_t crypto_hashblocks_sha256_armv8(uint8_t *statebytes, /* store back to little-endian */ d0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(d0))); d1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(d1))); - vst1q_u32((uint32_t *)(statebytes + 0), d0); + vst1q_u32((uint32_t *)(statebytes + 0), d0); vst1q_u32((uint32_t *)(statebytes + 16), d1); return length; - } void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const uint8_t *in, size_t inlen) { @@ -180,7 +178,8 @@ void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const ui if (new_inlen == inlen) { new_in = in; - } else { //Combine incremental data with final input + } else { + // Combine incremental data with final input tmp_in = malloc(tmp_len); if (tmp_in == NULL) { exit(111); @@ -201,7 +200,6 @@ void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const ui new_inlen &= 63; new_in -= new_inlen; - for (size_t i = 0; i < new_inlen; ++i) { padded[i] = new_in[i]; } @@ -211,27 +209,27 @@ void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const ui for (size_t i = new_inlen + 1; i < 56; ++i) { padded[i] = 0; } - padded[56] = (uint8_t) (bytes >> 53); - padded[57] = (uint8_t) (bytes >> 45); - padded[58] = (uint8_t) (bytes >> 37); - padded[59] = (uint8_t) (bytes >> 29); - padded[60] = (uint8_t) (bytes >> 21); - padded[61] = (uint8_t) (bytes >> 13); - padded[62] = (uint8_t) (bytes >> 5); - padded[63] = (uint8_t) (bytes << 3); + padded[56] = (uint8_t)(bytes >> 53); + padded[57] = (uint8_t)(bytes >> 45); + padded[58] = (uint8_t)(bytes >> 37); + padded[59] = (uint8_t)(bytes >> 29); + padded[60] = (uint8_t)(bytes >> 21); + padded[61] = (uint8_t)(bytes >> 13); + padded[62] = (uint8_t)(bytes >> 5); + padded[63] = (uint8_t)(bytes << 3); crypto_hashblocks_sha256_armv8(state->ctx, padded, 64); } else { for (size_t i = new_inlen + 1; i < 120; ++i) { padded[i] = 0; } - padded[120] = (uint8_t) (bytes >> 53); - padded[121] = (uint8_t) (bytes >> 45); - padded[122] = (uint8_t) (bytes >> 37); - padded[123] = (uint8_t) (bytes >> 29); - padded[124] = (uint8_t) (bytes >> 21); - padded[125] = (uint8_t) (bytes >> 13); - padded[126] = (uint8_t) (bytes >> 5); - padded[127] = (uint8_t) (bytes << 3); + padded[120] = (uint8_t)(bytes >> 53); + padded[121] = (uint8_t)(bytes >> 45); + padded[122] = (uint8_t)(bytes >> 37); + padded[123] = (uint8_t)(bytes >> 29); + padded[124] = (uint8_t)(bytes >> 21); + padded[125] = (uint8_t)(bytes >> 13); + padded[126] = (uint8_t)(bytes >> 5); + padded[127] = (uint8_t)(bytes << 3); crypto_hashblocks_sha256_armv8(state->ctx, padded, 128); } @@ -314,7 +312,7 @@ void oqs_sha2_sha256_inc_armv8(sha256ctx *state, const uint8_t *in, size_t len) } void oqs_sha2_sha224_inc_blocks_armv8(sha224ctx *state, const uint8_t *in, size_t inblocks) { - oqs_sha2_sha256_inc_blocks_armv8((sha256ctx *) state, in, inblocks); + oqs_sha2_sha256_inc_blocks_armv8((sha256ctx *)state, in, inblocks); } void oqs_sha2_sha256_armv8(uint8_t *out, const uint8_t *in, size_t inlen) { diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index 7fdfd7bdb9..9d533a8b27 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -221,6 +221,7 @@ #cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6 1 #cmakedefine OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 1 + #cmakedefine OQS_ENABLE_SIG_STFL_LMS 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w1 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w2 1 @@ -235,3 +236,4 @@ #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h15_w4 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 1 + diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h index b583782e64..4405e60c1c 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.h +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -251,8 +251,8 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w4_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W8_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w8_new(void); -OQS_API OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); -OQS_API OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *totaln, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *totaln, const OQS_SIG_STFL_SECRET_KEY *secret_key); void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk); diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index 70797ee80a..a0691a9d59 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -485,7 +485,7 @@ OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk); * @param[in] lock function pointer * */ -void OQS_SIG_STFL_SECRET_KEY_SET_lock(OQS_SIG_STFL_SECRET_KEY *sk, lock_key lock); +OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_lock(OQS_SIG_STFL_SECRET_KEY *sk, lock_key lock); /** * OQS_SIG_STFL_SECRET_KEY_SET_unlock . @@ -496,7 +496,7 @@ void OQS_SIG_STFL_SECRET_KEY_SET_lock(OQS_SIG_STFL_SECRET_KEY *sk, lock_key lock * @param[in] unlock function pointer * */ -void OQS_SIG_STFL_SECRET_KEY_SET_unlock(OQS_SIG_STFL_SECRET_KEY *sk, unlock_key unlock); +OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_unlock(OQS_SIG_STFL_SECRET_KEY *sk, unlock_key unlock); /** * OQS_SIG_STFL_SECRET_KEY_SET_mutex . @@ -507,7 +507,7 @@ void OQS_SIG_STFL_SECRET_KEY_SET_unlock(OQS_SIG_STFL_SECRET_KEY *sk, unlock_key * @param[in] mutex function pointer * */ -void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void *mutex); +OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void *mutex); /** * OQS_SIG_STFL_SECRET_KEY_lock . @@ -518,7 +518,7 @@ void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void *mutex) * @return OQS_SUCCESS if successful, or OQS_ERROR if the object fails to apply the lock * */ -OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk); +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk); /** * OQS_SIG_STFL_SECRET_KEY_unlock . @@ -529,7 +529,7 @@ OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk); * @return OQS_SUCCESS if successful, or OQS_ERROR if the object fails to release the lock * */ -OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk); +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk); /** * OQS_SIG_STFL_SECRET_KEY_SET_store_cb . @@ -543,7 +543,7 @@ OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk); * Applications allocates, tracks, deallocates this. Signature generation fails without this set. * */ -void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); +OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); /** * OQS_SECRET_KEY_STFL_serialize_key . @@ -572,7 +572,7 @@ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(uint8_t **sk_buf_ptr, size_ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf, void *context); #if defined(__cplusplus) -} // extern "C" +// extern "C" #endif #endif /* OQS_SIG_STATEFUL_H */ diff --git a/src/sig_stfl/xmss/external/xmss_commons.c b/src/sig_stfl/xmss/external/xmss_commons.c index 9838f755b0..5f3818d184 100644 --- a/src/sig_stfl/xmss/external/xmss_commons.c +++ b/src/sig_stfl/xmss/external/xmss_commons.c @@ -151,8 +151,8 @@ int xmssmt_core_sign_open(const xmss_params *params, unsigned char *root = leaf + params->n; unsigned long long prefix_length = params->padding_len + 3*params->n; - unsigned char m_with_prefix[mlen + prefix_length]; - + unsigned long long m_with_prefix_len = mlen + prefix_length; + unsigned char *m_with_prefix = NULL; unsigned char *mhash = root; unsigned long long idx = 0; unsigned int i, ret; @@ -169,13 +169,18 @@ int xmssmt_core_sign_open(const xmss_params *params, // Unused since smlen is a constant (void) smlen; + if ((m_with_prefix_len == 0) || (m_with_prefix = malloc(m_with_prefix_len)) == NULL){ + ret = -1; + goto fail; + } + /* Convert the index bytes from the signature to an integer. */ idx = bytes_to_ull(sm, params->index_bytes); /* Put the message at the m_with_prefix buffer, so that we can * prepend the required other inputs for the hash function. */ - memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, prefix_length); - memcpy(m_with_prefix + prefix_length, m, mlen); + memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, (size_t)prefix_length); + memcpy(m_with_prefix + prefix_length, m, (size_t)mlen); /* Compute the message hash. */ hash_message(params, mhash, sm + params->index_bytes, pk, idx, @@ -221,6 +226,7 @@ int xmssmt_core_sign_open(const xmss_params *params, ret = 0; fail: OQS_MEM_insecure_free(tmp); + OQS_MEM_insecure_free(m_with_prefix); return ret; } diff --git a/src/sig_stfl/xmss/external/xmss_core_fast.c b/src/sig_stfl/xmss/external/xmss_core_fast.c index deaedefa8a..70b4b9774e 100644 --- a/src/sig_stfl/xmss/external/xmss_core_fast.c +++ b/src/sig_stfl/xmss/external/xmss_core_fast.c @@ -13,7 +13,7 @@ typedef struct{ unsigned char h; - unsigned long next_idx; + unsigned long long next_idx; unsigned char stackusage; unsigned char completed; unsigned char *node; @@ -27,7 +27,7 @@ typedef struct { unsigned char *keep; treehash_inst *treehash; unsigned char *retain; - unsigned int next_leaf; + unsigned long long next_leaf; } bds_state; /* These serialization functions provide a transition between the current @@ -94,7 +94,7 @@ static void xmssmt_deserialize_state(const xmss_params *params, states[i].stack = sk; sk += (params->tree_height + 1) * params->n; - states[i].stackoffset = bytes_to_ull(sk, 4); + states[i].stackoffset = (unsigned int)bytes_to_ull(sk, 4); sk += 4; states[i].stacklevels = sk; @@ -107,16 +107,16 @@ static void xmssmt_deserialize_state(const xmss_params *params, sk += (params->tree_height >> 1) * params->n; for (j = 0; j < params->tree_height - params->bds_k; j++) { - states[i].treehash[j].h = bytes_to_ull(sk, 1); + states[i].treehash[j].h = (unsigned char)bytes_to_ull(sk, 1); sk += 1; - states[i].treehash[j].next_idx = bytes_to_ull(sk, 4); + states[i].treehash[j].next_idx = (unsigned long long)bytes_to_ull(sk, 4); sk += 4; - states[i].treehash[j].stackusage = bytes_to_ull(sk, 1); + states[i].treehash[j].stackusage = (unsigned char)bytes_to_ull(sk, 1); sk += 1; - states[i].treehash[j].completed = bytes_to_ull(sk, 1); + states[i].treehash[j].completed = (unsigned char)bytes_to_ull(sk, 1); sk += 1; states[i].treehash[j].node = sk; @@ -126,7 +126,7 @@ static void xmssmt_deserialize_state(const xmss_params *params, states[i].retain = sk; sk += ((1 << params->bds_k) - params->bds_k - 1) * params->n; - states[i].next_leaf = bytes_to_ull(sk, 4); + states[i].next_leaf = (unsigned long long)bytes_to_ull(sk, 4); sk += 4; } @@ -149,9 +149,9 @@ static void xmss_deserialize_state(const xmss_params *params, static void memswap(void *a, void *b, void *t, unsigned long long len) { - memcpy(t, a, len); - memcpy(a, b, len); - memcpy(b, t, len); + memcpy(t, a, (size_t)len); + memcpy(a, b, (size_t)len); + memcpy(b, t, (size_t)len); } /** @@ -637,7 +637,7 @@ int xmss_core_sign(const xmss_params *params, // Delete secret key here. We only do this in memory, production code // has to make sure that this happens on disk. memset(sk, 0xFF, params->index_bytes); - memset(sk + params->index_bytes, 0, (params->sk_bytes - params->index_bytes)); + memset(sk + params->index_bytes, 0, (size_t)(params->sk_bytes - params->index_bytes)); if (idx > ((1ULL << params->full_height) - 1)) { ret = -2; // We already used all one-time keys goto cleanup; @@ -682,9 +682,9 @@ int xmss_core_sign(const xmss_params *params, /* Already put the message in the right place, to make it easier to prepend * things when computing the hash over the message. */ unsigned long long prefix_length = params->padding_len + 3*params->n; - unsigned char *m_with_prefix = malloc(mlen + prefix_length); - memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, prefix_length); - memcpy(m_with_prefix + prefix_length, m, mlen); + unsigned char *m_with_prefix = malloc((size_t)(mlen + prefix_length)); + memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, (size_t)prefix_length); + memcpy(m_with_prefix + prefix_length, m, (size_t)mlen); /* Compute the message hash. */ hash_message(params, msg_h, R, pub_root, idx, @@ -717,7 +717,7 @@ int xmss_core_sign(const xmss_params *params, // Prepare Address set_type(ots_addr, 0); - set_ots_addr(ots_addr, idx); + set_ots_addr(ots_addr, (uint32_t) idx); // Compute WOTS signature wots_sign(params, sm, msg_h, sk_seed, pub_seed, ots_addr); @@ -728,8 +728,8 @@ int xmss_core_sign(const xmss_params *params, // the auth path was already computed during the previous round memcpy(sm, state.auth, params->tree_height*params->n); - if (idx < (1U << params->tree_height) - 1) { - bds_round(params, &state, idx, sk_seed, pub_seed, ots_addr); + if (idx < (1ULL << params->tree_height) - 1) { + bds_round(params, &state, (const unsigned long)idx, sk_seed, pub_seed, ots_addr); bds_treehash_update(params, &state, (params->tree_height - params->bds_k) >> 1, sk_seed, pub_seed, ots_addr); } @@ -829,7 +829,7 @@ int xmssmt_core_sign(const xmss_params *params, uint64_t idx_tree; uint32_t idx_leaf; - uint64_t i, j; + unsigned int i, j; int needswap_upto = -1; unsigned int updates; @@ -847,7 +847,8 @@ int xmssmt_core_sign(const xmss_params *params, unsigned char *wots_sigs = NULL; unsigned long long prefix_length = params->padding_len + 3*params->n; - unsigned char m_with_prefix[mlen + prefix_length]; + unsigned long long m_with_prefix_len = mlen + prefix_length; + unsigned char *m_with_prefix = NULL; int ret = 0; // TODO refactor BDS state not to need separate treehash instances @@ -864,6 +865,11 @@ int xmssmt_core_sign(const xmss_params *params, states[i].next_leaf = 0; } + if ((m_with_prefix_len == 0) || (m_with_prefix = malloc(m_with_prefix_len)) == NULL) { + ret = -1; + goto cleanup; + } + xmssmt_deserialize_state(params, states, &wots_sigs, sk); // Extract SK @@ -887,7 +893,7 @@ int xmssmt_core_sign(const xmss_params *params, // Delete secret key here. We only do this in memory, production code // has to make sure that this happens on disk. memset(sk, 0xFF, params->index_bytes); - memset(sk + params->index_bytes, 0, (params->sk_bytes - params->index_bytes)); + memset(sk + params->index_bytes, 0, (size_t)(params->sk_bytes - params->index_bytes)); if (idx > ((1ULL << params->full_height) - 1)) { // We already used all one-time keys ret = -2; @@ -895,9 +901,9 @@ int xmssmt_core_sign(const xmss_params *params, } } - memcpy(sk_seed, sk+params->index_bytes, params->n); - memcpy(sk_prf, sk+params->index_bytes+params->n, params->n); - memcpy(pub_seed, sk+params->index_bytes+3*params->n, params->n); + memcpy(sk_seed, sk+params->index_bytes, (size_t)params->n); + memcpy(sk_prf, sk+params->index_bytes+params->n, (size_t)params->n); + memcpy(pub_seed, sk+params->index_bytes+3*params->n, (size_t)params->n); // Update SK for (i = 0; i < params->index_bytes; i++) { @@ -991,24 +997,24 @@ int xmssmt_core_sign(const xmss_params *params, set_tree_addr(addr, (idx_tree + 1)); // mandatory update for NEXT_0 (does not count towards h-k/2) if NEXT_0 exists - if ((1 + idx_tree) * (1 << params->tree_height) + idx_leaf < (1ULL << params->full_height)) { + if ((1 + idx_tree) * (1ULL << params->tree_height) + idx_leaf < (1ULL << (unsigned long long) params->full_height)) { bds_state_update(params, &states[params->d], sk_seed, pub_seed, addr); } for (i = 0; i < params->d; i++) { // check if we're not at the end of a tree if (! (((idx + 1) & ((1ULL << ((i+1)*params->tree_height)) - 1)) == 0)) { - idx_leaf = (idx >> (params->tree_height * i)) & ((1 << params->tree_height)-1); + idx_leaf = (uint32_t)((idx >> (params->tree_height * i)) & ((1 << params->tree_height)-1)); idx_tree = (idx >> (params->tree_height * (i+1))); set_layer_addr(addr, i); - set_tree_addr(addr, idx_tree); + set_tree_addr(addr, (uint32_t)idx_tree); if (i == (unsigned int) (needswap_upto + 1)) { bds_round(params, &states[i], idx_leaf, sk_seed, pub_seed, addr); } updates = bds_treehash_update(params, &states[i], updates, sk_seed, pub_seed, addr); set_tree_addr(addr, (idx_tree + 1)); // if a NEXT-tree exists for this level; - if ((1 + idx_tree) * (1 << params->tree_height) + idx_leaf < (1ULL << (params->full_height - params->tree_height * i))) { + if ((1 + idx_tree) * (1ULL << params->tree_height) + idx_leaf < (1ULL << (params->full_height - params->tree_height * i))) { if (i > 0 && updates > 0 && states[params->d + i].next_leaf < (1ULL << params->full_height)) { bds_state_update(params, &states[params->d + i], sk_seed, pub_seed, addr); updates--; @@ -1018,9 +1024,9 @@ int xmssmt_core_sign(const xmss_params *params, else if (idx < (1ULL << params->full_height) - 1) { deep_state_swap(params, &states[params->d + i], &states[i]); - set_layer_addr(ots_addr, (i+1)); + set_layer_addr(ots_addr, (uint32_t)(i+1)); set_tree_addr(ots_addr, ((idx + 1) >> ((i+2) * params->tree_height))); - set_ots_addr(ots_addr, (((idx >> ((i+1) * params->tree_height)) + 1) & ((1 << params->tree_height)-1))); + set_ots_addr(ots_addr, (((idx >> ((i+1) * params->tree_height)) + 1) & ((1ULL << params->tree_height)-1))); wots_sign(params, wots_sigs + i*params->wots_sig_bytes, states[i].stack, sk_seed, pub_seed, ots_addr); @@ -1028,7 +1034,7 @@ int xmssmt_core_sign(const xmss_params *params, states[params->d + i].next_leaf = 0; updates--; // WOTS-signing counts as one update - needswap_upto = i; + needswap_upto = (int)i; for (j = 0; j < params->tree_height-params->bds_k; j++) { states[i].treehash[j].completed = 1; } @@ -1041,6 +1047,7 @@ int xmssmt_core_sign(const xmss_params *params, OQS_MEM_insecure_free(treehash); OQS_MEM_insecure_free(states); OQS_MEM_insecure_free(tmp); + OQS_MEM_insecure_free(m_with_prefix); return ret; } diff --git a/tests/helpers.py b/tests/helpers.py index b911f5d9bd..077b4d428f 100644 --- a/tests/helpers.py +++ b/tests/helpers.py @@ -175,7 +175,8 @@ def path_to_executable(program_name): for executable in [ os.path.join(path, program_name), os.path.join(path, program_name + ".EXE"), - os.path.join(path, program_name + ".exe")]: + os.path.join(path, program_name + ".exe"), + os.path.join(path, "Debug", program_name + ".exe"),]: if os.path.isfile(executable): return executable assert False, "Unable to find executable file {}".format(program_name) diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index a3d4bfd3f5..a8b3e7962d 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -7,10 +7,14 @@ #include #include #include +#if defined(_WIN32) #include +#define strcasecmp _stricmp +#else +#include +#endif #include -#include #include #include "tmp_store.c" @@ -1100,10 +1104,17 @@ int main(int argc, char **argv) { OQS_MEM_insecure_free(lock_test_context); OQS_MEM_insecure_free(signature_1); OQS_MEM_insecure_free(signature_2); - if (rc != OQS_SUCCESS || rc1 != OQS_SUCCESS || - rc_create != OQS_SUCCESS || rc_sign != OQS_SUCCESS || rc_query != OQS_SUCCESS) { + + OQS_destroy(); + if (rc != OQS_SUCCESS || rc1 != OQS_SUCCESS) { return EXIT_FAILURE; } + +#if OQS_USE_PTHREADS_IN_TESTS + if (rc_create != OQS_SUCCESS || rc_sign != OQS_SUCCESS || rc_query != OQS_SUCCESS) { + return EXIT_FAILURE; + } +#endif return exit_status; #else rc = sig_stfl_test_correctness(alg_name, katfile); From bb658b79261e3f7187bd03c8ee19223555b2a96a Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Thu, 11 Jan 2024 12:52:08 -0500 Subject: [PATCH 27/68] Address stateful-sigs comments in #1650 (#1656) * Add sig_stfl to configure.md * Add OQS_MEM_checked_malloc and OQS_MEM_checked_aligned_alloc * Use memcpy and checked_malloc --- CONFIGURE.md | 28 +++++++------- src/common/common.c | 20 ++++++++++ src/common/common.h | 55 +++++++++++++++++++++++++++ src/common/sha2/sha2_armv8.c | 20 +++------- src/common/sha2/sha2_c.c | 70 +++++++++++------------------------ src/common/sha3/ossl_sha3.c | 12 +----- src/common/sha3/ossl_sha3x4.c | 12 +----- src/common/sha3/xkcp_sha3.c | 25 +++---------- src/common/sha3/xkcp_sha3x4.c | 10 +---- 9 files changed, 129 insertions(+), 123 deletions(-) diff --git a/CONFIGURE.md b/CONFIGURE.md index 6605c7f3c5..ffc40273e2 100644 --- a/CONFIGURE.md +++ b/CONFIGURE.md @@ -8,7 +8,7 @@ The following options can be passed to CMake before the build file generation pr - [CMAKE_INSTALL_PREFIX](#CMAKE_INSTALL_PREFIX) - [OQS_ALGS_ENABLED](#OQS_ALGS_ENABLED) - [OQS_BUILD_ONLY_LIB](#OQS_BUILD_ONLY_LIB) -- [OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG](#OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG) +- [OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG/OQS_ENABLE_SIG_STFL_ALG](#OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG/OQS_ENABLE_SIG_STFL_ALG) - [OQS_MINIMAL_BUILD](#OQS_MINIMAL_BUILD) - [OQS_DIST_BUILD](#OQS_DIST_BUILD) - [OQS_USE_CPUFEATURE_INSTRUCTIONS](OQS_USE_CPUFEATURE_INSTRUCTIONS) @@ -42,21 +42,23 @@ Can be set to the following values: See the [CMake documentation](https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html). -## OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG +## OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG/OQS_ENABLE_SIG_STFL_ALG -Note: `ALG` in `OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG` should be replaced with the specific algorithm name as demonstrated below. +Note: `ALG` in `OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG/OQS_ENABLE_SIG_STFL_ALG` should be replaced with the specific algorithm name as demonstrated below. This can be set to `ON` or `OFF`, and is `ON` by default. When `OFF`, `ALG` and its code are excluded from the build process. When `ON`, made available are additional options whereby individual variants of `ALG` can be excluded from the build process. For example: if `OQS_ENABLE_KEM_BIKE` is set to `ON`, the options `OQS_ENABLE_KEM_bike_l1`, `OQS_ENABLE_KEM_bike_l3`, and `OQS_ENABLE_KEM_bike_l5` are made available (and are set to be `ON` by default). +To enable `XMSS` stateful signature, set `OQS_ENABLE_SIG_STFL_XMSS` to `ON`, the options `OQS_ENABLE_SIG_STFL_xmss_sha256_h10` and its variants are also set to be `ON` by default. Similarly, `LMS` stateful signature family can also be enabled by setting `OQS_ENABLE_SIG_STFL_LMS` to `ON`. + For a full list of such options and their default values, consult [.CMake/alg_support.cmake](https://github.com/open-quantum-safe/liboqs/blob/master/.CMake/alg_support.cmake). **Default**: Unset. ## OQS_ALGS_ENABLED -Selects algorithm set enabled. Possible values are "STD" selecting all algorithms standardized by NIST; "NIST_R4" selecting all algorithms evaluated in round 4 of the NIST PQC competition; "All" (or any other value) selecting all algorithms integrated into liboqs. Parameter setting "STD" minimizes library size but may require re-running code generator scripts in projects integrating `liboqs`; e.g., [oqs-provider](https://github.com/open-quantum-safe/oqs-provider) and [oqs-boringssl](https://github.com/open-quantum-safe/boringssl). +A selected algorithm set is enabled. Possible values are "STD" selecting all algorithms standardized by NIST; "NIST_R4" selecting all algorithms evaluated in round 4 of the NIST PQC competition; "All" (or any other value) selecting all algorithms integrated into liboqs. Parameter setting "STD" minimizes library size but may require re-running code generator scripts in projects integrating `liboqs`; e.g., [oqs-provider](https://github.com/open-quantum-safe/oqs-provider) and [oqs-boringssl](https://github.com/open-quantum-safe/boringssl). **Attention**: If you use any predefined value (`STD` or `NIST_R4` as of now) for this variable, the values added via [OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG](#OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG) variables will be ignored. @@ -70,9 +72,9 @@ Can be `ON` or `OFF`. When `ON`, only liboqs is built, and all the targets: `run ## OQS_MINIMAL_BUILD -If set, this defines a semicolon deliminated list of algorithms to be contained in a minimal build of `liboqs`: Only algorithms explicitly set here are included in a build: For example running `cmake -DOQS_MINIMAL_BUILD="KEM_kyber_768;SIG_dilithium_3" ..` will build a minimum-size `liboqs` library only containing support for Kyber768 and Dilithium3. +If set, this defines a semicolon-delimited list of algorithms to be contained in a minimal build of `liboqs`: Only algorithms explicitly set here are included in a build: For example running `cmake -DOQS_MINIMAL_BUILD="KEM_kyber_768;SIG_dilithium_3" ..` will build a minimum-size `liboqs` library only containing support for Kyber768 and Dilithium3. -The full list of identifiers that can set are listed [here for KEM algorithms](https://github.com/open-quantum-safe/liboqs/blob/main/src/kem/kem.h#L34) and [here for Signature algorithms](https://github.com/open-quantum-safe/liboqs/blob/f3caccff9e6225e7c50ca27f5ee6e58b7bc74188/src/sig/sig.h#L34). Default setting is empty, thus including all [supported algorithms](https://github.com/open-quantum-safe/liboqs#supported-algorithms) in the build. +The full list of identifiers that can be set is listed [here for KEM algorithms](https://github.com/open-quantum-safe/liboqs/blob/main/src/kem/kem.h#L34) and [here for Signature algorithms](https://github.com/open-quantum-safe/liboqs/blob/f3caccff9e6225e7c50ca27f5ee6e58b7bc74188/src/sig/sig.h#L34). The default setting is empty, thus including all [supported algorithms](https://github.com/open-quantum-safe/liboqs#supported-algorithms) in the build. **Default**: Unset. @@ -92,13 +94,13 @@ When built for use on a single machine, the library will only include the best a Note: `CPUFEATURE` in `OQS_USE_CPUFEATURE_INSTRUCTIONS` should be replaced with the specific CPU feature as noted below. -These can be set to `ON` or `OFF` and take an effect if liboqs is built for use on a single machine. By default, the CPU features are automatically determined and set to `ON` or `OFF` based on the CPU features available on the build system. The default values can be overridden by providing CMake build options. The available options on x86-64 are: `OQS_USE_ADX_INSTRUCTIONS`, `OQS_USE_AES_INSTRUCTIONS`, `OQS_USE_AVX_INSTRUCTIONS`, `OQS_USE_AVX2_INSTRUCTIONS`, `OQS_USE_AVX512_INSTRUCTIONS`, `OQS_USE_BMI1_INSTRUCTIONS`, `OQS_USE_BMI2_INSTRUCTIONS`, `OQS_USE_PCLMULQDQ_INSTRUCTIONS`, `OQS_USE_VPCLMULQDQ_INSTRUCTIONS`, `OQS_USE_POPCNT_INSTRUCTIONS`, `OQS_USE_SSE_INSTRUCTIONS`, `OQS_USE_SSE2_INSTRUCTIONS` and `OQS_USE_SSE3_INSTRUCTIONS`. The available options on ARM64v8 are `OQS_USE_ARM_AES_INSTRUCTIONS`, `OQS_USE_ARM_SHA2_INSTRUCTIONS`, `OQS_USE_ARM_SHA3_INSTRUCTIONS` and `OQS_USE_ARM_NEON_INSTRUCTIONS`. +These can be set to `ON` or `OFF` and take effect if liboqs is built for use on a single machine. By default, the CPU features are automatically determined and set to `ON` or `OFF` based on the CPU features available on the build system. The default values can be overridden by providing CMake build options. The available options on x86-64 are: `OQS_USE_ADX_INSTRUCTIONS`, `OQS_USE_AES_INSTRUCTIONS`, `OQS_USE_AVX_INSTRUCTIONS`, `OQS_USE_AVX2_INSTRUCTIONS`, `OQS_USE_AVX512_INSTRUCTIONS`, `OQS_USE_BMI1_INSTRUCTIONS`, `OQS_USE_BMI2_INSTRUCTIONS`, `OQS_USE_PCLMULQDQ_INSTRUCTIONS`, `OQS_USE_VPCLMULQDQ_INSTRUCTIONS`, `OQS_USE_POPCNT_INSTRUCTIONS`, `OQS_USE_SSE_INSTRUCTIONS`, `OQS_USE_SSE2_INSTRUCTIONS` and `OQS_USE_SSE3_INSTRUCTIONS`. The available options on ARM64v8 are `OQS_USE_ARM_AES_INSTRUCTIONS`, `OQS_USE_ARM_SHA2_INSTRUCTIONS`, `OQS_USE_ARM_SHA3_INSTRUCTIONS` and `OQS_USE_ARM_NEON_INSTRUCTIONS`. **Default**: Options valid on the build machine. ## OQS_USE_OPENSSL -In order to save size and limit the amount of different cryptographic code bases, it is possible to use OpenSSL as a crypto code provider by setting this configuration option. +To save size and limit the amount of different cryptographic code bases, it is possible to use OpenSSL as a crypto code provider by setting this configuration option. This can be set to `ON` or `OFF`. When `ON`, the additional options `OQS_USE_AES_OPENSSL`, `OQS_USE_SHA2_OPENSSL`, and `OQS_USE_SHA3_OPENSSL` are made available to control whether liboqs uses OpenSSL's AES, SHA-2, and SHA-3 implementations. @@ -107,7 +109,7 @@ By default, - `OQS_USE_SHA2_OPENSSL` is `ON` - `OQS_USE_SHA3_OPENSSL` is `OFF`. -These default choices have been made in order to optimize the default performance of all algorithms. Changing them implies performance penalties. +These default choices have been made to optimize the default performance of all algorithms. Changing them implies performance penalties. When `OQS_USE_OPENSSL` is `ON`, CMake also scans the filesystem to find the minimum version of OpenSSL required by liboqs (which happens to be 1.1.1). The [OPENSSL_ROOT_DIR](https://cmake.org/cmake/help/latest/module/FindOpenSSL.html) option can be set to aid CMake in its search. @@ -133,7 +135,7 @@ An optimization target. Only has an effect if the compiler is GCC or Clang and ` Can be `ON` or `OFF`. When `ON`, the benchmarking script will try to use the ARMv8 Performance Monitoring Unit (PMU). This will make cycle counts on ARMv8 platforms significantly more accurate. -In order to use this option, user mode access to the PMU must be enabled via a kernel module. If user mode access is not enabled via kernel module, benchmarking will throw an `Illegal Instruction` error. A kernel module that has been found to work on several platforms can be found [here for linux](https://github.com/mupq/pqax#enable-access-to-performance-counters). Follow the instructions there (i.e., clone the repository, `cd enable_ccr` and `make install`) to load the kernel module, after which benchmarking should work. Superuser permissions are required. Linux header files must also be installed on your platform, which may not be present by default. +In order to use this option, user mode access to the PMU must be enabled via a kernel module. If user mode access is not enabled via the kernel module, benchmarking will throw an `Illegal Instruction` error. A kernel module that has been found to work on several platforms can be found [here for Linux](https://github.com/mupq/pqax#enable-access-to-performance-counters). Follow the instructions there (i.e., clone the repository, `cd enable_ccr` and `make install`) to load the kernel module, after which benchmarking should work. Superuser permissions are required. Linux header files must also be installed on your platform, which may not be present by default. Note that this option is not known to work on Apple M1 chips. @@ -141,7 +143,7 @@ Note that this option is not known to work on Apple M1 chips. ## USE_SANITIZER -This has effect when the compiler is Clang and when [CMAKE_BUILD_TYPE](#CMAKE_BUILD_TYPE) is `Debug`. Then, it can be set to: +This has an effect when the compiler is Clang and when [CMAKE_BUILD_TYPE](#CMAKE_BUILD_TYPE) is `Debug`. Then, it can be set to: - `Address`: This enables Clang's `AddressSanitizer` - `Memory`: This enables Clang's `MemorySanitizer` @@ -156,13 +158,13 @@ This has effect when the compiler is Clang and when [CMAKE_BUILD_TYPE](#CMAKE_BU This is used in conjunction with `tests/test_constant_time.py` to use Valgrind to look for instances of secret-dependent control flow. liboqs must also be compiled with [CMAKE_BUILD_TYPE](#CMAKE_BUILD_TYPE) set to `Debug`. -See the documentation in [`tests/test_constant_time.py`](https://github.com/open-quantum-safe/liboqs/blob/main/tests/test_constant_time.py) for more information on usage. +See the documentation in [`tests/test_constant_time.py`](https://github.com/open-quantum-safe/liboqs/blob/main/tests/test_constant_time.py) for more usage information. **Default**: `OFF`. ## OQS_STRICT_WARNINGS -Can be `ON` or `OFF`. When `ON`, all compiler warnings are enabled and treated as errors. This setting is recommended to be enabled prior to submission of a Pull Request as CI runs with this setting active. When `OFF`, significantly fewer compiler warnings are enabled such as to avoid undue build errors triggered by (future) compiler warning features/unknown at development time of this library. +Can be `ON` or `OFF`. When `ON`, all compiler warnings are enabled and treated as errors. This setting is recommended to be enabled prior to submission of a Pull Request as CI runs with this setting active. When `OFF`, significantly fewer compiler warnings are enabled such as to avoid undue build errors triggered by (future) compiler warning features/unknown at the development time of this library. **Default**: `OFF`. diff --git a/src/common/common.c b/src/common/common.c index 7de1e65815..1146f5c45b 100644 --- a/src/common/common.c +++ b/src/common/common.c @@ -271,6 +271,26 @@ OQS_API void OQS_MEM_cleanse(void *ptr, size_t len) { #endif } +void *OQS_MEM_checked_malloc(size_t len) { + void *ptr = malloc(len); + if (ptr == NULL) { + fprintf(stderr, "Memory allocation failed\n"); + exit(EXIT_FAILURE); + } + + return ptr; +} + +void *OQS_MEM_checked_aligned_alloc(size_t alignment, size_t size) { + void *ptr = OQS_MEM_aligned_alloc(alignment, size); + if (ptr == NULL) { + fprintf(stderr, "Memory allocation failed\n"); + exit(EXIT_FAILURE); + } + + return ptr; +} + OQS_API void OQS_MEM_secure_free(void *ptr, size_t len) { if (ptr != NULL) { OQS_MEM_cleanse(ptr, len); diff --git a/src/common/common.h b/src/common/common.h index 8ddeef6f8f..b092baa036 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -180,6 +180,59 @@ OQS_API int OQS_MEM_secure_bcmp(const void *a, const void *b, size_t len); */ OQS_API void OQS_MEM_cleanse(void *ptr, size_t len); +/** + * Allocates memory of a specified size and checks for successful allocation. + * + * This function attempts to allocate a block of memory of the specified size. + * If the allocation is successful, it returns a pointer to the beginning of the + * memory block. If the allocation fails, it prints an error message to stderr + * and terminates the program. + * + * @param[in] len The size of the memory block to allocate, in bytes. + * + * @return A pointer to the allocated memory block if the allocation is successful. + * + * @note This function is intended to be used when the allocation must succeed, + * and failure to allocate memory is considered a fatal error. As such, + * it does not return if the allocation fails, but instead terminates the + * program with an exit status indicating failure. + * + * @note The memory block returned by this function is not initialized. The caller + * is responsible for initializing the memory if required. + * + * @note The allocated memory should be freed using the standard `free` function + * when it is no longer needed. + */ +void *OQS_MEM_checked_malloc(size_t len); + +/** + * Allocates memory of a specified size and alignment and checks for successful allocation. + * + * This function attempts to allocate a block of memory with the specified size + * and alignment. If the allocation is successful, it returns a pointer to the + * memory block. If the allocation fails, it prints an error message to stderr + * and terminates the program. + * + * Alignment must be a power of two and a multiple of sizeof(void *). + * + * @param[in] alignment The alignment of the memory block to allocate. + * @param[in] size The size of the memory block to allocate, in bytes. + * + * @return A pointer to the allocated memory block if the allocation is successful. + * + * @note This function is intended to be used when the allocation must succeed, + * and failure to allocate memory is considered a fatal error. As such, + * it does not return if the allocation fails, but instead terminates the + * program with an exit status indicating failure. + * + * @note The memory block returned by this function is not initialized. The caller + * is responsible for initializing the memory if required. + * + * @note The allocated memory should be freed with `OQS_MEM_aligned_free` when it + * is no longer needed. + */ +void *OQS_MEM_checked_aligned_alloc(size_t alignment, size_t size); + /** * Zeros out `len` bytes of memory starting at `ptr`, then frees `ptr`. * @@ -211,6 +264,8 @@ OQS_API void OQS_MEM_insecure_free(void *ptr); * Allocates size bytes of uninitialized memory with a base pointer that is * a multiple of alignment. Alignment must be a power of two and a multiple * of sizeof(void *). Size must be a multiple of alignment. + * @note The allocated memory should be freed with `OQS_MEM_aligned_free` when it + * is no longer needed. */ void *OQS_MEM_aligned_alloc(size_t alignment, size_t size); diff --git a/src/common/sha2/sha2_armv8.c b/src/common/sha2/sha2_armv8.c index dc8661485b..65ea6750c3 100644 --- a/src/common/sha2/sha2_armv8.c +++ b/src/common/sha2/sha2_armv8.c @@ -180,10 +180,7 @@ void oqs_sha2_sha256_inc_finalize_armv8(uint8_t *out, sha256ctx *state, const ui new_in = in; } else { // Combine incremental data with final input - tmp_in = malloc(tmp_len); - if (tmp_in == NULL) { - exit(111); - } + tmp_in = OQS_MEM_checked_malloc(tmp_len); memcpy(tmp_in, state->data, state->data_len); if (in && inlen) { @@ -257,10 +254,7 @@ void oqs_sha2_sha256_inc_blocks_armv8(sha256ctx *state, const uint8_t *in, size_ /* Process any existing incremental data first */ if (state->data_len) { - tmp_in = malloc(buf_len); - if (tmp_in == NULL) { - exit(111); - } + tmp_in = OQS_MEM_checked_malloc(buf_len); memcpy(tmp_in, state->data, state->data_len); memcpy(tmp_in + state->data_len, in, buf_len - state->data_len); @@ -280,17 +274,15 @@ void oqs_sha2_sha256_inc_blocks_armv8(sha256ctx *state, const uint8_t *in, size_ } void oqs_sha2_sha256_inc_armv8(sha256ctx *state, const uint8_t *in, size_t len) { - uint64_t bytes = 0; - size_t in_index = 0; while (len) { size_t incr = 64 - state->data_len; if (incr > len) { incr = len; } - for (size_t i = 0; i < incr; ++i, state->data_len++, in_index++) { - state->data[state->data_len] = in[in_index]; - } + memcpy(state->data + state->data_len, in, incr); + state->data_len += incr; + in += incr; if (state->data_len < 64) { break; @@ -299,7 +291,7 @@ void oqs_sha2_sha256_inc_armv8(sha256ctx *state, const uint8_t *in, size_t len) /* * Process a complete block now */ - bytes = load_bigendian_64(state->ctx + 32) + 64; + uint64_t bytes = load_bigendian_64(state->ctx + 32) + 64; crypto_hashblocks_sha256_armv8(state->ctx, state->data, 64); store_bigendian_64(state->ctx + 32, bytes); diff --git a/src/common/sha2/sha2_c.c b/src/common/sha2/sha2_c.c index b0f628136a..e5bd350889 100644 --- a/src/common/sha2/sha2_c.c +++ b/src/common/sha2/sha2_c.c @@ -502,10 +502,8 @@ static const uint8_t iv_512[64] = { }; void oqs_sha2_sha224_inc_init_c(sha224ctx *state) { - state->ctx = malloc(PQC_SHA256CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_malloc(PQC_SHA256CTX_BYTES); + for (size_t i = 0; i < 32; ++i) { state->ctx[i] = iv_224[i]; } @@ -518,10 +516,8 @@ void oqs_sha2_sha224_inc_init_c(sha224ctx *state) { void oqs_sha2_sha256_inc_init_c(sha256ctx *state) { state->data_len = 0; - state->ctx = malloc(PQC_SHA256CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_malloc(PQC_SHA256CTX_BYTES); + for (size_t i = 0; i < 32; ++i) { state->ctx[i] = iv_256[i]; } @@ -533,10 +529,8 @@ void oqs_sha2_sha256_inc_init_c(sha256ctx *state) { } void oqs_sha2_sha384_inc_init_c(sha384ctx *state) { - state->ctx = malloc(PQC_SHA512CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_malloc(PQC_SHA512CTX_BYTES); + for (size_t i = 0; i < 64; ++i) { state->ctx[i] = iv_384[i]; } @@ -548,10 +542,8 @@ void oqs_sha2_sha384_inc_init_c(sha384ctx *state) { } void oqs_sha2_sha512_inc_init_c(sha512ctx *state) { - state->ctx = malloc(PQC_SHA512CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_malloc(PQC_SHA512CTX_BYTES); + for (size_t i = 0; i < 64; ++i) { state->ctx[i] = iv_512[i]; } @@ -563,40 +555,32 @@ void oqs_sha2_sha512_inc_init_c(sha512ctx *state) { } void oqs_sha2_sha224_inc_ctx_clone_c(sha224ctx *stateout, const sha224ctx *statein) { - stateout->ctx = malloc(PQC_SHA256CTX_BYTES); - if (stateout->ctx == NULL) { - exit(111); - } + stateout->ctx = OQS_MEM_checked_malloc(PQC_SHA256CTX_BYTES); + stateout->data_len = statein->data_len; memcpy(stateout->data, statein->data, 128); memcpy(stateout->ctx, statein->ctx, PQC_SHA256CTX_BYTES); } void oqs_sha2_sha256_inc_ctx_clone_c(sha256ctx *stateout, const sha256ctx *statein) { - stateout->ctx = malloc(PQC_SHA256CTX_BYTES); - if (stateout->ctx == NULL) { - exit(111); - } + stateout->ctx = OQS_MEM_checked_malloc(PQC_SHA256CTX_BYTES); + stateout->data_len = statein->data_len; memcpy(stateout->data, statein->data, 128); memcpy(stateout->ctx, statein->ctx, PQC_SHA256CTX_BYTES); } void oqs_sha2_sha384_inc_ctx_clone_c(sha384ctx *stateout, const sha384ctx *statein) { - stateout->ctx = malloc(PQC_SHA512CTX_BYTES); - if (stateout->ctx == NULL) { - exit(111); - } + stateout->ctx = OQS_MEM_checked_malloc(PQC_SHA512CTX_BYTES); + stateout->data_len = statein->data_len; memcpy(stateout->data, statein->data, 128); memcpy(stateout->ctx, statein->ctx, PQC_SHA512CTX_BYTES); } void oqs_sha2_sha512_inc_ctx_clone_c(sha512ctx *stateout, const sha512ctx *statein) { - stateout->ctx = malloc(PQC_SHA512CTX_BYTES); - if (stateout->ctx == NULL) { - exit(111); - } + stateout->ctx = OQS_MEM_checked_malloc(PQC_SHA512CTX_BYTES); + stateout->data_len = statein->data_len; memcpy(stateout->data, statein->data, 128); memcpy(stateout->ctx, statein->ctx, PQC_SHA512CTX_BYTES); @@ -630,10 +614,7 @@ void oqs_sha2_sha256_inc_blocks_c(sha256ctx *state, const uint8_t *in, size_t in /* Process any existing incremental data first */ if (state->data_len) { - tmp_in = malloc(tmp_buflen); - if (tmp_in == NULL) { - exit(111); - } + tmp_in = OQS_MEM_checked_malloc(tmp_buflen); memcpy(tmp_in, state->data, state->data_len); memcpy(tmp_in + state->data_len, in, tmp_buflen - state->data_len); @@ -653,17 +634,15 @@ void oqs_sha2_sha256_inc_blocks_c(sha256ctx *state, const uint8_t *in, size_t in } void oqs_sha2_sha256_inc_c(sha256ctx *state, const uint8_t *in, size_t len) { - uint64_t bytes = 0; - size_t in_index = 0; while (len) { size_t incr = 64 - state->data_len; if (incr > len) { incr = len; } - for (size_t i = 0; i < incr; ++i, state->data_len++, in_index++) { - state->data[state->data_len] = in[in_index]; - } + memcpy(state->data + state->data_len, in, incr); + state->data_len += incr; + in += incr; if (state->data_len < 64) { break; @@ -672,9 +651,8 @@ void oqs_sha2_sha256_inc_c(sha256ctx *state, const uint8_t *in, size_t len) { /* * Process a complete block now */ - bytes = load_bigendian_64(state->ctx + 32); + uint64_t bytes = load_bigendian_64(state->ctx + 32) + 64; crypto_hashblocks_sha256_c(state->ctx, state->data, 64); - bytes += 64; store_bigendian_64(state->ctx + 32, bytes); /* @@ -713,10 +691,7 @@ void oqs_sha2_sha256_inc_finalize_c(uint8_t *out, sha256ctx *state, const uint8_ if (new_inlen == inlen) { new_in = in; } else { //Combine incremental data with final input - tmp_in = malloc(tmp_len); - if (tmp_in == NULL) { - exit(111); - } + tmp_in = OQS_MEM_checked_malloc(tmp_len); memcpy(tmp_in, state->data, state->data_len); if (in && inlen) { @@ -868,4 +843,3 @@ void oqs_sha2_sha512_c(uint8_t *out, const uint8_t *in, size_t inlen) { oqs_sha2_sha512_inc_init_c(&state); oqs_sha2_sha512_inc_finalize_c(out, &state, in, inlen); } - diff --git a/src/common/sha3/ossl_sha3.c b/src/common/sha3/ossl_sha3.c index 1b65b37662..5d36f2280c 100644 --- a/src/common/sha3/ossl_sha3.c +++ b/src/common/sha3/ossl_sha3.c @@ -198,11 +198,7 @@ static void SHA3_shake128_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_s if (s->n_out == 0) { OSSL_FUNC(EVP_DigestFinalXOF)(clone, output, outlen); } else { - uint8_t *tmp; - tmp = malloc(s->n_out + outlen); - if (tmp == NULL) { - exit(111); - } + uint8_t *tmp = OQS_MEM_checked_malloc(s->n_out + outlen); OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(output, tmp + s->n_out, outlen); free(tmp); // IGNORE free-check @@ -276,11 +272,7 @@ static void SHA3_shake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_s if (s->n_out == 0) { OSSL_FUNC(EVP_DigestFinalXOF)(clone, output, outlen); } else { - uint8_t *tmp; - tmp = malloc(s->n_out + outlen); - if (tmp == NULL) { - exit(111); - } + uint8_t *tmp = OQS_MEM_checked_malloc(s->n_out + outlen); OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(output, tmp + s->n_out, outlen); free(tmp); // IGNORE free-check diff --git a/src/common/sha3/ossl_sha3x4.c b/src/common/sha3/ossl_sha3x4.c index 971a26c4e8..1f6a03c615 100644 --- a/src/common/sha3/ossl_sha3x4.c +++ b/src/common/sha3/ossl_sha3x4.c @@ -81,11 +81,7 @@ static void SHA3_shake128_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t * OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx3); OSSL_FUNC(EVP_DigestFinalXOF)(clone, out3, outlen); } else { - uint8_t *tmp; - tmp = malloc(s->n_out + outlen); - if (tmp == NULL) { - exit(111); - } + uint8_t *tmp = OQS_MEM_checked_malloc(s->n_out + outlen); OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx0); OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(out0, tmp + s->n_out, outlen); @@ -206,11 +202,7 @@ static void SHA3_shake256_x4_inc_squeeze(uint8_t *out0, uint8_t *out1, uint8_t * OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx3); OSSL_FUNC(EVP_DigestFinalXOF)(clone, out3, outlen); } else { - uint8_t *tmp; - tmp = malloc(s->n_out + outlen); - if (tmp == NULL) { - exit(111); - } + uint8_t *tmp = OQS_MEM_checked_malloc(s->n_out + outlen); OSSL_FUNC(EVP_MD_CTX_copy_ex)(clone, s->mdctx0); OSSL_FUNC(EVP_DigestFinalXOF)(clone, tmp, s->n_out + outlen); memcpy(out0, tmp + s->n_out, outlen); diff --git a/src/common/sha3/xkcp_sha3.c b/src/common/sha3/xkcp_sha3.c index 2fce9d9fe0..196652d85d 100644 --- a/src/common/sha3/xkcp_sha3.c +++ b/src/common/sha3/xkcp_sha3.c @@ -199,10 +199,7 @@ static void SHA3_sha3_256(uint8_t *output, const uint8_t *input, size_t inlen) { } static void SHA3_sha3_256_inc_init(OQS_SHA3_sha3_256_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); keccak_inc_reset((uint64_t *)state->ctx); } @@ -238,10 +235,7 @@ static void SHA3_sha3_384(uint8_t *output, const uint8_t *input, size_t inlen) { } static void SHA3_sha3_384_inc_init(OQS_SHA3_sha3_384_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); keccak_inc_reset((uint64_t *)state->ctx); } @@ -277,10 +271,7 @@ static void SHA3_sha3_512(uint8_t *output, const uint8_t *input, size_t inlen) { } static void SHA3_sha3_512_inc_init(OQS_SHA3_sha3_512_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); keccak_inc_reset((uint64_t *)state->ctx); } @@ -319,10 +310,7 @@ static void SHA3_shake128(uint8_t *output, size_t outlen, const uint8_t *input, /* SHAKE128 incremental */ static void SHA3_shake128_inc_init(OQS_SHA3_shake128_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); keccak_inc_reset((uint64_t *)state->ctx); } @@ -364,10 +352,7 @@ static void SHA3_shake256(uint8_t *output, size_t outlen, const uint8_t *input, /* SHAKE256 incremental */ static void SHA3_shake256_inc_init(OQS_SHA3_shake256_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_CTX_ALIGNMENT, KECCAK_CTX_BYTES); keccak_inc_reset((uint64_t *)state->ctx); } diff --git a/src/common/sha3/xkcp_sha3x4.c b/src/common/sha3/xkcp_sha3x4.c index 8ed5da878b..bd441a01ff 100644 --- a/src/common/sha3/xkcp_sha3x4.c +++ b/src/common/sha3/xkcp_sha3x4.c @@ -167,10 +167,7 @@ static void SHA3_shake128_x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_ /* SHAKE128 incremental */ static void SHA3_shake128_x4_inc_init(OQS_SHA3_shake128_x4_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_X4_CTX_ALIGNMENT, KECCAK_X4_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_X4_CTX_ALIGNMENT, KECCAK_X4_CTX_BYTES); keccak_x4_inc_reset((uint64_t *)state->ctx); } @@ -212,10 +209,7 @@ static void SHA3_shake256_x4(uint8_t *out0, uint8_t *out1, uint8_t *out2, uint8_ /* SHAKE256 incremental */ static void SHA3_shake256_x4_inc_init(OQS_SHA3_shake256_x4_inc_ctx *state) { - state->ctx = OQS_MEM_aligned_alloc(KECCAK_X4_CTX_ALIGNMENT, KECCAK_X4_CTX_BYTES); - if (state->ctx == NULL) { - exit(111); - } + state->ctx = OQS_MEM_checked_aligned_alloc(KECCAK_X4_CTX_ALIGNMENT, KECCAK_X4_CTX_BYTES); keccak_x4_inc_reset((uint64_t *)state->ctx); } From 7db8ddfe24a189e84e0d72dc127a8c09c8c89f24 Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Thu, 11 Jan 2024 14:39:43 -0500 Subject: [PATCH 28/68] Update `sig_stfl.h` document for #1650 (#1655) * update the stateful siganture header documentation * catch the case when mutex is not set * stress that only the Signing operation need to be locked/unlocked. * make lock and unlock function to internal APIs. --- src/sig_stfl/sig_stfl.c | 15 ++- src/sig_stfl/sig_stfl.h | 284 +++++++++++++++++++++++++--------------- 2 files changed, 195 insertions(+), 104 deletions(-) diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 6b63f8a73e..e3a9d0f71c 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -1370,7 +1370,7 @@ OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void } /* OQS_SIG_STFL_SECRET_KEY_lock */ -OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk) { +OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk) { if (sk == NULL) { return OQS_ERROR; } @@ -1378,16 +1378,27 @@ OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk) { return OQS_SUCCESS; } + // Try to lock the private key but the mutex is unset. + if (sk->mutex == NULL) { + return OQS_ERROR; + } + return (sk->lock_key(sk->mutex)); } /* OQS_SIG_STFL_SECRET_KEY_unlock */ -OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk) { +OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk) { if (sk == NULL) { return OQS_ERROR; } if (sk->unlock_key == NULL) { return OQS_SUCCESS; } + + // Try to unlock the private key but the mutex is unset. + if (sk->mutex == NULL) { + return OQS_ERROR; + } + return (sk->unlock_key(sk->mutex)); } diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index a0691a9d59..ac95842400 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -39,7 +39,8 @@ */ #if defined(__cplusplus) -extern "C" { +extern "C" +{ #endif /* Algorithm identifier for XMSS-SHA2_10_256 */ @@ -98,22 +99,22 @@ extern "C" { #define OQS_SIG_STFL_alg_lms_sha256_h25_w4 "LMS_SHA256_H25_W4" //"25/4" #define OQS_SIG_STFL_alg_lms_sha256_h25_w8 "LMS_SHA256_H25_W8" //"25/8" -//2-Level LMS +// 2-Level LMS #define OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8 "LMS_SHA256_H5_W8_H5_W8" //"5/8, 5/8" -//RFC 6554 +// RFC 6554 #define OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8 "LMS_SHA256_H10_W4_H5_W8" //"10/4, 5/8" -#define OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8 "LMS_SHA256_H10_W8_H5_W8" //"10/8, 5/8" +#define OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8 "LMS_SHA256_H10_W8_H5_W8" //"10/8, 5/8" #define OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2 "LMS_SHA256_H10_W2_H10_W2" //"10/2, 10/2" #define OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4 "LMS_SHA256_H10_W4_H10_W4" //"10/4, 10/4" #define OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8 "LMS_SHA256_H10_W8_H10_W8" //"10/8, 10/8" -#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8 "LMS_SHA256_H15_W8_H5_W8" //"15/8, 5/8" +#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8 "LMS_SHA256_H15_W8_H5_W8" //"15/8, 5/8" #define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8 "LMS_SHA256_H15_W8_H10_W8" //"15/8, 10/8" #define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8 "LMS_SHA256_H15_W8_H15_W8" //"15/8, 15/8" -#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8 "LMS_SHA256_H20_W8_H5_W8" //"20/8, 5/8" +#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8 "LMS_SHA256_H20_W8_H5_W8" //"20/8, 5/8" #define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8 "LMS_SHA256_H20_W8_H10_W8" //"20/8, 10/8" #define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8 "LMS_SHA256_H20_W8_H15_W8" //"20/8, 15/8" #define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8 "LMS_SHA256_H20_W8_H20_W8" //"20/8, 20/8" @@ -136,7 +137,6 @@ typedef OQS_STATUS (*secure_store_sk)(uint8_t *sk_buf, size_t buf_len, void *con /** * Application provided function to lock secret key object serialize access - * @param[in] sk pointer to the secret key object to lock * @param[in] mutex pointer to mutex struct * return OQS_SUCCESS if successful, otherwise OQS_ERROR */ @@ -144,14 +144,13 @@ typedef OQS_STATUS (*lock_key)(void *mutex); /** * Application provided function to unlock secret key object - * @param[in] sk pointer to the secret key object to unlock * @param[in] mutex pointer to mutex struct * return OQS_SUCCESS if successful, otherwise OQS_ERROR */ typedef OQS_STATUS (*unlock_key)(void *mutex); /** - * Returns identifiers for available signature schemes in liboqs. Used with OQS_SIG_STFL_new. + * Returns identifiers for available signature schemes in liboqs. Used with `OQS_SIG_STFL_new`. * * Note that algorithm identifiers are present in this list even when the algorithm is disabled * at compile time. @@ -162,12 +161,12 @@ typedef OQS_STATUS (*unlock_key)(void *mutex); OQS_API const char *OQS_SIG_STFL_alg_identifier(size_t i); /** - * Returns the number of signature mechanisms in liboqs. They can be enumerated with + * Returns the number of stateful signature mechanisms in liboqs. They can be enumerated with * OQS_SIG_STFL_alg_identifier. * * Note that some mechanisms may be disabled at compile time. * - * @return The number of signature mechanisms. + * @return The number of stateful signature mechanisms. */ OQS_API int OQS_SIG_STFL_alg_count(void); @@ -186,7 +185,7 @@ typedef struct OQS_SIG_STFL { /** * A local ordinal representing the LMS/XMSS OID parameter of the signature scheme. - * This OID is unrelated to ASN.1 OID or anything, it's only for LMS/XMSS internal usage. + * This OID is unrelated to ASN.1 OID, it's only for LMS/XMSS internal usage. */ uint32_t oid; @@ -227,6 +226,10 @@ typedef struct OQS_SIG_STFL { /** * Signature generation algorithm. * + * For stateful signatures, there is always a limited number of signatures that can be used, + * The private key signature counter is increased by one once a signature is successfully generated, + * When the signature counter reaches the maximum number of available signatures, the signature generation always fails. + * * Caller is responsible for allocating sufficient memory for `signature`, * based on the `length_*` members in this object or the per-scheme * compile-time macros `OQS_SIG_STFL_*_length_*`. @@ -237,6 +240,9 @@ typedef struct OQS_SIG_STFL { * @param[in] message_len The length of the message to sign. * @param[in] secret_key The secret key object pointer. * @return OQS_SUCCESS or OQS_ERROR + * + * @note Internally, if `lock/unlock` functions and `mutex` are set, it will attempt to lock the private key and unlock + * the private key after the Signing operation is completed. */ OQS_STATUS (*sign)(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -253,7 +259,9 @@ typedef struct OQS_SIG_STFL { OQS_STATUS (*verify)(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); /** - * Query number of remaining signatures + * Query the number of remaining signatures. + * + * The remaining signatures are the number of signatures available before the private key runs out of its total signature and expires. * * @param[out] remain The number of remaining signatures * @param[in] secret_key The secret key object pointer. @@ -262,7 +270,9 @@ typedef struct OQS_SIG_STFL { OQS_STATUS (*sigs_remaining)(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); /** - * Total number of signatures + * Query the total number of signatures. + * + * The total number of signatures is the constant number present in how many signatures can be generated from a private key. * * @param[out] total The total number of signatures * @param[in] secret_key The secret key key object pointer. @@ -284,37 +294,46 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { /* The (maximum) length, in bytes, of secret keys for this signature scheme. */ size_t length_secret_key; - /* The variant-specific secret key data, must be allocated at the initialization. */ + /* The variant-specific secret key data must be allocated at the initialization. */ void *secret_key_data; - /* mutual exclusion struct */ + /* The mutual exclusion struct */ void *mutex; - /* Application managed data related to secure storage of secret key data */ + /* Application-managed data related to secure storage of secret key data */ void *context; /** - * Secret Key retrieval Function + * Serialize the stateful secret key. * - * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object - * @param[out] sk_len length of the private key as a byte stream - * @param[out] sk_buf_ptr pointer to private key data as a byte stream - * @returns length of key material data available - * Caller is responsible for **deallocating** the pointer to buffer `sk_buf_ptr`. + * This function encodes the stateful secret key represented by `sk` into a byte stream + * for storage or transfer. The `sk_buf_ptr` will point to the allocated memory containing + * the byte stream. Users must free the `sk_buf_ptr` using `OQS_MEM_secure_free` after use. + * The `sk_len` will contain the length of the byte stream. + * + * @param[out] sk_buf_ptr Pointer to the byte stream representing the serialized secret key. + * @param[out] sk_len Pointer to the length of the serialized byte stream. + * @param[in] sk Pointer to the `OQS_SIG_STFL_SECRET_KEY` object to serialize. + * @return The number of bytes in the serialized byte stream upon success, or an OQS error code on failure. + * + * @attention The caller is responsible for ensuring that `sk` is a valid object before calling this function. */ OQS_STATUS (*serialize_key)(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); /** - * Secret Key to internal structure Function + * Deserialize a byte stream into the internal representation of a stateful secret key. + * + * This function takes a series of bytes representing a stateful secret key and initializes + * the internal `OQS_SIG_STFL_SECRET_KEY` object with the key material. This is particularly + * useful for reconstructing key objects from persisted or transmitted state. + * + * @param[out] sk Pointer to an uninitialized `OQS_SIG_STFL_SECRET_KEY` object to hold the secret key. + * @param[in] sk_len The length of the secret key byte stream. + * @param[in] sk_buf Pointer to the byte stream containing the serialized secret key data. + * @param[in] context Pointer to application-specific data, handled externally, associated with the key. + * @returns OQS_SUCCESS if the deserialization succeeds, with the `sk` object populated with the key material. * - * @param[in] sk OQS_SIG_STFL_SECRET_KEY object - * @param[in] key_len length of the returned byte string - * @param[in] sk_buf The secret key data to populate the key object - * @param[in] context application-specific data - * used to keep track of this secret key stored in a secure manner. - * The application manages this memory. - * @returns status of the operation populated with key material none zero length. - * Caller is responsible to **unallocate** the buffer `sk_buf`. + * @attention The caller is responsible for ensuring that `sk_buf` is securely deallocated when it's no longer needed. */ OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); @@ -336,42 +355,48 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { /** * Store Secret Key Function + * * Callback function used to securely store key data after a signature generation. - * When populated, this pointer points to the application supplied secure storage function. + * When populated, this pointer points to the application-supplied secure storage function. * @param[in] sk_buf The serialized secret key data to secure store * @param[in] buf_len length of data to secure * @param[in] context application supplied data used to locate where this secret key * is stored (passed in at the time the function pointer was set). * * @return OQS_SUCCESS or OQS_ERROR - * Ideally written to secure device + * Ideally written to a secure device. */ OQS_STATUS (*secure_store_scrt_key)(uint8_t *sk_buf, size_t buf_len, void *context); /** * Free internal variant-specific data * - * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object - * @return none + * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object. + * @return None. */ void (*free_key)(OQS_SIG_STFL_SECRET_KEY *sk); - /* - * Secure storage for private keys used in stateful signature schemes is outside the scope of the OQS library. - * This is the responsibility of any adopting application. The application must supply - * a function to for this purpose. A callback function and context data must be set in-order - * to perform stateful signature generation. - * The context var may contain, for example an HSM context, a filename or other such data that - * is used to store the private key. This var is passed into the OQS lib when the application sets - * the callback function use to save/update the private key. - */ /** - * Set Secret Key store callback Function + * Set Secret Key Store Callback Function + * + * This function is used to establish a callback mechanism for secure storage + * of private keys involved in stateful signature Signing operation. The secure storage + * and the management of private keys is the responsibility of the adopting application. + * Therefore, before invoking stateful signature generation, a callback function and + * associated context data must be provided by the application to manage the storage. * - * @param[in] sk secret key pointer to be updated - * @param[in] store_cb callback pointer - * @param[in] context application data related to secret key data/identifier storage. - * Provided when OQS_SIG_STFL_SECRET_KEY_SET_store_cb() is called. + * The `context` argument is designed to hold information requisite for private key storage, + * such as a hardware security module (HSM) context, a file path, or other relevant data. + * This context is passed to the libOQS when the callback function is registered. + * + * @param[in] sk A pointer to the secret key object that requires secure storage management + * after signature Signing operations. + * @param[in] store_cb A pointer to the callback function provided by the application + * for storing and updating the private key securely. + * @param[in] context Application-specific context information for the private key storage, + * furnished when setting the callback function via + * OQS_SIG_STFL_SECRET_KEY_set_store_cb(). + * @return None. */ void (*set_scrt_key_store_cb)(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); } OQS_SIG_STFL_SECRET_KEY; @@ -393,7 +418,7 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name); * Caller is responsible for allocating sufficient memory for `public_key` based * on the `length_*` members in this object or the per-scheme compile-time macros * `OQS_SIG_STFL_*_length_*`. The caller is also responsible for initializing - * `secret_key` using the OQS_SIG_STFL_SECRET_KEY(*) function + * `secret_key` using the OQS_SIG_STFL_SECRET_KEY(*) function. * * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. * @param[out] public_key The public key is represented as a byte string. @@ -405,6 +430,10 @@ OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public /** * Signature generation algorithm. * + * For stateful signatures, there is always a limited number of signatures that can be used, + * The private key signature counter is increased by one once a signature is successfully generated, + * When the signature counter reaches the maximum number of available signatures, the signature generation always fails. + * * Caller is responsible for allocating sufficient memory for `signature`, * based on the `length_*` members in this object or the per-scheme * compile-time macros `OQS_SIG_STFL_*_length_*`. @@ -416,6 +445,9 @@ OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public * @param[in] message_len The length of the message to sign. * @param[in] secret_key The secret key object pointer. * @return OQS_SUCCESS or OQS_ERROR + * + * @note Internally, if `lock/unlock` functions and `mutex` are set, it will attempt to lock the private key and unlock + * the private key after the Signing operation is completed. */ OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -433,7 +465,9 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key); /** - * Query number of remaining signatures + * Query the number of remaining signatures. + * + * The remaining signatures are the number of signatures available before the private key runs out of its total signature and expires. * * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. * @param[in] secret_key The secret key object. @@ -442,7 +476,9 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); /** - * * Total number of signatures + * Query the total number of signatures. + * + * The total number of signatures is the constant number present in how many signatures can be generated from a private key. * * @param[in] sig The OQS_SIG_STFL object representing the signature scheme. * @param[out] max The number of remaining signatures @@ -452,13 +488,13 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned long long *max, const OQS_SIG_STFL_SECRET_KEY *secret_key); /** - * Frees an OQS_SIG_STFL object that was constructed by OQS_SIG_STFL_new. + * Free an OQS_SIG_STFL object that was constructed by OQS_SIG_STFL_new. * */ OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig); /** - * Constructs an OQS_SIG_STFL_SECRET_KEY object for a particular algorithm. + * Construct an OQS_SIG_STFL_SECRET_KEY object for a particular algorithm. * * Callers should always check whether the return value is `NULL`, which indicates either than an * invalid algorithm name was provided, or that the requested algorithm was disabled at compile-time. @@ -469,7 +505,7 @@ OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_name); /** - * Frees an OQS_SIG_STFL_SECRET_KEY object that was constructed by OQS_SECRET_KEY_new. + * Free an OQS_SIG_STFL_SECRET_KEY object that was constructed by OQS_SECRET_KEY_new. * * @param[in] sig The OQS_SIG_STFL_SECRET_KEY object to free. * @return OQS_SUCCESS if successful, or OQS_ERROR if the object cannot be freed. @@ -477,97 +513,141 @@ OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_ OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk); /** - * OQS_SIG_STFL_SECRET_KEY_SET_lock . + * Attach a locking mechanism to a secret key object. * - * Sets function to prevent multiple processes from using the sk at the same time. + * This allows for proper synchronization in a multi-threaded or multi-process environment, + * by ensuring that a secret key is not used concurrently by multiple entities, which could otherwise lead to security issues. * - * @param[in] sk secret key pointer to be updated - * @param[in] lock function pointer + * @param[in] sk Pointer to the secret key object whose lock function is to be set. + * @param[in] lock Function pointer to the locking routine provided by the application. + * @return None. * + * @note It's not required to set the lock and unlock functions in a single-threaded environment. + * + * @note Once the `lock` function is set, users must also set the `mutex` and `unlock` functions. + * + * @note By default, the internal value of `sk->lock` is NULL, which does nothing to lock the private key. */ OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_lock(OQS_SIG_STFL_SECRET_KEY *sk, lock_key lock); /** - * OQS_SIG_STFL_SECRET_KEY_SET_unlock . + * Attach an unlock mechanism to a secret key object. + * + * This allows for proper synchronization in a multi-threaded or multi-process environment, + * by ensuring that a secret key is not used concurrently by multiple entities, which could otherwise lead to security issues. + * + * @param[in] sk Pointer to the secret key object whose unlock function is to be set. + * @param[in] unlock Function pointer to the unlock routine provided by the application. + * @return None. * - * Sets function to prevent multiple processes from using the sk at the same time. + * @note It's not required to set the lock and unlock functions in a single-threaded environment. * - * @param[in] sk secret key pointer to be updated - * @param[in] unlock function pointer + * @note Once the `unlock` function is set, users must also set the `mutex` and `lock` functions. * + * @note By default, the internal value of `sk->unlock` is NULL, which does nothing to unlock the private key. */ OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_unlock(OQS_SIG_STFL_SECRET_KEY *sk, unlock_key unlock); /** - * OQS_SIG_STFL_SECRET_KEY_SET_mutex . + * Assign a mutex function to handle concurrency control over the secret key. * - * Sets function to prevent multiple processes from using the sk at the same time. + * This is to ensure that only one process can access or modify the key at any given time. * - * @param[in] sk secret key pointer to be updated - * @param[in] mutex function pointer + * @param[in] sk A pointer to the secret key that the mutex functionality will protect. + * @param[in] mutex A function pointer to the desired concurrency control mechanism. + * @return None. * + * @note It's not required to set the lock and unlock functions in a single-threaded environment. + * + * @note By default, the internal value of `sk->mutex` is NULL, it must be set to be used in `lock` or `unlock` the private key. */ OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void *mutex); /** - * OQS_SIG_STFL_SECRET_KEY_lock . + * Lock the secret key to ensure exclusive access in a concurrent environment. + * + * If the `mutex` is not set, this lock operation will fail. + * This lock operation is essential in multi-threaded or multi-process contexts + * to prevent simultaneous Signing operations that could compromise the stateful signature security. + * + * @warning If the `lock` function is set and `mutex` is not set, this lock operation will fail. * - * Locks the secret key so only one application that holds the lock can access it. + * @param[in] sk Pointer to the secret key to be locked. + * @return OQS_SUCCESS if the lock is successfully applied; OQS_ERROR otherwise. * - * @param[in] sk secret key pointer to be locked - * @return OQS_SUCCESS if successful, or OQS_ERROR if the object fails to apply the lock + * @note It's not necessary to use this function in either Keygen or Verifying operations. + * In a concurrent environment, the user is responsible for locking and unlocking the private key, + * to make sure that only one thread can access the private key during a Signing operation. * + * @note If the `lock` function and `mutex` are both set, proceed to lock the private key. */ -OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk); +OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk); /** - * OQS_SIG_STFL_SECRET_KEY_unlock . + * Unlock the secret key, making it accessible to other processes. * - * Unlocks the secret key so that the next process can access it. + * This function is crucial in environments where multiple processes need to coordinate access to + * the secret key, as it allows a process to signal that it has finished using the key, so + * others can safely use it. * - * @param[in] sk secret key pointer - * @return OQS_SUCCESS if successful, or OQS_ERROR if the object fails to release the lock + * @warning If the `unlock` function is set and `mutex` is not set, this unlock operation will fail. * + * @param[in] sk Pointer to the secret key whose lock should be released. + * @return OQS_SUCCESS if the lock was successfully released; otherwise, OQS_ERROR. + * + * @note It's not necessary to use this function in either Keygen or Verifying operations. + * In a concurrent environment, the user is responsible for locking and unlocking the private key, + * to make sure that only one thread can access the private key during a Signing operation. + * + * @note If the `unlock` function and `mutex` are both set, proceed to unlock the private key. */ -OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk); +OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk); /** - * OQS_SIG_STFL_SECRET_KEY_SET_store_cb . - * - * Can be called after creating a new stateful secret key has been generated. - * Allows the lib to securely store and update the secret key after a sign operation. - * - * @param[in] sk secret key pointer to be updated - * @param[in] store_cb callback pointer - * @param[in] context application data related to where/how secret key data storage. - * Applications allocates, tracks, deallocates this. Signature generation fails without this set. - * + * Set the callback and context for securely storing a stateful secret key. + * + * This function is designed to be called after a new stateful secret key + * has been generated. It enables the library to securely store secret key + * and update it every time a Signing operation occurs. + * Without properly setting this callback and context, signature generation + * will not succeed as the updated state of the secret key cannot be preserved. + * + * @param[in] sk Pointer to the stateful secret key to be managed. + * @param[in] store_cb Callback function that handles the secure storage of the key. + * @param[in] context Application-specific context that assists in the storage of secret key data. + * This context is managed by the application, which allocates it, keeps track of it, + * and deallocates it as necessary. + * @return None. */ OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); /** - * OQS_SECRET_KEY_STFL_serialize_key . + * Serialize the stateful secret key data into a byte array. + * + * Converts an OQS_SIG_STFL_SECRET_KEY object into a byte array for storage or transmission. * - * Serialize stateful secret key data into a byte string, and - * return an allocated buffer. Users are responsible for deallocating - * the buffer `sk_buf_ptr`. + * @param[out] sk_buf_ptr Pointer to the allocated byte array containing the serialized key. + * @param[out] sk_len Length of the serialized key byte array. + * @param[in] sk Pointer to the OQS_SIG_STFL_SECRET_KEY object to be serialized. + * @return OQS_SUCCESS on success, or an OQS error code on failure. * - * @param[out] sk_buf_ptr secret key buffer returned. Caller deletes. - * @param[out] sk_len size of the buffer returned - * @param[in] sk secret key pointer to be serialize + * @note The function allocates memory for the byte array, and it is the caller's responsibility to free this memory after use. */ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); /** - * OQS_SECRET_KEY_STFL_deserialize_key . + * Deserialize a byte array into an OQS_SIG_STFL_SECRET_KEY object. + * + * Transforms a binary representation of a secret key into an OQS_SIG_STFL_SECRET_KEY structure. + * After deserialization, the secret key object can be used for subsequent cryptographic operations. * - * Insert stateful byte string into a secret key object. - * Users are responsible for deallocating buffer `sk_buf`. + * @param[out] sk A pointer to the secret key object that will be populated from the binary data. + * @param[in] key_len The length of the binary secret key data in bytes. + * @param[in] sk_buf The buffer containing the serialized secret key data. + * @param[in] context Application-specific data used to maintain context about the secret key. + * @return OQS_SUCCESS if deserialization was successful; otherwise, OQS_ERROR. * - * @param[in] sk secret key pointer to be populated - * @param[in] sk_len size of the supplied buffer - * @param[in] sk_buf secret key buffer. Caller deletes. - * @param[in] context application managed data related to where/how secret key data is stored. + * @attention The caller is responsible for freeing the `sk_buf` memory when it is no longer needed. */ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf, void *context); From cf03392510f426da2f1283b4c709d39fb92bcaf8 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Sat, 13 Jan 2024 00:27:58 -0500 Subject: [PATCH 29/68] Update README.md Co-authored-by: Spencer Wilson --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 926a8ce28a..1f549a3b14 100644 --- a/README.md +++ b/README.md @@ -126,7 +126,7 @@ The following instructions assume we are in `build`. - `test_kem`: Simple test harness for key encapsulation mechanisms - `test_sig`: Simple test harness for key signature schemes - - `test_sig_stfl`: Simple test harness for stateful key signature schemes + - `test_sig_stfl`: Simple test harness for stateful signature schemes - `test_kem_mem`: Simple test harness for checking memory consumption of key encapsulation mechanisms - `test_sig_mem`: Simple test harness for checking memory consumption of key signature schemes - `kat_kem`: Program that generates known answer test (KAT) values for key encapsulation mechanisms using the same procedure as the NIST submission requirements, for checking against submitted KAT values using `tests/test_kat.py` From 93257132a7b4687674803fd903ab986a32fd1143 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Sat, 13 Jan 2024 00:28:28 -0500 Subject: [PATCH 30/68] Update README.md Co-authored-by: Spencer Wilson --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1f549a3b14..7baf922749 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ The following instructions assume we are in `build`. 3. By default the main build result is `lib/liboqs.a`, a static library. If you want to build a shared/dynamic library, append [`-DBUILD_SHARED_LIBS=ON`](CONFIGURE.md#build_shared_libs) to the `cmake -GNinja ..` command above and the result will be `lib/liboqs.so|dylib|dll`. The public headers are located in the `include` directory. There are also a variety of programs built under the `tests` directory: - `test_kem`: Simple test harness for key encapsulation mechanisms - - `test_sig`: Simple test harness for key signature schemes + - `test_sig`: Simple test harness for signature schemes - `test_sig_stfl`: Simple test harness for stateful signature schemes - `test_kem_mem`: Simple test harness for checking memory consumption of key encapsulation mechanisms - `test_sig_mem`: Simple test harness for checking memory consumption of key signature schemes From a52b2176eceed0ccff2df31302907b50c8d2dc22 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Sat, 13 Jan 2024 00:28:45 -0500 Subject: [PATCH 31/68] Update README.md Co-authored-by: Spencer Wilson --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7baf922749..c589d7c18b 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ The following instructions assume we are in `build`. - `test_sig`: Simple test harness for signature schemes - `test_sig_stfl`: Simple test harness for stateful signature schemes - `test_kem_mem`: Simple test harness for checking memory consumption of key encapsulation mechanisms - - `test_sig_mem`: Simple test harness for checking memory consumption of key signature schemes + - `test_sig_mem`: Simple test harness for checking memory consumption of signature schemes - `kat_kem`: Program that generates known answer test (KAT) values for key encapsulation mechanisms using the same procedure as the NIST submission requirements, for checking against submitted KAT values using `tests/test_kat.py` - `kat_sig`: Program that generates known answer test (KAT) values for signature schemes using the same procedure as the NIST submission requirements, for checking against submitted KAT values using `tests/test_kat.py` - `kat_stfl_sig`: Program for checking results against submitted KAT values using `tests/test_kat.py` From d442ac9ba861f9171b45a34de148f935a5de600d Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Sat, 13 Jan 2024 00:29:05 -0500 Subject: [PATCH 32/68] Update README.md Co-authored-by: Spencer Wilson --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c589d7c18b..0752ad5163 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ The following instructions assume we are in `build`. - `test_sig_mem`: Simple test harness for checking memory consumption of signature schemes - `kat_kem`: Program that generates known answer test (KAT) values for key encapsulation mechanisms using the same procedure as the NIST submission requirements, for checking against submitted KAT values using `tests/test_kat.py` - `kat_sig`: Program that generates known answer test (KAT) values for signature schemes using the same procedure as the NIST submission requirements, for checking against submitted KAT values using `tests/test_kat.py` - - `kat_stfl_sig`: Program for checking results against submitted KAT values using `tests/test_kat.py` + - `kat_sig_stfl`: Program for checking results against submitted KAT values using `tests/test_kat.py` - `speed_kem`: Benchmarking program for key encapsulation mechanisms; see `./speed_kem --help` for usage instructions - `speed_sig`: Benchmarking program for signature mechanisms; see `./speed_sig --help` for usage instructions - `example_kem`: Minimal runnable example showing the usage of the KEM API From 72ab47826cac51e47ea00cfccdeac2bc4c9c0485 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Sat, 13 Jan 2024 00:32:50 -0500 Subject: [PATCH 33/68] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 0752ad5163..b47b82d660 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,7 @@ The following instructions assume we are in `build`. - `speed_sig`: Benchmarking program for signature mechanisms; see `./speed_sig --help` for usage instructions - `example_kem`: Minimal runnable example showing the usage of the KEM API - `example_sig`: Minimal runnable example showing the usage of the signature API + - `example_sig_stfl`: Minimal runnable example showing the usage of the stateful signature API - `test_aes`, `test_sha3`: Simple test harnesses for crypto sub-components - `test_portability`: Simple test harnesses for checking cross-CPU code portability; requires presence of `qemu`; proper operation validated only on Ubuntu From 5967f12281ac99b206407c44e340026fdb2ef7c7 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Sat, 13 Jan 2024 00:33:57 -0500 Subject: [PATCH 34/68] Update src/CMakeLists.txt Co-authored-by: Spencer Wilson --- src/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b6772ee9ff..a5b64fd294 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -73,8 +73,6 @@ add_library(oqs kem/kem.c ${SIG_OBJS} sig_stfl/sig_stfl.c ${SIG_STFL_OBJS} - sig_stfl/sig_stfl.c - ${SIG_STFL_OBJS} ${COMMON_OBJS}) # Internal library to be used only by test programs From fc6d512ac18d08727a73b4232f1f5030eced7fe0 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Fri, 19 Jan 2024 14:22:27 -0500 Subject: [PATCH 35/68] Update documentation and license text. (#1663) * Update documentation and license text. * Fix missing CR in calls to printf * Updates per review comments --- docs/algorithms/sig_stfl/lms.md | 50 ++++ docs/algorithms/sig_stfl/lms.yml | 216 ++++++++++++++++++ docs/algorithms/sig_stfl/sig_stfl.md | 29 +++ docs/algorithms/sig_stfl/xmss.md | 44 ++++ docs/algorithms/sig_stfl/xmss.yml | 187 +++++++++++++++ scripts/update_docs_from_yaml.py | 61 +++++ src/sig_stfl/lms/external/common_defs.h | 1 + src/sig_stfl/lms/external/config.h | 1 + src/sig_stfl/lms/external/endian.c | 1 + src/sig_stfl/lms/external/endian.h | 1 + src/sig_stfl/lms/external/hash.c | 1 + src/sig_stfl/lms/external/hash.h | 1 + src/sig_stfl/lms/external/hss.c | 1 + src/sig_stfl/lms/external/hss.h | 1 + src/sig_stfl/lms/external/hss_alloc.c | 1 + src/sig_stfl/lms/external/hss_aux.c | 1 + src/sig_stfl/lms/external/hss_aux.h | 1 + src/sig_stfl/lms/external/hss_common.c | 1 + src/sig_stfl/lms/external/hss_common.h | 1 + src/sig_stfl/lms/external/hss_compute.c | 1 + src/sig_stfl/lms/external/hss_derive.c | 1 + src/sig_stfl/lms/external/hss_derive.h | 1 + src/sig_stfl/lms/external/hss_generate.c | 1 + src/sig_stfl/lms/external/hss_internal.h | 1 + src/sig_stfl/lms/external/hss_keygen.c | 1 + src/sig_stfl/lms/external/hss_param.c | 1 + src/sig_stfl/lms/external/hss_reserve.c | 1 + src/sig_stfl/lms/external/hss_reserve.h | 1 + src/sig_stfl/lms/external/hss_sign.c | 1 + src/sig_stfl/lms/external/hss_sign_inc.c | 1 + src/sig_stfl/lms/external/hss_sign_inc.h | 1 + src/sig_stfl/lms/external/hss_thread.h | 1 + .../lms/external/hss_thread_pthread.c | 1 + src/sig_stfl/lms/external/hss_thread_single.c | 1 + src/sig_stfl/lms/external/hss_verify.c | 1 + src/sig_stfl/lms/external/hss_verify.h | 1 + src/sig_stfl/lms/external/hss_verify_inc.c | 1 + src/sig_stfl/lms/external/hss_verify_inc.h | 1 + src/sig_stfl/lms/external/hss_zeroize.c | 1 + src/sig_stfl/lms/external/hss_zeroize.h | 1 + src/sig_stfl/lms/external/license.txt | 29 +++ src/sig_stfl/lms/external/lm_common.c | 1 + src/sig_stfl/lms/external/lm_common.h | 1 + src/sig_stfl/lms/external/lm_ots.h | 1 + src/sig_stfl/lms/external/lm_ots_common.c | 1 + src/sig_stfl/lms/external/lm_ots_common.h | 1 + src/sig_stfl/lms/external/lm_ots_sign.c | 1 + src/sig_stfl/lms/external/lm_ots_verify.c | 1 + src/sig_stfl/lms/external/lm_ots_verify.h | 1 + src/sig_stfl/lms/external/lm_verify.c | 1 + src/sig_stfl/lms/external/lm_verify.h | 1 + src/sig_stfl/lms/external/lms_namespace.h | 1 + 52 files changed, 661 insertions(+) create mode 100644 docs/algorithms/sig_stfl/lms.md create mode 100644 docs/algorithms/sig_stfl/lms.yml create mode 100644 docs/algorithms/sig_stfl/sig_stfl.md create mode 100644 docs/algorithms/sig_stfl/xmss.md create mode 100644 docs/algorithms/sig_stfl/xmss.yml create mode 100644 src/sig_stfl/lms/external/license.txt diff --git a/docs/algorithms/sig_stfl/lms.md b/docs/algorithms/sig_stfl/lms.md new file mode 100644 index 0000000000..8357d0a8f6 --- /dev/null +++ b/docs/algorithms/sig_stfl/lms.md @@ -0,0 +1,50 @@ +# LMS + +- **Algorithm type**: Digital signature scheme. +- **Main cryptographic assumption**: hash function second-preimage resistance. +- **Principal submitters**: Scott Fluhrer. +- **Auxiliary submitters**: C Martin, Maurice Hieronymus. +- **Authors' website**: https://www.rfc-editor.org/info/rfc8554 +- **Specification version**: None. +- **Primary Source**: + - **Source**: https://github.com/cisco/hash-sigs + - **Implementation license (SPDX-Identifier)**: MIT + + +## Parameter set summary + +| Parameter set | Security model | Claimed NIST Level | Public key size (bytes) | Secret key size (bytes) | Signature size (bytes) | +|:------------------------:|:-----------------|:---------------------|--------------------------:|--------------------------:|-------------------------:| +| LMS_SHA256_H5_W1 | | | 60 | 64 | 8688 | +| LMS_SHA256_H5_W2 | | | 60 | 64 | 4464 | +| LMS_SHA256_H5_W4 | | | 60 | 64 | 2352 | +| LMS_SHA256_H5_W8 | | | 60 | 64 | 1296 | +| LMS_SHA256_H10_W1 | | | 60 | 64 | 8848 | +| LMS_SHA256_H10_W2 | | | 60 | 64 | 4624 | +| LMS_SHA256_H10_W4 | | | 60 | 64 | 2512 | +| LMS_SHA256_H10_W8 | | | 60 | 64 | 1456 | +| LMS_SHA256_H15_W1 | | | 60 | 64 | 9008 | +| LMS_SHA256_H15_W2 | | | 60 | 64 | 4784 | +| LMS_SHA256_H15_W4 | | | 60 | 64 | 2672 | +| LMS_SHA256_H15_W8 | | | 60 | 64 | 1616 | +| LMS_SHA256_H20_W1 | | | 60 | 64 | 9168 | +| LMS_SHA256_H20_W2 | | | 60 | 64 | 4944 | +| LMS_SHA256_H20_W4 | | | 60 | 64 | 2832 | +| LMS_SHA256_H20_W8 | | | 60 | 64 | 1776 | +| LMS_SHA256_H25_W1 | | | 60 | 64 | 9328 | +| LMS_SHA256_H25_W2 | | | 60 | 64 | 5104 | +| LMS_SHA256_H25_W4 | | | 60 | 64 | 2992 | +| LMS_SHA256_H25_W8 | | | 60 | 64 | 1936 | +| LMS_SHA256_H5_W8_H5_W8 | | | 60 | 64 | 2644 | +| LMS_SHA256_H10_W4_H5_W8 | | | 60 | 64 | 2804 | +| LMS_SHA256_H10_W8_H5_W8 | | | 60 | 64 | 3860 | +| LMS_SHA256_H10_W2_H10_W2 | | | 60 | 64 | 9300 | +| LMS_SHA256_H10_W4_H10_W4 | | | 60 | 64 | 5076 | +| LMS_SHA256_H10_W8_H10_W8 | | | 60 | 64 | 2964 | +| LMS_SHA256_H15_W8_H5_W8 | | | 60 | 64 | 2964 | +| LMS_SHA256_H15_W8_H10_W8 | | | 60 | 64 | 3124 | +| LMS_SHA256_H15_W8_H15_W8 | | | 60 | 64 | 3284 | +| LMS_SHA256_H20_W8_H5_W8 | | | 60 | 64 | 3124 | +| LMS_SHA256_H20_W8_H10_W8 | | | 60 | 64 | 3284 | +| LMS_SHA256_H20_W8_H15_W8 | | | 60 | 64 | 3444 | +| LMS_SHA256_H20_W8_H20_W8 | | | 60 | 64 | 3604 | diff --git a/docs/algorithms/sig_stfl/lms.yml b/docs/algorithms/sig_stfl/lms.yml new file mode 100644 index 0000000000..2741a3afea --- /dev/null +++ b/docs/algorithms/sig_stfl/lms.yml @@ -0,0 +1,216 @@ +name: LMS +type: stateful signature +principal-submitters: +- Scott Fluhrer +auxiliary-submitters: +- C Martin +- Maurice Hieronymus + +crypto-assumption: hash function second-preimage resistance +website: https://www.rfc-editor.org/info/rfc8554 +nist-round: +spec-version: +spdx-license-identifier: +primary-upstream: + source: https://github.com/cisco/hash-sigs + spdx-license-identifier: MIT + upstream-ancestors: +parameter-sets: +- name: LMS_SHA256_H5_W1 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 8688 +- name: LMS_SHA256_H5_W2 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 4464 +- name: LMS_SHA256_H5_W4 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 2352 +- name: LMS_SHA256_H5_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 1296 +- name: LMS_SHA256_H10_W1 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 8848 +- name: LMS_SHA256_H10_W2 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 4624 +- name: LMS_SHA256_H10_W4 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 2512 +- name: LMS_SHA256_H10_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 1456 +- name: LMS_SHA256_H15_W1 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 9008 +- name: LMS_SHA256_H15_W2 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 4784 +- name: LMS_SHA256_H15_W4 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 2672 +- name: LMS_SHA256_H15_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 1616 +- name: LMS_SHA256_H20_W1 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 9168 +- name: LMS_SHA256_H20_W2 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 4944 +- name: LMS_SHA256_H20_W4 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 2832 +- name: LMS_SHA256_H20_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 1776 +- name: LMS_SHA256_H25_W1 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 9328 +- name: LMS_SHA256_H25_W2 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 5104 +- name: LMS_SHA256_H25_W4 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 2992 +- name: LMS_SHA256_H25_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 1936 +- name: LMS_SHA256_H5_W8_H5_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 2644 +- name: LMS_SHA256_H10_W4_H5_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 2804 +- name: LMS_SHA256_H10_W8_H5_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 3860 +- name: LMS_SHA256_H10_W2_H10_W2 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 9300 +- name: LMS_SHA256_H10_W4_H10_W4 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 5076 +- name: LMS_SHA256_H10_W8_H10_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 2964 +- name: LMS_SHA256_H15_W8_H5_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 2964 +- name: LMS_SHA256_H15_W8_H10_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 3124 +- name: LMS_SHA256_H15_W8_H15_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 3284 +- name: LMS_SHA256_H20_W8_H5_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 3124 +- name: LMS_SHA256_H20_W8_H10_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 3284 +- name: LMS_SHA256_H20_W8_H15_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 3444 +- name: LMS_SHA256_H20_W8_H20_W8 + claimed-nist-level: + claimed-security: + length-public-key: 60 + length-secret-key: 64 + length-signature: 3604 diff --git a/docs/algorithms/sig_stfl/sig_stfl.md b/docs/algorithms/sig_stfl/sig_stfl.md new file mode 100644 index 0000000000..dfd0403066 --- /dev/null +++ b/docs/algorithms/sig_stfl/sig_stfl.md @@ -0,0 +1,29 @@ + +# **Stateful Hash Based Signatures** + +The security of hash based signatures (HBS) is based on the underlying hash functions on which they are built. +NIST recommendation is that they are suitable for near term use to mitigate against attacks mounted by quantum computers. +While not a general purpose solution, they are useful means to authenticate boot or firmware images. + +**General** + +This package provides full support for a variety of variants for XMSS and LMS. +Key generation, signature generation, and signature verification. +Security of HBS also depends on the management of the state of the secret key. Secret keys can only used once to generate a signature. +Multiple signing with same key can reveal that key to an attacker. +Because of this, NIST recommends that key and signature generation be done in hardware security modules. +Having said that, this library is fully functional for research purposes. Secret keys are incremented after each sign operation. +However, secure storage and lifecycle management of the secret keys are left to applications using this feature. +Secret key storage is easily done by supplying a callback function to the library. This callback is invoked to store the secret key. + + +**Key State Management** + +Application writers have to supply callback functions to store and update secret keys. +After a sign operation the secret key index is advanced and stored. This ensures one-time use of the key. +Signing operations will fail without this callback set because the private key cannot be advanced (to prevent reuse). + +Stateful keys can generate a finite number of signatures. A counter tracks the limit when the key is created and is decremented after each signature is generated. +When the counter is down to 0, signature generation fails. Applications can query the remaining count via an API. + + diff --git a/docs/algorithms/sig_stfl/xmss.md b/docs/algorithms/sig_stfl/xmss.md new file mode 100644 index 0000000000..b78dce983b --- /dev/null +++ b/docs/algorithms/sig_stfl/xmss.md @@ -0,0 +1,44 @@ +# XMSS + +- **Algorithm type**: Digital signature scheme. +- **Main cryptographic assumption**: hash function second-preimage resistance. +- **Principal submitters**: Joost Rijneveld, A. Huelsing, David Cooper, Bas Westerbaan. +- **Authors' website**: https://www.rfc-editor.org/info/rfc8391 +- **Specification version**: None. +- **Primary Source**: + - **Source**: https://github.com/XMSS/xmss-reference + - **Implementation license (SPDX-Identifier)**: Apache-2.0 AND MIT + + +## Parameter set summary + +| Parameter set | Security model | Claimed NIST Level | Public key size (bytes) | Secret key size (bytes) | Signature size (bytes) | +|:----------------------:|:-----------------|:---------------------|--------------------------:|--------------------------:|-------------------------:| +| XMSS-SHA2_10_256 | | | 64 | 1373 | 2500 | +| XMSS-SHA2_16_256 | | | 64 | 2093 | 2692 | +| XMSS-SHA2_20_256 | | | 64 | 2573 | 2820 | +| XMSS-SHAKE_10_256 | | | 64 | 1373 | 2500 | +| XMSS-SHAKE_16_256 | | | 64 | 2093 | 2692 | +| XMSS-SHAKE_20_256 | | | 64 | 2573 | 2820 | +| XMSS-SHA2_10_512 | | | 128 | 2653 | 9092 | +| XMSS-SHA2_16_512 | | | 128 | 4045 | 9476 | +| XMSS-SHA2_20_512 | | | 128 | 2653 | 9732 | +| XMSS-SHAKE_10_512 | | | 128 | 2653 | 9092 | +| XMSS-SHAKE_16_512 | | | 128 | 4045 | 9476 | +| XMSS-SHAKE_20_512 | | | 128 | 4973 | 9732 | +| XMSSMT-SHA2_20/2_256 | | | 64 | 5998 | 4963 | +| XMSSMT-SHA2_20/4_256 | | | 64 | 10938 | 9251 | +| XMSSMT-SHA2_40/2_256 | | | 64 | 9600 | 5605 | +| XMSSMT-SHA2_40/4_256 | | | 64 | 15252 | 9893 | +| XMSSMT-SHA2_40/8_256 | | | 64 | 24516 | 18469 | +| XMSSMT-SHA2_60/3_256 | | | 64 | 16629 | 8392 | +| XMSSMT-SHA2_60/6_256 | | | 64 | 24507 | 14824 | +| XMSSMT-SHA2_60/12_256 | | | 64 | 38095 | 27688 | +| XMSSMT-SHAKE_20/2_256 | | | 64 | 5998 | 4963 | +| XMSSMT-SHAKE_20/4_256 | | | 64 | 10938 | 9251 | +| XMSSMT-SHAKE_40/2_256 | | | 64 | 9600 | 5605 | +| XMSSMT-SHAKE_40/4_256 | | | 64 | 15252 | 9893 | +| XMSSMT-SHAKE_40/8_256 | | | 64 | 24516 | 18469 | +| XMSSMT-SHAKE_60/3_256 | | | 64 | 24516 | 8392 | +| XMSSMT-SHAKE_60/6_256 | | | 64 | 24507 | 14824 | +| XMSSMT-SHAKE_60/12_256 | | | 64 | 38095 | 27688 | diff --git a/docs/algorithms/sig_stfl/xmss.yml b/docs/algorithms/sig_stfl/xmss.yml new file mode 100644 index 0000000000..bf57a7eeb8 --- /dev/null +++ b/docs/algorithms/sig_stfl/xmss.yml @@ -0,0 +1,187 @@ +name: XMSS +type: stateful signature +principal-submitters: +- Joost Rijneveld +- A. Huelsing +- David Cooper +- Bas Westerbaan +auxiliary-submitters: + +crypto-assumption: hash function second-preimage resistance +website: https://www.rfc-editor.org/info/rfc8391 +nist-round: +spec-version: +spdx-license-identifier: Apache-2.0 AND MIT +primary-upstream: + source: https://github.com/XMSS/xmss-reference + spdx-license-identifier: Apache-2.0 AND MIT + upstream-ancestors: +parameter-sets: +- name: XMSS-SHA2_10_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 1373 + length-signature: 2500 +- name: XMSS-SHA2_16_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 2093 + length-signature: 2692 +- name: XMSS-SHA2_20_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 2573 + length-signature: 2820 +- name: XMSS-SHAKE_10_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 1373 + length-signature: 2500 +- name: XMSS-SHAKE_16_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 2093 + length-signature: 2692 +- name: XMSS-SHAKE_20_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 2573 + length-signature: 2820 +- name: XMSS-SHA2_10_512 + claimed-nist-level: + claimed-security: + length-public-key: 128 + length-secret-key: 2653 + length-signature: 9092 +- name: XMSS-SHA2_16_512 + claimed-nist-level: + claimed-security: + length-public-key: 128 + length-secret-key: 4045 + length-signature: 9476 +- name: XMSS-SHA2_20_512 + claimed-nist-level: + claimed-security: + length-public-key: 128 + length-secret-key: 2653 + length-signature: 9732 +- name: XMSS-SHAKE_10_512 + claimed-nist-level: + claimed-security: + length-public-key: 128 + length-secret-key: 2653 + length-signature: 9092 +- name: XMSS-SHAKE_16_512 + claimed-nist-level: + claimed-security: + length-public-key: 128 + length-secret-key: 4045 + length-signature: 9476 +- name: XMSS-SHAKE_20_512 + claimed-nist-level: + claimed-security: + length-public-key: 128 + length-secret-key: 4973 + length-signature: 9732 +- name: XMSSMT-SHA2_20/2_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 5998 + length-signature: 4963 +- name: XMSSMT-SHA2_20/4_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 10938 + length-signature: 9251 +- name: XMSSMT-SHA2_40/2_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 9600 + length-signature: 5605 +- name: XMSSMT-SHA2_40/4_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 15252 + length-signature: 9893 +- name: XMSSMT-SHA2_40/8_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 24516 + length-signature: 18469 +- name: XMSSMT-SHA2_60/3_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 16629 + length-signature: 8392 +- name: XMSSMT-SHA2_60/6_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 24507 + length-signature: 14824 +- name: XMSSMT-SHA2_60/12_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 38095 + length-signature: 27688 +- name: XMSSMT-SHAKE_20/2_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 5998 + length-signature: 4963 +- name: XMSSMT-SHAKE_20/4_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 10938 + length-signature: 9251 +- name: XMSSMT-SHAKE_40/2_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 9600 + length-signature: 5605 +- name: XMSSMT-SHAKE_40/4_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 15252 + length-signature: 9893 +- name: XMSSMT-SHAKE_40/8_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 24516 + length-signature: 18469 +- name: XMSSMT-SHAKE_60/3_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 24516 + length-signature: 8392 +- name: XMSSMT-SHAKE_60/6_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 24507 + length-signature: 14824 +- name: XMSSMT-SHAKE_60/12_256 + claimed-nist-level: + claimed-security: + length-public-key: 64 + length-secret-key: 38095 + length-signature: 27688 \ No newline at end of file diff --git a/scripts/update_docs_from_yaml.py b/scripts/update_docs_from_yaml.py index ef152d376a..a07a81c2d0 100644 --- a/scripts/update_docs_from_yaml.py +++ b/scripts/update_docs_from_yaml.py @@ -17,6 +17,7 @@ def file_get_contents(filename, encoding=None): kem_yamls = [] sig_yamls = [] +sig_stfl_yamls = [] ######################################## # Update the KEM markdown documentation. @@ -269,6 +270,66 @@ def do_it(liboqs_root): out_md.write('- **Large Stack Usage**: Implementations identified as having such may cause failures when running in threads or in constrained environments.') + ############################################## + # Update the stateful signature markdown documentation. + ############################################## + for sig_stfl_yaml_path in sorted(glob.glob(os.path.join(liboqs_root, 'docs', 'algorithms', 'sig_stfl', '*.yml'))): + sig_stfl_yaml = load_yaml(sig_stfl_yaml_path) + sig_stfl_yamls.append(sig_stfl_yaml) + sig_stfl_name = os.path.splitext(os.path.basename(sig_stfl_yaml_path))[0] + print('Updating {}/{}.md'.format(os.path.dirname(sig_stfl_yaml_path), sig_stfl_name)) + + with open(os.path.join(liboqs_root, 'docs', 'algorithms', 'sig_stfl', '{}.md'.format(sig_stfl_name)), mode='w', encoding='utf-8') as out_md: + out_md.write('# {}\n\n'.format(sig_stfl_yaml['name'])) + out_md.write('- **Algorithm type**: Digital signature scheme.\n') + out_md.write('- **Main cryptographic assumption**: {}.\n'.format(sig_stfl_yaml['crypto-assumption'])) + out_md.write('- **Principal submitters**: {}.\n'.format(', '.join(sig_stfl_yaml['principal-submitters']))) + if 'auxiliary-submitters' in sig_stfl_yaml and sig_stfl_yaml['auxiliary-submitters']: + out_md.write('- **Auxiliary submitters**: {}.\n'.format(', '.join(sig_stfl_yaml['auxiliary-submitters']))) + out_md.write('- **Authors\' website**: {}\n'.format(sig_stfl_yaml['website'])) + out_md.write('- **Specification version**: {}.\n'.format(sig_stfl_yaml['spec-version'])) + + out_md.write('- **Primary Source**:\n') + out_md.write(' - **Source**: {}\n'.format(sig_stfl_yaml['primary-upstream']['source'])) + out_md.write(' - **Implementation license (SPDX-Identifier)**: {}\n'.format(sig_stfl_yaml['primary-upstream']['spdx-license-identifier'])) + if 'optimized-upstreams' in sig_stfl_yaml: + out_md.write('- **Optimized Implementation sources**: {}\n'.format(sig_stfl_yaml['primary-upstream']['source'])) + for opt_upstream in sig_stfl_yaml['optimized-upstreams']: + out_md.write(' - **{}**:\n'.format(opt_upstream, opt_upstream)) + out_md.write(' - **Source**: {}\n'.format(sig_stfl_yaml['optimized-upstreams'][opt_upstream]['source'])) + out_md.write(' - **Implementation license (SPDX-Identifier)**: {}\n'.format(sig_stfl_yaml['optimized-upstreams'][opt_upstream]['spdx-license-identifier'])) + + if 'upstream-ancestors' in sig_stfl_yaml: + out_md.write(', which takes it from:\n') + for url in sig_stfl_yaml['upstream-ancestors'][:-1]: + out_md.write(' - {}, which takes it from:\n'.format(url)) + out_md.write(' - {}\n'.format(sig_stfl_yaml['upstream-ancestors'][-1])) + else: + out_md.write('\n') + + if 'advisories' in sig_stfl_yaml: + out_md.write('\n## Advisories\n\n') + for advisory in sig_stfl_yaml['advisories']: + out_md.write('- {}\n'.format(advisory)) + + out_md.write('\n## Parameter set summary\n\n') + table = [['Parameter set', + 'Security model', + 'Claimed NIST Level', + 'Public key size (bytes)', + 'Secret key size (bytes)', + 'Signature size (bytes)']] + for parameter_set in sig_stfl_yaml['parameter-sets']: + table.append([parameter_set['name'], + parameter_set['claimed-security'], + parameter_set['claimed-nist-level'], + parameter_set['length-public-key'], + parameter_set['length-secret-key'], + parameter_set['length-signature']]) + out_md.write(tabulate.tabulate(table, tablefmt="pipe", headers="firstrow", colalign=("center",))) + out_md.write('\n') + + #################### # Update the README. diff --git a/src/sig_stfl/lms/external/common_defs.h b/src/sig_stfl/lms/external/common_defs.h index 83739949ee..1c7c85d382 100644 --- a/src/sig_stfl/lms/external/common_defs.h +++ b/src/sig_stfl/lms/external/common_defs.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( COMMON_DEFS_H_ ) #define COMMON_DEFS_H_ diff --git a/src/sig_stfl/lms/external/config.h b/src/sig_stfl/lms/external/config.h index e23d19fa9a..f9549858a9 100644 --- a/src/sig_stfl/lms/external/config.h +++ b/src/sig_stfl/lms/external/config.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( CONFIG_H_ ) #define CONFIG_H_ diff --git a/src/sig_stfl/lms/external/endian.c b/src/sig_stfl/lms/external/endian.c index 0c3c55b0fe..52f8439baf 100644 --- a/src/sig_stfl/lms/external/endian.c +++ b/src/sig_stfl/lms/external/endian.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #include "endian.h" void put_bigendian( void *target, unsigned long long value, size_t bytes ) { diff --git a/src/sig_stfl/lms/external/endian.h b/src/sig_stfl/lms/external/endian.h index a94177ddeb..09b9a609da 100644 --- a/src/sig_stfl/lms/external/endian.h +++ b/src/sig_stfl/lms/external/endian.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( ENDIAN_H_ ) #define ENDIAN_H_ diff --git a/src/sig_stfl/lms/external/hash.c b/src/sig_stfl/lms/external/hash.c index 0fe23ecc62..090dafd66c 100644 --- a/src/sig_stfl/lms/external/hash.c +++ b/src/sig_stfl/lms/external/hash.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #include #include "hash.h" #include "hss_zeroize.h" diff --git a/src/sig_stfl/lms/external/hash.h b/src/sig_stfl/lms/external/hash.h index 8b1891f108..bd42d3f0e9 100644 --- a/src/sig_stfl/lms/external/hash.h +++ b/src/sig_stfl/lms/external/hash.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( HASH_H__ ) #define HASH_H__ #include diff --git a/src/sig_stfl/lms/external/hss.c b/src/sig_stfl/lms/external/hss.c index c38455daed..fd5342a982 100644 --- a/src/sig_stfl/lms/external/hss.c +++ b/src/sig_stfl/lms/external/hss.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is an implementation of the HSS signature scheme from LMS * This is designed to be full-featured diff --git a/src/sig_stfl/lms/external/hss.h b/src/sig_stfl/lms/external/hss.h index 5ff8fc5c52..675089ddf0 100644 --- a/src/sig_stfl/lms/external/hss.h +++ b/src/sig_stfl/lms/external/hss.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined(HSS_H_) #define HSS_H_ diff --git a/src/sig_stfl/lms/external/hss_alloc.c b/src/sig_stfl/lms/external/hss_alloc.c index 9e6e7694c1..53eaa762e2 100644 --- a/src/sig_stfl/lms/external/hss_alloc.c +++ b/src/sig_stfl/lms/external/hss_alloc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is the code which allocates a working key (and initializes the fields * that are independent of the key) diff --git a/src/sig_stfl/lms/external/hss_aux.c b/src/sig_stfl/lms/external/hss_aux.c index 0d8777386f..a53b73a42b 100644 --- a/src/sig_stfl/lms/external/hss_aux.c +++ b/src/sig_stfl/lms/external/hss_aux.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is the implementation of the aux data within the HSS tree */ diff --git a/src/sig_stfl/lms/external/hss_aux.h b/src/sig_stfl/lms/external/hss_aux.h index 02e6677a38..8e5386b5b3 100644 --- a/src/sig_stfl/lms/external/hss_aux.h +++ b/src/sig_stfl/lms/external/hss_aux.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( HSS_AUX_H_ ) #define HSS_AUX_H_ diff --git a/src/sig_stfl/lms/external/hss_common.c b/src/sig_stfl/lms/external/hss_common.c index d07261dd26..4c764d6650 100644 --- a/src/sig_stfl/lms/external/hss_common.c +++ b/src/sig_stfl/lms/external/hss_common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is the code that is common between an HSS verifier, and a full HSS * implementation that both signs and verifies diff --git a/src/sig_stfl/lms/external/hss_common.h b/src/sig_stfl/lms/external/hss_common.h index a5640d669e..17729a6a97 100644 --- a/src/sig_stfl/lms/external/hss_common.h +++ b/src/sig_stfl/lms/external/hss_common.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( HSS_COMMON_H_ ) #define HSS_COMMON_H_ diff --git a/src/sig_stfl/lms/external/hss_compute.c b/src/sig_stfl/lms/external/hss_compute.c index 752a7e2868..f4b1f3c1cd 100644 --- a/src/sig_stfl/lms/external/hss_compute.c +++ b/src/sig_stfl/lms/external/hss_compute.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This includes some computation methods that are shared between different * subsystems of the HSS signature package diff --git a/src/sig_stfl/lms/external/hss_derive.c b/src/sig_stfl/lms/external/hss_derive.c index fc8833594a..d978fc5a66 100644 --- a/src/sig_stfl/lms/external/hss_derive.c +++ b/src/sig_stfl/lms/external/hss_derive.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is the file that contains the routines that generate various 'random' * values from the master seed. diff --git a/src/sig_stfl/lms/external/hss_derive.h b/src/sig_stfl/lms/external/hss_derive.h index 57ba4a1bc8..4886ab3f6a 100644 --- a/src/sig_stfl/lms/external/hss_derive.h +++ b/src/sig_stfl/lms/external/hss_derive.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( HSS_DERIVE_H_ ) #define HSS_DERIVE_H_ diff --git a/src/sig_stfl/lms/external/hss_generate.c b/src/sig_stfl/lms/external/hss_generate.c index 5d6880c267..28fcc9eaee 100644 --- a/src/sig_stfl/lms/external/hss_generate.c +++ b/src/sig_stfl/lms/external/hss_generate.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is the routine that generates the ephemeral ("working") key from the * short private value. It builds all the various current, building and diff --git a/src/sig_stfl/lms/external/hss_internal.h b/src/sig_stfl/lms/external/hss_internal.h index 4e7c53675d..3458e9ef85 100644 --- a/src/sig_stfl/lms/external/hss_internal.h +++ b/src/sig_stfl/lms/external/hss_internal.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( HSS_INTERNAL_H_ ) #define HSS_INTERNAL_H_ diff --git a/src/sig_stfl/lms/external/hss_keygen.c b/src/sig_stfl/lms/external/hss_keygen.c index 7a364b3f04..71da413325 100644 --- a/src/sig_stfl/lms/external/hss_keygen.c +++ b/src/sig_stfl/lms/external/hss_keygen.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #include #include #include "common_defs.h" diff --git a/src/sig_stfl/lms/external/hss_param.c b/src/sig_stfl/lms/external/hss_param.c index a1c20ab14c..838f7a8381 100644 --- a/src/sig_stfl/lms/external/hss_param.c +++ b/src/sig_stfl/lms/external/hss_param.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #include #include "hss.h" #include "hss_internal.h" diff --git a/src/sig_stfl/lms/external/hss_reserve.c b/src/sig_stfl/lms/external/hss_reserve.c index 7ef8585560..662df26628 100644 --- a/src/sig_stfl/lms/external/hss_reserve.c +++ b/src/sig_stfl/lms/external/hss_reserve.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #include #include "common_defs.h" #include "hss_internal.h" diff --git a/src/sig_stfl/lms/external/hss_reserve.h b/src/sig_stfl/lms/external/hss_reserve.h index 14f4da3096..d5c8284cf9 100644 --- a/src/sig_stfl/lms/external/hss_reserve.h +++ b/src/sig_stfl/lms/external/hss_reserve.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( HSS_RESERVE_H_ ) #define HSS_RESERVE_H_ diff --git a/src/sig_stfl/lms/external/hss_sign.c b/src/sig_stfl/lms/external/hss_sign.c index cbcbdf845b..44e850424e 100644 --- a/src/sig_stfl/lms/external/hss_sign.c +++ b/src/sig_stfl/lms/external/hss_sign.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is an implementation of the HSS signature scheme from LMS * This is the part that actually generates the signature diff --git a/src/sig_stfl/lms/external/hss_sign_inc.c b/src/sig_stfl/lms/external/hss_sign_inc.c index 6890a4a621..72a8a22c91 100644 --- a/src/sig_stfl/lms/external/hss_sign_inc.c +++ b/src/sig_stfl/lms/external/hss_sign_inc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is the code that implements the hierarchical part of the LMS hash * based signatures; in this case, incremental signing diff --git a/src/sig_stfl/lms/external/hss_sign_inc.h b/src/sig_stfl/lms/external/hss_sign_inc.h index cf4f25aec6..ddca5ea63e 100644 --- a/src/sig_stfl/lms/external/hss_sign_inc.h +++ b/src/sig_stfl/lms/external/hss_sign_inc.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( HSS_SIGN_INC_H_ ) #define HSS_SIGN_INC_H_ #include diff --git a/src/sig_stfl/lms/external/hss_thread.h b/src/sig_stfl/lms/external/hss_thread.h index 0fa48e958c..d2dcd8a3ea 100644 --- a/src/sig_stfl/lms/external/hss_thread.h +++ b/src/sig_stfl/lms/external/hss_thread.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( HSS_THREAD_H_ ) #define HSS_THREAD_H_ /* diff --git a/src/sig_stfl/lms/external/hss_thread_pthread.c b/src/sig_stfl/lms/external/hss_thread_pthread.c index b5f64d3764..1ea90cc161 100644 --- a/src/sig_stfl/lms/external/hss_thread_pthread.c +++ b/src/sig_stfl/lms/external/hss_thread_pthread.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #include "hss_thread.h" #include diff --git a/src/sig_stfl/lms/external/hss_thread_single.c b/src/sig_stfl/lms/external/hss_thread_single.c index d844385293..698e2dba6a 100644 --- a/src/sig_stfl/lms/external/hss_thread_single.c +++ b/src/sig_stfl/lms/external/hss_thread_single.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #include "hss_thread.h" #include "config.h" diff --git a/src/sig_stfl/lms/external/hss_verify.c b/src/sig_stfl/lms/external/hss_verify.c index b7f0f8b489..1b993aa9b4 100644 --- a/src/sig_stfl/lms/external/hss_verify.c +++ b/src/sig_stfl/lms/external/hss_verify.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is the code that implements the hierarchical part of the LMS hash * based signatures diff --git a/src/sig_stfl/lms/external/hss_verify.h b/src/sig_stfl/lms/external/hss_verify.h index 6561ee2a3c..d806900fe4 100644 --- a/src/sig_stfl/lms/external/hss_verify.h +++ b/src/sig_stfl/lms/external/hss_verify.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( HSS_VERIFY_H_ ) #define HSS_VERIFY_H_ diff --git a/src/sig_stfl/lms/external/hss_verify_inc.c b/src/sig_stfl/lms/external/hss_verify_inc.c index 4b5cf7e7a1..e12cf5c021 100644 --- a/src/sig_stfl/lms/external/hss_verify_inc.c +++ b/src/sig_stfl/lms/external/hss_verify_inc.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is the code that implements the hierarchical part of the LMS hash * based signatures; in this case, incremental verification diff --git a/src/sig_stfl/lms/external/hss_verify_inc.h b/src/sig_stfl/lms/external/hss_verify_inc.h index 6c3ec74da1..c09d006e4a 100644 --- a/src/sig_stfl/lms/external/hss_verify_inc.h +++ b/src/sig_stfl/lms/external/hss_verify_inc.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( HSS_VERIFY_INC_H_ ) #define HSS_VERIFY_INC_H_ #include diff --git a/src/sig_stfl/lms/external/hss_zeroize.c b/src/sig_stfl/lms/external/hss_zeroize.c index f2bd334903..9c31168069 100644 --- a/src/sig_stfl/lms/external/hss_zeroize.c +++ b/src/sig_stfl/lms/external/hss_zeroize.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #include "hss_zeroize.h" #include diff --git a/src/sig_stfl/lms/external/hss_zeroize.h b/src/sig_stfl/lms/external/hss_zeroize.h index bfe84db155..6571c4233d 100644 --- a/src/sig_stfl/lms/external/hss_zeroize.h +++ b/src/sig_stfl/lms/external/hss_zeroize.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( HSS_ZEROIZE_H_ ) #define HSS_ZEROIZE_H_ diff --git a/src/sig_stfl/lms/external/license.txt b/src/sig_stfl/lms/external/license.txt new file mode 100644 index 0000000000..4e5a9b9b1e --- /dev/null +++ b/src/sig_stfl/lms/external/license.txt @@ -0,0 +1,29 @@ +****************************************************************************** +Copyright (c) 2017 Cisco Systems, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. +Neither the name of the Cisco Systems, Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. +****************************************************************************** diff --git a/src/sig_stfl/lms/external/lm_common.c b/src/sig_stfl/lms/external/lm_common.c index 5976f4b589..6f37af627e 100644 --- a/src/sig_stfl/lms/external/lm_common.c +++ b/src/sig_stfl/lms/external/lm_common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is the code that implements the tree part of the LMS hash * based signatures diff --git a/src/sig_stfl/lms/external/lm_common.h b/src/sig_stfl/lms/external/lm_common.h index b577c22462..c7197fd5a0 100644 --- a/src/sig_stfl/lms/external/lm_common.h +++ b/src/sig_stfl/lms/external/lm_common.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined(LM_COMMON_H_) #define LM_COMMON_H_ diff --git a/src/sig_stfl/lms/external/lm_ots.h b/src/sig_stfl/lms/external/lm_ots.h index 4e33d9e9fd..f0cc42d11f 100644 --- a/src/sig_stfl/lms/external/lm_ots.h +++ b/src/sig_stfl/lms/external/lm_ots.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( LM_OTS_H_ ) #define LM_OTS_H_ diff --git a/src/sig_stfl/lms/external/lm_ots_common.c b/src/sig_stfl/lms/external/lm_ots_common.c index 45672e18b2..100eff606a 100644 --- a/src/sig_stfl/lms/external/lm_ots_common.c +++ b/src/sig_stfl/lms/external/lm_ots_common.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is the code that implements the one-time-signature part of the LMS hash * based signatures diff --git a/src/sig_stfl/lms/external/lm_ots_common.h b/src/sig_stfl/lms/external/lm_ots_common.h index fe6faebe98..db25d20999 100644 --- a/src/sig_stfl/lms/external/lm_ots_common.h +++ b/src/sig_stfl/lms/external/lm_ots_common.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( LM_OTS_COMMON_H_ ) #define LM_OTS_COMMON_H_ diff --git a/src/sig_stfl/lms/external/lm_ots_sign.c b/src/sig_stfl/lms/external/lm_ots_sign.c index ee8f56b0a2..7e0950c564 100644 --- a/src/sig_stfl/lms/external/lm_ots_sign.c +++ b/src/sig_stfl/lms/external/lm_ots_sign.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is the code that implements the one-time-signature part of the LMS hash * based signatures diff --git a/src/sig_stfl/lms/external/lm_ots_verify.c b/src/sig_stfl/lms/external/lm_ots_verify.c index 478f5ffe8d..b6e3980ab7 100644 --- a/src/sig_stfl/lms/external/lm_ots_verify.c +++ b/src/sig_stfl/lms/external/lm_ots_verify.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is the code that implements the one-time-signature part of the LMS hash * based signatures diff --git a/src/sig_stfl/lms/external/lm_ots_verify.h b/src/sig_stfl/lms/external/lm_ots_verify.h index dcf6551b0f..006ffe23bd 100644 --- a/src/sig_stfl/lms/external/lm_ots_verify.h +++ b/src/sig_stfl/lms/external/lm_ots_verify.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined( LM_OTS_VERIFY_H_ ) #define LM_OTS_VERIFY_H_ diff --git a/src/sig_stfl/lms/external/lm_verify.c b/src/sig_stfl/lms/external/lm_verify.c index 3ec4cb6599..50fa54f475 100644 --- a/src/sig_stfl/lms/external/lm_verify.c +++ b/src/sig_stfl/lms/external/lm_verify.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT /* * This is the code that implements the tree part of the LMS hash * based signatures diff --git a/src/sig_stfl/lms/external/lm_verify.h b/src/sig_stfl/lms/external/lm_verify.h index b7b6b0736d..ff67f51ac8 100644 --- a/src/sig_stfl/lms/external/lm_verify.h +++ b/src/sig_stfl/lms/external/lm_verify.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #if !defined(LM_VERIFY_H_) #define LM_VERIFY_H_ diff --git a/src/sig_stfl/lms/external/lms_namespace.h b/src/sig_stfl/lms/external/lms_namespace.h index c1b8f142ae..099a37c19b 100644 --- a/src/sig_stfl/lms/external/lms_namespace.h +++ b/src/sig_stfl/lms/external/lms_namespace.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT #ifndef _LMS_NAMESPACE_H #define _LMS_NAMESPACE_H From c3e57507e57cd406c420e35ec13cdd7214402be1 Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Fri, 19 Jan 2024 14:37:07 -0500 Subject: [PATCH 36/68] Add Apache 2.0 and MIT License to XMSS (#1662) * Add Apache 2.0 and MIT License to XMSS --- CONTRIBUTORS | 1 + src/sig_stfl/xmss/CMakeLists.txt | 2 +- src/sig_stfl/xmss/LICENSE | 12 ++++++++++++ src/sig_stfl/xmss/LICENSE-MIT | 9 +++++++++ src/sig_stfl/xmss/external/core_hash.c | 1 + src/sig_stfl/xmss/external/core_hash.h | 1 + src/sig_stfl/xmss/external/hash.c | 1 + src/sig_stfl/xmss/external/hash.h | 1 + src/sig_stfl/xmss/external/hash_address.c | 1 + src/sig_stfl/xmss/external/hash_address.h | 1 + src/sig_stfl/xmss/external/namespace.h | 1 + src/sig_stfl/xmss/external/params.c | 1 + src/sig_stfl/xmss/external/params.h | 1 + src/sig_stfl/xmss/external/utils.c | 1 + src/sig_stfl/xmss/external/utils.h | 1 + src/sig_stfl/xmss/external/wots.c | 1 + src/sig_stfl/xmss/external/wots.h | 1 + src/sig_stfl/xmss/external/xmss.c | 1 + src/sig_stfl/xmss/external/xmss.h | 1 + src/sig_stfl/xmss/external/xmss_commons.c | 1 + src/sig_stfl/xmss/external/xmss_commons.h | 1 + src/sig_stfl/xmss/external/xmss_core.c | 1 + src/sig_stfl/xmss/external/xmss_core.h | 1 + src/sig_stfl/xmss/external/xmss_core_fast.c | 1 + src/sig_stfl/xmss/sig_stfl_xmss.h | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_functions.c | 3 +-- .../xmss/sig_stfl_xmss_secret_key_functions.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c | 2 +- 56 files changed, 75 insertions(+), 34 deletions(-) create mode 100644 src/sig_stfl/xmss/LICENSE create mode 100644 src/sig_stfl/xmss/LICENSE-MIT diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 918394b8c4..83d9337ca5 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -34,5 +34,6 @@ Karolin Varner Sebastian Verschoor (University of Waterloo) Thom Wiggers (Radboud University) Dindyal Jeevesh Rishi (University of Mauritius / cyberstorm.mu) +Duc Tri Nguyen See additional contributors at https://github.com/open-quantum-safe/liboqs/graphs/contributors diff --git a/src/sig_stfl/xmss/CMakeLists.txt b/src/sig_stfl/xmss/CMakeLists.txt index e1d287472f..dc57732e16 100644 --- a/src/sig_stfl/xmss/CMakeLists.txt +++ b/src/sig_stfl/xmss/CMakeLists.txt @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: MIT +# SPDX-License-Identifier: Apache-2.0 AND MIT set(_XMSS_OBJS "") diff --git a/src/sig_stfl/xmss/LICENSE b/src/sig_stfl/xmss/LICENSE new file mode 100644 index 0000000000..90a1bebcfa --- /dev/null +++ b/src/sig_stfl/xmss/LICENSE @@ -0,0 +1,12 @@ +## License + +This XMSS reference implementation is Copyright (c) 2024 SandboxAQ and licensed under both the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) and [MIT License](LICENSE-MIT). + +Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. + +This XMSS reference implementation is based on the [XMSS reference implementation written by Andreas Hülsing and Joost Rijneveld](https://github.com/XMSS/xmss-reference#license) provided under the CC0 1.0 Universal Public Domain Dedication. + + +## Disclaimer + +The software and documentation are provided "as is" and SandboxAQ hereby disclaims all warranties, whether express, implied, statutory, or otherwise. SandboxAQ specifically disclaims, without limitation, all implied warranties of merchantability, fitness for a particular purpose, title, and non-infringement, and all warranties arising from course of dealing, usage, or trade practice. SandboxAQ makes no warranty of any kind that the software and documentation, or any products or results of the use thereof, will meet any person's requirements, operate without interruption, achieve any intended result, be compatible or work with any software, system or other services, or be secure, accurate, complete, free of harmful code, or error-free. \ No newline at end of file diff --git a/src/sig_stfl/xmss/LICENSE-MIT b/src/sig_stfl/xmss/LICENSE-MIT new file mode 100644 index 0000000000..7b1af979f6 --- /dev/null +++ b/src/sig_stfl/xmss/LICENSE-MIT @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright © 2024 SandboxAQ + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/sig_stfl/xmss/external/core_hash.c b/src/sig_stfl/xmss/external/core_hash.c index b27ad2ca9b..72fe4e9d5c 100644 --- a/src/sig_stfl/xmss/external/core_hash.c +++ b/src/sig_stfl/xmss/external/core_hash.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include #include "core_hash.h" diff --git a/src/sig_stfl/xmss/external/core_hash.h b/src/sig_stfl/xmss/external/core_hash.h index f350857d14..e292e4c06d 100644 --- a/src/sig_stfl/xmss/external/core_hash.h +++ b/src/sig_stfl/xmss/external/core_hash.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #ifndef CORE_HASH #define CORE_HASH diff --git a/src/sig_stfl/xmss/external/hash.c b/src/sig_stfl/xmss/external/hash.c index a6bac00724..557c8de7db 100644 --- a/src/sig_stfl/xmss/external/hash.c +++ b/src/sig_stfl/xmss/external/hash.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/external/hash.h b/src/sig_stfl/xmss/external/hash.h index 076b3b56ec..bd1e1c1202 100644 --- a/src/sig_stfl/xmss/external/hash.h +++ b/src/sig_stfl/xmss/external/hash.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #ifndef XMSS_HASH_H #define XMSS_HASH_H diff --git a/src/sig_stfl/xmss/external/hash_address.c b/src/sig_stfl/xmss/external/hash_address.c index 7aacee5a58..a9fec506b5 100644 --- a/src/sig_stfl/xmss/external/hash_address.c +++ b/src/sig_stfl/xmss/external/hash_address.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include "hash_address.h" diff --git a/src/sig_stfl/xmss/external/hash_address.h b/src/sig_stfl/xmss/external/hash_address.h index 50ad17885e..06f5c502bd 100644 --- a/src/sig_stfl/xmss/external/hash_address.h +++ b/src/sig_stfl/xmss/external/hash_address.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #ifndef XMSS_HASH_ADDRESS_H #define XMSS_HASH_ADDRESS_H diff --git a/src/sig_stfl/xmss/external/namespace.h b/src/sig_stfl/xmss/external/namespace.h index 468388aa3b..7bb7d05349 100644 --- a/src/sig_stfl/xmss/external/namespace.h +++ b/src/sig_stfl/xmss/external/namespace.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #ifndef XMSS_NAMESPACE_H #define XMSS_NAMESPACE_H diff --git a/src/sig_stfl/xmss/external/params.c b/src/sig_stfl/xmss/external/params.c index fdb9c76f2c..f9ba544e47 100644 --- a/src/sig_stfl/xmss/external/params.c +++ b/src/sig_stfl/xmss/external/params.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/external/params.h b/src/sig_stfl/xmss/external/params.h index 59b86d3da6..f75e3c97c5 100644 --- a/src/sig_stfl/xmss/external/params.h +++ b/src/sig_stfl/xmss/external/params.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #ifndef XMSS_PARAMS_H #define XMSS_PARAMS_H diff --git a/src/sig_stfl/xmss/external/utils.c b/src/sig_stfl/xmss/external/utils.c index 855f63654d..c2d76aba15 100644 --- a/src/sig_stfl/xmss/external/utils.c +++ b/src/sig_stfl/xmss/external/utils.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #include "utils.h" /** diff --git a/src/sig_stfl/xmss/external/utils.h b/src/sig_stfl/xmss/external/utils.h index fc5df634a6..14d8588ddc 100644 --- a/src/sig_stfl/xmss/external/utils.h +++ b/src/sig_stfl/xmss/external/utils.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #ifndef XMSS_UTILS_H #define XMSS_UTILS_H diff --git a/src/sig_stfl/xmss/external/wots.c b/src/sig_stfl/xmss/external/wots.c index 09db90e55c..a4bfae956d 100644 --- a/src/sig_stfl/xmss/external/wots.c +++ b/src/sig_stfl/xmss/external/wots.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/external/wots.h b/src/sig_stfl/xmss/external/wots.h index 0ee55b5b10..e0e3f1d0a9 100644 --- a/src/sig_stfl/xmss/external/wots.h +++ b/src/sig_stfl/xmss/external/wots.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #ifndef XMSS_WOTS_H #define XMSS_WOTS_H diff --git a/src/sig_stfl/xmss/external/xmss.c b/src/sig_stfl/xmss/external/xmss.c index 53ea10c24a..17b40f5627 100644 --- a/src/sig_stfl/xmss/external/xmss.c +++ b/src/sig_stfl/xmss/external/xmss.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include "params.h" diff --git a/src/sig_stfl/xmss/external/xmss.h b/src/sig_stfl/xmss/external/xmss.h index b21db845d3..53d21e2dbd 100644 --- a/src/sig_stfl/xmss/external/xmss.h +++ b/src/sig_stfl/xmss/external/xmss.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #ifndef XMSS_H #define XMSS_H diff --git a/src/sig_stfl/xmss/external/xmss_commons.c b/src/sig_stfl/xmss/external/xmss_commons.c index 5f3818d184..168e6ffed5 100644 --- a/src/sig_stfl/xmss/external/xmss_commons.c +++ b/src/sig_stfl/xmss/external/xmss_commons.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include #include diff --git a/src/sig_stfl/xmss/external/xmss_commons.h b/src/sig_stfl/xmss/external/xmss_commons.h index dbe841c6bf..26eb537ee3 100644 --- a/src/sig_stfl/xmss/external/xmss_commons.h +++ b/src/sig_stfl/xmss/external/xmss_commons.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #ifndef XMSS_COMMONS_H #define XMSS_COMMONS_H diff --git a/src/sig_stfl/xmss/external/xmss_core.c b/src/sig_stfl/xmss/external/xmss_core.c index daaf6aa6e4..4d7e8de096 100644 --- a/src/sig_stfl/xmss/external/xmss_core.c +++ b/src/sig_stfl/xmss/external/xmss_core.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include #include diff --git a/src/sig_stfl/xmss/external/xmss_core.h b/src/sig_stfl/xmss/external/xmss_core.h index bed99862c5..007c42172a 100644 --- a/src/sig_stfl/xmss/external/xmss_core.h +++ b/src/sig_stfl/xmss/external/xmss_core.h @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #ifndef XMSS_CORE_H #define XMSS_CORE_H diff --git a/src/sig_stfl/xmss/external/xmss_core_fast.c b/src/sig_stfl/xmss/external/xmss_core_fast.c index 70b4b9774e..71b0f471ca 100644 --- a/src/sig_stfl/xmss/external/xmss_core_fast.c +++ b/src/sig_stfl/xmss/external/xmss_core_fast.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index d1663f1720..4166cafcb7 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #ifndef OQS_SIG_STFL_XMSS_H #define OQS_SIG_STFL_XMSS_H diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c index bfdf3e023b..a19cdc7527 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c @@ -1,5 +1,4 @@ -// SPDX-License-Identifier: MIT - +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c index cfeab4548e..40ad786c4e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c index 849839ef0d..ebcf4f7608 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c index 53fd443a44..d401b2aa75 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c index a95007730b..5cc2804754 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c index 6c382dcabb..b77a8c8436 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c index c9b2a3e51e..695d5de288 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c index 817004658b..f4b579deec 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c index 971b3de4ed..d216a02a15 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c index 93abb5d6e2..bb0bd4684b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c index 1e320ed7ba..b601e09a4e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c index d67c17015b..33b685c20b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c index e938187119..02781a8600 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c index 15f591466e..f4d856c34a 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c index d1aa9e923d..a3a2257b1c 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c index ab3c2d6765..3d90674459 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c index 62df91e621..0305764855 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c index 0ff6054cc6..19db158709 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c index 721eba5f9f..0f17088d4b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c index 9433c61944..b985951514 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c index edfc7239d6..60e3cae071 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c index 1d66ba99cc..fc5cf35c23 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c index e445cb05f8..6f055e949b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c index 13e9ae5d8e..98a085ce22 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c index 1e1ac0915d..37ee00a20b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c index 3bc608f484..a4175423a7 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c index 0bee9336da..bbadceea0f 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c index 994393935f..14b3b50ffb 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c index c60eecd101..74c378ac7e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c index 5c3242a8e1..f7bae2956c 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c index 3874589c2f..33f714d702 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: MIT +// SPDX-License-Identifier: Apache-2.0 AND MIT #include #include From e7a83c7167032084a9fe8ab2ae86f4b2e19c4bf5 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Tue, 30 Jan 2024 11:45:30 -0500 Subject: [PATCH 37/68] Disable Stateful Signatures in the build by default (#1676) * Disable stateful signature as default. When enabled, key and signature generation is disabled by default. Only signature verification is allowed. Key and signature generation can be enabled by defining OQS_ENABLE_SIG_STFL_KEY_SIG_GEN * Fixed format * Address unused variables * Update .CMake/alg_support.cmake Co-authored-by: Spencer Wilson * Update CONFIGURE.md Co-authored-by: Spencer Wilson * Update example_sig_stfl.c Fixed compile error, unused function. Added a negative test when stateful signature is disabled. * Fix build error. Allow some key generation tests to run as negative tests when key and sig gen is off * Fix format * Fix build error * Fix build error --------- Co-authored-by: Spencer Wilson --- .CMake/alg_support.cmake | 22 ++++- CONFIGURE.md | 18 ++++ src/oqsconfig.h.cmake | 4 + src/sig_stfl/lms/external/hss_keygen.c | 3 + src/sig_stfl/lms/external/hss_sign_inc.c | 3 + src/sig_stfl/lms/sig_stfl_lms_functions.c | 30 +++++++ src/sig_stfl/sig_stfl.c | 17 ++++ src/sig_stfl/xmss/external/xmss.c | 22 +++++ src/sig_stfl/xmss/sig_stfl_xmss_functions.c | 8 +- .../xmss/sig_stfl_xmss_secret_key_functions.c | 4 + src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c | 8 +- tests/example_sig_stfl.c | 33 ++++++- tests/kat_sig_stfl.c | 38 ++++++++ tests/test_sig_stfl.c | 88 +++++++++++++++++-- 14 files changed, 285 insertions(+), 13 deletions(-) diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index d1f9e8daae..bcf6150e7e 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -497,7 +497,7 @@ endif() ##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_ADD_ENABLE_BY_ALG_END -option(OQS_ENABLE_SIG_STFL_XMSS "Enable XMSS algorithm family" ON) +option(OQS_ENABLE_SIG_STFL_XMSS "Enable XMSS algorithm family" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha256_h10 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha256_h16 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha256_h20 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) @@ -528,7 +528,7 @@ cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6 "" ON "OQS_ENAB cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) -option(OQS_ENABLE_SIG_STFL_LMS "Enable LMS algorithm family" ON) +option(OQS_ENABLE_SIG_STFL_LMS "Enable LMS algorithm family" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h5_w1 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h5_w2 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h5_w4 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) @@ -563,6 +563,24 @@ cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h10_w8 "" ON "OQS_E cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h15_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h20_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +option(OQS_ENABLE_SIG_STFL_KEY_SIG_GEN "Enable stateful key and signature generation for research and experimentation" OFF) +cmake_dependent_option(OQS_ALLOW_SFTL_KEY_AND_SIG_GEN "" ON "OQS_ENABLE_SIG_STFL_KEY_SIG_GEN" OFF) + +if (${OQS_ENABLE_SIG_STFL_KEY_SIG_GEN} AND ${OQS_ENABLE_SIG_STFL_XMSS}) + set(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN ON) +else() + set(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN OFF) +endif() + +if (${OQS_ENABLE_SIG_STFL_KEY_SIG_GEN} AND ${OQS_ENABLE_SIG_STFL_LMS}) + set(OQS_ALLOW_LMS_KEY_AND_SIG_GEN ON) +else() + set(OQS_ALLOW_LMS_KEY_AND_SIG_GEN OFF) +endif() + +if(OQS_ALLOW_SFTL_KEY_AND_SIG_GEN STREQUAL "ON") + message(STATUS "Experimental stateful key and signature generation is enabled. Ensure secret keys are securely stored to prevent multiple simultaneous sign operations.") +endif() if((OQS_MINIMAL_BUILD STREQUAL "ON")) message(FATAL_ERROR "OQS_MINIMAL_BUILD option ${OQS_MINIMAL_BUILD} no longer supported") diff --git a/CONFIGURE.md b/CONFIGURE.md index ffc40273e2..89bd01e042 100644 --- a/CONFIGURE.md +++ b/CONFIGURE.md @@ -121,6 +121,24 @@ Dynamically load OpenSSL through `dlopen`. When using liboqs from other cryptogr Only has an effect if the system supports `dlopen` and ELF binary format, such as Linux or BSD family. +## Stateful Hash Based Signatures + +XMSS and LMS are the two supported Hash-Based Signatures schemes. +`OQS_ENABLE_SIG_STFL_XMSS` and `OQS_ENABLE_SIG_STFL_LMS` control these algorithms, which are disabled by default. +A thrid variable, `OQS_ENABLE_SIG_STFL_KEY_SIG_GEN`, also controls the ability to generate keys and signatures. This is also disabled by default. +Each of these variables can be set to `ON` or `OFF`. +When all three are `ON`, stateful signatures are fully functional and can generate key pairs, sign data, and verify signatures. +If `OQS_ENABLE_SIG_STFL_KEY_SIG_GEN` is `OFF` signature verification is the only functional operation. + +Standards bodies, such as NIST, recommend that key and signature generation only by done in hardware in order to best enforce the one-time use of secret keys. +Keys stored in a file system are extremely susceptible to simultaneous use. +When enabled in this library a warning message will be generated by the config process. + +By default, +- `OQS_ENABLE_SIG_STFL_XMSS` is `OFF` +- `OQS_ENABLE_SIG_STFL_LMS` is `OFF` +- `OQS_ENABLE_SIG_STFL_KEY_SIG_GEN` is `OFF`. + **Default**: `OFF`. ## OQS_OPT_TARGET diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index 9d533a8b27..ac13bf093c 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -237,3 +237,7 @@ #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 1 +#cmakedefine OQS_ENABLE_SIG_STFL_KEY_SIG_GEN 1 +#cmakedefine OQS_ALLOW_SFTL_KEY_AND_SIG_GEN 1 +#cmakedefine OQS_ALLOW_XMSS_KEY_AND_SIG_GEN 1 +#cmakedefine OQS_ALLOW_LMS_KEY_AND_SIG_GEN 1 \ No newline at end of file diff --git a/src/sig_stfl/lms/external/hss_keygen.c b/src/sig_stfl/lms/external/hss_keygen.c index 71da413325..d85d9626c7 100644 --- a/src/sig_stfl/lms/external/hss_keygen.c +++ b/src/sig_stfl/lms/external/hss_keygen.c @@ -10,6 +10,7 @@ #include "hss_thread.h" #include "lm_common.h" #include "lm_ots_common.h" +#include /* Count the number of 1 bits at the end (lsbits) of the integer */ /* Do it in the obvious way; straightline code may be faster (no */ @@ -51,6 +52,7 @@ static int trailing_1_bits(merkle_index_t n) { * * This returns true on success, false on failure */ +#ifdef OQS_ALLOW_LMS_KEY_AND_SIG_GEN bool hss_generate_private_key( bool (*generate_random)(void *output, size_t length), unsigned levels, @@ -356,6 +358,7 @@ bool hss_generate_private_key( free(temp_buffer); // IGNORE free-check return true; } +#endif /* * The length of the private key diff --git a/src/sig_stfl/lms/external/hss_sign_inc.c b/src/sig_stfl/lms/external/hss_sign_inc.c index 72a8a22c91..ab3112ee03 100644 --- a/src/sig_stfl/lms/external/hss_sign_inc.c +++ b/src/sig_stfl/lms/external/hss_sign_inc.c @@ -16,6 +16,7 @@ #include "hss_internal.h" #include "hss_sign_inc.h" #include "hss_derive.h" +#include /* * Start the process of creating an HSS signature incrementally. Parameters: @@ -28,6 +29,7 @@ * this_is_the_last_signature - if non-NULL, this will be set if this * signature is the last for this private key */ +#ifdef OQS_ALLOW_LMS_KEY_AND_SIG_GEN bool hss_sign_init( struct hss_sign_inc *ctx, struct hss_working_key *w, @@ -217,3 +219,4 @@ bool hss_sign_finalize( hss_zeroize( seed_buff, sizeof seed_buff ); return success; } +#endif diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index be709fc71c..d0b1559e2d 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -11,6 +11,12 @@ #include "external/hss_internal.h" #include "sig_stfl_lms_wrap.h" +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif + #define DEFAULT_AUX_DATA 10916 /* Use 10+k of aux data (which works well */ /* with the above default parameter set) */ /** @@ -46,6 +52,12 @@ typedef struct OQS_LMS_KEY_DATA { void *context; } oqs_lms_key_data; +#ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(UNUSED uint8_t *signature, UNUSED size_t *signature_length, UNUSED const uint8_t *message, + UNUSED size_t message_len, UNUSED OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_ERROR; +} +#else OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signature_length, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { OQS_STATUS status = OQS_ERROR; @@ -117,6 +129,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signatu } return status; } +#endif OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { @@ -219,6 +232,11 @@ bool LMS_randombytes(void *buffer, size_t length) { return true; } +#ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN +int oqs_sig_stfl_lms_keypair(UNUSED uint8_t *pk, UNUSED OQS_SIG_STFL_SECRET_KEY *sk, UNUSED const uint32_t oid) { + return -1; +} +#else int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uint32_t oid) { int ret = -1; @@ -522,7 +540,14 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uin ret = 0; return ret; } +#endif +#ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN +int oqs_sig_stfl_lms_sign(UNUSED OQS_SIG_STFL_SECRET_KEY *sk, UNUSED uint8_t *sm, UNUSED size_t *smlen, + UNUSED const uint8_t *m, UNUSED size_t mlen) { + return -1; +} +#else int oqs_sig_stfl_lms_sign(OQS_SIG_STFL_SECRET_KEY *sk, uint8_t *sm, size_t *smlen, const uint8_t *m, size_t mlen) { @@ -598,6 +623,7 @@ int oqs_sig_stfl_lms_sign(OQS_SIG_STFL_SECRET_KEY *sk, return 0; } +#endif int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, const uint8_t *sm, size_t smlen, @@ -714,6 +740,10 @@ OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_ return OQS_ERROR; } +#ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN + return OQS_ERROR; +#endif + aux_buf_len = sk_len - lms_sk_len; if (sk->secret_key_data) { // Key data already present diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index e3a9d0f71c..0f6ebff7af 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -878,21 +878,38 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { } OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { +#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN + (void)sig; + (void)public_key; + (void)secret_key; + return OQS_ERROR; +#else if (sig == NULL || sig->keypair == NULL || sig->keypair(public_key, secret_key) != 0) { return OQS_ERROR; } else { return OQS_SUCCESS; } return OQS_ERROR; +#endif } OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { +#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN + (void)sig; + (void)signature; + (void)signature_len; + (void)message; + (void)message_len; + (void)secret_key; + return OQS_ERROR; +#else if (sig == NULL || sig->sign == NULL || sig->sign(signature, signature_len, message, message_len, secret_key) != 0) { return OQS_ERROR; } else { return OQS_SUCCESS; } +#endif } OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/external/xmss.c b/src/sig_stfl/xmss/external/xmss.c index 17b40f5627..71d3f0a463 100644 --- a/src/sig_stfl/xmss/external/xmss.c +++ b/src/sig_stfl/xmss/external/xmss.c @@ -6,6 +6,13 @@ #include "utils.h" #include "xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + /* This file provides wrapper functions that take keys that include OIDs to identify the parameter set to be used. After setting the parameters accordingly it falls back to the regular XMSS core functions. */ @@ -25,6 +32,12 @@ it falls back to the regular XMSS core functions. */ * @return an integer value. If the function executes successfully, it will return 0. If there is an * error, it will return -1. */ +#ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN +int xmss_keypair(XMSS_UNUSED_ATT unsigned char *pk, XMSS_UNUSED_ATT unsigned char *sk, XMSS_UNUSED_ATT const uint32_t oid) +{ + return -1; +} +#else int xmss_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid) { xmss_params params; @@ -42,6 +55,7 @@ int xmss_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid) } return xmss_core_keypair(¶ms, pk + XMSS_OID_LEN, sk + XMSS_OID_LEN); } +#endif /** * This function parses the XMSS OID from a secret key, uses it to determine the XMSS parameters, and @@ -57,6 +71,13 @@ int xmss_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid) * @return an integer value. If the function executes successfully, it will return 0. If there is an * error, it will return -1. */ +#ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN +int xmss_sign(XMSS_UNUSED_ATT unsigned char *sk, XMSS_UNUSED_ATT unsigned char *sm, XMSS_UNUSED_ATT unsigned long long *smlen, + XMSS_UNUSED_ATT const unsigned char *m, XMSS_UNUSED_ATT unsigned long long mlen) +{ + return -1; +} +#else int xmss_sign(unsigned char *sk, unsigned char *sm, unsigned long long *smlen, const unsigned char *m, unsigned long long mlen) @@ -73,6 +94,7 @@ int xmss_sign(unsigned char *sk, } return xmss_core_sign(¶ms, sk + XMSS_OID_LEN, sm, smlen, m, mlen); } +#endif /** * The function xmss_sign_open verifies a signature and retrieves the original message using the XMSS diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c index a19cdc7527..ce2df38238 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c @@ -14,7 +14,12 @@ #endif /* -------------- XMSS -------------- */ - +#ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sign(XMSS_UNUSED_ATT uint8_t *signature, XMSS_UNUSED_ATT size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, + XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_ERROR; +} +#else OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { OQS_STATUS status = OQS_SUCCESS; @@ -59,6 +64,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sign(uint8_t *signature, size_t *signat return status; } +#endif OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c index 40ad786c4e..4f6413a98b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c @@ -112,6 +112,10 @@ OQS_STATUS OQS_SECRET_KEY_XMSS_inner_serialize_key(uint8_t **sk_buf_ptr, size_t /* Deserialize XMSS byte string into an XMSS secret key data. */ OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, XMSS_UNUSED_ATT void *context) { +#ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN + return OQS_ERROR; +#endif + if (sk == NULL || sk_buf == NULL || (sk_len != sk->length_secret_key)) { return OQS_ERROR; } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c index a3a2257b1c..f5d99705d3 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c @@ -15,7 +15,12 @@ #endif /* -------------- XMSSMT -------------- */ - +#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(XMSS_UNUSED_ATT uint8_t *signature, XMSS_UNUSED_ATT size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, + XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_ERROR; +} +#else OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { OQS_STATUS status = OQS_SUCCESS; @@ -60,6 +65,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(uint8_t *signature, size_t *sign return status; } +#endif OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/tests/example_sig_stfl.c b/tests/example_sig_stfl.c index cbabee8b14..cdcd9f6472 100644 --- a/tests/example_sig_stfl.c +++ b/tests/example_sig_stfl.c @@ -121,13 +121,44 @@ static OQS_STATUS stfl_example(char *method_name) { } int main(void) { +#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN OQS_init(); - if (stfl_example((char *)"XMSS-SHA2_10_256") == OQS_SUCCESS && stfl_example((char *)"LMS_SHA256_H10_W4") == OQS_SUCCESS) { + printf("Stateful signature algorithms key and signature generation is not enabled.\n"); + if (stfl_example((char *)"XMSS-SHA2_10_256") == OQS_ERROR && stfl_example((char *)"LMS_SHA256_H10_W4") == OQS_ERROR) { OQS_destroy(); return EXIT_SUCCESS; } else { OQS_destroy(); return EXIT_FAILURE; } +#else + OQS_STATUS lms_status; + OQS_STATUS xmss_status; + OQS_init(); + xmss_status = stfl_example((char *)"XMSS-SHA2_10_256"); + lms_status = stfl_example((char *)"LMS_SHA256_H10_W4"); + OQS_destroy(); + +#ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN + if (xmss_status == OQS_ERROR) { + xmss_status = OQS_SUCCESS; + } else { + xmss_status = OQS_ERROR; + } +#endif +#ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN + if (lms_status == OQS_ERROR) { + lms_status = OQS_SUCCESS; + } else { + lms_status = OQS_ERROR; + } +#endif + if ((xmss_status == OQS_SUCCESS) && (lms_status == OQS_SUCCESS)) { + return EXIT_SUCCESS; + } else { + return EXIT_FAILURE; + } +#endif } + diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index 457a5c3778..23ec293e4b 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -243,6 +243,7 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { OQS_fprintBstr(fh, "msg = ", msg, msg_len); +#ifdef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN rc = OQS_SIG_STFL_sign(sig, signature, &signature_len, msg, msg_len, secret_key); if (rc != OQS_SUCCESS) { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sign failed!\n", method_name); @@ -289,7 +290,44 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { ret = OQS_SUCCESS; goto cleanup; +#else + /* + * Signature generation is disabled so only signature verification can be tested. + */ + signature_len = sig->length_signature; + if (!ReadHex(fp_rsp, signature_kat, signature_len, "sm = ")) { + fprintf(stderr, "ERROR: unable to read 'msg' from <%s>\n", katfile); + goto err; + } + + //Echo back the signature read to keep the test tool happy. + fprintf(fh, "smlen = %zu\n", sig->length_signature); + fprintBstr(fh, "sm = ", signature_kat, sig->length_signature); + rc = OQS_SIG_STFL_verify(sig, msg, msg_len, signature_kat, signature_len, public_key); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_verify failed!\n", method_name); + goto err; + } + + rc = OQS_SIG_STFL_sigs_remaining(sig, &sigs_remain, secret_key); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_remaining failed!\n", method_name); + goto err; + } + //Update value to keep the test tool happy + fprintf(fh, "remain = %llu\n", sigs_remain - 1); + + rc = OQS_SIG_STFL_sigs_total(sig, &sigs_maximum, secret_key); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_total failed!\n", method_name); + goto err; + } + fprintf(fh, "max = %llu", sigs_maximum); + + ret = OQS_SUCCESS; + goto cleanup; +#endif err: ret = OQS_ERROR; goto cleanup; diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index a8b3e7962d..f0a51aac74 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -321,11 +321,13 @@ OQS_STATUS sig_stfl_KATs_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_ } else { goto from_keygen; } - +#ifdef OQS_ENABLE_SIG_STFL_XMSS from_kats: return sig_stfl_keypair_from_KATs(sig, public_key, secret_key, katfile); +#endif from_keygen: + (void)(katfile); return sig_stfl_keypair_from_keygen(sig, public_key, secret_key); } @@ -947,7 +949,7 @@ typedef struct thread_data { const char *alg_name; const char *katfile; OQS_STATUS rc; - OQS_STATUS rc1; + // OQS_STATUS rc1; } thread_data_t; typedef struct lock_test_data { @@ -980,13 +982,46 @@ void *test_create_keys(void *arg) { return NULL; } -void *test_wrapper(void *arg) { +void *test_correctness_wrapper(void *arg) { struct thread_data *td = arg; td->rc = sig_stfl_test_correctness(td->alg_name, td->katfile); - td->rc1 = sig_stfl_test_secret_key(td->alg_name, td->katfile); return NULL; } + +void *test_secret_key_wrapper(void *arg) { + struct thread_data *td = arg; + td->rc = sig_stfl_test_secret_key(td->alg_name, td->katfile); + return NULL; +} +#endif + +/* + * When key and signature generation is off + * these operations should fail. So flip the results. + */ +static OQS_STATUS update_test_result( OQS_STATUS rc, int xmss_or_lms) { + OQS_STATUS rc_update = rc; + if (xmss_or_lms) { + ; +#ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN + if (rc_update == OQS_ERROR) { + rc_update = OQS_SUCCESS; + } else { + rc_update = OQS_ERROR; + } #endif + } else { + ; +#ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN + if (rc_update == OQS_ERROR) { + rc_update = OQS_SUCCESS; + } else { + rc_update = OQS_ERROR; + } +#endif + } + return rc_update; +} int main(int argc, char **argv) { OQS_init(); @@ -1012,11 +1047,31 @@ int main(int argc, char **argv) { const char *alg_name = argv[1]; const char *katfile = argv[2]; + int is_xmss = 0; + if (strstr(alg_name, "XMSS") != NULL) { + is_xmss = 1; + } + /* + * Tests executed by CI/DI only run algoritms that have been emabled. + * + */ if (!OQS_SIG_STFL_alg_is_enabled(alg_name)) { printf("Stateful signature algorithm %s not enabled!\n", alg_name); OQS_destroy(); - return EXIT_FAILURE; + if (is_xmss) { +#ifndef OQS_ENABLE_SIG_STFL_XMSS + return EXIT_SUCCESS; +#else + return EXIT_FAILURE; +#endif + } else { +#ifndef OQS_ENABLE_SIG_STFL_LMS + return EXIT_SUCCESS; +#else + return EXIT_FAILURE; +#endif + } } #ifdef OQS_ENABLE_TEST_CONSTANT_TIME @@ -1037,7 +1092,9 @@ int main(int argc, char **argv) { pthread_t sign_key_thread; pthread_t query_key_thread; - thread_data_t td = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR, .rc1 = OQS_ERROR}; + thread_data_t td = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR}; + thread_data_t td_2 = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR}; + lock_test_data_t td_create = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR}; lock_test_data_t td_sign = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR}; lock_test_data_t td_query = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR}; @@ -1057,14 +1114,23 @@ int main(int argc, char **argv) { goto err; } - if (pthread_create(&thread, NULL, test_wrapper, &td)) { + if (pthread_create(&thread, NULL, test_correctness_wrapper, &td)) { fprintf(stderr, "ERROR: Creating pthread for test_wrapper\n"); exit_status = EXIT_FAILURE; goto err; } pthread_join(thread, NULL); rc = td.rc; - rc1 = td.rc1; + rc = update_test_result(rc, is_xmss); + + if (pthread_create(&thread, NULL, test_secret_key_wrapper, &td_2)) { + fprintf(stderr, "ERROR: Creating pthread for test_wrapper_2\n"); + exit_status = EXIT_FAILURE; + goto err; + } + pthread_join(thread, NULL); + rc1 = td_2.rc; + rc1 = update_test_result(rc1, is_xmss); if (pthread_create(&create_key_thread, NULL, test_create_keys, &td_create)) { fprintf(stderr, "ERROR: Creating pthread for test_create_keys\n"); @@ -1073,6 +1139,7 @@ int main(int argc, char **argv) { } pthread_join(create_key_thread, NULL); rc_create = td_create.rc; + rc_create = update_test_result(rc_create, is_xmss); if (pthread_create(&sign_key_thread, NULL, test_sig_gen, &td_sign)) { fprintf(stderr, "ERROR: Creating pthread for test_sig_gen\n"); @@ -1081,6 +1148,7 @@ int main(int argc, char **argv) { } pthread_join(sign_key_thread, NULL); rc_sign = td_sign.rc; + rc_sign = update_test_result(rc_sign, is_xmss); if (pthread_create(&query_key_thread, NULL, test_query_key, &td_query)) { fprintf(stderr, "ERROR: Creating pthread for test_query_key\n"); @@ -1089,6 +1157,7 @@ int main(int argc, char **argv) { } pthread_join(query_key_thread, NULL); rc_query = td_query.rc; + rc_query = update_test_result(rc_query, is_xmss); err: if (test_sk_lock) { @@ -1121,6 +1190,9 @@ int main(int argc, char **argv) { rc1 = sig_stfl_test_secret_key(alg_name, katfile); OQS_destroy(); + rc = update_test_result(rc, is_xmss); + rc1 = update_test_result(rc1, is_xmss); + if (rc != OQS_SUCCESS || rc1 != OQS_SUCCESS) { return EXIT_FAILURE; From 6c81bae0099c069c5e9b08fb0ea87d40302c07b9 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Thu, 8 Feb 2024 14:09:28 -0500 Subject: [PATCH 38/68] Na stateful macro (#1687) * Use OQS_SIG data struct for verify only capability. Refactor code via macro * Fix format issues * Fix build error * Fix build error * Remove comments --- src/sig_stfl/lms/sig_stfl_lms.c | 2954 +---------------- src/sig_stfl/lms/sig_stfl_lms.h | 17 - src/sig_stfl/sig_stfl.c | 17 + src/sig_stfl/sig_stfl.h | 4 + src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c | 73 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c | 73 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c | 73 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c | 74 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c | 73 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c | 73 +- .../xmss/sig_stfl_xmss_shake128_h10.c | 74 +- .../xmss/sig_stfl_xmss_shake128_h16.c | 75 +- .../xmss/sig_stfl_xmss_shake128_h20.c | 74 +- .../xmss/sig_stfl_xmss_shake256_h10.c | 74 +- .../xmss/sig_stfl_xmss_shake256_h16.c | 75 +- .../xmss/sig_stfl_xmss_shake256_h20.c | 74 +- src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c | 85 + .../xmss/sig_stfl_xmssmt_sha256_h20_2.c | 74 +- .../xmss/sig_stfl_xmssmt_sha256_h20_4.c | 74 +- .../xmss/sig_stfl_xmssmt_sha256_h40_2.c | 74 +- .../xmss/sig_stfl_xmssmt_sha256_h40_4.c | 74 +- .../xmss/sig_stfl_xmssmt_sha256_h40_8.c | 73 +- .../xmss/sig_stfl_xmssmt_sha256_h60_12.c | 72 +- .../xmss/sig_stfl_xmssmt_sha256_h60_3.c | 74 +- .../xmss/sig_stfl_xmssmt_sha256_h60_6.c | 73 +- .../xmss/sig_stfl_xmssmt_shake128_h20_2.c | 73 +- .../xmss/sig_stfl_xmssmt_shake128_h20_4.c | 73 +- .../xmss/sig_stfl_xmssmt_shake128_h40_2.c | 73 +- .../xmss/sig_stfl_xmssmt_shake128_h40_4.c | 73 +- .../xmss/sig_stfl_xmssmt_shake128_h40_8.c | 73 +- .../xmss/sig_stfl_xmssmt_shake128_h60_12.c | 74 +- .../xmss/sig_stfl_xmssmt_shake128_h60_3.c | 73 +- .../xmss/sig_stfl_xmssmt_shake128_h60_6.c | 73 +- tests/test_sig_stfl.c | 5 +- 34 files changed, 340 insertions(+), 4800 deletions(-) create mode 100644 src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c diff --git a/src/sig_stfl/lms/sig_stfl_lms.c b/src/sig_stfl/lms/sig_stfl_lms.c index 9e65a5e442..7e5e99ea45 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.c +++ b/src/sig_stfl/lms/sig_stfl_lms.c @@ -7,6 +7,50 @@ #include "sig_stfl_lms_wrap.h" #include "sig_stfl_lms.h" +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); + +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); + +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); + +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); + + +// OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void); +// OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +// OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w2_new(void); +// OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W2_new(void); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); + +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); + /* Convert LMS secret key object to byte string */ static OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); @@ -15,2858 +59,212 @@ static OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk static void OQS_SECRET_KEY_LMS_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); -// ======================== LMS-SHA256 H5/W1 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h5_w1) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h5_w1; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h5_w1; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; +// ======================== LMS Maccros ======================== // +// macro to en/disable OQS_SIG_STFL-only structs used only in sig&gen case: +#ifdef OQS_ALLOW_LMS_KEY_AND_SIG_GEN +#define LMS_SIGGEN(lms_variant, LMS_VARIANT) \ + sig->oid = OQS_LMS_ID_##lms_variant; \ + sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; \ + sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; \ + sig->keypair = OQS_SIG_STFL_alg_lms_##lms_variant##_keypair; \ + sig->sign = OQS_SIG_STFL_alg_lms_sign; +#else +#define LMS_SIGGEN(lms_variant, LMS_VARIANT) +#endif +// generator for all alg-specific functions: +#define LMS_ALG(lms_variant, LMS_VARIANT) \ +OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_##lms_variant##_new(void) { \ +\ + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); \ + if (sig == NULL) { \ + return NULL; \ + } \ + memset(sig, 0, sizeof(OQS_SIG_STFL)); \ +\ + LMS_SIGGEN(lms_variant, ) \ + sig->method_name = OQS_SIG_STFL_alg_lms_##lms_variant; \ + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; \ + sig->euf_cma = true; \ +\ + sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; \ + sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; \ + sig->length_signature = OQS_SIG_STFL_alg_lms_##lms_variant##_length_signature; \ +\ + sig->verify = OQS_SIG_STFL_alg_lms_verify; \ +\ + return sig;\ +} \ +\ +OQS_STATUS OQS_SIG_STFL_alg_lms_##lms_variant##_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) {\ + if (secret_key == NULL || public_key == NULL) {\ + return OQS_ERROR;\ + }\ +\ + if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_##lms_variant) != 0) {\ + return OQS_ERROR;\ + }\ + return OQS_SUCCESS;\ +}\ +\ +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_##LMS_VARIANT##_new(void) {\ +\ + OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY));\ + if (sk == NULL) {\ + return NULL;\ + }\ + memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY));\ +\ + sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key;\ +\ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key;\ +\ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key;\ +\ + sk->lock_key = NULL;\ +\ + sk->unlock_key = NULL;\ +\ + sk->secure_store_scrt_key = NULL;\ +\ + sk->free_key = OQS_SECRET_KEY_LMS_free;\ +\ + sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb;\ +\ + return sk;\ } -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} +// ======================== LMS-SHA256 H5/W1 ======================== // +LMS_ALG(sha256_h5_w1, SHA256_H5_W1) // ======================== LMS-SHA256 H5/W2 ======================== // -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h5_w2) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w2_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h5_w2; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h5_w2; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h5_w2_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W2_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} +LMS_ALG(sha256_h5_w2, SHA256_H5_W2) // ======================== LMS-SHA256 H5/W4 ======================== // -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h5_w4) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w4_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h5_w4; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h5_w4; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h5_w4_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W4_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} +LMS_ALG(sha256_h5_w4, SHA256_H5_W4) // ======================== LMS-SHA256 H5/W8 ======================== // -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h5_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h5_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h5_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h5_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} +LMS_ALG(sha256_h5_w8, SHA256_H5_W8) // ======================== LMS-SHA256 H10/W1 ======================== // -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w1) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w1_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h10_w1; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w1; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h10_w1_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w1_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w1_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w1_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W1_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w1_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} +LMS_ALG(sha256_h10_w1, SHA256_H10_W1) // ======================== LMS-SHA256 H10/W2 ======================== // -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w2) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w2_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h10_w2; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w2; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w2_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W2_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w2_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} +LMS_ALG(sha256_h10_w2, SHA256_H10_W2) // ======================== LMS-SHA256 H10/W4 ======================== // -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w4) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h10_w4; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w4; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w4_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w4_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} +LMS_ALG(sha256_h10_w4, SHA256_H10_W4) // ======================== LMS-SHA256 H10/W8 ======================== // -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h10_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h10_w8_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} +LMS_ALG(sha256_h10_w8, SHA256_H10_W8) // ======================== LMS-SHA256 H15/W1 ======================== // -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w1) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} +LMS_ALG(sha256_h15_w1, SHA256_H15_W1) -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w1_new(void) { +// ======================== LMS-SHA256 H15/W2 ======================== // - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); +LMS_ALG(sha256_h15_w2, SHA256_H15_W2) - sig->oid = OQS_LMS_ID_sha256_h15_w1; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w1; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; +// ======================== LMS-SHA256 H15/W4 ======================== // - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h15_w1_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w1_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w1_length_sk; +LMS_ALG(sha256_h15_w4, SHA256_H15_W4) - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w1_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; +// ======================== LMS-SHA256 H15/W8 ======================== // - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; +LMS_ALG(sha256_h15_w8, SHA256_H15_W8) - return sig; -} +// ======================== LMS-SHA256 H20/W1 ======================== // -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W1_new(void) { +LMS_ALG(sha256_h20_w1, SHA256_H20_W1) - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); +// // ======================== LMS-SHA256 H20/W2 ======================== // - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w1_length_sk; +LMS_ALG(sha256_h20_w2, SHA256_H20_W2) - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; +// ======================== LMS-SHA256 H20/W4 ======================== // - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; +LMS_ALG(sha256_h20_w4, SHA256_H20_W4) - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; +// ======================== LMS-SHA256 H20/W8 ======================== // - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; +LMS_ALG(sha256_h20_w8, SHA256_H20_W8) - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; +// ======================== LMS-SHA256 H25/W1 ======================== // - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; +LMS_ALG(sha256_h25_w1, SHA256_H25_W1) - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; +// ======================== LMS-SHA256 H25/W2 ======================== // - return sk; -} +LMS_ALG(sha256_h25_w2, SHA256_H25_W2) -// ======================== LMS-SHA256 H15/W2 ======================== // +// ======================== LMS-SHA256 H25/W4 ======================== // -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } +LMS_ALG(sha256_h25_w4, SHA256_H25_W4) - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w2) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} +// ======================== LMS-SHA256 H25/W8 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w2_new(void) { +LMS_ALG(sha256_h25_w8, SHA256_H25_W8) - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); +// +//2-Level LMS +// ======================== LMS-SHA256 H5/W8, H5/W8 ======================== // - sig->oid = OQS_LMS_ID_sha256_h15_w2; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w2; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; +LMS_ALG(sha256_h5_w8_h5_w8, SHA256_H5_W8_H5_W8) - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_sk; +// ======================== LMS-SHA256 H10/W2, H10/W2 ======================== // - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w2_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; +LMS_ALG(sha256_h10_w2_h10_w2, SHA256_H10_W2_H10_W2) - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; +// ======================== LMS-SHA256 H10/W4, H5/W8 ======================== // - return sig; -} +LMS_ALG(sha256_h10_w4_h5_w8, SHA256_H10_W4_H5_W8) -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W2_new(void) { +// ======================== LMS-SHA256 H10/W4, H10/W4 ======================== // - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); +LMS_ALG(sha256_h10_w4_h10_w4, SHA256_H10_W4_H10_W4) - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w2_length_sk; +// ======================== LMS-SHA256 H10/W8, H5/W8 ======================== // - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; +LMS_ALG(sha256_h10_w8_h5_w8, SHA256_H10_W8_H5_W8) - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; +// ======================== LMS-SHA256 H10/W8, H10/W8 ======================== // - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; +LMS_ALG(sha256_h10_w8_h10_w8, SHA256_H10_W8_H10_W8) - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; +// ======================== LMS-SHA256 H15/W8, H5/W8 ======================== // - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; +LMS_ALG(sha256_h15_w8_h5_w8, SHA256_H15_W8_H5_W8) - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; +// ======================== LMS-SHA256 H15/W8, H10/W8 ======================== // - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; +LMS_ALG(sha256_h15_w8_h10_w8, SHA256_H15_W8_H10_W8) - return sk; -} +// ======================== LMS-SHA256 H15/W8, H15/W8 ======================== // -// ======================== LMS-SHA256 H15/W4 ======================== // +LMS_ALG(sha256_h15_w8_h15_w8, SHA256_H15_W8_H15_W8) -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } +// ======================== LMS-SHA256 H20/W8, H5/W8 ======================== // - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w4) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} +LMS_ALG(sha256_h20_w8_h5_w8, SHA256_H20_W8_H5_W8) -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w4_new(void) { +// ======================== LMS-SHA256 H20/W8, H10/W8 ======================== // - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); +LMS_ALG(sha256_h20_w8_h10_w8, SHA256_H20_W8_H10_W8) - sig->oid = OQS_LMS_ID_sha256_h15_w4; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w4; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; +// ======================== LMS-SHA256 H20/W8, H15/W8 ======================== // - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_sk; +LMS_ALG(sha256_h20_w8_h15_w8, SHA256_H20_W8_H15_W8) - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w4_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; +// ======================== LMS-SHA256 H20/W8, H20/W8 ======================== // - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W4_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w4_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H15/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h15_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h15_w8_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H20/W1 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w1) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w1_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h20_w1; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w1; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h20_w1_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w1_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w1_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w1_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W1_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w1_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H20/W2 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w2) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w2_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h20_w2; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w2; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w2_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W2_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w2_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H20/W4 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w4) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w4_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h20_w4; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w4; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w4_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W4_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w4_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H20/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h20_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h20_w8_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H25/W1 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h25_w1) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w1_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h25_w1; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h25_w1; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h25_w1_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h25_w1_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w1_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h25_w1_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W1_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w1_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H25/W2 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h25_w2) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w2_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h25_w2; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h25_w2; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h25_w2_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W2_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w2_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H25/W4 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h25_w4) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w4_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h25_w4; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h25_w4; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h25_w4_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W4_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w4_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H25/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h25_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h25_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h25_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h25_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_pk; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_sk; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h25_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H25_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h25_w8_length_sk; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// -//2-Level LMS -// ======================== LMS-SHA256 H5/W8, H5/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h5_w8_h5_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h5_w8_h5_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W8_H5_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H10/W2, H10/W2 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w2_h10_w2) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h10_w2_h10_w2; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W2_H10_W2_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H10/W4, H5/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w4_h5_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h10_w4_h5_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_H5_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H10/W4, H10/W4 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w4_h10_w4) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h10_w4_h10_w4; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_H10_W4_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H10/W8, H5/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w8_h5_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h10_w8_h5_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_H5_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H10/W8, H10/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h10_w8_h10_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h15_w4; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_H10_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H15/W8, H5/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w8_h5_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h15_w8_h5_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H5_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H15/W8, H10/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w8_h10_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h15_w8_h10_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H10_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H15/W8, H15/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h15_w8_h15_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h15_w8_h15_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H15_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H20/W8, H5/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w8_h5_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h20_w8_h5_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H5_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H20/W8, H10/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w8_h10_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h20_w8_h10_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H10_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H20/W8, H15/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w8_h15_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h20_w8_h15_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H15_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} - -// ======================== LMS-SHA256 H20/W8, H20/W8 ======================== // - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { - if (secret_key == NULL || public_key == NULL) { - return OQS_ERROR; - } - - if (oqs_sig_stfl_lms_keypair(public_key, secret_key, (const uint32_t)OQS_LMS_ID_sha256_h20_w8_h20_w8) != 0) { - return OQS_ERROR; - } - return OQS_SUCCESS; -} - -OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_LMS_ID_sha256_h20_w8_h20_w8; - sig->method_name = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8554"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_lms_length_public_key; - sig->length_signature = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_length_signature; - sig->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - sig->keypair = OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_keypair; - sig->sign = OQS_SIG_STFL_alg_lms_sign; - sig->verify = OQS_SIG_STFL_alg_lms_verify; - - sig->sigs_remaining = OQS_SIG_STFL_lms_sigs_left; - sig->sigs_total = OQS_SIG_STFL_lms_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H20_W8_new(void) { - - // Initialize the secret key in the heap with adequate memory - OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); - if (sk == NULL) { - return NULL; - } - memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY)); - - // Initialize the key with length_secret_key amount of bytes. - sk->length_secret_key = OQS_SIG_STFL_alg_lms_length_private_key; - - /* - * Secret Key retrieval Function - */ - sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; - - /* - * set Secret Key to internal structure Function - */ - sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; - - /* - * Set Secret Key Locking Function - */ - sk->lock_key = NULL; - - /* - * Set Secret Key Unlocking / Releasing Function - */ - sk->unlock_key = NULL; - - /* - * Set Secret Key Saving Function - */ - sk->secure_store_scrt_key = NULL; - - /* - * Set Secret Key free function - */ - sk->free_key = OQS_SECRET_KEY_LMS_free; - - sk->set_scrt_key_store_cb = OQS_SECRET_KEY_LMS_set_store_cb; - - return sk; -} +LMS_ALG(sha256_h20_w8_h20_w8, SHA256_H20_W8_H20_W8) //2-Level LMS diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h index 4405e60c1c..c5deed2f40 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.h +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -96,28 +96,24 @@ #define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_sk 64 OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); #define OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_signature 4464 #define OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h5_w2_length_sk 64 OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w2_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W2_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); #define OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_signature 2352 #define OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h5_w4_length_sk 64 OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w4_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W4_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); #define OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_signature 1296 #define OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h5_w8_length_sk 64 OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w8_new(void); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); //H10 // H10 W1 60 8848 64 @@ -279,55 +275,42 @@ void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk); #define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_length_signature 3444 #define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_length_signature 3604 -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W8_H5_W8_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_H5_W8_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_H5_W8_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W2_H10_W2_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W4_H10_W4_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H10_W8_H10_W8_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H5_W8_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H10_W8_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H15_W8_H15_W8_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H5_W8_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H10_W8_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H15_W8_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H20_W8_H20_W8_new(void); OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_new(void); diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 0f6ebff7af..69fdbc352c 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -912,6 +912,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature #endif } + OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { if (sig == NULL || sig->verify == NULL || sig->verify(message, message_len, signature, signature_len, public_key) != 0) { return OQS_ERROR; @@ -920,20 +921,36 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m } } + OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { +#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN + (void)sig; + (void)remain; + (void)secret_key; + return OQS_ERROR; +#else if (sig == NULL || sig->sigs_remaining == NULL || sig->sigs_remaining(remain, secret_key) != 0) { return OQS_ERROR; } else { return OQS_SUCCESS; } +#endif //OQS_ALLOW_SFTL_KEY_AND_SIG_GEN } + OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned long long *max, const OQS_SIG_STFL_SECRET_KEY *secret_key) { +#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN + (void)sig; + (void)max; + (void)secret_key; + return OQS_ERROR; +#else if (sig == NULL || sig->sigs_total == NULL || sig->sigs_total(max, secret_key) != 0) { return OQS_ERROR; } else { return OQS_SUCCESS; } +#endif //OQS_ALLOW_SFTL_KEY_AND_SIG_GEN } OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig) { diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index ac95842400..b0cb69b843 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -178,6 +178,9 @@ OQS_API int OQS_SIG_STFL_alg_count(void); */ OQS_API int OQS_SIG_STFL_alg_is_enabled(const char *method_name); +#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +#define OQS_SIG_STFL OQS_SIG +#else /** * Stateful signature scheme object */ @@ -281,6 +284,7 @@ typedef struct OQS_SIG_STFL { OQS_STATUS (*sigs_total)(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); } OQS_SIG_STFL; +#endif //OQS_ALLOW_SFTL_KEY_AND_SIG_GEN /** * @brief OQS_SIG_STFL_SECRET_KEY object for stateful signature schemes diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c index ebcf4f7608..7b9bcff39b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHA2_10_256 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmss_sha256_h10_oid; - sig->method_name = "XMSS-SHA2_10_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha256_h10_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmss_sha256_h10_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmss_sha256_h10_keypair; - sig->sign = OQS_SIG_STFL_alg_xmss_sha256_h10_sign; - sig->verify = OQS_SIG_STFL_alg_xmss_sha256_h10_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_sha256_h10_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); -} +XMSS_ALG(, _sha256_h10, _SHA256_H10) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c index d401b2aa75..c883e21e0e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHA2_16_256 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h16_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmss_sha256_h16_oid; - sig->method_name = "XMSS-SHA2_16_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha256_h16_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h16_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmss_sha256_h16_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmss_sha256_h16_keypair; - sig->sign = OQS_SIG_STFL_alg_xmss_sha256_h16_sign; - sig->verify = OQS_SIG_STFL_alg_xmss_sha256_h16_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H16_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_sha256_h16_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_sha256_h16_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); -} +XMSS_ALG(, _sha256_h16, _SHA256_H16) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c index 5cc2804754..a190255f2c 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHA2_16_256 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h20_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmss_sha256_h20_oid; - sig->method_name = "XMSS-SHA2_20_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha256_h20_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h20_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmss_sha256_h20_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmss_sha256_h20_keypair; - sig->sign = OQS_SIG_STFL_alg_xmss_sha256_h20_sign; - sig->verify = OQS_SIG_STFL_alg_xmss_sha256_h20_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H20_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_sha256_h20_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_sha256_h20_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); -} +XMSS_ALG(, _sha256_h20, _SHA256_H20) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c index b77a8c8436..1ff4cd891a 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c @@ -1,76 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHA2_10_512 ======================== // - -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h10_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmss_sha512_h10_oid; - sig->method_name = "XMSS-SHA2_10_512"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha512_h10_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h10_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmss_sha512_h10_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmss_sha512_h10_keypair; - sig->sign = OQS_SIG_STFL_alg_xmss_sha512_h10_sign; - sig->verify = OQS_SIG_STFL_alg_xmss_sha512_h10_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H10_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_sha512_h10_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_sha512_h10_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); -} +XMSS_ALG(, _sha512_h10, _SHA512_H10) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c index 695d5de288..c1b5ed9150 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHA2_16_512 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h16_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmss_sha512_h16_oid; - sig->method_name = "XMSS-SHA2_16_512"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha512_h16_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h16_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmss_sha512_h16_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmss_sha512_h16_keypair; - sig->sign = OQS_SIG_STFL_alg_xmss_sha512_h16_sign; - sig->verify = OQS_SIG_STFL_alg_xmss_sha512_h16_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H16_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_sha512_h16_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_sha512_h16_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); -} +XMSS_ALG(, _sha512_h16, _SHA512_H16) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c index f4b579deec..bf0a5b8d12 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHA2_20_512 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha512_h20_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmss_sha512_h20_oid; - sig->method_name = "XMSS-SHA2_20_512"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmss_sha512_h20_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmss_sha512_h20_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmss_sha512_h20_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmss_sha512_h20_keypair; - sig->sign = OQS_SIG_STFL_alg_xmss_sha512_h20_sign; - sig->verify = OQS_SIG_STFL_alg_xmss_sha512_h20_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA512_H20_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_sha512_h20_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_sha512_h20_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha512_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); -} +XMSS_ALG(, _sha512_h20, _SHA512_H20) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c index d216a02a15..8c01394663 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c @@ -1,76 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHAKE_10_256 ======================== // - -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h10_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmss_shake128_h10_oid; - sig->method_name = "XMSS-SHAKE_10_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmss_shake128_h10_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h10_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmss_shake128_h10_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmss_shake128_h10_keypair; - sig->sign = OQS_SIG_STFL_alg_xmss_shake128_h10_sign; - sig->verify = OQS_SIG_STFL_alg_xmss_shake128_h10_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H10_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_shake128_h10_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_shake128_h10_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); -} +XMSS_ALG(, _shake128_h10, _SHAKE128_H10) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c index bb0bd4684b..ff45fc0f5f 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c @@ -1,77 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHAKE_10_256 ======================== // - -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h16_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmss_shake128_h16_oid; - sig->method_name = "XMSS-SHAKE_16_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmss_shake128_h16_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h16_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmss_shake128_h16_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmss_shake128_h16_keypair; - sig->sign = OQS_SIG_STFL_alg_xmss_shake128_h16_sign; - sig->verify = OQS_SIG_STFL_alg_xmss_shake128_h16_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H16_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_shake128_h16_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_shake128_h16_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); -} - +XMSS_ALG(, _shake128_h16, _SHAKE128_H16) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c index b601e09a4e..d566069a82 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c @@ -1,76 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHAKE_10_256 ======================== // - -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake128_h20_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmss_shake128_h20_oid; - sig->method_name = "XMSS-SHAKE_20_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmss_shake128_h20_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmss_shake128_h20_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmss_shake128_h20_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmss_shake128_h20_keypair; - sig->sign = OQS_SIG_STFL_alg_xmss_shake128_h20_sign; - sig->verify = OQS_SIG_STFL_alg_xmss_shake128_h20_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE128_H20_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_shake128_h20_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_shake128_h20_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake128_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); -} +XMSS_ALG(, _shake128_h20, _SHAKE128_H20) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c index 33b685c20b..aea7ef0204 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c @@ -1,76 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHAKE_10_512 ======================== // - -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h10_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmss_shake256_h10_oid; - sig->method_name = "XMSS-SHAKE_10_512"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmss_shake256_h10_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h10_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmss_shake256_h10_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmss_shake256_h10_keypair; - sig->sign = OQS_SIG_STFL_alg_xmss_shake256_h10_sign; - sig->verify = OQS_SIG_STFL_alg_xmss_shake256_h10_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H10_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_shake256_h10_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_shake256_h10_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h10_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); -} +XMSS_ALG(, _shake256_h10, _SHAKE256_H10) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c index 02781a8600..d96e7644b3 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c @@ -1,77 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHAKE_16_512 ======================== // - -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h16_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmss_shake256_h16_oid; - sig->method_name = "XMSS-SHAKE_16_512"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmss_shake256_h16_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h16_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmss_shake256_h16_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmss_shake256_h16_keypair; - sig->sign = OQS_SIG_STFL_alg_xmss_shake256_h16_sign; - sig->verify = OQS_SIG_STFL_alg_xmss_shake256_h16_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H16_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_shake256_h16_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_shake256_h16_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h16_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); -} - +XMSS_ALG(, _shake256_h16, _SHAKE256_H16) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c index f4d856c34a..5bf41b07f9 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c @@ -1,76 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHAKE_20_512 ======================== // - -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_shake256_h20_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmss_shake256_h20_oid; - sig->method_name = "XMSS-SHAKE_20_512"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmss_shake256_h20_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmss_shake256_h20_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmss_shake256_h20_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmss_shake256_h20_keypair; - sig->sign = OQS_SIG_STFL_alg_xmss_shake256_h20_sign; - sig->verify = OQS_SIG_STFL_alg_xmss_shake256_h20_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHAKE256_H20_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss_shake256_h20_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmss_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss_shake256_h20_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmss_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_shake256_h20_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmss_sigs_total(total, secret_key); -} +XMSS_ALG(, _shake256_h20, _SHAKE256_H20) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c b/src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c new file mode 100644 index 0000000000..1b81bec309 --- /dev/null +++ b/src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: Apache-2.0 AND MIT + +#include +#include + +#include +#include "sig_stfl_xmss.h" + +#include "external/xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + + +// macro to en/disable OQS_SIG_STFL-only structs used only in sig&gen case: +#ifdef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN +#define XMSS_SIGGEN(xmss_v, XMSS_V) \ + sig->oid = OQS_SIG_STFL_alg_xmss##xmss_v##_oid; \ + sig->sigs_remaining = OQS_SIG_STFL_alg_xmss##xmss_v##_sigs_remaining;\ + sig->sigs_total = OQS_SIG_STFL_alg_xmss##xmss_v##_sigs_total;\ + sig->keypair = OQS_SIG_STFL_alg_xmss##xmss_v##_keypair;\ + sig->sign = OQS_SIG_STFL_alg_xmss##xmss_v##_sign; +#else +#define XMSS_SIGGEN(xmss_v, XMSS_V) +#endif + +// generator for all alg-specific functions: +#define XMSS_ALG(mt, xmss_v, XMSS_V) \ +OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss##xmss_v##_new(void) { \ +\ + OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); \ + if (sig == NULL) { \ + return NULL; \ + } \ + memset(sig, 0, sizeof(OQS_SIG_STFL)); \ +\ + XMSS_SIGGEN(xmss_v, XMSS_V) \ + sig->method_name = OQS_SIG_STFL_alg_xmss##xmss_v; \ + sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; \ + sig->euf_cma = true; \ +\ + sig->length_public_key = OQS_SIG_STFL_alg_xmss##xmss_v##_length_pk; \ + sig->length_secret_key = OQS_SIG_STFL_alg_xmss##xmss_v##_length_sk; \ + sig->length_signature = OQS_SIG_STFL_alg_xmss##xmss_v##_length_signature; \ +\ + sig->verify = OQS_SIG_STFL_alg_xmss##xmss_v##_verify;\ +\ + return sig;\ +} \ +\ +OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS##XMSS_V##_new(void) {\ + return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmss##xmss_v##_length_sk);\ +}\ +\ +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss##xmss_v##_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) {\ +\ + if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) {\ + return OQS_ERROR;\ + }\ +\ + if (xmss##mt##_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmss##xmss_v##_oid)) {\ + return OQS_ERROR;\ + }\ +\ + return OQS_SUCCESS;\ +}\ +\ +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss##xmss_v##_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) {\ + return OQS_SIG_STFL_alg_xmss##mt##_sign(signature, signature_len, message, message_len, secret_key);\ +}\ +\ +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss##xmss_v##_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) {\ + return OQS_SIG_STFL_alg_xmss##mt##_verify(message, message_len, signature, signature_len, public_key);\ +}\ +\ +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss##xmss_v##_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) {\ + return OQS_SIG_STFL_alg_xmss##mt##_sigs_remaining(remain, secret_key);\ +}\ +\ +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss##xmss_v##_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) {\ + return OQS_SIG_STFL_alg_xmss##mt##_sigs_total(total, secret_key);\ +} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c index 3d90674459..0c6057eef9 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c @@ -1,76 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHA2_20/2_256 ======================== // - -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_oid; - sig->method_name = "XMSSMT-SHA2_20/2_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_2_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_sha256_h20_2, MT_SHA256_H20_2) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c index 0305764855..867e0928b1 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c @@ -1,76 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHA2_20/4_256 ======================== // - -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_oid; - sig->method_name = "XMSSMT-SHA2_20/4_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H20_4_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h20_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_sha256_h20_4, MT_SHA256_H20_4) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c index 19db158709..e972df04ee 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c @@ -1,76 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHA2_40/2_256 ======================== // - -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_oid; - sig->method_name = "XMSSMT-SHA2_40/2_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_2_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_sha256_h40_2, MT_SHA256_H40_2) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c index 0f17088d4b..63c9af0bc8 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c @@ -1,76 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHA2_40/4_256 ======================== // - -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_oid; - sig->method_name = "XMSSMT-SHA2_40/4_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_4_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_sha256_h40_4, MT_SHA256_H40_4) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c index b985951514..156c2e3fd6 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHA2_40/8_256 ======================== // +XMSS_ALG(mt, mt_sha256_h40_8, MT_SHA256_H40_8) -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_oid; - sig->method_name = "XMSSMT-SHA2_40/8_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H40_8_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h40_8_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c index 60e3cae071..64f6576f82 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c @@ -1,76 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include +#include "sig_stfl_xmss_xmssmt.c" -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif // ======================== XMSSMT-SHA2_60/12_256 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_oid; - sig->method_name = "XMSSMT-SHA2_60/12_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_12_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_12_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_sha256_h60_12, MT_SHA256_H60_12) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c index fc5cf35c23..d37e1244ae 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c @@ -1,76 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHA2_60/3_256 ======================== // - -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_oid; - sig->method_name = "XMSSMT-SHA2_60/3_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_3_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_3_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_sha256_h60_3, MT_SHA256_H60_3) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c index 6f055e949b..d5992617c0 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHA2_60/6_256 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_oid; - sig->method_name = "XMSSMT-SHA2_60/6_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHA256_H60_6_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sha256_h60_6_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_sha256_h60_6, MT_SHA256_H60_6) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c index 98a085ce22..76c8523a80 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHAKE_20/2_256 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_oid; - sig->method_name = "XMSSMT-SHAKE_20/2_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_2_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_shake128_h20_2, MT_SHAKE128_H20_2) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c index 37ee00a20b..0dec4743e6 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHAKE_20/4_256 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_oid; - sig->method_name = "XMSSMT-SHAKE_20/4_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H20_4_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h20_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_shake128_h20_4, MT_SHAKE128_H20_4) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c index a4175423a7..765694287d 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHAKE_40/2_256 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_oid; - sig->method_name = "XMSSMT-SHAKE_40/2_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_2_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_2_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_shake128_h40_2, MT_SHAKE128_H40_2) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c index bbadceea0f..7ce156c659 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHAKE_40/4_256 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_oid; - sig->method_name = "XMSSMT-SHAKE_40/4_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_4_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_4_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_shake128_h40_4, MT_SHAKE128_H40_4) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c index 14b3b50ffb..1c3f9671c0 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHAKE_40/8_256 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_oid; - sig->method_name = "XMSSMT-SHAKE_40/8_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H40_8_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h40_8_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_shake128_h40_8, MT_SHAKE128_H40_8) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c index 74c378ac7e..793393eaf3 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c @@ -1,77 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHAKE_60/12_256 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_oid; - sig->method_name = "XMSSMT-SHAKE_60/12_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_12_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_12_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} - +XMSS_ALG(mt, mt_shake128_h60_12, MT_SHAKE128_H60_12) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c index f7bae2956c..09edd7ebd7 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHAKE_60/3_256 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_oid; - sig->method_name = "XMSSMT-SHAKE_60/3_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_3_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_3_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_shake128_h60_3, MT_SHAKE128_H60_3) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c index 33f714d702..aae4ca20a6 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c @@ -1,76 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 AND MIT -#include -#include - -#include -#include "sig_stfl_xmss.h" - -#include "external/xmss.h" - -#if defined(__GNUC__) || defined(__clang__) -#define XMSS_UNUSED_ATT __attribute__((unused)) -#else -#define XMSS_UNUSED_ATT -#endif +#include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHAKE_60/6_256 ======================== // -OQS_SIG_STFL *OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_new(void) { - - OQS_SIG_STFL *sig = (OQS_SIG_STFL *)malloc(sizeof(OQS_SIG_STFL)); - if (sig == NULL) { - return NULL; - } - memset(sig, 0, sizeof(OQS_SIG_STFL)); - - sig->oid = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_oid; - sig->method_name = "XMSSMT-SHAKE_60/6_256"; - sig->alg_version = "https://datatracker.ietf.org/doc/html/rfc8391"; - sig->euf_cma = true; - - sig->length_public_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_pk; - sig->length_secret_key = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_sk; - sig->length_signature = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_signature; - - sig->keypair = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_keypair; - sig->sign = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sign; - sig->verify = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_verify; - sig->sigs_remaining = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining; - sig->sigs_total = OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total; - - return sig; -} - -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSSMT_SHAKE128_H60_6_new(void) { - return OQS_SECRET_KEY_XMSS_new(OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_length_sk); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - - if (public_key == NULL || secret_key == NULL || secret_key->secret_key_data == NULL) { - return OQS_ERROR; - } - - if (xmssmt_keypair(public_key, secret_key->secret_key_data, OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_oid)) { - return OQS_ERROR; - } - - return OQS_SUCCESS; -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sign(signature, signature_len, message, message_len, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { - return OQS_SIG_STFL_alg_xmssmt_verify(message, message_len, signature, signature_len, public_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_remaining(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_remaining(remain, secret_key); -} - -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_shake128_h60_6_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_SIG_STFL_alg_xmssmt_sigs_total(total, secret_key); -} +XMSS_ALG(mt, mt_shake128_h60_6, MT_SHAKE128_H60_6) diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index f0a51aac74..5626eee5b3 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -263,8 +263,8 @@ OQS_STATUS sig_stfl_KATs_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_ return OQS_ERROR; } +#ifdef OQS_ENABLE_SIG_STFL_XMSS if (0) { - #ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 } else if (strcmp(sig->method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { goto from_kats; @@ -321,12 +321,11 @@ OQS_STATUS sig_stfl_KATs_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_ } else { goto from_keygen; } -#ifdef OQS_ENABLE_SIG_STFL_XMSS from_kats: return sig_stfl_keypair_from_KATs(sig, public_key, secret_key, katfile); -#endif from_keygen: +#endif //OQS_ENABLE_SIG_STFL_XMSS (void)(katfile); return sig_stfl_keypair_from_keygen(sig, public_key, secret_key); } From 001e96a03a853d07518f8215634a98f439d5eab3 Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Tue, 13 Feb 2024 11:07:06 -0500 Subject: [PATCH 39/68] Update GitHub Actions workflows for stateful signatures (#1692) Co-authored-by: Duc Nguyen --- .github/workflows/android.yml | 4 +++- .github/workflows/apple.yml | 5 ++++- .github/workflows/unix.yml | 22 +++++++++++++++++----- .github/workflows/windows.yml | 8 ++++++-- scripts/build-android.sh | 9 ++++++--- tests/kat_sig_stfl.c | 33 +++++++++++++++++++-------------- 6 files changed, 55 insertions(+), 26 deletions(-) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 895ed7b171..26b4d13186 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -10,8 +10,10 @@ jobs: fail-fast: false matrix: abi: [armeabi-v7a, arm64-v8a, x86, x86_64] + stfl_opt: [ON, OFF] + steps: - name: Checkout code uses: actions/checkout@v3 - name: Build project - run: ./scripts/build-android.sh $ANDROID_NDK_HOME -a ${{ matrix.abi }} + run: ./scripts/build-android.sh $ANDROID_NDK_HOME -a ${{ matrix.abi }} -f "-DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }}" diff --git a/.github/workflows/apple.yml b/.github/workflows/apple.yml index 1ced2dea76..bb9a2f47b6 100644 --- a/.github/workflows/apple.yml +++ b/.github/workflows/apple.yml @@ -10,10 +10,13 @@ jobs: fail-fast: false matrix: platform: [OS64, TVOS] + stfl_opt: [OFF, ON] steps: - name: Checkout code uses: actions/checkout@v3 - name: Generate project - run: cmake -B build --toolchain .CMake/apple.cmake -DOQS_USE_OPENSSL=OFF -DPLATFORM=${{ matrix.platform }} . + run: | + cmake -B build --toolchain .CMake/apple.cmake -DOQS_USE_OPENSSL=OFF -DPLATFORM=${{ matrix.platform }} \ + -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . - name: Build project run: cmake --build build diff --git a/.github/workflows/unix.yml b/.github/workflows/unix.yml index ab0213ef34..3e534319c7 100644 --- a/.github/workflows/unix.yml +++ b/.github/workflows/unix.yml @@ -74,15 +74,19 @@ jobs: include: - name: alpine container: openquantumsafe/ci-alpine-amd64:latest - CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py + - name: alpine-no-stfl-key-sig-gen + container: openquantumsafe/ci-alpine-amd64:latest + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: alpine-openssl-all container: openquantumsafe/ci-alpine-amd64:latest - CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_USE_AES_OPENSSL=ON -DOQS_USE_SHA2_OPENSSL=ON -DOQS_USE_SHA3_OPENSSL=ON + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_USE_AES_OPENSSL=ON -DOQS_USE_SHA2_OPENSSL=ON -DOQS_USE_SHA3_OPENSSL=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: alpine-noopenssl container: openquantumsafe/ci-alpine-amd64:latest - CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=OFF + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=OFF -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: focal-nistr4-openssl container: openquantumsafe/ci-ubuntu-focal-x86_64:latest @@ -98,7 +102,11 @@ jobs: PYTEST_ARGS: --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py - name: address-sanitizer container: openquantumsafe/ci-ubuntu-focal-x86_64:latest - CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address + CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + PYTEST_ARGS: --ignore=tests/test_distbuild.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py --numprocesses=auto --maxprocesses=10 + - name: address-sanitizer-no-stfl-key-sig-gen + container: openquantumsafe/ci-ubuntu-focal-x86_64:latest + CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_distbuild.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py --numprocesses=auto --maxprocesses=10 container: image: ${{ matrix.container }} @@ -137,7 +145,11 @@ jobs: include: - name: armhf ARCH: armhf - CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic + CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py + - name: armhf-no-stfl-key-sig-gen + ARCH: armhf + CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py # no longer supporting armel # - name: armel diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 8b5716554f..de0d5e82db 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -6,10 +6,13 @@ jobs: windows-arm64: runs-on: windows-2022 + strategy: + matrix: + stfl_opt: [ON, OFF] steps: - uses: actions/checkout@v3 - name: Generate Project - run: cmake -B build --toolchain .CMake/toolchain_windows_arm64.cmake . + run: cmake -B build --toolchain .CMake/toolchain_windows_arm64.cmake -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . - name: Build Project run: cmake --build build @@ -19,10 +22,11 @@ jobs: fail-fast: false matrix: toolchain: [.CMake/toolchain_windows_x86.cmake, .CMake/toolchain_windows_amd64.cmake] + stfl_opt: [ON, OFF] steps: - uses: actions/checkout@v3 - name: Generate Project - run: cmake -B build --toolchain ${{ matrix.toolchain }} . + run: cmake -B build --toolchain ${{ matrix.toolchain }} -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . - name: Build Project run: cmake --build build - name: Test dependencies diff --git a/scripts/build-android.sh b/scripts/build-android.sh index 574c8d8ea4..54a03d21b3 100755 --- a/scripts/build-android.sh +++ b/scripts/build-android.sh @@ -6,12 +6,13 @@ set -e show_help() { echo "" - echo " Usage: ./build-android -a [abi] -b [build-directory] -s [sdk-version]" + echo " Usage: ./build-android -a [abi] -b [build-directory] -s [sdk-version] -f [extra-cmake-flags]" echo " ndk-dir: the directory of the Android NDK (required)" echo " abi: the Android ABI to target for the build" echo " build-directory: the directory in which to build the project" echo " sdk-version: the minimum Android SDK version to target" + echo " extra-cmake-flags: extra flags to use for CMake configuration" echo "" exit 0 } @@ -52,12 +53,13 @@ MINSDKVERSION=21 BUILDDIR="build" OPTIND=2 -while getopts "a:s:b:" flag +while getopts "a:s:b:f:" flag do case $flag in a) ABI=$OPTARG;; s) MINSDKVERSION=$OPTARG;; b) BUILDDIR=$OPTARG;; + f) EXTRAFLAGS="$OPTARG";; *) exit 1 esac done @@ -107,7 +109,8 @@ cmake .. -DOQS_USE_OPENSSL=OFF \ -DBUILD_SHARED_LIBS=ON \ -DCMAKE_TOOLCHAIN_FILE="$NDK"/build/cmake/android.toolchain.cmake \ -DANDROID_ABI="$ABI" \ - -DANDROID_NATIVE_API_LEVEL="$MINSDKVERSION" + -DANDROID_NATIVE_API_LEVEL="$MINSDKVERSION" \ + $EXTRAFLAGS cmake --build ./ # Provide rudimentary information following build diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index 23ec293e4b..52245f3dac 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -300,9 +300,9 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { goto err; } - //Echo back the signature read to keep the test tool happy. + // Echo back the signature read to keep the test tool happy. fprintf(fh, "smlen = %zu\n", sig->length_signature); - fprintBstr(fh, "sm = ", signature_kat, sig->length_signature); + OQS_fprintBstr(fh, "sm = ", signature_kat, sig->length_signature); rc = OQS_SIG_STFL_verify(sig, msg, msg_len, signature_kat, signature_len, public_key); if (rc != OQS_SUCCESS) { @@ -310,20 +310,23 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { goto err; } - rc = OQS_SIG_STFL_sigs_remaining(sig, &sigs_remain, secret_key); - if (rc != OQS_SUCCESS) { + // Echo back remain + if (FindMarker(fp_rsp, "remain = ")) { + fscanf(fp_rsp, "%lld", &sigs_remain); + fprintf(fh, "remain = %llu\n", sigs_remain); + } else { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_remaining failed!\n", method_name); goto err; } - //Update value to keep the test tool happy - fprintf(fh, "remain = %llu\n", sigs_remain - 1); - rc = OQS_SIG_STFL_sigs_total(sig, &sigs_maximum, secret_key); - if (rc != OQS_SUCCESS) { + // Echo back max + if (FindMarker(fp_rsp, "max = ")) { + fscanf(fp_rsp, "%lld", &sigs_maximum); + fprintf(fh, "max = %llu", sigs_maximum); + } else { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_total failed!\n", method_name); goto err; } - fprintf(fh, "max = %llu", sigs_maximum); ret = OQS_SUCCESS; goto cleanup; @@ -347,7 +350,9 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { OQS_MEM_insecure_free(msg_rand); OQS_SIG_STFL_free(sig); OQS_KAT_PRNG_free(prng); - fclose(fp_rsp); + if (fp_rsp != NULL) { + fclose(fp_rsp); + } return ret; } @@ -430,7 +435,7 @@ static OQS_STATUS test_lms_kat(const char *method_name, const char *katfile) { goto err; } - //Verify KAT + // Verify KAT rc = OQS_SIG_STFL_verify(sig, msg, msg_len, sm, sig->length_signature, public_key); if (rc != OQS_SUCCESS) { fprintf(stderr, "ERROR: Verify test vector failed: %s\n", method_name); @@ -477,10 +482,10 @@ int main(int argc, char **argv) { char *alg_name = argv[1]; char *katfile = argv[2]; - if (strncmp(alg_name, "LMS", 3) != 0) { - rc = sig_stfl_kat(alg_name, katfile); - } else { + if (strncmp(alg_name, "LMS", 3) == 0) { rc = test_lms_kat(alg_name, katfile); + } else { + rc = sig_stfl_kat(alg_name, katfile); } if (rc != OQS_SUCCESS) { OQS_destroy(); From e1f02b2d6dca61523094640868116a8d997eb14e Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Tue, 13 Feb 2024 12:45:42 -0500 Subject: [PATCH 40/68] Change XMSS License from `(Apache 2.0 AND MIT)` to `(Apache 2.0 OR MIT) AND CC0-1.0` (#1697) * include CC0 and convert to Apache 2.0 OR MIT * update license * Add missing CC0-1.0 --- docs/algorithms/sig_stfl/xmss.md | 2 +- docs/algorithms/sig_stfl/xmss.yml | 4 ++-- src/sig_stfl/xmss/CMakeLists.txt | 2 +- src/sig_stfl/xmss/LICENSE | 14 ++++++++++++-- src/sig_stfl/xmss/LICENSE-MIT | 9 --------- src/sig_stfl/xmss/external/core_hash.c | 2 +- src/sig_stfl/xmss/external/core_hash.h | 2 +- src/sig_stfl/xmss/external/hash.c | 2 +- src/sig_stfl/xmss/external/hash.h | 2 +- src/sig_stfl/xmss/external/hash_address.c | 2 +- src/sig_stfl/xmss/external/hash_address.h | 2 +- src/sig_stfl/xmss/external/namespace.h | 2 +- src/sig_stfl/xmss/external/params.c | 2 +- src/sig_stfl/xmss/external/params.h | 2 +- src/sig_stfl/xmss/external/utils.c | 2 +- src/sig_stfl/xmss/external/utils.h | 2 +- src/sig_stfl/xmss/external/wots.c | 2 +- src/sig_stfl/xmss/external/wots.h | 2 +- src/sig_stfl/xmss/external/xmss.c | 2 +- src/sig_stfl/xmss/external/xmss.h | 2 +- src/sig_stfl/xmss/external/xmss_commons.c | 2 +- src/sig_stfl/xmss/external/xmss_commons.h | 2 +- src/sig_stfl/xmss/external/xmss_core.c | 2 +- src/sig_stfl/xmss/external/xmss_core.h | 2 +- src/sig_stfl/xmss/external/xmss_core_fast.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss.h | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_functions.c | 2 +- .../xmss/sig_stfl_xmss_secret_key_functions.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c | 3 ++- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c | 3 ++- src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c | 3 ++- src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c | 3 ++- src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c | 3 ++- src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c | 3 ++- src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c | 3 ++- src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c | 3 ++- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c | 3 ++- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c | 3 ++- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c | 3 ++- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c | 4 ++-- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c | 3 +-- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c | 3 ++- src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c | 2 +- .../xmss/sig_stfl_xmssmt_shake128_h60_12.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c | 2 +- src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c | 2 +- 58 files changed, 82 insertions(+), 70 deletions(-) delete mode 100644 src/sig_stfl/xmss/LICENSE-MIT diff --git a/docs/algorithms/sig_stfl/xmss.md b/docs/algorithms/sig_stfl/xmss.md index b78dce983b..b68bfc3020 100644 --- a/docs/algorithms/sig_stfl/xmss.md +++ b/docs/algorithms/sig_stfl/xmss.md @@ -7,7 +7,7 @@ - **Specification version**: None. - **Primary Source**: - **Source**: https://github.com/XMSS/xmss-reference - - **Implementation license (SPDX-Identifier)**: Apache-2.0 AND MIT + - **Implementation license (SPDX-Identifier)**: (Apache-2.0 OR MIT) AND CC0-1.0 ## Parameter set summary diff --git a/docs/algorithms/sig_stfl/xmss.yml b/docs/algorithms/sig_stfl/xmss.yml index bf57a7eeb8..ccc92c26ea 100644 --- a/docs/algorithms/sig_stfl/xmss.yml +++ b/docs/algorithms/sig_stfl/xmss.yml @@ -11,10 +11,10 @@ crypto-assumption: hash function second-preimage resistance website: https://www.rfc-editor.org/info/rfc8391 nist-round: spec-version: -spdx-license-identifier: Apache-2.0 AND MIT +spdx-license-identifier: (Apache-2.0 OR MIT) AND CC0-1.0 primary-upstream: source: https://github.com/XMSS/xmss-reference - spdx-license-identifier: Apache-2.0 AND MIT + spdx-license-identifier: (Apache-2.0 OR MIT) AND CC0-1.0 upstream-ancestors: parameter-sets: - name: XMSS-SHA2_10_256 diff --git a/src/sig_stfl/xmss/CMakeLists.txt b/src/sig_stfl/xmss/CMakeLists.txt index dc57732e16..f9fc4fc08d 100644 --- a/src/sig_stfl/xmss/CMakeLists.txt +++ b/src/sig_stfl/xmss/CMakeLists.txt @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: Apache-2.0 AND MIT +# SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 set(_XMSS_OBJS "") diff --git a/src/sig_stfl/xmss/LICENSE b/src/sig_stfl/xmss/LICENSE index 90a1bebcfa..6fc799ea78 100644 --- a/src/sig_stfl/xmss/LICENSE +++ b/src/sig_stfl/xmss/LICENSE @@ -1,8 +1,18 @@ ## License -This XMSS reference implementation is Copyright (c) 2024 SandboxAQ and licensed under both the [Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) and [MIT License](LICENSE-MIT). +This XMSS reference implementation is Copyright (c) 2024 SandboxAQ and licensed under the CC0-1.0 AND ([Apache License, Version 2.0](https://www.apache.org/licenses/LICENSE-2.0.txt) OR MIT License) at your option. -Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. +--------------------------------- +The MIT License (MIT) + +Copyright © 2024 SandboxAQ + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +--------------------------------- This XMSS reference implementation is based on the [XMSS reference implementation written by Andreas Hülsing and Joost Rijneveld](https://github.com/XMSS/xmss-reference#license) provided under the CC0 1.0 Universal Public Domain Dedication. diff --git a/src/sig_stfl/xmss/LICENSE-MIT b/src/sig_stfl/xmss/LICENSE-MIT deleted file mode 100644 index 7b1af979f6..0000000000 --- a/src/sig_stfl/xmss/LICENSE-MIT +++ /dev/null @@ -1,9 +0,0 @@ -The MIT License (MIT) - -Copyright © 2024 SandboxAQ - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/sig_stfl/xmss/external/core_hash.c b/src/sig_stfl/xmss/external/core_hash.c index 72fe4e9d5c..7c80f3f860 100644 --- a/src/sig_stfl/xmss/external/core_hash.c +++ b/src/sig_stfl/xmss/external/core_hash.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include #include #include "core_hash.h" diff --git a/src/sig_stfl/xmss/external/core_hash.h b/src/sig_stfl/xmss/external/core_hash.h index e292e4c06d..dbbeecca83 100644 --- a/src/sig_stfl/xmss/external/core_hash.h +++ b/src/sig_stfl/xmss/external/core_hash.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #ifndef CORE_HASH #define CORE_HASH diff --git a/src/sig_stfl/xmss/external/hash.c b/src/sig_stfl/xmss/external/hash.c index 557c8de7db..f9272f01c3 100644 --- a/src/sig_stfl/xmss/external/hash.c +++ b/src/sig_stfl/xmss/external/hash.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include #include diff --git a/src/sig_stfl/xmss/external/hash.h b/src/sig_stfl/xmss/external/hash.h index bd1e1c1202..708dd6932a 100644 --- a/src/sig_stfl/xmss/external/hash.h +++ b/src/sig_stfl/xmss/external/hash.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #ifndef XMSS_HASH_H #define XMSS_HASH_H diff --git a/src/sig_stfl/xmss/external/hash_address.c b/src/sig_stfl/xmss/external/hash_address.c index a9fec506b5..eaa5ff6fc9 100644 --- a/src/sig_stfl/xmss/external/hash_address.c +++ b/src/sig_stfl/xmss/external/hash_address.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include #include "hash_address.h" diff --git a/src/sig_stfl/xmss/external/hash_address.h b/src/sig_stfl/xmss/external/hash_address.h index 06f5c502bd..3929558546 100644 --- a/src/sig_stfl/xmss/external/hash_address.h +++ b/src/sig_stfl/xmss/external/hash_address.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #ifndef XMSS_HASH_ADDRESS_H #define XMSS_HASH_ADDRESS_H diff --git a/src/sig_stfl/xmss/external/namespace.h b/src/sig_stfl/xmss/external/namespace.h index 7bb7d05349..3fe67527d2 100644 --- a/src/sig_stfl/xmss/external/namespace.h +++ b/src/sig_stfl/xmss/external/namespace.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #ifndef XMSS_NAMESPACE_H #define XMSS_NAMESPACE_H diff --git a/src/sig_stfl/xmss/external/params.c b/src/sig_stfl/xmss/external/params.c index f9ba544e47..a1d49d1340 100644 --- a/src/sig_stfl/xmss/external/params.c +++ b/src/sig_stfl/xmss/external/params.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include #include diff --git a/src/sig_stfl/xmss/external/params.h b/src/sig_stfl/xmss/external/params.h index f75e3c97c5..e9a5faaa2b 100644 --- a/src/sig_stfl/xmss/external/params.h +++ b/src/sig_stfl/xmss/external/params.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #ifndef XMSS_PARAMS_H #define XMSS_PARAMS_H diff --git a/src/sig_stfl/xmss/external/utils.c b/src/sig_stfl/xmss/external/utils.c index c2d76aba15..f03ef93d40 100644 --- a/src/sig_stfl/xmss/external/utils.c +++ b/src/sig_stfl/xmss/external/utils.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "utils.h" /** diff --git a/src/sig_stfl/xmss/external/utils.h b/src/sig_stfl/xmss/external/utils.h index 14d8588ddc..e3c1d2853d 100644 --- a/src/sig_stfl/xmss/external/utils.h +++ b/src/sig_stfl/xmss/external/utils.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #ifndef XMSS_UTILS_H #define XMSS_UTILS_H diff --git a/src/sig_stfl/xmss/external/wots.c b/src/sig_stfl/xmss/external/wots.c index a4bfae956d..8ef4f026cd 100644 --- a/src/sig_stfl/xmss/external/wots.c +++ b/src/sig_stfl/xmss/external/wots.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include #include diff --git a/src/sig_stfl/xmss/external/wots.h b/src/sig_stfl/xmss/external/wots.h index e0e3f1d0a9..8f8756ede3 100644 --- a/src/sig_stfl/xmss/external/wots.h +++ b/src/sig_stfl/xmss/external/wots.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #ifndef XMSS_WOTS_H #define XMSS_WOTS_H diff --git a/src/sig_stfl/xmss/external/xmss.c b/src/sig_stfl/xmss/external/xmss.c index 71d3f0a463..6a224a8d3e 100644 --- a/src/sig_stfl/xmss/external/xmss.c +++ b/src/sig_stfl/xmss/external/xmss.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include #include "params.h" diff --git a/src/sig_stfl/xmss/external/xmss.h b/src/sig_stfl/xmss/external/xmss.h index 53d21e2dbd..566b809b9e 100644 --- a/src/sig_stfl/xmss/external/xmss.h +++ b/src/sig_stfl/xmss/external/xmss.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #ifndef XMSS_H #define XMSS_H diff --git a/src/sig_stfl/xmss/external/xmss_commons.c b/src/sig_stfl/xmss/external/xmss_commons.c index 168e6ffed5..645faf0112 100644 --- a/src/sig_stfl/xmss/external/xmss_commons.c +++ b/src/sig_stfl/xmss/external/xmss_commons.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include #include #include diff --git a/src/sig_stfl/xmss/external/xmss_commons.h b/src/sig_stfl/xmss/external/xmss_commons.h index 26eb537ee3..958fd3ffa3 100644 --- a/src/sig_stfl/xmss/external/xmss_commons.h +++ b/src/sig_stfl/xmss/external/xmss_commons.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #ifndef XMSS_COMMONS_H #define XMSS_COMMONS_H diff --git a/src/sig_stfl/xmss/external/xmss_core.c b/src/sig_stfl/xmss/external/xmss_core.c index 4d7e8de096..1052d4d7e5 100644 --- a/src/sig_stfl/xmss/external/xmss_core.c +++ b/src/sig_stfl/xmss/external/xmss_core.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include #include #include diff --git a/src/sig_stfl/xmss/external/xmss_core.h b/src/sig_stfl/xmss/external/xmss_core.h index 007c42172a..54cccc25e4 100644 --- a/src/sig_stfl/xmss/external/xmss_core.h +++ b/src/sig_stfl/xmss/external/xmss_core.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #ifndef XMSS_CORE_H #define XMSS_CORE_H diff --git a/src/sig_stfl/xmss/external/xmss_core_fast.c b/src/sig_stfl/xmss/external/xmss_core_fast.c index 71b0f471ca..d539c1f6c2 100644 --- a/src/sig_stfl/xmss/external/xmss_core_fast.c +++ b/src/sig_stfl/xmss/external/xmss_core_fast.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index 4166cafcb7..a926c5ddd3 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #ifndef OQS_SIG_STFL_XMSS_H #define OQS_SIG_STFL_XMSS_H diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c index ce2df38238..64d714e600 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c index 4f6413a98b..59321ffcfa 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c index 7b9bcff39b..7e4a5e50c2 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c index c883e21e0e..bcd4cd56de 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h16.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c index a190255f2c..80392100cd 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha256_h20.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c index 1ff4cd891a..1a4fe53c41 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h10.c @@ -1,6 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHA2_10_512 ======================== // + XMSS_ALG(, _sha512_h10, _SHA512_H10) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c index c1b5ed9150..2e8f87c026 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h16.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c index bf0a5b8d12..bc3827e3de 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_sha512_h20.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c index 8c01394663..85fde8add4 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h10.c @@ -1,6 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHAKE_10_256 ======================== // + XMSS_ALG(, _shake128_h10, _SHAKE128_H10) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c index ff45fc0f5f..8b48276f45 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h16.c @@ -1,6 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHAKE_10_256 ======================== // + XMSS_ALG(, _shake128_h16, _SHAKE128_H16) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c index d566069a82..30d34b9633 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake128_h20.c @@ -1,6 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHAKE_10_256 ======================== // + XMSS_ALG(, _shake128_h20, _SHAKE128_H20) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c index aea7ef0204..dde4f1d400 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h10.c @@ -1,6 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHAKE_10_512 ======================== // + XMSS_ALG(, _shake256_h10, _SHAKE256_H10) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c index d96e7644b3..1a41d0f172 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h16.c @@ -1,6 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHAKE_16_512 ======================== // + XMSS_ALG(, _shake256_h16, _SHAKE256_H16) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c index 5bf41b07f9..321876fb97 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_shake256_h20.c @@ -1,6 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" // ======================== XMSS-SHAKE_20_512 ======================== // + XMSS_ALG(, _shake256_h20, _SHAKE256_H20) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c b/src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c index 1b81bec309..7868d68c94 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c index f5d99705d3..ec1143f1b8 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include #include diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c index 0c6057eef9..1ce98d95ff 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_2.c @@ -1,6 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHA2_20/2_256 ======================== // + XMSS_ALG(mt, mt_sha256_h20_2, MT_SHA256_H20_2) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c index 867e0928b1..c914958bb1 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h20_4.c @@ -1,6 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHA2_20/4_256 ======================== // + XMSS_ALG(mt, mt_sha256_h20_4, MT_SHA256_H20_4) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c index e972df04ee..187292a29e 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_2.c @@ -1,6 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHA2_40/2_256 ======================== // + XMSS_ALG(mt, mt_sha256_h40_2, MT_SHA256_H40_2) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c index 63c9af0bc8..db6ac22a05 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_4.c @@ -1,6 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHA2_40/4_256 ======================== // + XMSS_ALG(mt, mt_sha256_h40_4, MT_SHA256_H40_4) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c index 156c2e3fd6..293810cc19 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h40_8.c @@ -1,7 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHA2_40/8_256 ======================== // -XMSS_ALG(mt, mt_sha256_h40_8, MT_SHA256_H40_8) +XMSS_ALG(mt, mt_sha256_h40_8, MT_SHA256_H40_8) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c index 64f6576f82..eb80bd0f91 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_12.c @@ -1,8 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" - // ======================== XMSSMT-SHA2_60/12_256 ======================== // XMSS_ALG(mt, mt_sha256_h60_12, MT_SHA256_H60_12) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c index d37e1244ae..05a4cef584 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_3.c @@ -1,6 +1,7 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" // ======================== XMSSMT-SHA2_60/3_256 ======================== // + XMSS_ALG(mt, mt_sha256_h60_3, MT_SHA256_H60_3) diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c index d5992617c0..b0a552ca26 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_sha256_h60_6.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c index 76c8523a80..682859a90c 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c index 0dec4743e6..9325b6b81d 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h20_4.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c index 765694287d..9ef0fccb47 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_2.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c index 7ce156c659..2568826e85 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_4.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c index 1c3f9671c0..9605ef940c 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h40_8.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c index 793393eaf3..db71c1ca4f 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_12.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c index 09edd7ebd7..60dfeaf572 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_3.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c index aae4ca20a6..e658846d57 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_shake128_h60_6.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: Apache-2.0 AND MIT +// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 #include "sig_stfl_xmss_xmssmt.c" From 17c12c3c7f0e1b0c92085f5001559e0f892f9d18 Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Fri, 1 Mar 2024 10:30:12 -0500 Subject: [PATCH 41/68] Add return status for XMSS lock/unlock functions. (#1712) * Add return status for XMSS lock/unlock functions. * it should say return ERROR instead of SUCCESS. --- src/sig_stfl/xmss/sig_stfl_xmss.h | 4 +- .../xmss/sig_stfl_xmss_secret_key_functions.c | 39 ++++++++++++------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index a926c5ddd3..6ee03f3b12 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -582,9 +582,9 @@ void OQS_SECRET_KEY_XMSS_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_ void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk); /* Lock the key if possible */ -void OQS_SECRET_KEY_XMSS_acquire_lock(const OQS_SIG_STFL_SECRET_KEY *sk); +OQS_STATUS OQS_SECRET_KEY_XMSS_acquire_lock(const OQS_SIG_STFL_SECRET_KEY *sk); /* Unlock the key if possible */ -void OQS_SECRET_KEY_XMSS_release_lock(const OQS_SIG_STFL_SECRET_KEY *sk); +OQS_STATUS OQS_SECRET_KEY_XMSS_release_lock(const OQS_SIG_STFL_SECRET_KEY *sk); #endif /* OQS_SIG_STFL_XMSS_H */ diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c index 59321ffcfa..1ccc8e8c09 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c @@ -11,8 +11,7 @@ #define XMSS_UNUSED_ATT #endif -extern inline -OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_new(size_t length_secret_key) { +extern inline OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_new(size_t length_secret_key) { // Initialize the secret key in the heap with adequate memory OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY)); @@ -71,7 +70,9 @@ OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_le } /* Lock the key if possible */ - OQS_SECRET_KEY_XMSS_acquire_lock(sk); + if (OQS_SECRET_KEY_XMSS_acquire_lock(sk) != OQS_SUCCESS) { + return OQS_ERROR; + } uint8_t *sk_buf = malloc(sk->length_secret_key * sizeof(uint8_t)); if (sk_buf == NULL) { @@ -85,7 +86,9 @@ OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_le *sk_len = sk->length_secret_key; /* Unlock the key if possible */ - OQS_SECRET_KEY_XMSS_release_lock(sk); + if (OQS_SECRET_KEY_XMSS_release_lock(sk) != OQS_SUCCESS) { + return OQS_ERROR; + } return OQS_SUCCESS; } @@ -143,24 +146,32 @@ void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk) { sk->secret_key_data = NULL; } -void OQS_SECRET_KEY_XMSS_acquire_lock(const OQS_SIG_STFL_SECRET_KEY *sk) { +OQS_STATUS OQS_SECRET_KEY_XMSS_acquire_lock(const OQS_SIG_STFL_SECRET_KEY *sk) { if (sk == NULL) { - return; + return OQS_ERROR; } - /* Lock the key if possible */ - if ((sk->lock_key != NULL) && (sk->mutex != NULL)) { - sk->lock_key(sk->mutex); + /* Lock the key if possible, otherwise return OQS_ERROR because the lock_key, unlock_key and mutex are not defined.*/ + if ((sk->lock_key != NULL) && (sk->mutex != NULL) && (sk->unlock_key != NULL)) { + if (sk->lock_key(sk->mutex) != OQS_SUCCESS) { + return OQS_ERROR; + } } + + return OQS_SUCCESS; } -void OQS_SECRET_KEY_XMSS_release_lock(const OQS_SIG_STFL_SECRET_KEY *sk) { +OQS_STATUS OQS_SECRET_KEY_XMSS_release_lock(const OQS_SIG_STFL_SECRET_KEY *sk) { if (sk == NULL) { - return; + return OQS_ERROR; } - /* Unlock the key if possible */ - if ((sk->unlock_key != NULL) && (sk->mutex != NULL)) { - sk->unlock_key(sk->mutex); + /* Unlock the key if possible, otherwise return OQS_ERROR because the lock_key, unlock_key and mutex are not defined. */ + if ((sk->unlock_key != NULL) && (sk->mutex != NULL) && (sk->lock_key != NULL)) { + if (sk->unlock_key(sk->mutex) != OQS_SUCCESS) { + return OQS_ERROR; + } } + + return OQS_SUCCESS; } From 32949b7dfbc72458d18e06c3e8b4be4cb688dd1e Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Mon, 11 Mar 2024 14:33:41 -0400 Subject: [PATCH 42/68] Reformat LMS / XMSS KAT files (#1722) Signed-off-by: Spencer Wilson --- tests/KATs/sig_stfl/kats.json | 94 +++++++++---------- tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W1.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W2.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4.rsp | 2 - .../sig_stfl/lms/LMS_SHA256_H10_W4_H5_W8.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W8.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W1.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W2.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W4.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W8.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W1.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W2.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W4.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W8.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W1.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W2.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W4.rsp | 2 - tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8.rsp | 2 - .../sig_stfl/lms/LMS_SHA256_H5_W8_H5_W8.rsp | 2 - tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp | 4 +- tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_512.rsp | 4 +- tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_256.rsp | 4 +- tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_512.rsp | 4 +- tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_256.rsp | 4 +- tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_512.rsp | 4 +- .../KATs/sig_stfl/xmss/XMSS-SHAKE_10_256.rsp | 4 +- .../KATs/sig_stfl/xmss/XMSS-SHAKE_10_512.rsp | 4 +- .../KATs/sig_stfl/xmss/XMSS-SHAKE_16_256.rsp | 4 +- .../KATs/sig_stfl/xmss/XMSS-SHAKE_16_512.rsp | 4 +- .../KATs/sig_stfl/xmss/XMSS-SHAKE_20_256.rsp | 4 +- .../KATs/sig_stfl/xmss/XMSS-SHAKE_20_512.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHA2_20-2_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHA2_20-4_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHA2_40-2_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHA2_40-4_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHA2_40-8_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHA2_60-12_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHA2_60-3_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHA2_60-6_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHAKE_20-2_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHAKE_20-4_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHAKE_40-2_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHAKE_40-4_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHAKE_40-8_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHAKE_60-12_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHAKE_60-3_256.rsp | 4 +- .../sig_stfl/xmss/XMSSMT-SHAKE_60-6_256.rsp | 4 +- tests/kat_sig_stfl.c | 6 +- 48 files changed, 77 insertions(+), 171 deletions(-) diff --git a/tests/KATs/sig_stfl/kats.json b/tests/KATs/sig_stfl/kats.json index 59bda4d7e2..21d0c11252 100644 --- a/tests/KATs/sig_stfl/kats.json +++ b/tests/KATs/sig_stfl/kats.json @@ -1,48 +1,48 @@ { - "XMSS-SHA2_10_256": "4ff9ea00bec98f790a5b5e96ddb8441d58e646d679a47f02db21085c35a006f4", - "XMSS-SHA2_16_256": "398ef810276efaeabc84780816950a9243be0b37122f33db556010a5ec606a8d", - "XMSS-SHA2_20_256": "d695061163e3a5124222a6d3202f1e397cde65733b84d700196a9c55b7d721a2", - "XMSS-SHAKE_10_256": "b5ec13a0eceb7cc1bd14f2288557b7dcb431c3c930ed8eb2d09be32eca52f722", - "XMSS-SHAKE_16_256": "2875eafcdad20e964c6abf4d90bdb73e1ab47fd2e636ed949502fff9f77ea94f", - "XMSS-SHAKE_20_256": "7e78a5792165d0ba1484f4cca60985373be475fbf1047e58997798b2048f5048", - "XMSS-SHA2_10_512": "791840f9f015bad6df9138d2ced1690daea746f65d54826ce85a6ba38211d16c", - "XMSS-SHA2_16_512": "c060814c9e029d9272c8942bb3f9a5ca46cf361e59c16bf70065476243095196", - "XMSS-SHA2_20_512": "c5684bba5d53983cf3c52b45ca0b443a38102573cae4aeab5e4a911b02b0fe47", - "XMSS-SHAKE_10_512": "edd6ff8923afdefa3ad7b5158f2adc90eb58c377b847c5c35508546a7ea2ca3c", - "XMSS-SHAKE_16_512": "537540146232f6647c215e32ae057fc9cf3e83932a6447953c7f9ac5d38eccf0", - "XMSS-SHAKE_20_512": "e803f3af92cea3f8004a94484f8f666b306fa353c3b09e9e0763b63f7f9b20d6", - "XMSSMT-SHA2_20/2_256": "da52ae24ebd6fb3ef85a80d83357835164a292fd8c0e83a32c21d386969d5c0b", - "XMSSMT-SHA2_20/4_256": "eb5a0afd967f660714b1b9bb6a214f348cfeb06e474048c94d6e08de183b78fe", - "XMSSMT-SHA2_40/2_256": "0cb74272d179eaefc180303cfaaaed13093268ead2b6e3d066228b64077609ee", - "XMSSMT-SHA2_40/4_256": "16a7047724db2ff45999a4e95048bae3bac5d645986d6670014c53478412b4f1", - "XMSSMT-SHA2_40/8_256": "fff5c6a02f8995342199155052ac5115af6340ff9e729a1609c815c891797111", - "XMSSMT-SHA2_60/12_256": "2e5869150c17da8c13094b66a94a94342d62d035fa63bd972757f3eda2c9c248", - "XMSSMT-SHA2_60/3_256": "04b10f0320cd77b8094b1116d67085b38a0d68f02aa9b0ec5938a511ece1ef6f", - "XMSSMT-SHA2_60/6_256": "0ea5be22f851a84e1bbbc21a84dfb5c5a5d2f5d636dbae49e1e092e6ec5833f9", - "XMSSMT-SHAKE_20/2_256": "5893c3acc4ab1448510888ca6c6f483d1ed247028900752d11d2ec9dea77356d", - "XMSSMT-SHAKE_20/4_256": "eece12452652dc37d1600b39e4bf589ac12bee6d5e5025845bc06c7e5321669e", - "XMSSMT-SHAKE_40/2_256" : "c5a539dc3cd7af4710362c3e9962137e33e4061099bb2dd0a03eff862c9cd01d", - "XMSSMT-SHAKE_40/4_256" : "b25c826e97d442ade70dff6e7008e95c099d7cde6f533fb9059299d9e1ff200c", - "XMSSMT-SHAKE_40/8_256" : "cf301b7d978d5c0afcdf3300ba97d829e2e5f737cb449968b19b45f05b987591", - "XMSSMT-SHAKE_60/3_256" : "09d26df5e911e98e71ef73a1ab6f224964d4a7beacd8071b4c7f7d1930a537bd", - "XMSSMT-SHAKE_60/6_256" : "0692a32e318d5c3ac8631120910b783edfed4cb7ed69e3ffa29f83aaa34e27d5", - "XMSSMT-SHAKE_60/12_256" : "1a05ff4a4fea850a5fe5c9e976006577335eab0494e1759fe217c2f33f5a84e6", - "LMS_SHA256_H5_W1" : "6b5ffc953ee90b32ee4f1972de5bbb8f055073e831009fc3004e1ead32ecf64e", - "LMS_SHA256_H5_W2" : "68f4412a902595e6debe7da1af714ba3179e2ea21053d8fa25acc1bddad7232c", - "LMS_SHA256_H5_W4" : "01c828a559c5b91b3347c4a1ff5040a50371b7056b4248cba6b8d35080240e37", - "LMS_SHA256_H5_W8" : "f8bc9145732676a2017a3cd065cca68d224cef1671487e3cbd921bd9c772c745", - "LMS_SHA256_H10_W1" : "276a037406ce9f1df6a8ff87f6b892d45bd42af5724a2ebd3fdb1d64b3d94d5f", - "LMS_SHA256_H10_W2" : "c59da910cf06a8de9f0c5fd4b55895ce1996a55983f4c8d9be328c5d83831041", - "LMS_SHA256_H10_W4" : "2ae301108ed8c9eb363e423a483925dcfc089720cd5b9cf8eee62bd1869c8182", - "LMS_SHA256_H10_W8" : "3eac8278b3f9eaea6361ced30149d2d3136c153c6e45d59899af4322e5df7941", - "LMS_SHA256_H15_W1" : "a68af38d6c955fda6c6deabb6925a686ad768ffaa0f6a93d8649e5985dbc6be1", - "LMS_SHA256_H15_W2" : "3ce54ed403203c996c50bf50c69492acb7cadbb41521c2b7d49baed65fe2bda4", - "LMS_SHA256_H15_W4" : "38cce574c163e6a7167ae328dc6bdd44c60d4e9be08408eaa6c239d8625d5a07", - "LMS_SHA256_H15_W8" : "a2e16430224b3caeebd63397e9780be087efcf672421ffc5008f852af2597692", - "LMS_SHA256_H20_W1" : "b31f8b45eee9ec551178cb260cc431256ed7ddd233e69de1587579f0b8ff0128", - "LMS_SHA256_H20_W2" : "0d9ced22271ab0bf90968ec4934a4a44211ef25df11e562bc32767a42cd3a9b2", - "LMS_SHA256_H20_W4" : "7f52315a8fe04caee69874e87bc0f7f4ce38a250f95a0ed39baecc0cb55cad54", - "LMS_SHA256_H20_W8" : "1f5d5a149830ad72a9709659d5968997ffe4a43e034a5c72550032ce6dbb53c2", - "LMS_SHA256_H5_W8_H5_W8": "fa6f9a0948626c1e078ad442ea2fccdf456b529413eba441c175cbb681f9bc32", - "LMS_SHA256_H10_W4_H5_W8": "2485c56164bbfa4bdc8604195bf397bfe8f54e2ebe925423e4e70fce173c0fff" -} \ No newline at end of file + "XMSS-SHA2_10_256": "7acc06cc456a087456f937d07c7acae2ffeee517cf71b1693adc916f638df388", + "XMSS-SHA2_16_256": "b20ee19984d6a47529c8e2c127e43e619090a7dff0f2dfdc750d96b6d2453275", + "XMSS-SHA2_20_256": "0632c1e3049918a208676d9d39a97b81f3296665205ad342ed0f0042c7ad848c", + "XMSS-SHAKE_10_256": "f5175c88db4f0ffca54998e0e46cc15d02b5f193063cc349926e493fbe8c39f4", + "XMSS-SHAKE_16_256": "519f61b7c839cf29b4a67b8fa9bfa64a37b360cb98232363a7768a5004ac8a37", + "XMSS-SHAKE_20_256": "0b1e25ce1c89709624a3a668a4ac75ae053f1306b5f461b9424ca3ae6a153057", + "XMSS-SHA2_10_512": "854cb9aede50a359703934010d08db846a3a8c4b9b984471cba74ef07d620bc5", + "XMSS-SHA2_16_512": "772613c5d30da675b87a4f3f932ac71c7dc3ebf8803a9bc12936e6683c3f60d1", + "XMSS-SHA2_20_512": "7ae409257aaf6756ac9a804aec3df8ab98916e026f6ffa2a78da3bbc97dd48b7", + "XMSS-SHAKE_10_512": "8142c58d407dab3f39f1142e253fff535c572d5adcb4fd21b51a62eef33453d8", + "XMSS-SHAKE_16_512": "29150754aad6d8150e86f58224f72521d76d5bfba43d5f54791c1d5def27a205", + "XMSS-SHAKE_20_512": "fbe74ab00eb150f63b9da9ddd325b667e55a65bb994434ccf2c7b670e7e22406", + "XMSSMT-SHA2_20/2_256": "9f117294999c886ac6b69d6f32c3fc152599343add210f4464aee5d1ca0ec34d", + "XMSSMT-SHA2_20/4_256": "0c990e8ff8189140e8539b11ae3f85040544fc7d549f8db17d83392569647de9", + "XMSSMT-SHA2_40/2_256": "91605c4b67afb4e17d57ed076e10d3c4287264deea4a46092e374199c041d489", + "XMSSMT-SHA2_40/4_256": "78e16d2935701cda17ecf493f5ed292827c20f0bf34c1c63c25c94f028ee62c9", + "XMSSMT-SHA2_40/8_256": "f0feef94797276e832634a3b55020a8791dbe14d400e3c076d4f8ecd53892dac", + "XMSSMT-SHA2_60/12_256": "7bdbc5498d33dffcb32675df8578d8ef590f0f06cbac6685342a131cc34bc720", + "XMSSMT-SHA2_60/3_256": "62ee9b8b9a46ed95a2e4fb3d18552fe2e87f91e530b0fb82c5edb1242c0e0258", + "XMSSMT-SHA2_60/6_256": "5ab099ea120729e8b4fbbd074bc7b60396c009a69725eeefefa9d89274b2ba83", + "XMSSMT-SHAKE_20/2_256": "75d79d1a8a0cc714a97acc956f12040808c9382b37e3fb2d389e5ad29a1f3b53", + "XMSSMT-SHAKE_20/4_256": "391f4d0b64d1a24f53fcc642bd679f4b6f9230abd1c4641f30e6c7d7dee451f9", + "XMSSMT-SHAKE_40/2_256": "f2601cb4acc1422852ff3dd933ed84f3ce4dcb0218db6f43793bb146e6b75a10", + "XMSSMT-SHAKE_40/4_256": "eb578e8b7d7dad45e99a177abe482fbd087c9281767b1a3bdd660c2d5e04712d", + "XMSSMT-SHAKE_40/8_256": "1597d62ea8aebbebaf364141d1443a804fe3f6d0705165a55794096a4a3b1c71", + "XMSSMT-SHAKE_60/3_256": "7ca90f7c64b21d844975ef39c48405dc61922f6fd0be8cbb88b2a18a54bc754d", + "XMSSMT-SHAKE_60/6_256": "c11ca5be510f88c9c8188cb98da65e7d4b2be1cd7efc5a9769348c4fa2b33b24", + "XMSSMT-SHAKE_60/12_256": "79b6690809f1317fbc2466590e4fccc8a7f706b05abcb277ad1018565096ad88", + "LMS_SHA256_H5_W1": "26273b16351d40b7a7bf73db200c4494cba890624235d214bca9368e60cd1c02", + "LMS_SHA256_H5_W2": "a4877dbf9f06a08469afaee13cf25ef98e20064d2be0009888c68698995aca7d", + "LMS_SHA256_H5_W4": "e13ceda1f66c90cad1a15087f26bb025378f7fbb69ecfc138ac365a9bf3fb6a5", + "LMS_SHA256_H5_W8": "175f2b5b8a6e8a5faa82bdeb2779a88cc977ad7cca46d815b0d02c6dd672396d", + "LMS_SHA256_H10_W1": "b52bb3ff8fab21d69eb0933f5eeffac1380f87c1c8154983cfe4f3f27fcfb1e9", + "LMS_SHA256_H10_W2": "a1a2709362ac8aeb956d0d88cd4a42ce2fc8df9a69979270299b9471f61c3dbd", + "LMS_SHA256_H10_W4": "707e4ff1adb835f6e79453caca0c787c156a2ee270b1657a42ebbe6eb7424494", + "LMS_SHA256_H10_W8": "799e7bdf00fc0839519e6847b7df40763b89949e1d1b99bd5b9f669387bf0fbc", + "LMS_SHA256_H15_W1": "af9d334c2d306bb1f5409f45c4669799c952593cb23e1ecd5acce37900bf598b", + "LMS_SHA256_H15_W2": "0c6455312cd68eb9023ed4e74474c000210d67d042038a62dbe322a3f4c43c2b", + "LMS_SHA256_H15_W4": "9e2a4d4b52212ecfbb0a1df877aaef0406e373bcec54597df81bd1d300c2eaba", + "LMS_SHA256_H15_W8": "ea0f3dcdcf73a2b990b86707c480fc698f9325537672928064c9b40348ce1cca", + "LMS_SHA256_H20_W1": "5670ee0668ccb704e15c9f6e42f4a017f4b8cf8aa34c311ca905b1b538a2352f", + "LMS_SHA256_H20_W2": "53e844066e5dda43713261704c6d07b785373dccc37293b2cbe2ba1b7b961382", + "LMS_SHA256_H20_W4": "55a9c196d69acdff73b2e95f9d0bb97b9edd260bd93f53b5ce4f50c26d6575a4", + "LMS_SHA256_H20_W8": "2594c05e1ae86a029ff42a74d2b3ab4d0adf01729f4fbfe81269037ac029c184", + "LMS_SHA256_H5_W8_H5_W8": "a20ce5f27d9962865463223a138a7507f30690ec7268e802eb6ba2f04c6bd99e", + "LMS_SHA256_H10_W4_H5_W8": "f51cd27e5a35f63586796a39f00d6729f5148fb6d454e61737fbdeebbde3aed8" +} diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W1.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W1.rsp index 206c2dd284..13e87a9215 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W1.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W1.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H10_W1 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 000000000000000000000001c044f6230d8e90854489e823101a65fd2f0ef7ee9c0d49fcf5a354076f3aee868880df42fe232b55bde5016e05e454850883a80d3570cf9ecd0c960b9701fa0617c2e0b4a730c7e1fe228ac702e0f68c0ea9b3985e0704db86f1bf0305addfd7b7db7617bc50db44b28dec65d4727393a6362cbaac5d368ed18e0f4b06d77088d97fe31a2276fc39885891915bd7a738aa81c360177de403ec91338f2c3d6097c7afbf153370a416161c03a4977ae1eed6ad61eea2d0dcd081d2533499c213cef6585a0210e8f806a064f739e1d3e630ecd4e422fa3967895ddda5621b176e1e4b3f20c11f875e45d7ea0f765875376cece2acd7ade36c52f3511aeb23624fa0b3a4bb554cf8abfe8adf0e5129a821fe71b0420ed90ef0c670e68ee81897a3665aa40bdc6e86614b91e042854b71fb1372db99872bdfd7979e8552a2633e8d123150f06c6ec2316aae6bf64ac2a2db5349b7d08a7b9a97152193747a69081fd3b57cd666cd28555e531bb870483a0144cc13075dafae36993b1aa3fb7ddc6dbf095a7c2142ecfcab40830a293ea6303b5666518692f468bdf82c0e802624621c5cbad8056aebf836506ecbd4992ced3e8c8e5ba2633591f3b0ab3f0fd61ee396a7fea0f0661d8271d56796a48cc88bb555c74c2b500d512622149b13a49550597cf1b17e140cfb3738ec36a386f1d9aa92caf1e75e7c9c819419a69e1711e4fd461dd1e00059e8172f0c5f8550c0a95b1eaf9f2796df7bbd8d0e08ab1a240a6049678f481a0097e3fd05359c78dd6fa3d9d53bba7fa3083f041820561703c5a5f071f3b3d33024657840d72156daa207a8c6308af5bf0b50e476292d95d6786092622c109d9fd388dd8f9f2bdfc31a95bedf6deead4760a6e76b363932246c8437294566da6f372dd61b1a0d957f7393c7b3dc43d26c4b413380d1a3e9fcb70c8c2028932b913fdd0e81b360b76b27662cc1e8119db1d00e35999196918fdc1763aca80c861bf8563cff7f62fd5c4713a5a44e9f6fe9ca3855183e1aaa120d72d27bac94aaf7f2216c9b1287c05e60da13799ebc3f8fd2ed9cd873707d0f093a1a57e169d88dbee305c7e08cbefa8bcf2e643dda0f464b7450e57cab132101e0da4612941c50f809c2a592e6c15f791cfa91d4dee9aacd064a4e1a147a52ad353710f15db8159e283ae8399620b58401373fc093d91303a9bda436a23390023897bf3747c55a103c18a4f40dea1029b2ae1c6404d0387a7c5c7f1202ba8cd49c451d9bcabd23489ab3a5e82cef30712c95d02bb804ab01993c9e765474cfc9cdf9b7b68d6e6228f1481e73ca03138ff76d92d37dcb5ba9047b9ca8cddc7427b1d01f33114a2262df1ce69711920fe7ac428b2a92f0df08f3059be97e404b34d1ad3c04a837d76b3ad7966335568247f386bd5fa9de5cbafe53000ee3559eb6c06a3a3c85fa8ecd68e2ab30cc02db71aa9cfaaeae95dde704b353945198f75874dc746b3c169bf2edd15cb24f7414a070643b882a39720804e8f845dcfcd4254fb717d0748a9c9186eeae81b8066533b1dfed213886fb579e660bb2b9660b6878b02b514bc9ae3026a161b23bd3f1e0ad57bad5a4861e8930c20731e6dba31a6de742820384611cd2ff2e392a37402ff7016ee68d2ea04e00f7eed62a5c1fff05c2e32326b37f19ab7b36b57f43ac4ed784ade45dc2a7b69c5b93fadf362920e23bc000b2700c8b3fa81f43149d2a1300638af7c780813c11bc9eec1cfb3e719a02eec19c0205581d371f2d4892e1725f286ea62fb92bcf002b4ff2cd03c4ce8de4bba8cab2b3d060ec504f51de9858e4ebd87700192d06062fc19b75709215d080e04f2d1bf1330336c70d21d996f5597c971e6a91aaef92fb712908d1dd6338be54fe6b433752e92f4d841844f63bb42fe25eba83978664ceb75229b9406acca437b627b262b4f73d2e6221695f8f8e23cfde9c4933b6d22705536eb66f9a6bb8892c5fd47b014bfd81bdba6bd53e2cc5c8e4af2a275735fb974d675ec1abf6a4b46ccbd7eb9853252055143d054dc22114fd12a74ea3672952f6796dbfee528e744ae8808fb94f44aa289465805bac2446e1e2652bef7a411d12f8f28bece67c3d71723aa4c345e91077230e93eefcd19933b2ad7ce6f2a4e716b22201509a797531856920a3ad3d0b256eef648414b1ce56193994035de4f755927324300b0187571683905acae0ed98a6c9cc5487aeb006a4e8b20077ec6749ed8e8d6c1ba74746f47580d6fd834ff19076a1a53d4f627d83c8eeb54383071eecd277531a1f17b078a57875464d069f7de6ba87ebed03b6133b70807989aa1d887e875a0dd6caa1fb7577ac7db6196040473c5116c19ad0f78add6041d3790b8b124fb87d3290e14ed4437a040b557f6a57bbe35df9ab0b593998ea6002a7d33ea0053bf07ac82842d8bccf0f8f6366e0a496e4470825c00d5f88c4726f4e6bffe39aaa127d868b71ede4fa178501888a985241ead8d21145d0e78200ffab22b38708220a6313b507e3282dd575f070868790efaf886dfb4d18144488fb992d8e8e9983151310ddcac4a6a10af0708a10b9e74f46c972a852d1352538849d53f23887bff6ad1d56cec8ee77097b50184f27efd6ff5643bd8f9a7438bfb00937a13a6a65ea4cf70c2287a80c2de433878a504433fd2244c59d8f65e907a15ffefe7b7ba487e1d39749aa3503dcddf071c6e904d98b070c2c226da31fc17c649dc494263009abdbcd2bfce0c96d2e53ab169cee718c4809b3e1f49d43d60369b79af9c0dac15799576c58163b513db329729fd391a4ee5adc3df2f6cffd927187c2714f2f0ef52796550d71c93982e1406b37221cdde3da3675638f5c9ea2c4fab3ffc03519616a09138be036a33ab7f3b025608b3cbc263d44729a02d3af7f7aa587ad2661067cb88d3aac03f3efb3f3eb7da876ed42a7b8292406a965bc3da2fe2f5d815183e291b0a667e442ff907127e48a6e7aa70ce6b893720eb4fe104935fbda3ce1ddc4f0c2cc8ba6ab0e66d1850ecb32ed50f3767763593e8223304ff768ced4e03816526b6d3958477fe2ff57f77a2a1c80745a3737883196aa7aeb090655626a3d3682c9aab46fa0090cb09c398dc14be9a16a52281df2a875a2e7690923a8d63be691e6c519ae41cc550c8618af002ad5b826badc763762046e4ebcc474b3618b56fe2deed72425252390c20fda469d4ea19ba8746aaf06b10e7dc822c0ef872ec1b85e39c3b2944d1680964c11f5eee844bb6b9d97952e29b946c9c71fa0f7c94dbb6cac5b701d03690b5ffa669089118af04e42e5a12ab0b7199bcdfa41933a7de4de50239ab0f82ba223fea923c2ac4bb37534aeeb0abe8883cb458a8388fb94e0e1c7cae58689d297d8ef2bfb356993f761754ac1ffa5670b69a43e61362a3e71f99d0f1d95ab0789d8a831efa30a388d3b3f191237026a541f556b44d67d131c29a9329634bdf7deef48ddfb1636b9094ddee01261e135c7fc782faccf9489de8ca1b2790af3d8b77ab92a9dd992139a6fc0f369e2031bb9df07ad67bbb7ed9366f214ff9efb115c9510b219afbc7decf1de3c0e471adf5897189745dabd7525c760bc49739f1a45ef64f126de0dde44e95a44801a617191e960b72a6a3d362e84b7f8c0a852fae3191a8be19e4fdef968586b20dc51b78029722d7f44eeac63e50a3e19f9b49e2a47495d708e59091e78f57e4e17cb8cd37971aa83ead384da8fab871aa3a90a506fb7ef2cf316b626bf0e34a4f6718af6df12dc38ea7b382cc5bb5fe15ee5c5fa54a54824e31faaed6ced9364cd7e0692d76979d95b0ca7c1e912c9a6a6e882e2df0e143562b17e33c81a5d7e5c0a44cced6bc961d11fe6d7a7ceae323f8e136842982ee764f9b7622dcc43639bbbd55207165aa6525415af15813260e9b7735fc68ebcc7cd8346cd8fb661aec511e5a17d11892a5c8cf84d3cacc9971edf88f979be7f891aff54de818486d03f51581e10e12bbb8ac43587d0b0e87aa0c1302346ae31aaacb290968a56b88b7e06c99591b5e096f638f540d6627a0ec9c0be8a71426c7581baac231b8cbbbd8b1d4a8e6332782aba68c61c274fd39b2c04fed27ff8c6afffdc285f652fcc3e4f81fe2667f04f0aaa043162ab7fc0fa2e5dace3ee139bd7a2a7c4137b786e8e631d39313ffe4d6359be064b97f87a43ea52b59830a791399b60e567e3ab072ccbc85ee731cb0e3eec8eb588dd38b9128b948f9faafd1afbcd1c22808746306085763bb36cdac3ebf03c78c73522e7f9b048450afcf26aa4e6ba5c0b9d67a4f23a1737206e5a455fccaf939616dffb2a37bc4f0f8b07d50b6f165013fb8b19b7fdbe5fc963bf4ca5eed1cac12dc25f0bdbd7dfd155d92d7a67f5996684558c2391f7491e01777c8b870de45587195883ef84879185646833b305ff883b67700a2bdbad3cecc2c72c29f31afe69ea90d62b07d77985c6b66c98536abee2fb469beca6231a7b18e9e2f15d2b5cb1413ac0cac4306fab163abbc7825882f4469c819eb34e090980a7855289858967d68bce082629d1a284e128bc05d8aa3b20d3bc1cae265a279cdcabd582b3fb52afbd72f57402289946f9abe07b2e4a6e4be45996d7555eaa95c9964254f8a97f0d4f8dec47b451ad63b79b463c6ba27e81775edf8eda9d6109ee75534c7eca0bf0922cfa1764cae631535daa56d9db9af3ff7ca7294b6c8b94c416970bb5465dac9b437810ed393724d8f4b9aee0dfdb76c80634c512182ca3a61041f3a9ebd9b0ed13fe80ec347c60efffdf259f39c87cb87a107ae7b66f847fb30d62ac3fb3c4e364cce8a2d1c1b68da478e3cb18966510e3133f47be63f2247d95acef4959506ed21c4ee3a4dc2a6775feb0c317d6c96c58975901fd22a3cff32618b01d027ec5548ee82e7c6cad1401ec0de200d4ffa816a5c54ac344173a22145883c657d6b10bdcc522e9ddeb13d8c7cec932ef28dff74703f4a74fc75f75290227d11efd2909721b3f70a01db8b5a87c9e0bc63b30b2de13de8c0e25a91b6bd047148060f03783e6626252c8b278217d10df42db3b0fd1f7313270c141fadd1217972f3f78ee16607d3bb726dbe289355e1e277338bc60feedcff08f900d289db8a1e1670cae7a5ad5e4fd30aa367fc74854ba9dfb4084aec45bfdeba68ae85e9bf938b55b2db19d7d8b6f875bb2c74c2613edc3394d0e5bf3e71d01c2ee71d983083867efa32cae1c5cefa3089ea96500fe21f19920c8e182034fd3c009f9e48b6e49f6e691743c4066b478f73853f04485df6f3dfed6f307820c293ea8a7adf48a14e081b228136a74a51d59c14edd09decbe2903c4da0436e54b83626b678e75e91ac2e75e4180d6e1807110ba68576e59f80115926a352e8bc2d69e99b12f79537bf1264408fea3f0b6851d82557228291a39cbbe590f66b530fb022a7a3322b6a507fdb48f128c465ab1f98fee8ea442d957d14e3d060eed76cfa6f0d1cd1de93ec216bd5fcd9889afb0ca02c9ffc52fb92d76675dd30a4d2c2f937b7dad5044731a269b80c73f52db035474b6bb7f2124f50793a85818c0a1778ccae570002c695dc47641791eb89d7aab7370644fa9ec2f69c5349570cb0bfc9af395ec61589313121ae1a111028e0797845902fef6f2c2caf061d56674543b455acbf078378af10083adb7b29f9c347605c5d39287a5c94d6d512be0bb131ce06df64f2a5bf6e072b8d374afcc7a1eddfdb1d4ff98f0e2e015867e623f124a821d38c553ff4b899ea2e99fdba5b88ad921eb3c9a5bf42bd534972dac661eca5deb47c47bfe4af8bcf042d9f111613b11cace3332438cf10ad67b0e8c12faa1e60b460057cb36a719bef0fe9fd6dd672b30ccd61ae5d559e83b62bcae72db42da2b95217a7249fa8bc6878b9fc7f59c2988a27e1706bc84b47600ea42a45c3830752f00e33fa3318b2cdab84d44c9b7156bac88247dfaa5b3b7734aef4e12ffe77fcf399ef3916725ccd1214647339bee28b78c7bdd490ae7e8aa68e50f610ce12687e0c2faf91a2a84492067e17a7878a70d08f1f66c14aa556a2b9898273d4b7fbe5166baa52e9fee4daf24c9bdca63d543da430cb15318b5aadb721153dc6f3756c2f26d22780026e0e340246a5892787d6caf45dc3417d27c093d974edc3de8eaa34ae760081076389a050fd3b78f2e2c8c75250443f526361999f23d1a803c72246142e0203cba42c9fa4791623f7ffdb0fc9ae339ae92bcc66fda3e7d343ac701422dcdf4c89a2f2044d44093d225addaae2c3848a9e55c1643abb64e1222a33edfe62d44a3c146b48ff57c54408be6ccf605c5f4d97a1a4932d5bbdcebed5c6f8edcc35415c3be2cbd09166c03b5796417938ec7102943a9174ef3c377db5eba123b79830bf9aa9d6ba7094dd691400c1849fd987dfb94da5bc76537bd38504f7625d53f7adc60517e0b6420ab8d407293c1aaacafb9a73ce02436648c1343a24210a26fed2f6c73afada4d38da06231bbb8b7ccc1a9c045bba93f46abca2b691a0fbba1223274a9ce0e3221e4c606934ecbcfd5b1e6ff4bdb6c1fe1cdbc1b1a9fd3a4588a685ca786ab503767ba620d878f84d7b5338f0d9b6b07043453f53505e9d7e26f85ad8001aabdf661e92c06a8fac95590527aaffaa9502e689dceceee7322e63bbdd6dedf6c022c4d2fbe4cb68cab932a213a7dbb78e1c3d2dd8b147244faf11333f857311d3fc060816bd08b9bced8fd5c44ca9b4ec37355762caae31c0d3ed6b54ea06b46f6bec414e8ce70cf5e5ee2ba4d6e61aa7bf61d8fdc790d3f7e8d83df50000c9a3b627b5a79a974bc49ca887d5c81c4908d8a7b483f1cc8984bedcc346096ad8114722d23fedd319dcc95d3cda9f8a4af2d888751bbbd7138ab8d2d7dbc3a1505ac7675a7abd99c46f1d33a1b5e743be3cf002e7116eccd515cce11a46e198fd532bc0efb696fe871371c422486f5b0469a82869333a57df8a917b15f91960411743166c93ccd551bc48a779812a66550f4c4e395747ae09d35b28c466e5e61dc9f30ac2124a745bd3607b74021064bca34fe7fc99b5993ca0c35f8c7c751d35de70c25b2ca1e8e72e91841b9d9d436e115791ceb4a8e5ebf8bc232dfd3703975f0e5f50de5bc684232fff7a3a9da09cdb17c719e004d3354d90356bbe97624df21295cb372ad491b92d5b3487ccc27d4b65f0452a944d1f1e46a95c2d2195162f7fc76de43524104b6493dce02a8158a07504b37edab79c6cdfd4c849ff31d1b62e62516e7b306a8de7edf39ca6065cedced468e04a99585acc782bfa5e82372eaf284e5af5e9e5711d1188afeb3f5f4daaaeda0f018a6f69bb0eb5b9e759b846884889122a3cb2619788a7abcaa15a9a6296924cdb9e83df9761c0fbdc993a5d93a01f46d165d6bc9ba409ba6f16e4948849e9f03b3e14404df153f3fe4f10bc67bfd188897f0adef44428508733f11f49f10497e78f6070917d5b93c425ea628ac5c9fcce0f782132d74cb0347d90b3aabe395be584f497023984fccebc79d6634390080042567c4828ec7176ba8da4e05aa15d0e3c68f07caf5e373b8187c33de7387adb464d5e90378aaa5223d1360961f315c53c8cf6313c9fd48645f21c3fa7c3c1a685b93de4453bc09fc3b0ebdf6d52cc521818f1ba0c2e88fcb07a1a3f4e8cd33b9f0eb6fa811100169c6d4cbfb068bb22c618edb5c3d2cae01810151ebc960254284477ee68cf13c2e96f7aa5fb2666019d8abba36cfe9687658c378003e4e0d43d3771a850274d63d05686277ba10fe9fc134530f671344f77d5b9195fabaf5559399896222aecfe8d8bc4b1013429716ac93e676cb4a6326a0a7be15e917627ef9bfdef640579adc8e7aadd16f5c3352806ba9d380c65f927e1bab8fa0c1077490875890bf814256147ad951c5fe2d07f895946aae7ee5a24374255455d5aabf6104be3e3f4a4b36dc466a68486f1ae586e4db46da74dd3e195207c0f1fe34066871e9d7b28513d6b31f4f17a4a8a7a2e81b93c9c760c2a93ef24fc1d0321b64dd65845d1acf2d4dcc2fc3917935c59334d0e3268af83ccd350162d8e8930f04dd31c26bf2ba9d17168ba0f77451771bdcce1ab6205f2a8cf4df2f583a2ff43a049baf2beddd7d82e3239f8cbcfd50538656ffac80253e419a25b93bc931de0a24c9a37444a56a62d00ceb02664ab597719082f78ad463bf6d999f8c2e3cd0340dd1a5fa44c78196af816230ba3559c1c3bedae23a913b3d5b65a77e2a8bc6b39ef371cb82500e0124cc8179d26f8d9b21d82b1b81b323f42ff02584d16b020ff0319cd886a2b2492b4ed1c27b3f5b51ff759650bbb17643a18cdcd9f56b5e3e40c6762e20b147e55d56ee9773743db41a296fcc40b326d3e17062ebcc9720171cd8872001a9e5ee6135d1b9cd16e538ff8ba2a2d8ec3f931cd971b4757f4c92f840b0d985fac936ae6ab492b09ceb63ac80b13d5d9c5fc4508dc0cedb5bca1e2398dbb90c371696d93ec80a8cf2b6b9e5ee1a73b031da2709b4a6987af3bdf44fe2800502d10622884c562540d20c2c823eb92677d3accda6408b9ac3167adf889472c93405ffc37e2acfd8e2495725eef98b1b2c066af0e11a287e0313e63f79262e22921265614dac795912ac60ce6b626d5c2ad79420f136a9db58d2536d3525ebe30a00a88e81a787700ed2a077f6b4c1b6019115283c1d8a3a27dd4349fe0e77cb4b864c680dcc96410e00f5c1a09e6aace2ed201a8a0140c3156bd9d3ef2b08312cd22f04c2c7d08d7a298b7819d5f3a30877ad88b35aa5efd00cd7b5f01f0a5b491a6a1c7032fd19ce2e8a6e04693bd7d9481ccd22b57a0b8c749d975ecfc07e9c5205ecf4fa993ba866f5ae6eb45ad4518e3c94644fa5911141acc37ac2bf123ca70e627e604656c3615d38971e571019793e535a9ddc756dace6e1ba5a5d0135b7347d85d29adf6cbf17c6177346e4904353d5c8b44b2a0dedf4a039a9d945370697deeae5a850db0e8be9a003ad36ed3fb675ef5f6e386da850d3223549b1b6305159bcef54b3ddc39ada9d74d97ba4e7cd78d326c39eb9a9d5caaec9ac7ab7cd30181a9410a98b15a69c168c78b9b03d723f57b8be73b3698f7fceb5ccd92cb495a547ff2706805d97819a6f43d3423917f877dae750ebde6f81fe200b59c6dbc8565ccc5c96c55125e851783f3b60502df961e971fba37fbc592c05222bc1185763a5864479471ee97f05b1a953af6faca1f7669cda1f1bd7a4ca35d286cf1c699e4f74177f1a9feb71708c0404fcab769fe49fc0ec8ec2a8e310b69913f07ee69ece421379e0acd2381c7bdf9d877d847419181a9f27500b1750ee6f714beec530ce962829bdb9f1d1d6ff5ed7e28533abc4d3f31ca467627e34a89bfad4a50ce5b7c7409432c31319d98a0f986d4992a7709a949349b2caca79eb0fbb6c481f6e4b2cbf4eb89581694814ec968514915e92be777900564f99efb85d872bcf740cdd8f90b4c983f8677e43fd30f622ca502680f9f85e707c74f94e18e3fd9fa935f662004dd4af3d7e8cadc5bdd119806e2f630fea565dabdd51907035c8c8c4e5d94e37fe5efdab61ce8e459f5dea5a8582e3104741db18933907ca05c3fc93688fd75f60b4464a46a44356e78e8dcc8704eebc2c8c12b89ae7f3d64a9028cfb9b6284833695f565f8d6db30a2e597683c17e0529f653d6d90f290489cdd84b1b5f01a130c85b6ccdeb3ef3ff7ef8d8a8c2627aabab2b43e6cc957eb8165d6debcccb225f4d8d49ded27d1b5f9afbacc317fc289b951c22f390b91746c06d11e4c133318e24a62067873ca1147ac0f7b8b572ff4287fabd48d587f976d2b5eae6eef4d2acb924281891fc95304d5f99b3d0adfb3badf173b7ed56b3dc85fef93f917dfa4a45ce34ea61661e772e480c5bab1c09a07e3d4f5713f47f4a97f476a8188413479e6c0320db6b9a7ea2a05e130bb79eaf350b60d1d8936b29835d5fa873f70ed264dbfdc8172706ce713d7b52815bc458ca41f114b0897ee65dd59351db4fc4a069b344a1b95c53df6763f0e498958cbd3499c26fd8856cdfce17e8f8ced0f50a9afd62bbc2b1955bdc2c25b0a806f69e237cc2609182ce2d0916fe200027e038cb6d8e704b34ae7eb5b6408b42bed2f0ff03e3fd0e42b510cf1b0f9ff73c57120edf67f8742d75f5d7b8576049ce9ea5bb2cd8f3ad06e57b3155ef85f7539102c94bcc6fdd0a9faca161315c77906c5dcd6e0278498ceb2807fee87a6cfd387dea4605ff778449a000dfb7d79cfc194bb70e3e9f0a9c63faceeceebd47faff72f42493a18ede63f2cd06fd217d5772479d362055e27837157c047c5ef0a77bf5884ea78c9c618b571ac7dc2c24a81eab1a5d0c027ad5e1f9944d8200160c1a37ea44524fee0dadeca457cd259ac8766732acb7608ded63195a125221fb3d90b16f19cfef20953632dee7af848c75276e95ea9d34449e17465c91f2dc289c724d5179b7d2f83008d994e911a5d739c989dbf63d05dcefbb5a851045ae969787c167c8098bf14e473cd13848ce7ca4e16a440e0ec3dfae770d15201a41cf90b87d0e87ae78c0176b274a3b2c3fd9cb12e7eb4765dda7ed7eea3639b0cd11c862d7e2c65c1c6b0d1606595e9359bd6f94e20b12cdcb039cca934ee01f7f957c343cec9547592b180f6720cf2454b8fc526522c8c3071445d6ca95b47289862021855d9a2b38dd9d39a8fd633db4761a17969f941db403a7c0e260f0c8de4a1e45751aff151e33612dbefaad6809217023844e12f6a8b90be585c948c12a571b30ff0a69aa5bdb4c3c9b5018b77c57980c07dfbcf7667ebd7030406d3110d5406718b8e95d5d035a86dcf2c78fe575ac316d7c44407aa6c68087008433eada0e7bbf670b718830db42f668d203519d294ceb910edd4abeadc3af44cee24e0cbe6c436f3a523e60d0627129e9ea4ce01c5c45e0377c1655e8ed4b8f79ae0b8bef8a914f6326a0477d9f17e59ea6096d6a5ba75d64a94e68c8ce11e8f28eb80d07efac85c64a6c3c493516c7d929859307b33dda16c271cb21f4400f3156337ba02143f38f677b89b7907342fc16cc14bcf00ac312e0a0f9af6e0be926f345f556693d730e667f7f25098277efa691ef155fd65b8289c1e92d67dadb608902cbd4b567198cc776168a2c7543e58041a3f09989994a7aff610f9b35fe7aae6a8d43b676778dd7a8dc97475ace615e09e101de1a8f5f95ba082f296715aebb3d4ccd5f8d000ff8e3dd452a79f4b9ba75b7ec71545bad1c2ac91898d4564db141e42290a37390e0f4058274ffaed8ecba88a976761d716096babf3909bd37b873f1cd98cfbc3fed8978928c69211365519d30dc68598addf3f5ea2d0de53c4650d9b183834bd89b2fd55e1ae9ec2123e0fb66b8abb36b6ba62da3cc205f24edd14d68d355133de0aa26dae7c5d7b8b60bdbe4b6daa43aeeeeef410234d6b179557a39186022394615629430f783c8fc1efcfb23df92267cb81bdd20bce73f2e825d31c52d99d27b77a4cfe821d5f9b4d77c403e0640b0d53e04bba350228aac6a36fc7ec513cae4b832fb7de3b1938fc9aa35efe1df21ac41905fa9141cbe5719c3c3b73bc5b3d1a49d4c7e8e8f31f653634d8494b18c439e1f65751ecef9d95911370ec9c6ee74f632990aeb6ae3d04a429308177b6a7703b471a5335e2d356534c92768cf92e168e07d971a7abf08ab722622215982c97eccdf381f95c490f3596fd03c8465cdba4f9512767855dcc5a082f947e8f308f584d0971469fdf742dbdde2dbe79e97420f9f61076fc0dab44902f324f644ab22dac6374cc20f01e787da093ac0025e737fb2fd795cdd4f1da73018da1b992fab997189ea359c2cefa0465963c6505d0830ccc13c010295a61f69875e13dbf596a5e4320a648f07a9ef5d29c92babdf2757ebac1113dd761b2f5fa1fae5365aaea3ca3d0c3ae1de09f78ba8ece95e200000006a3761dc5d71c1cd0c210c04f7d6a2e64411150e168d7a5e83d532feee580087a78cd5fc4e68e3c9a2b34f4f5bf46a6773102f940d108e236c1830219c1ef88b8fd4846cc3f5f980b5aec0fc2a29d4408ad375735ce8803c9fad7b38c9e98dfe1dfeea1a3e57316f52addc5b501d133bcd1ca2e6a855f1705b6e946b2ee206446e1d400c943f425fc82ebaa069233b625195ab5bfbf9692d9607200c7442e33afc6cba48d00dfae2198d3c8a9d13f8b87774e41640ab9d7c2c66b778eb122e9b5298c717b3b4c58a2748ed811aa75154724454d8672a7cf49c0f9521993031e7cdb863bae7bfdd3d4d91ce8f61ffed3f8951b810594152fee76a4dd1c998f52b071f56a1e40a0b2963fb7ecf2a71952249fd9dd8ff29029d30a381dc6e1818224b2234904a8e50aa4e9df193b12c9d8a6f32b6c43c233889597e57abab57dcfaf diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W2.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W2.rsp index 4a8296a3b8..8bfba122e1 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W2.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W2.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H10_W2 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 000000000000000000000002fbe373f21f0131199ae1967db9e8c8e5e91b55b41c1a30b1074b4aae40788dcb1fe11bc5b99ce8c08bb612b75649e5e7966836669e5b4fafad1766c736e99d66c47d7cdfdb318def37933fecbdd392174e6bf3d476122609c175052b0b03e8ea63aa156096b3b23472ba6f1252285802ad7272a4174c69b255cc64583b543e13668beb8581ca27a10023757560b6f5273a56d5c2dd4adf9ede64a7eab5cdc189a64d91bd7ca4e2d3ea559981ad535e2425911b9d8ab94cb81416326d851aa8d81ddae453fc4cb231a58cf405c0ddeb06f5c67e611a411add275d9567d3f625cfa26384586c435609da22f62ee8f14af17ef86c10f72d2e15fc00d6563e113ff96347e550bda84502167c62a9520d7c7bceb772866f422e8410d62418f7508e2192f7cf28d6192e93bae26533bec0139ebf6869464ed0f62a2b5d10bcbfc78923747fac8f0102dce0f60252b1160406849180a70befa6f56d11daf1ea4a02d4f85e3e653c7eb3b6db7a705d499e51ed477c305d92ccec35198f2bec53133c147ecd694689a5b636f935c0fa08407298328207df0f38a3ebf7dde9985cb71a1129442e03eb414881d63be98361c244a4cc92cad855521da2345eb24b52963f55aa7c7fb13b11b06d6acf8c2108a9090e35e75b10b177351f196002198c7b3e7126df03d1e625aba220bcef06c885a041ef5f33340d2104509595140b64b8f0222474141d0371995fd6461764e87f3d94f6e1a7bf06e350cfa5982de3bcb4c2eee90e884be8c78bf1ecd60d466fb01a33431536dc9106e989f9af03517c78e89f855727c8590567e91193ec3e646f3f7bc99dd55cb889c4751e9209198b55f27e82a14d55bb62324bb1e65a4ec65244c90b755d729bc13cd81f15aace49b1de09ad58f052258db141a8051990edf33c38cab95978dea6b507191251f09f22c9c53300883928c5ad361039751088eadea38ba65b9abff4ca94ec4f5cf5e64189bf9630c7019a48701288a9d01ad1cadba3a6df888e3bbd91d28685f02aac6fe1ce4fd79ddc577dd08b3b3909877694f1482bf0e1011a5953a035f6c78d94d5f18260108205badeb37e6f6bed44f3a7c8fb72e7258c9c23c4ed8463959463f60e2cb71dbb51d0c78be4f817fbc6f1c0287af42b9c889081da7c4ad849dd1ef36b41561322585aa7c12b0affecdb282298b2e3f1dba120a450919631ec0542e1d4923351818be85ddb0d9af8a86b40750ddd65308bed9fd789c6bb127f5e0dd7e5b7954be351411c16985e651e9117bf620e57761ee1e08bd79ff50ecb09a7b9b8e27802c991930472712a6475367bbf60de34e586ad178093245f47dfd068600267945783c61d3afcb030ba3a10d349daec3bd62832260561b621e9638f9123948880bc448e4503822afb4765aa8829a4a41501abe11bacb790793e2baf52306be0fda5f2ad39ccf950ea5101c99fd3f360f6c9310ddf112109106c33ec95a56bf18e6675e365eb50913b08e5e0ed6a8a4eb51e62f2999b50c4e7f933d325bea4e27c629c91fc41cdd0831a9d1173ad4dfeda232668acd172595c9a22164db2e21b15119b45742615cfab51ae7ae500d0617f8a47e3cd38e7e216a3307ad7f6bd675b44db9fff1c6dc7334558a122708045d03dd082fcac0ff210181435bd77d5b3da9a95eec42721c264823bbf73cb747c00101e654f7308e00d35ec90af819cd83e1695dca689625daf70a46b0f1a6849b75020216f5cdfd7638eca97e798a11efcae371b79779d96b68b3bee2da785b1b7be96202428de97877e08b38b634453aedf262d063d057e2a088bf52da274ea8a85085492724e99bb939cb2f2ae8e32aeb6e457f5e25a0f32844518d1333497f015a95e77066748731b92ea75855eb4a091279f775292045e6759259b31411d301ea0b3aeb797e9057bf66ea26ecf3f2c5fdfba8e59bb571eb27870251c830dbbde7992c5900a638034c4fddc2f32c10d680043ae528046f0f9418b19a423ec2b1ef1c9cf2f8823897a25582e4874244560797ab6883b47f31df1929b37938d81d71934fb2a3642587428dc3b050aac515b5c0d5b51e671f4ba3ab4f1f4e50cb854e0a8df162672c61d009a1ce84536eaf81644f790f582072bdc68902c1e100bcd21a4d349b24d860b9ac73b0ffd83af5c371a2d7c164912a9a7e397ca69704cbf831b07d702520628869f89549e641331ca8137f5ba478f08f3323807313fe5ae54898a2dd0f9c8a76fdb9920e5a9077bb9b4a0825889244c59e9cfd81cb1c219ef6649cfb0ca0ae7548f11e109ad2ef4f1083f23c6fa57fdbfdf4fa6544f7422eae4c8d0c3b6dc9d3566eff5568698fb4f65155a17b6ee202c4478dccfc3563ad3736856f750860c38ef414eb57bf007423f67d47f4a2b72372089e1c906b0cb3f495ce37180049a7b1839cfbb4e1c943e54cc026829322fda4a13d7cacc2466e1b3a74c6095fac5c37393616621e8885182c992ebc040cdb2d3cd17dff9d7f761a793c8a7272adb4a6f3b6a945a6476590f3f0c5291b7d367e896824d51e0c9a8cac943ab86a4dad31b13299e5c05375b4a69e1cd1a5c1f0db8221cc1e64a7f2d940a1c3ab2884b121ed8a02f379cafb47ecd0d07df41df903486f88b1564be398a3694817e6d00b6a9d704259bcf368c36b612ff131b136f620af09bf9757cddc741d04a48fecf8944f848f8f84d16f8475d726538e600b9666904fe8154e641fc79377455dfeeec84297e5220a0c8bae196e1b4f7afa7c513dac1c27d9e55d5cd942737685134ad28156e295c89e8377fc2eefb1b6f78002e9207fe4e6b490e03621e15cd8db3379d78bee769fa505f0939ae07e24e0a29612acc2f2b5fc9c7797b111096b1120ebf2e9e44bec5f7fd9bfb20e8d39aa922d0c781c2c79ecdb3cd97c5476d7d22648c718b088e24ad01759dbd5e38d81cbf5007649807e737509b8f89da5f9ad3471d136b50685504e1a2b8b9167d91020a4c8648dbfe1af14074e9ef4ccb66e34304d41f35b1fc9672dc4430fbaa1c654643bd7fc5012df2ac7818dbb0b739986ea1a8360e710a69a2b3acaf683c62320b1c5184a6ed97af06413244bc73a0dcaa3a023bf8ef4048083df122d4f8616ffb648116fb959f044277c9ff7ccc634d1d64955fc9dea925e2c87a1c5244b47e06f3a7350b7269f37adc5b4b6d13fc8bcde6c0b1a895077780074a66563ac9871976167c3b8cb588a2c3646d22605d74b429b39ed28f90c358e37d05ebc8ea55012e14e3140ef33037169baa700df3a26b81b65276058c0c7da75d555ae9930edae33610dc005e12b5ca33b4fc0bdd827b6732ef531c5fd12974a0d6346a05fce10e5bfd39501ab27752a7f1d93e8c1ad30df412a654096d5ddf91ca7cde9fdb93a4c594eebd12438c0a9caba13a7f054bab27d0d3710bffb80fc9d27da1c80cc1adc1f1f74d39f1b87c55b4b8401fee6f03be85cadaa9f0599db12371abbec87f401c4247199b2448165fc309e8f03530cfa94a929f61cd90caa6a715f75e9f8f8eeb3c889f4368bc2d04bea1babe2d6681c85a7c3767e11da601e346a63363694aa5c9bbae69b33246d383d17a964bc3cd92a9e866158d8ece3359c119ad05a6bae1b76797a20381683bfa209acd00c8e9395eda6c309368d7e11e8b1bcb8197b0e5ab033dc76044a22a96a15b1b5d329d692b67a6365aeb6f41c0628a436f5aacdf400aad71f1ba89aee43c442d17c172bf7fae4f26d755152fad7e4b9a3c76ed365d6e6c3852584cdf7ffd3784d5473f75e126d5678dff50f0b3add401019d00c3d843bb7dbff67c6a80ef95a257dc46dd80a900b731b768c88e1550a4705a07a9acad0dee22ea92ef4fbccad11d805ce0b74d42f009e0e1db5808f230488d7ca36f9f41648a69ec6e9f82bff6fccf1a029c1b4133c8eede4cea8faec69ec3368acfeac3f503b0b8b39d8cfb4ba0cb558a9dfcb26bfa88071585f06d51c45f5dc69a898a422cfc93a28bfbb351c8bfd820d2af034d6b8873701396fe37d80691fbef22c81d2b59e2528900401fd52c92a01168bbfb0f38accf304432fdee1059aa76071635abbe552a297915a6b0e32617f945fc2a17c00312e771ba75b92471309d0868ee4be35feb6122cf644e3625e0f2b45622e096d23303c50d26dbc75134658bbd2cbcec849a969a6e32da2198dd6bbebd859dbd9559b5263b68a6236acaf67c1a24ffcf0396f7d6cb0a67f7d147f6636b111ffeacc86a5200c8fee40d03f2ab4cffb3ab8d0347621b1c812afba8b50099c06d3f39222708218c4481b1b03dc2afd0f528aabc5bd917d2da2c6f9be60b84c07e86c84cc2cb54041254013f60523948aa48ff6936d19f6658b6ebb043df00a3f67e1f5769145d5b2c9fbfcfad4718f2555dae7345ec3460a2d006410619c0ababf3af5fd24ae0c6f0a6afba83b467ebcad8f4bf975d12cd5fd3c4aa81eafdf65b7cbeb0a40c23e2a9646b459369681b9390436096b0363d96bb941669e247d541e6bfd082614bb880c922e56afb2e061b5836852530ed2d56fabfe3cd88d035561574215999a1a309dd8696a63452f44c73c17675316137ca4eb59638f83c5e751642164e7b3e8d6cb6b55e2da2bb413d16c5bb46ba7bb887bd42ef2c7e7172d744f96ee8a6e42caf7e1a608aa353ad9bf541820c1bb37895ff2b7a3bf60b261c28c36ce1f08a979b51c2ebabd3870c1ecc05256344c21f72367f0d10eacdd169d074dc48418c7e996ec9bee750dbed649202a2c6f30cdec8eab58c4b42aca7cf52e4e3c49674f8e64512dc429156830438794a3f3d787926d1c1e1c321becc09ef7958b2af3a3be4dfcdfb1fbf725e7d3712a875e2fd665a2077a60c2dfc818d9dd11a31d4f237c21d65f07f16c894401df1cac95f5f8086156e39bf7cb2e9a5bb17c775d6b76dcff9ecfb81f511041ac6bdc97719842333ee30c11484b4045f0111d56f40c913686c812bd7700896d77996ee2caea8b5429d8b4bb469b516ea65aea4675e4a8a15017a56da3242e11322fe9ed0112fd521af63aeed89769c51b2db665776a75e8e6049c548fa59c83b59df8fbb3e1042b56debe1639d66750fc2ccb8ab379fea3ec1730ac865d8f93df792f2f6eeb1ab52660942457a83077cf1cde57150806b12fcdb2491afd1f9350579cb8c094dff941b0b72867b4b7abe3e522930460cb4459401bd9183d504b19cc23b8d0b25ba8253568a8991cdfd0502c964c8ca9b76da74e2fc343afd1c1d2ac0ebd9e5f582b527de90b2ef53435a4ab5106f6fc724e3eaa7c24cc2de651e784221e0a698f22a1cb64362c3ced006a7031ec875ea4ecde9e901d6f094db57e53b617876ef3f5eca499dd6a43cd0da463a1c74d89e071d9ed265fcf3cd691f4de004d82ccfa54889c9885d1de8a5f0cd1adaac04cfd586963760c36e59882b5619707a31220c7ef13ba47fb5c4efd887e6aa417f4bbabe089a385f1115e1189976854b53e4d6a45db155689ef525287b5f853bb71d065243e696441564980f94b2d33d8976993904e9f5ab06d6807def08e6a37a6c554aca37698225d8eb0345899e1a6d06ae26c6e50c791338097081eb58ee2b019f295a482272f24047d429fee6e8b783498db27684d5d591a66a63f3ca4f9649b73abd1bc4ec55b928ede769e54f08aa8160a1ad68b41a12ab7d7585088c61db423d41e1693edefa536606722aece9f8552e7ec0ed4dcd2b322794d808acf0911490ba37db7dbe9a1bb6c0a93db328d71457acc4ea6585a1323b613265b50b13a5ed68376cea8cfbdd4d44ceba37edf4941d3e8dec0d1acb6b93ff3fb965710c36b8d7417bf0cc32519c1f0dae8320914faccbadf2f572dba4027e3746a685c8ddffd7f3667f7495223378f0c73aca0db3999f51ab4e46f8e3c27b033de2475d73e758f1409ac8be14a788f552bf3116ecd76948e8cecd03ed9f057064387939f471c03ad1769b63d300ca960c7130a279c92d1a1aac12d9d021f045fdbcc91bd81b1dd970311d9427121b8f2bdfae35bc08b31cae8f95e92c000000069001b4ba886086ca8ae0e5b1d7b99491d7a5f93012a9a8fe4b8b38f49bd6ef107a0679dffea4a8993d4eb8dbc65ddf29f7df08ef81aa69c396230d5372a659391db0a224dffcc1a3b11b8cd29a29542687ed6f23741cde1d38d4620024ed4c6d3ba55af8762dcd8b31774c61a2eb5ddf60e0d06cb3557d13b44b675409306e639b41850b005ad91ace703d12e2532881289e340274ec561b21efce4b68e8f5bcc3b6a261cce940316dce317f0facb914822afb9050378c9f9f35f95991e1266f9d95d9680464bd717ed6dd0b54a06e39a57813ff9dde406d418f2cc925a7c2f1ad134818ed84d0475bbf35d761fc3ed4905a08779d52002835bc5702b54df36957a49173b48261407ee35c3c8eadb59a407b38d9c83c0dc2e959c89d380998486fa5a2cf960ea54f743ef0e3c1851b0297e1bb2e0292ee3b47956d598fe202cf diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4.rsp index ed69d34822..a11e9ec00d 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H10_W4 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 000000000000000100000003584a33ceb2d50a9af04409357774dbaf8b8ea517370e62c4dc06882c1407baca174157ebbde27d8e255d5c522c78617f3cfa03b811e32593ca965f771f8d88fb3059a272c3b9af8e445b37650f3616b9a06d2a79e74e847dceddcb6f854fbae8e6790d241e5e496a66244ae738bca8482630b5369e2c45e27c7ed919fa298c1d5ca5efdde0a12b258a584c9f44799b5c40f3889b1e8f3c274a355e24c088bcdb5288a47bf40a4677062662f4feef135493ea4498640c8efca349dbedbf5525af5425a8aabbfb671de5f71072eb07867e15c383a06f39ca2a09ae0d53c4db18370011d4ab6842a35c3bab93e642bee89310ac457e68869f4289f9e93ba553e39892b2969578ca5a02ae8a0272f1b2d6c8a022dac6a397d84bd2ea56136ea45aaccc1122aca34bd4ba6a7a06b2cfede81ce193ff878368f9f2181b8116185558cee1cac048f61109ae5c7b3973241919d9974f8b44dde66f1a8b2830abebf3ba1a115f4563453fe20f7ac023f6a02544d24b38e661a25a68ccb44c287f28d3fb0769048eee6d8f41046423d77e56344f7d5771f8ebacda4a4b5069f0c4746a74e77aa8b5615257b2dbac9863937e6d9c905217341a825c0460dce7a13845db6449d1e1f86d42731df8eb6f4381d71dff4defc11fa5d6bc9a0309a47e298dcf55e559c750f3c5d0fc1a1fedc8c8c0248a7babf6390fbcf70ad7b51259b336a2a39e1306968abb7f39a94a36374910ffa96a436a225436f7753eb7a28198750c3b5deffa1092eeec7857244b4a4d13d1eec3adf0efcce3ea75507f376a6c7effcd9e904ef2bd7b3c8c092066d46955c7ca38ed79ca8a7ffb1617d1619026c8fcb3cdc23c7403cc3f90e3c3d88123b20d40e8763c0aeccaadf79c41a69667cdbdfb73b33642f1d1e3b021cf2400e6252526d3fe62edc9d022e88ef111b6b5b668d2b20e23baccd9746668fb63f3916630506d0b696d850dcc60eec42504398f4d25e2eb6f36a417bd71c20c780f1a5075f86e953302ef0b7a6a9b909857d0ee6fd4c1ade224cf667067d9df328433b19e136bed536e364f82ac05705439967560c8606cd1c26b7146b82e825a233dca703ce03ab7df5c5345b5285be16d542a47a1fb4af74e786cbfd01c0456b8f86fd0e685137617224ff627b5f3dfbb75c9258484d9347ad6282e170c2657f5721e24d5643a4705d6f9aa335294278421da783d44ac38cfc7676740a399f9002ecac9a78b41c70c3188298dca26452b72a8d582d167c3c965d5f5c8c8f57022f417b0941f7828721951978d568a3d2ee0b7a843e5c697b0c7fc0975f0f09fd18856a16fc63db04e0f3ce3a357e4d3208546460814c270629d7810e452454927f29666a919fc8fb104f3c9c1fd38c19c6574d4dddb5c18683a8973cd061faf5f5c18b66734bf8c08766612897d0d9025e380c6317d88791d0861484e51f205c14e0bd83d2d61c394df3645eb0d66c80ded707429fe5e1fa77f3c3389ac59b353ca657e6aa88dcf6498479e76bbba01e75e9d992e6d3181eccd53e122c0c3ed428d809eef91934ee657364151bf711f0c922b6490fa2a9ea9ef02a9fad3a655cd305a2ccff01f60b9ca0b3e8381cd83960c08c066a30a9f46585e7ba143da7700216cb5234406301beb66a0cecd7d8122429992f8eab74cebaa1e7c8ce4d54587056bdad8636c46326e484c63b5aef8b6560e289acc20b953e8bac254da2f22751d83845be6132c6595cbf91b0d2ff7402fd789c92249af031afc1076bc99b9e9cd6e42a1a2dcf8baa42a0c34dc343508e70bb0760e5f9d8ec6390995bbca810dff3a0474c59cf9fafd9d09bf190bbafe003c7576960a6dcfa0226f874a084b4a50d6a680f88f1f3f352c71eb26df521e5ac9c2c6cc410c51ecbfcd090d7c09541810c80cafa5710c849ed324ee734a8ec0610a1a0ccda429f86b28ca0d0cfdc7d29ec03ea1b97021dbb00a7837d5ec8f6e6ae198ae31c9b4365aec42e83e92e879fb641915ca129324176444171873a75b3df1322cc74796b5e6cac0f950d92c322a8a3c6c0a824f8f92ae30aa110c8a415687ce6dae5135b4121b67fe4e5bff65fda4e0cde3372a0937488d22211c92192eebb9c0b38770356fc65533a86efb75a759fcb02c62aff2f61d3af079ce09d6b01ec9d6fd3fa6f5e2f60273f4b9c3de7bed546311557c197dd2c5398853a5b768db5d45b64d2860137c1c1e9bf3bbaf8f44cda1ba1c88798bf91c962195a11d1d43b937801243ad3483d951ce3c250de463aa136273c9fb9404ea92a204ad15a161852182d271e6dccce0c1385eb8a192d063b0a018cfa36d8357d89f1257aef5be8be3f26051dcd238e4977324204029f2d70a4dd2a9e9cdef1831c7163276bcfff2f2530f29dff5dac9a7026f3ebf9ee0449465a61db572b18434dcbd30fb0843ed81560473f8529191b25abb086d5ee06022b10a64b3a1ff18aeeccf277c4b33c9ecf4097bd5097e6bd0a30ad4d52cf5db089d15f4627a44e0689781a6c6a8ce08d744123f6364b1e7428aea701b20985f2ef76cdb3023297c894c7f14892a3e891f396a3edc2507892034a142556e78deba31ee286f0e2752eea28a0322789fecdeec35306d87105ca2c19f977597bdce1de1f8cc1f00c45ab2ecc7dd6f2d8e8e7f625be39a2348e77688819ed541d2c12ed74688d201fa307d958ebc4b8ce08a6b0e9a3116b89a038807e587bceb9cc98cb91d69f884c67e88e30c7c8d72b208dca96f6af60a73c4444d5e7f5b472fd2ca3b36cfa2b4bcb767acea4d8085b080e57f76ccc0dce2c2943b6c806ce20c88300bed34a383e5bbcdfad496910b9198bd43364da92d1fec89b90b53ba54ac634d5ac1f7faf0385358b6b0b5f5d06e31df6d3b17eb9181cfa131897dacbde42ae3c66010b978ea391944db2b52e52e47ff7312b1600e569b46859bfb6af8c4402ccaa3632eb293ced20d61552c75f0068b5a0a7d71f276367f0061f01e7fe71985ecd70fea79d406217f42260791f554b1a1b943e5312ee65251ac228d78c90f517949f6460dd3664f09b092f483d6ef2c00000006ecf1ce60192137cb466675f2310292d462477d811c672cb1890ffff4979ded0aa791c87c602307be68e7e3ed69e59b7c22458d9d49f353679f1f89cba91cd886900b1eb3666e5f0e78dec37a110c5cf09c1571f66e5862d48f6f4dc01812fb600ab2b3ddb1c5585cb2127e4a5e5faf00636beeeafb3b18f2481de5a4dbb9182e93a5cad39c43bab87f66eefd1428d0a426e0ee8c41fab4baf40bb982b9b5f1ce9eb65ad914744b45a4f00c11dc8fb012844cde05816d91fd387be9a2087c3758634e4ae3658a035e9b9e2d50a98ecb21489779c538aac7fde32b293e4f809494a800bb16c5ad2e8d4f22d61fadd2cf82bcc9ac210bada1a203f90f67b115cca1f9c109cc955776335779e6d9153a9880c91c9af9eac9e88b7a5e5bceb3bba9ec9432fe015b672ce4c04cc49ec42b865038b7166de32c1f745c27ee919bc25d0a diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4_H5_W8.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4_H5_W8.rsp index d5b66c3f7d..638351718d 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4_H5_W8.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W4_H5_W8.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H10_W4_H5_W8 - msg = 54686520656e756d65726174696f6e20696e2074686520436f6e737469747574696f6e2c206f66206365727461696e207269676874732c207368616c6c206e6f7420626520636f6e73747275656420746f2064656e79206f7220646973706172616765206f74686572732072657461696e6564206279207468652070656f706c652e0a sm = 0000000100000003000000033d46bee8660f8f215d3f96408a7a64cf1c4da02b63a55f62c666ef5707a914ce0674e8cb7a55f0c48d484f31f3aa4af9719a74f22cf823b94431d01c926e2a76bb71226d279700ec81c9e95fb11a0d10d065279a5796e265ae17737c44eb8c594508e126a9a7870bf4360820bdeb9a01d9693779e416828e75bddd7d8c70d50a0ac8ba39810909d445f44cb5bb58de737e60cb4345302786ef2c6b14af212ca19edeaa3bfcfe8baa6621ce88480df2371dd37add732c9de4ea2ce0dffa53c92649a18d39a50788f4652987f226a1d48168205df6ae7c58e049a25d4907edc1aa90da8aa5e5f7671773e941d8055360215c6b60dd35463cf2240a9c06d694e9cb54e7b1e1bf494d0d1a28c0d31acc75161f4f485dfd3cb9578e836ec2dc722f37ed30872e07f2b8bd0374eb57d22c614e09150f6c0d8774a39a6e168211035dc52988ab46eaca9ec597fb18b4936e66ef2f0df26e8d1e34da28cbb3af752313720c7b345434f72d65314328bbb030d0f0f6d5e47b28ea91008fb11b05017705a8be3b2adb83c60a54f9d1d1b2f476f9e393eb5695203d2ba6ad815e6a111ea293dcc21033f9453d49c8e5a6387f588b1ea4f706217c151e05f55a6eb7997be09d56a326a32f9cba1fbe1c07bb49fa04cecf9df1a1b815483c75d7a27cc88ad1b1238e5ea986b53e087045723ce16187eda22e33b2c70709e53251025abde8939645fc8c0693e97763928f00b2e3c75af3942d8ddaee81b59a6f1f67efda0ef81d11873b59137f67800b35e81b01563d187c4a1575a1acb92d087b517a8833383f05d357ef4678de0c57ff9f1b2da61dfde5d88318bcdde4d9061cc75c2de3cd4740dd7739ca3ef66f1930026f47d9ebaa713b07176f76f953e1c2e7f8f271a6ca375dbfb83d719b1635a7d8a13891957944b1c29bb101913e166e11bd5f34186fa6c0a555c9026b256a6860f4866bd6d0b5bf90627086c6149133f8282ce6c9b3622442443d5eca959d6c14ca8389d12c4068b503e4e3c39b635bea245d9d05a2558f249c9661c0427d2e489ca5b5dde220a90333f4862aec793223c781997da98266c12c50ea28b2c438e7a379eb106eca0c7fd6006e9bf612f3ea0a454ba3bdb76e8027992e60de01e9094fddeb3349883914fb17a9621ab929d970d101e45f8278c14b032bcab02bd15692d21b6c5c204abbf077d465553bd6eda645e6c3065d33b10d518a61e15ed0f092c32226281a29c8a0f50cde0a8c66236e29c2f310a375cebda1dc6bb9a1a01dae6c7aba8ebedc6371a7d52aacb955f83bd6e4f84d2949dcc198fb77c7e5cdf6040b0f84faf82808bf985577f0a2acf2ec7ed7c0b0ae8a270e951743ff23e0b2dd12e9c3c828fb5598a22461af94d568f29240ba2820c4591f71c088f96e095dd98beae456579ebbba36f6d9ca2613d1c26eee4d8c73217ac5962b5f3147b492e8831597fd89b64aa7fde82e1974d2f6779504dc21435eb3109350756b9fdabe1c6f368081bd40b27ebcb9819a75d7df8bb07bb05db1bab705a4b7e37125186339464ad8faaa4f052cc1272919fde3e025bb64aa8e0eb1fcbfcc25acb5f718ce4f7c2182fb393a1814b0e942490e52d3bca817b2b26e90d4c9b0cc38608a6cef5eb153af0858acc867c9922aed43bb67d7b33acc519313d28d41a5c6fe6cf3595dd5ee63f0a4c4065a083590b275788bee7ad875a7f88dd73720708c6c6c0ecf1f43bbaadae6f208557fdc07bd4ed91f88ce4c0de842761c70c186bfdafafc444834bd3418be4253a71eaf41d718753ad07754ca3effd5960b0336981795721426803599ed5b2b7516920efcbe32ada4bcf6c73bd29e3fa152d9adeca36020fdeeee1b739521d3ea8c0da497003df1513897b0f54794a873670b8d93bcca2ae47e64424b7423e1f078d9554bb5232cc6de8aae9b83fa5b9510beb39ccf4b4e1d9c0f19d5e17f58e5b8705d9a6837a7d9bf99cd13387af256a8491671f1f2f22af253bcff54b673199bdb7d05d81064ef05f80f0153d0be7919684b23da8d42ff3effdb7ca0985033f389181f47659138003d712b5ec0a614d31cc7487f52de8664916af79c98456b2c94a8038083db55391e3475862250274a1de2584fec975fb09536792cfbfcf6192856cc76eb5b13dc4709e2f7301ddff26ec1b23de2d188c999166c74e1e14bbc15f457cf4e471ae13dcbdd9c50f4d646fc6278e8fe7eb6cb5c94100fa870187380b777ed19d7868fd8ca7ceb7fa7d5cc861c5bdac98e7495eb0a2ceec1924ae979f44c5390ebedddc65d6ec11287d978b8df064219bc5679f7d7b264a76ff272b2ac9f2f7cfc9fdcfb6a51428240027afd9d52a79b647c90c2709e060ed70f87299dd798d68f4fadd3da6c51d839f851f98f67840b964ebe73f8cec41572538ec6bc131034ca2894eb736b3bda93d9f5f6fa6f6c0f03ce43362b8414940355fb54d3dfdd03633ae108f3de3ebc85a3ff51efeea3bc2cf27e1658f1789ee612c83d0f5fd56f7cd071930e2946beeecaa04dccea9f97786001475e0294bc2852f62eb5d39bb9fbeef75916efe44a662ecae37ede27e9d6eadfdeb8f8b2b2dbccbf96fa6dbaf7321fb0e701f4d429c2f4dcd153a2742574126e5eaccc77686acf6e3ee48f423766e0fc466810a905ff5453ec99897b56bc55dd49b991142f65043f2d744eeb935ba7f4ef23cf80cc5a8a335d3619d781e7454826df720eec82e06034c44699b5f0c44a8787752e057fa3419b5bb0e25d30981e41cb1361322dba8f69931cf42fad3f3bce6ded5b8bfc3d20a2148861b2afc14562ddd27f12897abf0685288dcc5c4982f826026846a24bf77e383c7aacab1ab692b29ed8c018a65f3dc2b87ff619a633c41b4fadb1c78725c1f8f922f6009787b1964247df0136b1bc614ab575c59a16d089917bd4a8b6f04d95c581279a139be09fcf6e98a470a0bceca191fce476f9370021cbc05518a7efd35d89d8577c990a5e19961ba16203c959c91829ba7497cffcbb4b294546454fa5388a23a22e805a5ca35f956598848bda678615fec28afd5da61a00000006b326493313053ced3876db9d237148181b7173bc7d042cefb4dbe94d2e58cd21a769db4657a103279ba8ef3a629ca84ee836172a9c50e51f45581741cf8083150b491cb4ecbbabec128e7c81a46e62a67b57640a0a78be1cbf7dd9d419a10cd8686d16621a80816bfdb5bdc56211d72ca70b81f1117d129529a7570cf79cf52a7028a48538ecdd3b38d3d5d62d26246595c4fb73a525a5ed2c30524ebb1d8cc82e0c19bc4977c6898ff95fd3d310b0bae71696cef93c6a552456bf96e9d075e383bb7543c675842bafbfc7cdb88483b3276c29d4f0a341c2d406e40d4653b7e4d045851acf6a0a0ea9c710b805cced4635ee8c107362f0fc8d80c14d0ac49c516703d26d14752f34c1c0d2c4247581c18c2cf4de48e9ce949be7c888e9caebe4a415e291fd107d21dc1f084b1158208249f28f4f7c7e931ba7b3bd0d824a45700000000500000004215f83b7ccb9acbcd08db97b0d04dc2ba1cd035833e0e90059603f26e07ad2aad152338e7a5e5984bcd5f7bb4eba40b700000004000000040eb1ed54a2460d512388cad533138d240534e97b1e82d33bd927d201dfc24ebb11b3649023696f85150b189e50c00e98850ac343a77b3638319c347d7310269d3b7714fa406b8c35b021d54d4fdada7b9ce5d4ba5b06719e72aaf58c5aae7aca057aa0e2e74e7dcfd17a0823429db62965b7d563c57b4cec942cc865e29c1dad83cac8b4d61aacc457f336e6a10b66323f5887bf3523dfcadee158503bfaa89dc6bf59daa82afd2b5ebb2a9ca6572a6067cee7c327e9039b3b6ea6a1edc7fdc3df927aade10c1c9f2d5ff446450d2a3998d0f9f6202b5e07c3f97d2458c69d3c8190643978d7a7f4d64e97e3f1c4a08a7c5bc03fd55682c017e2907eab07e5bb2f190143475a6043d5e6d5263471f4eecf6e2575fbc6ff37edfa249d6cda1a09f797fd5a3cd53a066700f45863f04b6c8a58cfd341241e002d0d2c0217472bf18b636ae547c1771368d9f317835c9b0ef430b3df4034f6af00d0da44f4af7800bc7a5cf8a5abdb12dc718b559b74cab9090e33cc58a955300981c420c4da8ffd67df540890a062fe40dba8b2c1c548ced22473219c534911d48ccaabfb71bc71862f4a24ebd376d288fd4e6fb06ed8705787c5fedc813cd2697e5b1aac1ced45767b14ce88409eaebb601a93559aae893e143d1c395bc326da821d79a9ed41dcfbe549147f71c092f4f3ac522b5cc57290706650487bae9bb5671ecc9ccc2ce51ead87ac01985268521222fb9057df7ed41810b5ef0d4f7cc67368c90f573b1ac2ce956c365ed38e893ce7b2fae15d3685a3df2fa3d4cc098fa57dd60d2c9754a8ade980ad0f93f6787075c3f680a2ba1936a8c61d1af52ab7e21f416be09d2a8d64c3d3d8582968c2839902229f85aee297e717c094c8df4a23bb5db658dd377bf0f4ff3ffd8fba5e383a48574802ed545bbe7a6b4753533353d73706067640135a7ce517279cd683039747d218647c86e097b0daa2872d54b8f3e5085987629547b830d8118161b65079fe7bc59a99e9c3c7380e3e70b7138fe5d9be2551502b698d09ae193972f27d40f38dea264a0126e637d74ae4c92a6249fa103436d3eb0d4029ac712bfc7a5eacbdd7518d6d4fe903a5ae65527cd65bb0d4e9925ca24fd7214dc617c150544e423f450c99ce51ac8005d33acd74f1bed3b17b7266a4a3bb86da7eba80b101e15cb79de9a207852cf91249ef480619ff2af8cabca83125d1faa94cbb0a03a906f683b3f47a97c871fd513e510a7a25f283b196075778496152a91c2bf9da76ebe089f4654877f2d586ae7149c406e663eadeb2b5c7e82429b9e8cb4834c83464f079995332e4b3c8f5a72bb4b8c6f74b0d45dc6c1f79952c0b7420df525e37c15377b5f0984319c3993921e5ccd97e097592064530d33de3afad5733cbe7703c5296263f77342efbf5a04755b0b3c997c4328463e84caa2de3ffdcd297baaaacd7ae646e44b5c0f16044df38fabd296a47b3a838a913982fb2e370c078edb042c84db34ce36b46ccb76460a690cc86c302457dd1cde197ec8075e82b393d542075134e2a17ee70a5e187075d03ae3c853cff60729ba4000000054de1f6965bdabc676c5a4dc7c35f97f82cb0e31c68d04f1dad96314ff09e6b3de96aeee300d1f68bf1bca9fc58e4032336cd819aaf578744e50d1357a0e4286704d341aa0a337b19fe4bc43c2e79964d4f351089f2e0e41c7c43ae0d49e7f404b0f75be80ea3af098c9752420a8ac0ea2bbb1f4eeba05238aef0d8ce63f0c6e5e4041d95398a6f7f3e0ee97cc1591849d4ed236338b147abde9f51ef9fd4e1c1 diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W8.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W8.rsp index 500754baef..912d84328d 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W8.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H10_W8.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H10_W8 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 000000000000000000000004e8005f5e66764d13c1a66c4b0919b51b818e23767f813cd64ce8f961e189ad2287a30c45cb69478d54db906e55516483dc65862e24ef059bafa11845aba072ee4302a1e4c22243cd893f12b053529942bf1d3c97de2c317a317c9d2fe5dd7e3cdab428bcb8935db5f3efbd2757261b50431c9ef1cf49256a37355bbc2931ff7478acce22a47dcf7c0662d7b21a8727b0d1ae54473d2c761cdfddefcf10f050821345b78d6a1fb6399a0233d8cb0062792bd3e944951a9d1bc85922fd5bad206242800aa6070d1968d1738f2837039f1d8023543302c075ae3b7e490b4e49b1c2f52f7604f94d455d49c08695f4536d027374838fb11e1c32de758434c1b95aff54b3a949c2249eade7486bbd5a600060d1d925da6cf66ec882558813bc3c35c7b461b013f847c3fcde510affdbb548f0cb16d4151341ecbf521090d6d94062d4c06316a0c932a260cc3a93fe75a6e56e642238902fe1d064b43390e71c95ab901dffaa506aa89fb5e4620fd9b71718a8e4516b791c0ca899addd197172f26fecfb6905ef031679b85fc32b98bebf54c172d294d749e041d4b8e11dcca56c70a181c55d1fac4acc936efa857eca994ef6b4bdbea24881ca38607babb2bfa9635d824119d87c78aa919b9ed71d4708f044222f5c80590638981ed8b46a099c5162982665ed2c1bbe1a6f1a91ebb2c07dd5d577713bac16964eb5bbc763b7600c08a13e02bfa253caac622d038961fac0d45f3e3ffa998d13f80f78f454ec7593bcf47214584f4f32dd02350a0175f646c7a80685f2d5d2bfa3ec8f09bf45869d077a6fd43b777c95bf8f848445709acaac75e82fb479a578a16ae5724084b3bab6d8bb5006d246545dabe8a27bc7419f2cbb71beaf7d30d2213d053e3d75d3e785d7d76347b45f0ae31e1d4138da2836b401424213e08863e87760d3cee7caee7e5c9d576ddd3cd0a827960c2697751b855fdfbb1ae63a87317fcabcbe251a305340172bbf0d907ca57d4d01fc10abdd4d7191fcd9400cac13ab3c949f2ff0b1559cf6336f2cac59b97c45faa702b1212b341490bb0905b0598b8d76d95cec3ee6fc37d4096b625c84c2ce3a4bfd1e541661eb57bd4ca0a5d1a55578d0018bf0183cc2684fe61d8376ed35fc6c9715e03d20c3c103f29f8eb4d19bfbfe71a81cd587ec0a2302789bdc9b6741fa811e0b7dd4e66abf7287fa282d039f9c98cba1e46594ba3d2fd2b994794c7afc627f3dbb29900f42aeb0d7aad125634fc281e9c37047a1c7aa7cf9d78c3100e3d1395df86e785970f3e107bf12ffcf7ee3fa8c1169192c61dd9f3bebdc08d4290e36e8b135d6596b70c91c281b766b0ff8ecc82d2355f33d1077d7f0a5bfd05e19210b78408175b1e7c9330a8f4ab4ceeee202b3667694277169bd0403db497b57d9974a3c1ee438a0339908736e1f97ccb1ea3f324682f0786e218c59751f8231ab20d9bf2648e06e32018f3822d66a2d180fe5203484401e5471b925cf05aa64f287571b0645d05c438f61c14660c316dce2d8aaf22a64430f69d7c3bb14721ce16569863b7e65dbb6192b581751a903fa2de500000006979941fe2a0034185d9aeb8f6eb51ef6767f2e0218f9f1a20c604fb41592503e1efd6c941c7e3056ad0b47b3afc6954a6354791967c9274a43f835fc370099fe0d26a4850bd75228166c06d23d16cb07326be16f454269d1648fa58b6ce4738a8fb926d2a61b5aa66c4a3d4417b0ab7ba7fec2f7bcc1d1d179b7d7a90bc316975c81d903b29345a3ccb9309534aeeb6647dc5662a5a64e9b2c622bd394339b9963ac9e6c3479a5d6180400620115b6b09af77ad82c7a39e278ced784702d1ca621705827bce972d17fe501ad892d4de6f94e748cc7ebaf600ef73037d41a4719cb7a96ef86d89b0eb0e7da8668c85e52407b2b14c232ae6df56bed6d1ab6d7e5bd2448f15e0acdb7792f62cdc3e7ff1db99db034524e0e2b77749ef0b624dc6e2937e289954069c33fe4d0328672caceb377112bbdaa844bdef5bfdedc1950aa diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W1.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W1.rsp index 138da7ff33..3d78978c41 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W1.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W1.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H15_W1 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 0000000000000000000000017d1442b03e3d2c279b85ed284445fa421587601ebc1015f9b49ea82e29ae7fa09c61209ca5af037ba2779cd5e9ae813a491892562b8f737a6334445e63c739bd3ee3725b06f7b9a26316a6997f143db039f38134e35669d9dddf12e75dbcfc9cd0641d9281215a820882047fec3d52854c3285eb61b25c9b5db59d0fb4f38acf5a3bb2a14fa03e2e03a4df7570cdd167cbdddfa44973bcd3ebcf3501aa80a748b70fac5ae3735bbf1a8937d6b8621d837cf7c5edb65ffd08e830cd17bd6753cdc98df5a09fbbed909e812c50f80f71315e2ec337ea1ccd0f203c9932e889056e19144c0b17144bdcd0c50bb51e8f39ef8ba2d787fcf9536e55e59be8b5b5f55f15cb186678c41210466eb6843957f69f85fc0e1e789ac26c2a0744b076c971bd364cb121c87e2e08491734e51f9be2a3698373473761bdf54529fc40e2cfa865442f320e3045ca046ad2646f6a2e2e91f054a9c4ad449bdf7a35ac9b29e6b8385d342b49c15fb0077aa4a41c0d67dbbff3329c7f3a32f183b47affb5292af90082c6446999b1316c46f79716ff2c4a5a8d510977af1e86bae7cd578f43f4e8a85d8ab33541431499cfbbe66473f1d7653a3882ead0dae56f7e010fd17987361d5c48a2835f25ec9c70b7671dc53c950c27e4ebcce2b6d5b8332792afdf1a4ae1501af44799f9337edaf1933ad5b679b8291be1589190ace128670e5b3bc230925b78ae34a175c5d1dd7856812011da166d5d8ffaf33f60bf82223fa88bc25696fc21033c7ef5c47f6b0ae0ef47e2119b58882a379ff38b89cd6895cf84770abc68bdaf5309bb070a194f29f3aef69ad6731a741710951fbed65e82d259a73efd6cef99d642695651e1b0ca4dcbe39ae8fdb6ec4b1c44d9386125cac42335da4ca99610d0924473da7d1a85dd527999d363062bba6c919272cc529062120705fe39b11cf43003c851056cb858649da4a0b8eb53c056467163de4d3da8bfd370879c834f78553ad0921d5dde65855d47380121316e8e774adc1576ad529be5c7e465b77dc36e2b28cd88ea44574a8998e477911073fe4ead79e6ca304783ee4817cf1442d311ff17d949ad643f2abc4d71ee5332a62ce8be26623304e68ce1743acb9a25eac59d5ec657673278c28252a3dac364a232730eac4c0d03ea39ac7e954f1b551d8dfd5d429f944a357148f9ab5e74d05d4e2e3dc96c1f5d086e2e313e4ff986cae049445589de4be46e2360e311ddf0592f1c74224aecbf2dbfc72e8c9111fde1f64b7028702e8653f2f6a7823629e174b01c44bc33907709fd0e3673c5d087d730017ef2e61544ebe71ef69d23e0292afe1a7ebb41326cf530d1076b3cc863426d204c8e8b548640e62e1bb236a5d22f61bd1c769d70bace9e813f4ad7fcfa90167fe4c4c78648512185496e942331f0bf35f6bed5be20f9f7d77ca900871055eb9e84fd6c95e7e7bc72c0a92fac0c788841329921423e152c95efadbf31721a36194370bcb0d77738f3b1a4963056d220bc399276e7a0fdd3a1953bde9e2983fc2b045a5c6d5cec1bd6d8251184b93c7bbe06f2606a913f602bb7e2aa42264b25d8eb7d4aa9ec8bb6e90841e52e93b005539d3aa42e953c00a89289fbb75baecd04ba4fc13cb0e17989257cedaae0e52aaff6b06db21d4ab5fd45db385a1e978b91fe6c4aa9473ff6687a80b1f96bfb822f1314a2e097804602c81a1655b71ed74efbe23696e51310edf39b58091d791fd62d17432392e79cfc0c70b9da67f621bcc7fa93b9ee56d340450022f2b3ce5f01f3325c4a7851d7e64646241b394a65486829a794b82593d0579bf4a2203e673fcdc87411de87e157a1fabd7b137da30d632953460d76d48f461180c86cf77392265193906453ec36401340770fcd33a4a278d5c82059a089eb45fa784f5f5dca852f6cbf0ddfad9b8210d472be700e66efb8dc4fa66233a524daf2631be8e39f25119f6388c3d03ff75980d390c99392777ee8dbcc29ed93e9481dc4901d4d26ca5abbbc45a066b5318736967083f3abd97aa8ececf19822b22b3372a76095d5581c7e7a852438f937837cb7a9812234e93af88c465b201aedce324c2af3d7f75adad90e01b67e3e3fae8d8ea18b45506c00cb130312e3805ec4c38e4bc5264f4cee3ec1d1450752b4fb6c6466e3281527385c41e134945b80ba041a8b903a8e08124c9a3fe29bd9722cbd20f1f5f9a0b9cc67a118a504c89d4eceb7bdc87195930b1fa2c29c31abee9a0877f64dc02290871f204629b88a857bf2dc01ff1eeb80af9f44fe70d6f441edf54f72e8d96b0dcecdf7f2961aed57eadf36e40da8142f082cb118534fa7294cea8d741c8450075957f094eb170b6508cb504ee685dcc890d591f460a89c0c3cc08c4010d748c1b7bf32dabe1116dc0781bfded8d98c1c579d4b4f522c273f20255300e7e0b39123a1ba87f9dd4c8a6d435f6d6b4ad1c9580c7aaf5d0c5b4b4ecc1c201fb3fae9b76d14a6f64c1cdb101688909a4207176eeeeeaaa3f2abef9202d051b8042866b09db501adc7f6dd6ce283451f2b247ce89b1c177caf840865ab5cdb619928e92ac4a315eca917a52ab0af747c45c9d4f3977b96b84bf5b46e323ca4a0031ce21fb80021148b84218a420a9430bd23fca1bed37e84cec725b87d7b8e2a7a47d3d016cc434965ae6f6d106f46c8c4565fc467d8dfd24aed77db85834995f9f21c38f405c16d3212220415b3d0b5f97729ed438254a7aad03c8c555364b80885fe75f003b1cac833a4fa1cc3ec7af43e328e5498499836b830b310e46ddaa447c6e8db7d3eb0ee5523ccb52d05d84a4a51288bf73edaaac052fcf5130083937cac1d09e98a70f6f2610789476a30f8b9206448b448c36dd6874f9e5418ad11b7d790276140287f849b441409d2c7bb7b037bd15b5d52fc0190a02562734ac0349d5482b494c05321f0c484e5adc20d9b9d175491dbb05e7220996710d641449207d8d408e3bf4e5dab294381d72766a31038e02d08b007e30f21b79c655ca313a7fe1b893763f2b923dcaa23658d5cad13cd7818e3fab3ef2752b638bb6b5162578a74aa388628ff35e487d7754c4b7b18414973914fe4f075c63e81a7ffd474febf313edf64eff44d542afc40d5d90b7618b6577108523528d1d603535511f890e426da5cdc150d4c50b047a7159d48b7abfffe824cb176a8a6e5cf613bcce956a012b83b7d2b916f0b2db5d2e68b8255b6b3dd930fd8cd8eebc3fc0665865835dc0db816ef635275ec5f463b8edb99bec830746ec86bcf87cfc7cf3d6ce98528181d9f4c75bfdae6981e539ee06b97d48e1807eb4cbca3847debc05ca002b2f726018475de66e9ffc92adc1280774faf20162f9270fc6179ebca7ef612fef2dd253d637f51cf8c76fd1c831e4449091ff3aee820e8a545bfcf9a7c16d080c73aee97384618f24793cd6c37293c2c23d13ad0d7d03c38992215be779e73b6cb979908b2290d051297cc2591b5d7894da71f6c2dc255c9f01eb548c05b5fc5cfb4f9bdb6c007a03b173ec25970fe6b841754bbc529ca32486654556eb20a311f94983c77e118642d5de4d6eb2f4fc95f8b37c90a9825c56a2295e5dd166c9d0a1e3f94023738ae46fd4c99ba60c06d8d42cac8568e7547500a12d02c64a2d73bf075caa8218cab2ae30b0d2d45cc7c69fc44d21dc2cf17453eca38048e58f18980bb5c4c608f1e8f4c264f0683ae0229b8283c93a48eb1182857474a484f473b69aab94ab76ec62f9de834012c91f237d0fec778996482e04c58858bca4dc60573ab69628bb6b73e0fc51bdb3fdc684ebd00006210cce6ab04914001661c8d5b36260a0645053431ca8c29494efceafb20019ab9351225a20a513a8b2321f2c5a6e3c54424b4e9485e504701146812c051cd42fa482ac1c00ee2b227b978d7b0465114636cf1bc04c39840efdd33d033ff4067e850126acaa8b60005f61d69ad38613d3446bcb5e421371104c584711512f65d9131dc08a39291b910482438c6d459353d12d0d7ce4a06c3ac24facf80cf6d1b89b743467140a7d05a36b2eb970d38d914970b65eb6b6dec1b52f1e973b99d4a170bf31ca7908f4a4fb3cb62bc64aaf557b9e4c1511b0daed60f88bdf7aaa4f9b9a849758a6237467144b2aa2b0f24b16590bc151340235133827024fa8cb4e291fac6daa96e18afd121e076c12617d64a34139b1470fe7f7defe9653a6e416fec220656bbd1cf83adca819b7b415085bb746af4b0ff3ce65b5f8252f30ab100b46bff20c047ef76079e0061ac365a2a54d1020928c31d778e19676512d4bc359630b165534b7b6b50197d5146979336f33e9289a120dee4450a0a60394eb2e32a4b2a770a40f81fc98a02865833044f79ed73174118b2b201ce0c4d1a8a0ad9b44cbab004001c5d69734302f0d845cbefe6afa47342bf7924d8e8d231e7cb0e2e1af58938ee32bb08610864384c022f415876746454f427c0fd485d51707ef3227e0628076a14c0580dbd09fb05aab40bb307f290502b03b7d25d4c6259311255998c43be15f25c9f5a340a3cf1d2a6fe722689db45e283529a3c1237b9ecc84d76952a86c7461a73c7bb26aacffcf0a33f9cb21ad93e42e23c25090d7272c4721e48d73c752350a243a0d568b3d6da99ad1a5e31f1946ef130ebebfccaef41a28edcfb0bc3c7f76ac279d92979608f735ab4d5606ff04b21d67f4e44e3e152d871b3eb329612e8881a9e91e4ae037d7da1515397e8a99446ca0efdb889345db20c627b4b583e7d609c0bff453f7df98d3bda21c70187a14f8502699b4d55aa71b569a3f66b04c4b1791d830faec2fc9ab29c33b64165c9ac08377c475c2877e473b3d89018f734c1497bb7143b8e6386f474801403372f8acc43a7188c4fd67eafeb1f0637b9842dfccfb74468199bd90cb52fba0b556b8c32a5ef2ce65cbfdcc0bad3102861415405636a43c75f54b2844325cf7544a22d5c56f2d98c9fe6155c984ce23439440366a21a8ea24ce6846a7bfe40459039c0d7c1f3112a9d5ca8548f8f20d884086e907f9385a15493ebefbd509e7aa19691029741dbdabc15da65fb42f2816c633fbc1d5b42488466795a902ea4ccdfe4d70a50b6bb594f614e111f57527496a1901bb290c3c59f21aef0c68a877732de2774fd3823e2271ef0083bb35530158e9378fc050f0fe5df440a2e63fcab3e6b58a5ef185946f2f9fc780b329dff4fa5b29be55c1868812b71bebb26588c08b97878b7118412caf4ffe183efea366b626391a67f6d0ea2e00e28be4ecc261b397bd76cb9da3c99be84cf7ba4938622c3e7eb3965de2e1ae07e4e811811cdba640c9cc13c6fda6340df33e87ae23ae8edba372fd154b63e3851360380bda2b4856428f14f99d008357e45cef52b500cd84e6e07607d8b058fc2765ca7be87c3595d1455a05e984aac50f432145cdad0a98f2776b70c63ec6137754361d778a413fa657d0ca945682a179420c5ecec5d11d4088979bcf2a823c14fb3548108cc520560ed0e6842fe1a49268bcd69bc20e31136126f80084afc99444ff0b35824d3699c143a91eaf3e97ac4c01ea5c983c10cb910c0301d6ff257956789705be6445c56b260ce10dc8d8f165ce4619a8c56051a7fc4d62be54dffd06c3f95817c144282f33fbb7ecdf495dd44f2a4590137d3bf89b729ecd102e43e72b6f71a059baab8c54ade2d90f61a2dfa819443ccac6d3473a9fb6532820a3168e2a7870a07dc077fe3bffad4c9cd53dfa02a345b19115d89236fc843993c6a336d19bf666d67fb50b54e7001237137ea8c1ab4d35e9f330d322687e5b7653fbb72f14cebfa405dcb978eced6f313c3c6b2ed02892cf051ab489154a18ad86f59aa9e5af5c42b0cd85cd41d2e0294f5aa3989437535e4e362bcd92f6d7a74977590f1086e877ad1e291895a9913f24a44a5ee056b9e1624734c09d8ee02ec4da4a0327e5c3ec3d8441c1da8532214006b316ff404cda80d6595507676404ba8f3bab7a8b7459ec54e0acaa9b98263041d1e81b70bb48b24839cfc1737ff4116168f51dc5c9f84c91a3bbb4f7190da7271659f98286f11650a28c8bf8847810f7d286f3d28c5b86f2869e1d532e77f62ed0c24d4ee3c722038821736acfad959f763fc0b8d348f724d0a0a95371a6c4752f120eaddb080d73ca064751dcc3364fe950643a1f242be28d9b8a55a1a3d6bbb87b04eec17569011f19ae74ba249a12327d7f008442289d1c4324bc2f14d86283e195e76b47a9b599cad0a8ef23a952f85eb0610dc4a3cc2f77297c2a446ea43ea7839a0771c6b88b131ab2e2f2b39d031f39bad2c7336874db3f0b3b78274410321c61990498b16c68c1ca17e3f25c3ab283abb2938cc4e383dcb81432058abd8c7a298d0c892f482d77187fd25174b12b1194a50b29d90e7da3ec2388f75f85777bd2cbf224bf65ade3057561a0b37c6ff1c0ee59703fb7bff8ad9c58cd6d643b9a8da7116318c3cf737001af6a343104cfbacfff57fc82dcaadd13fd1ad6a8dff9506e1c3dff33832291e9174e8afd4c447164796d8daad8735922ec139a3bbc0721ed51e1ba85c5c9fb5cb0f4b23707cf32f7af4e61cd53775c4cd346dd09b8fa075adb9c311f3c4ecd79e9fa6bd3002651ea513765f847ce08ce5a0256501dde7804e320b1fa6528b88afa3f5094d326325d02ccddcf56a9be83afa5df7b69d83842e714f3cf18518f4145df769f7ae73856708aa90770496eb3e969e1f21aafbec05af7368e1bc31a668170a368bad96244a7cd42ac576f4d4b53324133fb0cfc849972781eabc2dc6d5361f9b5cfacd6d7f3a2cc69e1bcd6ca6515ac5d704ec53fa68f8422e7437a1df7db7fee7b0277b6ea71bb5c9c9f4f310faff9a0ccd118c0a463313ce4b0b9d61f72f48bd1ee8991f0e1120ece2255ca63e3a10750eec286b0d50ed7774206d0c268c9f5b29618547bf2bbaff0eccce72883b21dcad1b5bf47ab5a943da9823211684517ebf71745a2a0e627f15c8ebdfa104883b60693d4c3938dd6d6e5e170dcbafd9f15dbca23a4aef76c260d7f6394de91badda5ebc56e2fc19f7d5c663012a3be507a2f0648c31131128f6c0889fd65b323cb3d9a5d45a9e5a363dad6e450625bd5b227c37326789eb214725be108660cb30fa0de03637764156e72e1e545135698a561ff16d40ab264c2aab89494dd43afdd8ada1373e0c9dc703b2dd3af759d58fca6da57bea537ff54c8bfb7e8bf90d22fd7653b2695219136294bdcd68fce4fb19f53ee98bc6a677aca85bb74cf9a653996258bdf00b9f2d174163b330ecd55c86706e7d18983785e8bac6e2b3f96be025aa892bb4e02623d95f981d30d60f8583fb6f14bbfccafde70886d032c491df8e5d07dfced834e01a64b83fbf744a4c1c40afc38d6557f9258ab9fa49f52db50e3b261d367663f49bda16ef5e6c73635312b507132a1178cc8aa8b4befbcf1c595f966a36491ac23deb941e63b20f2d17d9e575043eeb3a2804cb6b509e731a54b718234c226c8efa217323924a0e09d73eabfc89399a49947e93c3d3ac6f65309fd70c09192d315dab37d2815077f684aaa9eaef4ce77b6d0653bc4d8bd77b0c5bd10174aeb5ad0dd7aa7af7fb79c8af3aff371f0a4c625e584a0b9c75c10187b009a6cf1bf7d92a44fa489aa1ffe90e00c1a5ee0a3ad9256c77be81f8adaa14311ea934bdbd9e1cdd0c31d9f7ed8004aa5343d28416e9e888a46be875bb8110d03b048a7de74b868b124b59a9f38d6f6164c263ad8d0fdc3728ae3aa7d103945faf106aa62db4401c3394ecde71b3e966aa4100efe8c2a233d97ddb3a376e0c5fcc2ea88fd35e8db7e391d9e5d6aba6d06137b725b7fe7d961773ffba819fb498185fc64399f7a45369cbd1138a67f2c8c8cf4aa112aae89e125b74adbf76b3e02bd1ae10670c57e3e87bcc2250682f34f7f41dcfc8a140b176a0e7254d8cbb9357e1daa642dfb72130649d1b9c680d7103ef60aa2cda3b661ccd41b310e6bb24f51531ee0ddf4255b50276199c01fa2b36b0b139b6fc245232371ca7239721a4d7ac080dc7dacfc12144f8e5186e7bbf89d4959351161be25407cf903290c1fbff1c52accb445e5aaeae4b49d35a3c4e4f2b6ce02947da170848a2e337c6f3cce5a3a32a3162b84b3e76e2b43be5600beeac09d2450f14dd7000d157f073b41ade05fec31e148dafe7a603cf9702e7b066418925c2182126d41a252c9f989f3d09483c5d036dabd5c00f0533a3691f834c88631f40b51d69356ff8310ca646ac1cb343866e6a721e118fa2ba83e18a00f0dbcc748feb16896908c4bb0607c02e235ff3d2376a8544f06322d27d88ea777e4bfa1473c855b9d42143cc7195eb796c5e5d1608aeab8806974c314b22e08eff7ce9547041c4fbd33858d5c2b6b56da4d64079745c02354ed18966a27548517aa255cdfc3e4cc7447e246d867eff4fb828a8d66e44c321bdc78bd34f6519a4d03a14b54727e6619e47a0d328b817ecfb44b7696de948aa382a0b9ef40201191aea8771aad83a7a854351942c7f1275667d0d55306a1484edea1f0c496ec3f73eb5c512a30de2fd3fb75bb9d438e328f18746309eacaba3e022a37d9e6a7ecd52565951609934bf206c9e3b547b56cbfdbaa1fb20c2cec67010180edaddf35613fbaab373895c3c0ed63ebdcb381a731690a96a2f3f7374dbfa74692bcf046c7dc093963f985501a8d3163e8deffc88b8af1492becb0246bae65cfc6270ac59b7cf6f89a75e2553427560343dd30da6e9cf9d286c7366f7612d33e123c759da9c77d86710463a6a4b940bbffa67834d471fe6fa1dd0d6a6eea669cea7dc2bfe265456e37e91caecb427900e3fe81e2ab3d89619b8887fdf07a1cfdf724a6ad7d3b64cdf6af69769f8baf3d6ec9b4cdd28dc255825d85a4e675b091cdd38074d81170e12820f2b87eb6bb9c28a6a810e867631930cb02283c3d7addcd7024a25199f1601f2afae5c41593c92d670ba4baaaaec69c472070205568dc084a2d11cf1d862c4ef31066031809990ba8abe27ad644559b2368c5495fb24bce089c6d84c539402a3a6da60477b032f4655b3f9750633f10527a1b9c08815bcef973d1c60e1c077b06dc0456288ff4cee7482215e2cd131875d19a46e88618a263e6fdd09ebdba9288ce359efbe18cb994eb5a532a52d6af1159fa0779be5faaa86f312c972516d4e752aedd501219f11f2f1ed0e646432bbf1220008007550b2ac59332728726f0e78774e16e085224c56da67b2da89a66c21233e14ebac292bc710a4e3420f821bbe79f3ecd76e6f27bea09604d7b9762b45147773742e7a98219708316e0d211a7829f179c038241f8289173a99c319702381f20aa96232da4d072dee8b587a1f1392939c9c0d2cdd0b2fd734b43cf5b742d5a11384503bbdfcccbb33c43795192e1f2e4c1309d4de9671d4e90a460159defc8f3d6fd7aee2ee2c07800d43d5a1a57c0d8a8f29ea1706bbb9d1c69cdbae5c27ddaed71b5483be5905037904ee19d2f126ee252dd7b769005b45428fc82447134b8c0a49759374ee62a1780b8797beef9e50acaee70c4cbda59eb615692f1c5f0de4e5b5f7468cfe5cebecf2d4fb33dc95b10627df81584dba001fcfdb1bdfed8b11022277f859fdb2bbe2083c124d15a260cf2160fdb8718258c0b10080a99e6e40f59b07f504b8cd526157f371c503e9e67c52ffcda238c3042d80d30f897a0ad481ac6771cf2556b07ccdcdcfe85c292e6b59c201889984758604e918b07270e38a182de814fc756763b10ab59cf832556c1813823ea2a276accae7b7e9e18a4cbcfcecb32f4745afa48305869fccd3d21a3c5d31105d64cc985cd9dd2d3fcefa6d6b397154dc219392dd7527ff4b0a3d62c3005bd770cbd00b4e15f6b85508e14c687ba63a167782a8392703f2f16010e1ef120e936efadc099a0e9e904e662f51f7f46951215773fc0eda8ae1f0f9411c799280cc2d2827e226ee1a7f7e225999aa49d47401b44a74dac13f16fcbe6709445addbd2005f390084d52e4a0c86d8a713ca5febf4f58ac66720f2f6d8382884a3c416b6e4c2f66ae865ac28f2a31d9ccf3bd7bfcad84d80116ce3c217b9f4ddb00db4dd8835b5ea1ed439c258ad054c8621d8842d95060e368be065f7b5c7f701f50d09c5d1c1c9ec085226894bb708bfc705fd7d63554c0a47742b0daf29de184b1bc96f7272449289054d6e8d35a27895b6f23ef2361ffc8a5ea338381bf39c63b4337c0779389f34e4ba8acc79fdffceddebc7999ec83d058e5f335f0962533aa8aed74d09dc2e21769e624b116ecefe4612f4c2552864e648b8c9f541469925d7f6601d778872515f675a446e908eadc235c9bcc6f84feea5e8b2ec7d437af884ccb619632959dd2ea272f38fc3c9ecd11d14857a499f8f98a358b5096b4f8565c3a72bca57dcce68f168c6bf092fe27a80084e5f803162f58ad7a0a5cb86e3ce57d2f5d4c3cbdfdb6d239e4d3ba25053127e2a5a668b7f955169135921ddb43839fe464dd2efb8a8c9fd93d62edcd0e2a949b69f398b0fe2f84b6e5aab4672a19d7454c9fbf9732da4252a1dd759a2d91aff5bbbd8a49b007087ac2c7663ce2f6801cb5668621c466fb273ed2584dcb3a7fd352156d4a9581ad007b1b5d072e8c2ff7ef003faad178c0fb2fe847c2991fbe952d59287e50d049b9745185ec9a64bb3bb9f9590fd890b3dfa2a415077322d308c84b3dbe1beea254cb583c87c88b22fd5e6e3ae819266cb777649519e839c52cf458a2ee5a1a4b2142baac0ebff7ff55e6fee2e362932ec9e58c5f106faebfe5079950a0d24ae615a8dd60e6611a9fd13bdc0b6de2f3e4b7cf355959e2803a430776d211aa97fa7f759ac4f8aa0bce11d9bab5ff2299bbc093a33d40054ca49f364e2afdb98b94ce7acb2f13e11dcfc7c9e16887df27f09c16dad202975d1683851d5bc410c1e1ddbc802f7493ea504076970f4b4c6d22ee0f1619e851238c3d056a6400ec0d27a9a20f41d238a2ee396bba4783fdadb71c266d110367bd9c64eb72dbd5a609f2ba414fb7f8f67b2b4da3339c43193df2c3d0942d3c3b30db2ab59b14a3fd30878a48c95ec161cccd572ea241ee4adc190b89560133475f5b99ac247b56c2488a8132c2f024472b45691223fdb9a46aeefb0df73e6ba3685dc2d19c909383d108fba300fdcb4a46cb8268cf6f19939c2cf789d009549d187d9b895e12034db35fd3a17e862795e50484dc071164bf2415eac1b0177e5677f20778ec4ed2cef56773b2f0227d355ed61804210ea7a136d6a0593b484c5ccfe733faf8244e5761225732a2aa1f6ad2f6a5263a4822a624ab308e590183af5663cf82f7043565edc1870c53f4d173189fd0e146925574e8e04b63d56d1eb9c3c67df7bd165ba2e089a7069a0678254cad9d15057c367de62b8e839128bb428dcbc3591443a5bb5afd147e1baae525cff0a7cda95587cedd15b67699b1378744b8143a0a112c5c467cfe26821a616107f9548e9418fb7e96cbaff23654cf029fe172a38fd830022ef2c05a8972593f6740fca55d68b924bda7ff73712f02288f195cfa6d9dcb66e5be19474aa7a584a282858fdb6341436140d7d11ec428e01d16cbf7a638dfbe9e18da8763fe2ec4f5987bcfce15e988a411da4b6e54f373f63fc6512a839a4840a37bcd845c4305e3723980647b038a7d298b67d94219b31a84ec3d4df4bb81aaa07a8a358736412bd5b761789dcff2d182a3ffd22ae05845af001f7f028fb3f46e461e4533db88b9fa11cfd12dd2d34ea11bc8c74b1843e8f28a5b845a8bb3c7277fd1c49ba1dd17acd340b1f63086fb9329c774c54c036798d5b5184de7097a71a4484bebb858a11428491669d4b41b652fb5848c8725938743aa03bff8d1bd5576155d77979cbe76fd5aa75875f395fbdb5d03af750dcbcf1afa0ffee9c7cfb1722b533c87f84a57b53b000000074390c608ff3cce57b78d6e566cfea91c5194e61fa3b921d8bf843acfcc90a14707eeb6d1583937420c247cff52d53f4400e90287ebb3ff64e2dd5b4455b39e56b4765ae3b1dac860e281ece98ddc4209d4e31c1ef61c01a8fe8027911f131d120b391b97b20915840e0e5cb9d727eed75623fa38673e6cb3a094e508d9a9983bde1bc386ee4d584347f341ea70358d9f35b1f64fbe08c8edfc4e4e1d79a44d2af06bc484d5a19d448adda5d1a5af9b7fbd5f9599c5e05a0f576cc3568cabf31541b650611d2793675d3edf1140b65f310f98be6af7618bb8735d7043d73df3409d37749582429085738936562f603720fa713f2df9e95fa47cf35f9b3bfa82618dd955d746010aab36d9d6e826e39eef5d682b87281b2ec40a1f03d9d1139361e15c12276ab4f1ef62e944538751e2a585118eb91581a2291d500075b7ad514cc840cd07a77accf69cb3b3ff7dd8d1c6eae293d702373647a8e215e7c386dbb9698ddbd84792d57c041ec08ae5b1e034f4bd6dda80c35d968397ee84afd6f533c90813a67f525faa2f5ff5bfda87c936fdbcc443b1f4e1ec87258484fbd36d3a708bdf805c5b8b287b352241df3f5ead4eb730276d5d7915cf5c6a8fcb357ae35b124439a5ae68d9425b3d476ec7de45d79e31a5732af9712d5844a7cc26889d diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W2.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W2.rsp index e478aa9d33..5ec6a5b991 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W2.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W2.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H15_W2 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 000000000000000000000002f08b5ed856f80451558c031cbeda91f6d5f610e6980ee56751444e2aa676356757ad620d1fd857d154c6c42ea5f4e169b4d9e71c8cc801cc32f9f5c675c6ed6b65ddfb0d0b3058e195d1abaf2db1c182a814453ff0bca5f67a5b7990aac2be11264c00cbe443510f9e7dc92b874fb03ba51f6841569f84c7be828662be715f3805e80ad07144ba1f74bcbdeacb4f487a04b4dfb873568eeea19da257507086c23e0e1c757ff97e4a3fddbf56caafde716eb678ccb9e70b097955d01a7354c32bb762af1aa18bba060580a9aa515507008ab99f0180f76d9d1548a85cb0c567129dfa7bcd632be21b545f0aaad3832ceab7dde6117f4f5cc65fe6e5d63b110badfee7d3233ac43d55717e721e5de68dcf99a13463823de42f488ac70d88fb04b50e2e4b8f9c3cfc57330ca0b84d33b8ec0842fabd160088e62dc64770aa3ee02e8840a7698183fb484c897fc7de9efd597347924921544fbb545ba4bb3ad3f95a05fa55e21a827f78d44d8ea96dde96a6d9bdce75491fd2e9c7edb3a0c155576cd083fdbf706d6c54ca1abed0e9ef069438779cf2fb20318b47db116c1fee2972617306a6bceb64bb910c11baacd8fcc0a63596d328dcab0f41bcdd1f5d4b17f3ec2a8b2726d2071d9257adf8fbfc52c620ca411c1a3d9afa3c224745f8601e28ef0e3351ca8593f119079b3ec16ae4009f78299eac494e5b4a4ed920dab2e2e9912856d586ff7d037f49f25dc5bcef30d0755f4949312cfc9a3673cbd4f636cf81350f5adc050c323ab9633bad880690cbc13f7cf0dd93922ea92688ef1fba968b903725c6ea09170f4d26bacd62132856b6972665b466f6688e37a6e8a8c938a72e1fccad2bc8c1fa7a246e1361ae543892f23c3637ddd20b3d8a3b0aeb68ccb5edff07be9e9169d93c6e4c0e5dd7adbb3384eb679b4b8c14c23e3679a6ff721678be639d3684375e9a01f14d29f310c8460fea41de9dc5289a784080c090d23da1ff5aad37caf80a920c82962f966f0a8f00cf4972752b44c4bf2af44e18cd373a6b5afc281055a71dc9d39d65233f1c397dcf8ffc0a32a07905f2007798979ef0123d65eb1033eb98be9481286b233875ca0e0e6a7734956c6120733ef49ffcadac9986e902a24aa00a5facebe20c8a90e899ef14cc4fb536cb2fd272849f448bdc30943fa027b697177dcd9dcb135c78d4e000230ba274754d5dc7591b0b818e8b2ec5eeb216e02415ffaddd6e10e42a2cb55c122bbe2dd7c19a70bb33b52e1450db1d49a30c1dda1673015cd7944b35efeda84a821134085193f70030a1e375fe43e89fe5e84a14283f78ab2a5985403b45f8da9ee082a1c773acc7c8b0faffdd433c840f5519a1945c622642548dfe4128a01bc15ddb3a4defdcc9fdeac62c27f8ea27e939966471ceb011e0a116b43b100050cb6c2d74c71156e48ad869c18b54d08196101f845ca21c89b647543fc38e05ce47fa3c21c3fd65401747ec0076fd74ba27e1c2d70db3c05bb1c08e2a392a8d548f428dcb572c7cfa49e709ef62305ac06ee9e705bb5c5c440ad92f8d72313dd0d35d244613b6df9a325e6b7670ed0838af40bd48bf42c239ba12408adbcfb492b9d2fc0eb523dfb419bf9eaebca4fa4305e622088a4482ca4735e14c0d8bb26305882c254e87f60d5039a1857b0d6d2a9dcbad8a10c802ab9a9ec8a6f5caf05a4dcfea0bff82b6830201978c145611a3eb060d08fb70e6d9a6eb85c6f779c7b50bf2c38f9631003a1d8c5943d24a987eddd3a9a27c694c6def4b3cb938515239a3e35452acefc29165e8c5cb3d8e8b5da9423debd3ce1ccce82d1279af8253c21e8dbf743fb80d8cb1f51d3d9afab06da2d11d99ebf26f69e93bf726d9d33a8f06ca228602692a7ba44ef95990ed181ca9acc62954f8a1af3b873b2a07faf575f387b3a3fdbd9ce68afcb2094f39713d2cdd430c85e534af140adf30d99167597d2b05ef7d7fb4a636bb8c94c4892484a00b987cb203ef3b038fd6034850015a0f3ee971896b9c76df5ff2d724ba2c5eaccf86f19e83bcf968774106d7fb42614cfcb5c1da672d5ca1bb41877bb3835ef3ad680f3c14ed7fb0e2839bde1a8d70ec318b1005ff0385f8cca6febb52294f4caa3b284349466d3fb2c65ba2df6fccbeed18187b24a65801304d1e09b56befbc5fa3ff1ef44d73e0f3e1dfb9b86f85f2f3a99c2541808071d20b9248e100e7813fe18d553b63ce520e3e60612aea4f076e65f53d23f122a9bf435eadf13e5053d8b509ca895844b7b36c284e6be757407d202c447355174634cee9c90a1c0c2d29628d9ac6e9c4996d6924f9f6b99adff788cb99e3a4ff46e257db3a9ce2b25e71dd783d59ac36f28d48e0d6271a1ddf1b4c5deaf1e97421031bf6d8e86579ffc1eef966e502b695878bfb514cb4524b28ce202d38e7d4545f14b4f4709f7b23de5a0b5695e9e1ccbd16bf8fc89b960da883667d256b08428f8b5874630213007a24d23c086e3b171ac61ea4a042f8129b22c1adc85de8d68f534116493980c28054f8a4887b7fb8d53bf0149927c5504956284f4105500c9b8170d2ec6746030ca343ad1224c836b4538fa9bedf2d2ee97ff85d6ea7290a1aa3df9e47550947c35a3b7c74e0969e6a3999deeaed57c9ce705fbf859f700a197f73ccceb5399a028c781aa42a4216500ac3a1592d7c3f58474986b0ae7f2685c6ede892b6098cbd6c9743fd974dc39d45d732f392617dabb33e12df59d4252bed5d19f36b77b67d45d56b9ffc26219fd9988646649742ee364f483aaccc9ef8c7aa16e19cf045a46dffb27863cbe8637403638826fcc79e79929f49dc315fe802301072b5fc9b26a91664e6b69ca897f4c5ff753e3be247a0adc3fe5e3d779f0da3c7f4be1340b6c38f596afafefd951760f4f25611f689aba3319dfe54044a1d6cc4aa9d6e3f1c21c35c6bc1dfeabff882eaa624fed9f50bac1fca9d53378629c1da9013c21750c820a860dd5a97ed04b3aaa771ed8135bb4ccb9bd3815fa925e464db27b96d4582c105c8a1f471dd5fd0c512a3e5f596856e3ca297e7b78bf654d078cdd2a46eea45ae7febd39f127351f2beeffa29d967417935dd98467d0f1766dadeac80f999d517902dc869fe13dbf186d7e871141e5e04f68a238140933a1e5b215666eb1c7499f28dbe2b3407f3bd2ce6a7088718768a6d71a24d3fa16e62d7d57e2643274029b5f87dd5e04d887012bab0eecab3c9b5f3391c713ed718e30b968d65e342f0b4a61baa381fc9c3d2aa398706a2ff9e6a7c5fb964cba0a1d58fcd6a133008245ad9788482e153effd601ac217568ff7a35675b0af3623df1ecb784f2e7b690a059870654057950a49cf7f037915baf02886badd23fcb2e61274482e7ba856d7203c620f81be9d22f24557c11126c79cbb45026e21c43638d059144c6a2dc7c161d87963b3185641d97bc8e2ffc9bf11e78d27b2bd62b1fd13f872c454d7354b92613436cce8a1333b59ef75409581c76fbfb76b2dfb157aa6a0fd85ef1cb38006c9ca2676b83ac624932175bd04f72b8ecca8b23a86bf440c9a8f9b874ad1508d515d18b5f097c7e182b63787d1acc78defed914cbd33ad0d07ffd9cfa73eaa956297281fe3e0310902b2dfa8fbbf21ac1ff387b1d8fb202a3be3b157bbd113c4db44e86329bc86080ee38593773f614ea7b7841583340fce41b7345607d84e877f8b715f5575fb57201572bf775c960cb17f976504a00a98b0057b664ecce394e3d117d62bf9b653b76ed6fb4e2436a22deb7f72b399154d151f85a224862c6bbe564c3ffae36a6732e528f84b15fd617e383663c3ee28cd442bd7ed4c38228fea64e543d684f6e613982bf8a9934e4f81db467ee1b5da2b8a2231eb5c2dac2795a478bfd91beeba8f3c731381c98593a4699a520437659a8dc297c561cfc66986e886b0f2a79899324af9029466f6593bf4dc5191f3ac0e2d0b7d6afa2764942987bcea3c0404de1942f0e058f5b1457a7713d987e408d54ac05bbc5322181fc30934d3fe516f1678f91ba1733b4b31fa1c968ab5bbc6567a436ad88b328b31194e7f3274ea9e14dfb2af9fd137dcf6bcb31ae8723d3d2b035cf062e614ddff037f3e636fba860ca70540dbb704fcf1886bd5453b028e7d50020973aef05155215b044ca7eff50cc74f1cb2cb6dd447f43d42ce8d3c69295aaac5433e72deea922afb0853b27bf5347d205eb121eefadd31fc337c4e67ecc1df4e36c125b77fe5dea89104a52a58b36e76a57cc5a5f61fbdd7ea04e7bfb0895a790724e9ea93eafe01d20d2f3a4db460fbd9728c0e954984851a48c3806fde2930b98274109201c57fe8d0ccffa2cceb7d7f1bac2264235676df2253d65de551b6112f0a617f9b16d64953c646b84137185e63018cbfd28643d4dc96c782a8ca43809426bb905a7d872fecfad0814fafdc0f6079aa80e1b7236e33f3ca28ac02fc32d4fc4e751fc053b5b31b38b76068dd443fbb9b37ac9ee779da0d90bd9b4fc80f1cb71675c243ad4f2c2f03e9cc58263da9bf5aed282b1ab905474bf3a37225f7bf7952c930b7135479f9fffdd2cf85f2c3d5664f696bd32832db043f6b39ff627448042f7248253ef8b9e3d577f824c5100230a35a3581eed96308693407fdfa960266f8e338a70e2a8206886467bdb5d7ef7e6695eb0145e52a370727cdc55f437469c56a52a69a667cac0f057caea787700c5ef454600574dc27784d9b6d4b91296d776752d12d0ba6b5569f79121bb1bcd3a11535c5badc7daa72362a23099aaa10d2e45c081423afa48d28203d18d16529610965e28af87ae97a73b7d5ae048dcd9f352381ac26b96ca3269da6dbf88e96c795650904e479b72b7dd6b9bf46ea10d24d88213a002d0655918cd9217d02750d396a44c653a71e2d9125a133542a5462756b0cfcd1e1d9e7be3b919a65042e69e3d3e293f1fc34974eb6a148700c7f74c5497351be1ded9060f95a103b5f1243db2acc218b30fe27697f5fa3bc7a43fe28174bf916e985750f3647b53479f1ebe74806322b64659ee49d3a754f5b1c22fd39f8b6f36aab9512b4371323a3d939b97aedd726303d91f804731ed921f70dab7c2475af8cdcd54bcb6747faf7e7b6a1aa579cedabf8447358d23aec2cc4b75a547e0b59de77984b33bf04557210150718f53f94dac4e80eff9e20c61bc457dcbfffb69c61d5df812ac70ed8600a2d8d9081e46c34ad9ce6a0f1aef9b25277b8600e3dc9a001ab305f732f5d01a1cd9096ae813c53731490e5af8018ea3a15618e365e12861340e7ca7f8afe683be65a508d8f8ca5dc701c2708ec1c2d70a80362a217cccbaec9bf6e1a201d70025701759121a5bced89d618a1fdd8b9456f23d7b3c105395f9397fb80ad8ca754c132f7d0e9f95ae2f956b18e313520da33dccf03e3ca0b37cc6a4034aa7d50489054970da47fc22f385a4ce208613fb347f74f02c0e17eaf381797362acbf78294609c343eb3035e42fe71ce86b9e0dad4f1777f29457e7ada88d3c0c3f8be6d59076bc2fcd9c52debe5fdfcc280b567bb7622c2012eed6cfefa3533d9a2606aef17ae20d9869f02f83606c93778529e20d2252ff239c4252b7944ed439f443c1b1394a1c1df5b386bf5f9a3a839d7b1f30aa6d04ae2f1348bc926c65c55880918a4ea278c141afc3229eb756e8f16402ad40ec7d30c8ee56317d6ff3023b58e468cbe0404decc7e2f548d41f4669c5ee79da45a3d30cfa9466ca9bc34474d1b3a3beede79ed5c177b2bb48edff3a8c3c71284a3bd1c29eef2bd1defb2d40c1c70f5fc02ff899dcd3e7c73d88602e7ff66b25b71537437eb0e349c4d62a306c97131f0cd5affde1e9938d86602df061f6837bd542d68600324f9f8120ee567c9ffc87fd0a9507b1034789055b932528d618959ae2c43778051824c117d884b3315a3c0fabe2ae16284ea6ac01712006d222f9874d7871777255b46cfb44b72b3048f1a43f7e9d72ae996ae791d2f17ad97c26ef23692126df47840f7219e414e4994ac281328000000071f0adb73b4cd33823d14c463983567475f253c2723200371379ddd88255aaa21bd9434e4366d569655f38c8f6f2d25c66fdf7450ae9aaac284e91d433870308864e3f2568c460cfe515027b525228a27f154ca0161e0c3571ad85e38b2b5e622871da013c0ce035df5cb59508775198d3b69dc52a7cbb459d10ca900172c9c46a44efaee553817d7fdc7f7f1e3f2f6714d101c8555756b1d5b8d13342d7fffe8f1a37aaa0cffb53ef5cd6c83bb78b450a026edfa8e34d18fc68743dceaba69ebc6b26d18d63a9b80f6dfcf9293b7cad5523e0b215539cfd6dd858471d7fd725e030265518140575ab772b858152f41844ef97e54b685e81745c47e9b7f0b9d375e65a2214ffb0fa163b8df334d1495b44b8232ce3dd8c5e2a760cd92eb59c80080c841d0150fed836cd7ac390ee1b17ff670869b98dc3ec29c5f42c4381a3866764e0754fb5f4b73050993e1445fccad4d346a2dc6b61476cf0cc8658b3ff406bb1ed89df047dcd49f2583911ca3a7c4bf17fe0dbf5ba32440f253f12f9f791b9bb80d413204c41b4e9689cd72b5b8bf73272fc005c6a9f230997310d49dddd68df985bba18ce58c1dc63d5c62c8f150b29e077892d148e1c6ebf342277990b51c26762bd0da452a6c88bc50de214cb59918583839641b67df417828fc2b9f08 diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W4.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W4.rsp index b63cadafb9..a3ba862944 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W4.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W4.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H15_W4 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 000000000000000000000003b15d44eb5dec79430945738b499d2beebb5302eafc1318028103aab6469c2cc9f7701919bad01498c915de8d56a9e221413bc8191bbb0a6e538298c49f46213ec9b6f27b26d85c13541b2dca4fde3fcb5c6cd830ba044c8e6478011c13a10e79d5ab11157d952166ca5e5cf7f36c675af016a4476d97b79bed46cc06d261e82ee8eceae9031cdf85e0afabb71aee45054e90534ea22e32987f6bdad1d82e5753c3d49b70a2da50e715598dc45e37ce67404f50d6f068ea9f053f89a25f3167b778f670834a4247dbf2f3463772f1af1fe98def960bad75531503874a8ba1679b0eaacfa0532017d7f12587180a0cadd20abd54e206f9482ff3d24be9efb41e6fe749facd7312927a81857f0810d14610528c4ea6b3fe3e8efb75f3c100ace31d91b273790534851f0ba37977178b38df4319405c8ad6c9a657c536836c6362f41fe67884198d8ec5366bc788c43b8f7c1689c47d4f3d1c33727937fcab453fccb7dfd4f1932caad1ad5ac45d51e4c4fec014ea796b3b9e70781a541e9bebdb309ebde3a30918b63d6d076c4ca22387e0b7a17a42e300ec1f9b750511d989c443edf89d9f24bcfe96767aca712ee08583a70fc80b6d7b7f3d7883c02491bcc02e37e267d9f14ac003fe002a669a8ff5ffb37e55a8c002bc1ed3743745119eb0ec227ff38eec5956f1a36390fa086f98ab4d9200e7c17a48ecd8f8b5bf38341ecbf8a5a0f5f3fe4b2a0f813df19df6277b014126d1c0d42e093d1bbc4e2cbae00422a78c1e70b2203ea18591b22d2015f8d4d000fa484e879d44ceb86e7ef89e11f3ea786f3b6d204e4ba13466bad37b1cfb4cdbe0f7bf26623d787681441e6a64d3d783bdeae7fceb6fad18c8b011c2f14b3660951a8cf87b75d292489dc87cfdfed0610cbc7b727b780400b8ddf7a1c5d5fc265a7f0d2356a7e39862dca4ceb0b07efbea59bfa5c8d27ca1c04857b5c033322dfa8bb5f0aad504c246f17d97e306c55cf17f0724d5201ef283f8e0191ddb9b5ffb5f2e86586a1ec2243dfe17b61e6c5b48204717a3de944a26082b396d016a3f689fec52354321d08722f2141e53063305f988a720a91cd326bd7ec72071ea45e314ad505c66a85ac4478fa2fbb7abfe83e890779f607de7bef9b852e1b72ca511cb49b5495884f04a6c6252dae87ad6154f0934c44ffd9f9b7e78ff32163f414fb1ae01d703b53afd5400178ebdfefaaff149de556b474d507cc4f83a2b6bc8d8aba86d55f32dd6c59f90376480d195ccb157201150438b93432b26cb6a437be4bc84b5239b89bc477ce4ad981c7c6ff38cee53091aa3489a095e72b582ccfcfe783554b3dedb32af18f136cbe0c83ace70cc09164debd2b67fc5aa9a9320024dec45a74be1793e3850062849860596cdc36b9ea154cada6ea752049b391082ba0107e4658e6efd741fc5899fb5ddb7549cae174fb9e08d0b42d75f15b1743d06f107045ec931f8ffcc67fe70779cfb6c3e3f58fa230c951cc6278571796cd0f83249ec93f7ba62868782e431c177a691fdf617e9af2221feab9ee09684365d0a8a5e1948de7a01b6e390d18651f26655d994c1363efb93e6dc196b64e65b8ce1150b7d020b280760e0354d561d08228611e2fe9f483ab574f93cbd709fb3b4b07af72d27f3960f6c6579ecc02ceaae745a3939112e883e9dca7856d5803dd5b21f889c145d3c54b2a5fc117c341e2109b935cde6c7959ef33e3c2a9aaf32cbe003c14aff7f36cabdf25f37467e7fcc58155eb0a354313057f30898370ecdc5b75eb2a74388197adfb36439ecf97a7f9302a2f4d7be079abb824db22f7e962136df36dad41cd5816f4e8deb434b59b4f308818a12963dcc0168f20a15017f941f129dbced6e41fadd87f91655655b7001170188fe9545fa93424f939464c7af32a5f282d999e5f93523ac2090041cb087f6be7e8cf2aeb95e05afba361e973c4a69eca8bf7c1f22bd98e94dd71e604561ccd316f6579a82c75b58f731282f658ed2de278ec4c627bd7e89b4f7c4a8ea68a48cf8744be232981218ca4ed83db5dce7719b3237236632e9679516271015ec8db512d517f03e038910cdac47ab895d8a8a17dc43fdb7c27273cb830372edc94e9188fc8eb0b95bbd6f10ea1d593a7aaccf302b6ceea1f6f3b71d7d4bff16abefdc5c065922e1eb3527af393186b963b15b3a5c0c7626e68b69de1df88dd9d5430d8919548b1dd21fc65f4e602b6a0e1fed96e931ad8953b30f84eaf86b630a104d5f296afd9196c865134e9f93ccafd17abcb2b2fad3d7c379cd4b7f2382b30af940474665eef0e0817e322cbaed4ff5607e7970a8b5292313a9594e5ad6878cfb8cd74e9c498dcc63510e7c28d931ff70253c602ab5cd2d600580ff642f68aabf7a3643f1c7af8a41e65310311ea43c75e95f8370ba5a6ac3cb0065d599d79e4d44f0591135a87245eaa7866f49046e764facfaddff76c5759fb7e58c215dd446f8a81ff4b8e48154e6840c38cd961b9b9dfcd55fd605880bdb8816d877fe1a53237b7a3e056f60476ef3ae607725eab95cf03290fda825d9db7ae0262ecfda3370e5799ea77dce227ed43316cbaca2bf61217151d703ad6801add7891d374353de6bedbf63c69bf33eff12c937df5300f52bfe07f7dc12f197e7aa071a76e0d2e3eba64f99737a8fc0f413b143c8a068e64fd7c0767094b46945ccb76ca3591c0f7cf02caf00254eec04585a8b9e38d3125283c3932fa6ea02999cde821a534272b267df5be0aa822a18edbd174bba9262d0f43a6870b2a5e95e8e673a00b7de8a0acaa0f38d78523564b7dd045c151e5c072f6e8d4b179eb36d7775d3f55523331527c1af2b623b4c894da1847a3bf9ace1eff733eb1dd0a04c09d8b378e9abbd00ffdb9d9bc8d73fd4977b8271240d1ddcda20bf41e2402e2f3085dd9ccd4ac881455a22d46cf9637ab93fcb3e4bdea1facb4f10fcbcd96fa21ec295837c56148dcad04c34a15db5aa2a9b0b4098493682e9d536acce9150cdbcfa62015c43473d58e5fb1f30adb8905b90a4426c81abdb345696f21da4bd210000000775500fe3a11d75bbd8a575414493dd05e9089d78918012e60f09610f1d957fc6724bc66eb0f0ecaaf9d040e31cd61531b5b950991637d97ec4aebbdd68efef4fa42b984809bf91e21b1b767d8550f0ed2d957fc61db16b5bcb2965436e5e15b76bc299f66f30d459eca6642eba5b5068cbdb38aa87def567852f1adce0d08175390ad6b1e9db4eaf8a07c11fdc7e68bbeb66afa3916aca2b7e9366cea55c60d643ddae869ef53e95a5e24866168c106f6ed019c0b120417c64b479bd973077c1543ca6242a05abc1d48e778eaaa3b3bd5e45bc9d569f372189309aa91a927ab31f67daf8b45a5947db1149a9ff29a4972ea03b0b238bde23599b4068f4075f02bce308631ad3b4a00babb5fef7a03a6a335a543e10e360824272d7d17b9f169f1a9d39e941c61da753842870f3d058192ba9b808376e08a5879c077ee8fca7228f96cbb6d694d6bc10be0cf5b718389378115e38943a57716e5d98041c4a6b93f40e2a781728d98d9965784f7404dc2fc7b63e3c8af12992afe5322284fed577a9e9c866a590332436b08fb783891cf1cc7c7b4753d24e23feb7046f90aa3bb9ec1e30ed1dfcc1f22e78ee63e648ed3bf949bc04e47f410a3441d614b912a8e7aa21ffbb15fa2f3261cddac3758c6f5a54fecf3153d7e168c0aeed75c91cbef8 diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W8.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W8.rsp index cc7ddaa6d2..06c629fe73 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W8.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H15_W8.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H15_W8 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 0000000000000000000000047af430445b89d9b8c82509c6d6e14559a7e26488764d076cb6428ec25a95afb01d0fa6b245bcd544909ca29bf1787ea02eb45ad125a5aff76f43fcf8d58c8c92559e4a1f99339a26f66a75296eaef6d9c087606dd3df5987808521b95905e0a6c7119faa2e57df8e1ec02be9d1ce346f32d465eb404e928080dbbbc6f9994bdf9ef72a44948a0f69794401fedab887ba9a8dcf117650c5cb45b239d08b9247dcde09b238a5cfa5fc26aa00f2060e7eda5bd7d5ce5b6037475185b0b2561d8851626b2beebe8f12b1efb24bdb9a86b657893ccbadbee0d04efb421fa494aa1dc926a3666a959313d08358dce4d7ce16b23e36cad0c26e56e2d5b32afa744ed53310fceea855092a45fcd7058568cbe4508d511b8bab52cd30a75d3c97cd1a42e7cc2f16a6242e8e10fb498606556d6e65e2f7d55294560856f706cddaaea7f3d495d4d0c6b655cba91b211b7d79dd9e4cb4e8c44f187ee7de6312c39a99c34590a8f50141c31be1efd6083a8aaf36f5da7eca4f66fdff1d984e764b720bdc830ee4f6c7406c2b0cf0889a00ed51d435f0b31c7b9a10eb8484c64d3d24cac953d38b11c02047d919da39782db070571a9a10658eac751c19eca9df0b0a0f68916ae4830f56d28eec5f18341542bbf2c8652b44ac354326a9b2a854f6326ae920f4f201f5f71a1c698ce69e9964fe7aca73f9080c420fffc8fa3838194ce479c87e6ed5619eab0bd317b84485755a2390ab4b8220d74b73d14087ea334c14f61bb06da084eaa77aa99f13b62758e6a83f9665999b0f86f92c854a1e44b45e5cb5209193025d78bc7e5fd8300c91740b444ae3cd3880bf22927f777d2833eae0d4792b917fae8dda163cf4be2928e8c881d0fbab323a4925657335a5964f2cf295de1d4c1817be9a78e89712accb11e4b02bb02ef55e42832f94b293c732e1164e1254c6597053620fd88b78d884106d98c88f87756656ab1fab40175542c4f716340d485441e9af121860e971eb8c2b26d8f5d262d09376e04c8cbfd79f5c45261cfb6c290563b4ea0b62c6464d40d1ef036a2cbc3e8e9e227c91798fc2018c393ad54a6709a8b13caa03e2c0c8cace8253baef126a4e2900ec69bd79e2a99faf088795b894b09f002e8c33ac189346003372543b186e145f322630883a283b9c31d8f0679b9fddf0b3a551c451bce5f9d6e47cd113894d723accf6ff6a28e37452884244456f55cc89514dc24585b458725595890c809a6e034e69135ce605bba18d813a3f68f0a91595b3c301e955a283620e88425d3ce747e68d081dcaca159d269adfdd8901920916ac8dc652fd2b019d86342d1b92e3e8dacae938fc14bc775021a8faac81f5722446c8e9715e23ce5c68a114ad1611a6e146dc80488d4f359537de3b44bd3f1b7ea74d045f6846931bfcf1747e089c75a5ffd2b7cc7adf693a282966d414ce7715fae6064938f7db7006bbd98c70b661f2b82bfe5dc4d30a9d7763e4be9bfefbc63bb7c5d4c8da6c9adf6a9e1f20025bef2564fa87886feed6789d555ebee11bc812660b5e5b4b54c196eea96f693324ff20646e1e4dba9400000007f656672dea662ec5bcc26a23487368222eade00324f8f5f72c9111c474af6995e54f45a1ea3ede6d95a73d863b1491982f23f2ecada075a63512600c7661590ea4097241a052c5bcad87ba7858e9d5458a9a7627c06ffb3a7351aa34e7654ea893deced8e5736374ad7a3efae2331d3f4ccfa90ba46871258a920ad200f575b755e977555f8480b3b59e1e5aca7300654b78a56befe6cbc8f7194ef7b451e09644d4220ddb8c52ddb9029d220bc3794a26581e2e1dab769184b502f32141242b0f73f608ecea7f3915e7e4730a99dca80a672cd4ee902b64e15ab4292e265431012040373192b3579d916b8cb20f746c512c065eed493dc15d7af1a7836caa481a3a0369373debf8061bc276f8fe6cdf6062c607457bb08653baad184ce8dc6262114e566eb3e6917a12977028a252d27b4d20f88a0157dd5bcda24fb14d9b55a4663782d6ba567f424acfcdaa1ef74e3b4467f42f78cb1a75e5df72d2f3f1f8b027252d2598fa3cfe6cb30db132eee876479f7de10a3988bf5f9f828bb34cd497307f92d16d14ea5041dcb7223099850a79f6411dd01eae4d04a5a029c6c32f728f778728492ff47cd2867a830a0c68db065021b163470ec315ac84d0f1086b841651ed5101170aa822dc63cd76d198a44d50ca755cc39d0cc421b9923ff4e2 diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W1.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W1.rsp index b9d272dd0d..94f25d3247 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W1.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W1.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H20_W1 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 000000000000000000000001c0228b6816e9c280638c69e725851f996df55bfaa61141788b213464e517bcfae1e2e52bccdd49fb616c682c3feff0257c25f758fb41e031b0de1999c68856c95de7f94489ff58f275cc6ae9084c0224c65f015b6a370965e4a16953f311b2cb2020f5d7fd649c2535d47409f7144817fcb8e3cc6e4faea1a4e49fe32af89087f7c992578df860af90f4e1357c3be9d05fc5b2dcd23840e708847d65433412df9f238afa72c6a7561b917f3e3313e44628daaed4663206a63a39d8e5eb2306857bb29f7667394937e7a9a7a1b3ab5e231046efb97028f0ac6bab86e2637c46bf164bcfe7d8613d9aeac631a3af401f562b7e6b24473e7c22d7030d27bed9ca721119e1b0ea2b195fe3f9b2abbb0ff03cd3fd666ce0d1cb94ade5a8b189be3bd888a21f41e5f9ade9ec1c377d047553185aad657609bd4356936c60ae1eb29ad56ff4de54b79a9027ab406e9ce8f4b5aae8fc4ee3a401950df35b3376394869abfa8276328de1e2b4d17e8d3ffa1ccdfe80c808514401def95d73c87c9af8e301b03ee17ed3a6d3a6a82664ba846600b9b2482a009cd1aaa1dfc319ee98e98619c91785a6f404508748205992e12f115a0f35640598241a5c320151d3d7568385d79cd8e7fecfa570538ad82fb1a5aed8fb13310f1791b9b885d638c182f148b9a035cd4774f303828a534c33590d6aa4cac1a8f51717694662f0995912ff63856179479c35e93fdcc079c3a7ee4ad220417be72d2634d2768103b5c1c9c7af1cf957cc89720fdd004da77a1e2fe9cff04aedc64b13f5a509b8810167aa2014a4036a89f5b4e03f72348882adf6b9aade977b6a61b0cfa0a789812c4086b7c1d0ad78fb0ceb59e246e06caae90011cdda63af047d4eeca24d631f72cb83cdf52d41814101af0d0c6261b034a9a5588945f046616f35049093ea66ca788cf7cefa41de218915ef934ce4c2c883a1f44682bc450fe8e78c5616e4598443611de11394d463744e3896f9de8c63af0e6caa11f4c9f1668f31e43fc7b78803b089f05314f781cb9c60f29f65f03fedc199f0f953d8f120b189977d028160b15b0607898722709cba176df3441894959dde46c52cf78987bf102b1ca44290efd51ad37fe969b2177e24983c4bd7569723c4c13ddef10222fe9277346e67db8ea3c7eb11e598044d514faf74f34c25e3ea6891c0a1ba4b91f1f0ae79d5a36174c342bc58e5dbe8840b4aea026c4353445b1068b29dc6d42632c2742606615b3c94116694e5051ceb193c6d10446f3529e513c2ac81e3e69e56db86dd17672eea3e6a4bd35dd8be87919a853694b65f439003e4631ee6a2ecf1e783bca8e87c5fd232ebb068fbef64ed41eb2e0c1f6ee536c23010574a23d5265bafbe40e6cac639469432d926caf4b3c3f9e04a4cc232b595777353f00ab2efac0a3d1175c1eeb9d9b160f7af3d2859e17efbf7dd5a3a9de48e27533728161ecd5880e6ac0865b4e1f2a5c517c449e7f336546655ad546d51d77b98f65290b003a89fd7f187f72daabb36010898709f85b959600f8f92323788fbba6e4d8c10c352f13dab5f1ad2dc5bfb3753b4b7f22207a8a591f1e291c02ae53b3c5d593238686907792ffb6118d162f8e8a884b8bf091f5a788250231aa5660f87ade9aaf7e1e87dc2fffaea7afcf584e6fba8cc8674b405921d32722f34002a0ef915e0c313c36b1e3ee600155ccbb0c09536256d83662896c4dde681747289dec9c9bada62312df7e69f6140b036a45801405163a7aafce19c642ff9bbdd807189fbbe5c4cd7490cf291010d4d3e7ff0713c611a3427a28782456c09faf1c40f76157a39adf0b805ea40070b08403821e416444f904e12d243cd2d92f026dc6cb4b9bdb6227ffd4e97ed1de4f7c23e1670a51710b60478ccadca849aba66871020d799f3a5ea4087fa0246ddaad1d4e7e6355076bd59a1c02822aaf12d1fb63a5648cbe597d839c142cb14b0f1998ef266a35ba5eec1f26e7f6587425cb3ffc0be475d56446a45bcfc45b781c1a8c32c98eecf271242a0c69ae67f01e6ec4df033b574ab143782ce393de71bcc0db84bb72c0319cf089f8707c3926eb0202ce01f08c548f579269e9f32254a6d2f8a83ae6ace7d80ca4aca63e08ad5169997c05b6a809f243f5c1e3dbd9d5fe0dcd3cf77cb17578f09a731d2a3891c8a4496ee62f87d93afbc9ba68039403234cb1e552133a88ae9c644c6d8504becbc5f457072cf07ba6a02cf49b22592d1963e01359326e476da37a439fe9c52c001519de2e4228e34c10e99f897749156769512ccb6efff3dea10fada8e1d49924f3c4b0e9f8360f0fc9c680e721f292d2744370674b1780eedc8e7e106024c5ed240dca97b0bc91de1d4e39a3921866785fec13e325ee3042b09e40b804b195eca06b488e53f0ce7dfec718004a5a3f2256b6044e8635cf8642949ea9550c9ed9ddecedca7bf886fff103c674ba334aed47c3734e7c0c8cb50f4fb197502886ec02017c18dd94d5df6e404e6312bad153abc8ac5d8c860f3b6d35c8ca1837ff40a35d55b210ee7ff6e9e9efc5617398727cca27768abeb372a19a79db130a5aa7e17dd53805d8c9b5ecf3b33bcabd89ca491c8b0dca65c218f03006c29ab6e145b7f4ce12df7575712a93ae7ab746ecac67358fda8b96b43bb144d15f15206636cc6d5404eb14bbfaafbb9c967a5849b1472a1829dc41e9277ffe2a1252d3346be797fdd6be25a203006fbeb5d4c44e2ac95e9066838d199f2c5fce7d6ed825851b6ba51d319eb50d7379edcf054d1620ac4d9c74f0a9c3339f69627ff961be41a603423fd5b23c8fd42120ff6ef745d72a8b82528edd42e0ab00a1bef3440bd671312a4c134f5d1e25314043c48296910cc4084dafdb0b392526b68d79c7a3cebc01300243e5de21a317e53f09e4b65872d769c19b1aa72768b3298496d5ab64bfc993c4ad21a25f5864d53d8ebd1d7cfaaa7ac12fa517af42c4e1d874ca356bb4d40a55a3276fe42ff468bd45618342baf4bdabff943b76a9822104207987d9278fde73e031e848183e11a85580aa99538ba1f69fe18f7a36e38caa69982bf62c67991c37632fa6522352776fec155f55e134b64e6b688a3b0734634a99b545aec48641ffc243ca9e6d83b203f6bd529010b99790779f5463c7ae521324cfb004d2df83881552215168efb59ec495d425f5d51f6c25eb4a4eb066f45fb754e7e1d869981d4ccb46b54554ff41f3a7228c07bd8ac2b4cc7f21a7b59007eab643581e89340910dc1e966c93e2b16f6b42d6638a95ccb1456225c4e1f16e9b81c6ad1c681a7dba004f60f312b15a34958b00198e19b351760ef7f54137096af6ee388cd3431e184f3fec8527fe3a9dffbe70f4bdf688ac845699c652f6c70c588d4ca1599e8274a15843d77f82b34c6f85571b565d485017b35e05da22b8428278e97dd2ea96ae4961ffe02dded0f1026af739484eb97a259c7a95c367e5408d527ed08f7e1d485ab7b6e806a6687c7bb4bcdb5ee6815fe38e83ba6380905902bf2a19f26e3811168544b68476dd6402a2ca14f625b0150ca18fce52444a93ed0004cd60f013e68f5d01335eccf3be61ac5cff0b67f876db0368a779f98d81d0f451bc353cbbe57d6d54dc450582f47c3fc626eadefb971f6b570ab943d02ccb016e90ac926ba73afb1d4c03f55b355143aa9356ac9821c53e2b6552369c5607b05cc2ecbf3a522cf2c442cf1341c42e06517f7191a7195f2e80f93d78b4e6ec0d65ccaf946b2e95d1e58e19d4601b85a8630a5d44cef2439eaa4437a99e743d5fcefe8f204fe3a02d080b1146423d08cbaa1eb46ca0ee414db14e9aa81028ab1ad4f760089c84e83ab5bf786ac9d8343de08a7f419b2f27bdec69c4dd36c905880b13c90edec09a4dc10cdcf7e045a7700c538837895383bfad6fa0f3820cc147dfcb0c649ad62cf79f97447b2e8001f68e0c59639f2c5e5ccdc7c8c8028cc528cd979a55eb3ae4aa9716ae9b8629574c37bfd9790f6027bc7e3053aa580e5af824199d14bd0c0f00dfcab665bd255c6eb367e6072b4eafbb68e1310eabb0be06493a542bd394c106a52741030e20d25ac1956485e4967fb8d5cd21a4e9165273beb2853d8c85de85a68771e87f57232eb2e600cd912a41da7c56ea0ebedf12db3b160e456f584ea870f13f973d7ceb8069a96dea7fb355d3ea077ef5949ff71a8f33b1e2d2b71d7f6b671da32ca60fd100e1261319bcc54eff8e9602ba4a5e5df945203b3112764baefd20154e662f8e0738ce867e4e8c13ecde81750981ab29c366a9709df04f5e3a425801125ece6029637d0dc7a15a180eaa22bd6105b6a774e306111ccbb4631316965aa61b9b51821c0d1bf77ab7f8227f60b9209e418fc90263536b5f616bfa23285a4054a9302aec6073d4eedd896415a4a6afb20b406e51914ed1f04fe83fed971e977c89cd01beb90e449ed1270e61a1dbd13e2b111d232e337d5d0813f1a89950db909b3bc3991cc65c54ad51c07197f3a6887a2d6c3343c7e708d3723037e1a3dcb5c921500224100aa6aef3d877993632cd3cf53702844d22249336cd3bbbf3a75b14958fe79850476ff9a142787484b134cf2689f48b3f3ae9f847f6f3682604fb7b58577093f39e65a2f9bbc4cb041194e62e9909b2104ff2d9520b541780c60cfdbc039758fd3e822648e0aa0de4507834a790a57b7dd3651b337e7757768547d92b9f3a41441f29dccc3d32321e445a3466604a0fd9779202918a172005bfff0e3d3604335de16185023dae0e5b06ee6dd24d5232149b5a2c36619479dc5d24f56a014e73431fa5562f8b4952d132ca77328b94c121fd63dfb071a881a349ddf00689b35066822e35d79203eb8544cca9f46dc860d6931b41e9cfdd0d68befa32ed018a4e40e989d22eaa9cc2b6bdd076a698e555e0ad7eb8d18b559e3bc1f6325a416c4f20c45e91f3537839889255c24498abfdfc62e31a58bb3c4adac6fc06c02ea797181d25a471788606d0b6cfc86ce9c3b648041be48238a76e48d21bc01c6089499d0ad702ee3a8db82c0b07e17801db880477bf51b9b5c5fa042aabc45322c5f2b480f291d77cba252b1b807e317851382bb4b9fbdc818baf23a84bb3e68daca17d0679b3310c70d261a541681d8ae3868aa4c82b35c7f7d341aaba00e23c39721692b4fe9f4b370ed737ba1a1425f1cc7966d06497ab9fc3454d51251c582d2f58ede07cc6ee4f5afed06014a1565b4db5c3291e05ef6724cd426cfcc351abb31791bf23fd02f9d0a94adfce6a5ffd0649dd731b716b650a81aacfbbc0f321e423df0399197f0117987726bbc5066befdf298a2626cdbc9bdfbc8fb4ca1019e10ae713e553689cfd262b0785f89c387223d414083456b14bac872b9d10d244585ae64c247bd49f89bf931b716439d6b62f25934f8115c5bb171878f9f7d8c2cc313ad461be60698074adf388ced446609d8ec6df763711d7c0a6b84f39a1df7b7b91dba55b2836a471c6f4b1fc71c63f2c7a902664931af1d533c28642fe6e1e7213f896b96445a66c02a2d18cab936298e49c7475cad39727ed018ec06abcd7f127899d6eb3c04fae1ecb4d898e31587cbca97c5ccaf072aa3b6687ec73049a838d39fc0eb23c9fb4e7f3cb9bc8ff59035948ba51e1b6227616e07ec238bf73e62778ade666ebaaf9ca1fc8f75061a274f05a81b453a82919626a5b4806bc90fa9e67759c393b2dd01e4355256f675726d0b427efaf9249d8a65597d84ca5202a2b25099750c5caecd998b6cc4f096663f2a22408a3c30a01a1a55576dfea2248ce9fe192d14d2c7847f331ffc55facc83ae63de3f06ed4da61a680f5398ef17de35f839c00561430d6d5f954045fe73cf4e4d5b5f7a6da31bebc22e7efdc09d2365e16fdf4005657132986a8b00a3e42803a0e7c5536b1e676969d710f1edae0bb10886410939aff6cfe873103c170178b3767c82c7bd517c2a4c9ef780b407c4d793bd37cd30841bd4bf92cad75c92d42b523f274ba5a5e70d73a7fcf4fac4096cc33f5c1fd414d98592f1dda66038dd43e279c4cfe53a7491151e534fcf9a0dffe6d8ab9816b71909d31172133a8688e7f6c686ba9cac6c3b5c3b97349c6d1d35159e065f8eec03ea00dc13b8a3aca6a214e0dd84784d8ca3bd7ba82f3e8b72fe9e795eddb1e40b892d22e678b821bfca547e39cac1d0ec79f41cfc838e12246a0d4afd25310cd8978511fd1350fb537985f8492dba75192395364f6139b1e6920ba5f798e4f856e4f43f1befd17efffe5e53e31c7ff03cc78dce7b262e939b8bc37a8c364272806d3c726c0b30db4d3604bf5511771b4c14cd17a15afa7a25c85427d3aed70b1f54dd6227ab2d134a5118decf9dd63f31f20f19c82bef4dcade144de5caa366ee7fd56d77850e6f49a302f4f3e4daea513985c2c6a56b9ef68b1150da5445fc7ed014f2630193640b0c54cf30e6db14c229639650e90131d8c2074551d9bffeeff5005293add6166581651bae5db6d0ece72d6393cc3216128b5161598e170093245a1e068b5b3b0e87991eb06622fc52796c79970ff7b813b952ebea86373377a7decb8de35fee87e00d7ae758165f2b244ec85aa96eceae5e37021958afbb50e81a9553b6358003f042936d15536ecb57d15846413cbedbc124c01777f0973954c7d93af230716526eba5bd84f0e35050c74b075023759b71074bc09a77dc1f9715cbd8858bd64068b376fca1b28e12f9644d314a31ba2a54f0a9119a04bd3ac40beff7d79d110a9861b5362b157dd5364fe9b778ba940aa1bfbfd88e9eca65b6f9cb6ae2823a056897b6fcfa402490801e3dcdca784bde34ca6e02ad1e3c33a2a21e8d4990d52ebb363119c30de6c6e882bdeabcec6b3e9fe55b5c2acbcd1ee39c4800d33266723b7fbfe3b2714d6f5de746fef266d692f0748906caedda4e7366dc8e515bfbe033044ef6694731f1fdac5f732498469033fb0e89e6a6003ba11eb2e75d131542c4ea9ce728282db5dd20254d9814e91dc8efeb3f11467c9410134a7d8f10201c6d6a6dd76909524a24138da4afade14c662ccd901f076c92321e2c55375900668eaca39aed979f25ecc0f646d5ecf7d276369b9c400c64abb86a086f8a7fbc87c9862ddbfa8e752c125927d52ddcb177488ea6dd486c9f4cff3979cd2a7ce422a1ab0cc5f50d9b04ec03c3aaad923c97dba8702fa573f66c3cfe48dd162b329ef8176f254292dd48197b67bfa3c2d4762d1bbad6b713b5da53425d2fc2ae192a5936692927c4d8b4528a6cadf4db389aa541c5dd217709b5be86d8d680bb408d7bfc3b4b6d74d66a07e7ae19aa4f4ab4977980741f026d79543460856e14c0be10fc7cdc8fb757b4d52072942693ade204e245f6cb7689a8a2ed626d73efea6d52c5f1fb8ee532ad72b069bfada33221785796186303a90620a809c07c051701b7b77882b00e243461bec75f00b82a009f91d26a602157f9199889c54be8e4cfb88488ce52e8ecec906d658228954699a533016e61e6dc2baf01373591945bf42fda64287cda318628e5b1d50f23cc7ddeabb49137d915621d47e8d8674ea4d28d66ca97d92b5a8766701fbe0e456c3c96cb981ad8fefbf7e2bec0e0c6e8416b6b16b92093dbfa70b1f22e5134b437870ebce5105c919ae78bbe11cfbc9f67b9b3a3f32bb7c4b377aa7240d7cb57986a69a7b09af890df89aa302b02dfb1c1890bb12ce2867548c1f82759e48809163b4dbef99b25a0530a379e4a6e9c34323aac76d6d0e2402d9fb5913f69b5a22bf963dd213009b2816f0f9aa40d1a53dcf55bcd4335cb3e4946eb692a997857d3fee5ccd3477f2c10eb7350940394ade01f1a0d4d91be111413b2e3439881a1b79f65b9293b743c9dcd4b125ba5a832b4a40bb0ba3db4f386272c7c197a0e61c33ae0faabe1e77f7be21be7a7c76545d0072d3ec5de25dfba72fea931b527e2753b0dface81fda30a6a2aa7a82508cd0f26c6b2618fe5f79ff649dcfd5c7aae489061d848f49fe3c3c8ba76cd140fa02a83db417fc6c5dbdfbf34b841318f86c7d3a7ffef5d3bb10d33aab4c6b37919bcef9c8b799f9c4ea1d26017a391bdf6b45d5eb1a9996b6236b8ab3296efa5e70b6a13e4fc22b9c0e6b51ffd13c079f05dc91168dd9c745452a57c16b68a138212946f1f70b4ed0334e6001c23bb8304ad95191870f5ee2b25e16c20250446f4c6aac9032f467705beb550c5493abbb9a84d245c4c80f5c6be3f40d8a3067c10a4f647e63ccc8047b1c48a904b2eb4c78755df457d5e09a12236e09097692dc0f5b87c9738fde4a863ff925380b62c5545b326403cf0d0f00a417a4f0e59a1d637833ba1d763427a5df1f291b94890b115cad736b387f106776c5c68258587960663d5bb985b1d13e35bab772046d79d6eecb8bb0417bf1faf6f76ada12f0c9a9a3a1ba15a376d0475a3a4bbe33fd1bee878a112bf7281bdc5b60b126e2e6c1c8ccc8731d0bb924099af1ea3b555fefa367bc9854f804363925c1c497011bc2b47bf938d48220e0e8a916b075cb52b24e4233d688c33eee9b6c00eb6f1c4f78d2dc8d59f759746891a05cd990016a7b9aae3392b23ad4568a0f727f9f73de9bcf66574b381e470d757eee50c9e0a208804da1ce8fb5fc2633723595c89dea8ab17b19f3489b1cc43c4be2d9762fe7f3233ab35bf82a91a097dce2957cb3ed7d2417fd5164919b8f3a9e9ba064a194c1b69d999e9334cd6715a5ff1d5f653d2389e1f10f9c2841bdbb5d1241489dafba462b0aee76eac30dea6f20625bcf7958245009e839c325774023e8da431c3863fda3667836678be1c2297c2e41d2620109299dcb1d5b1dc2e5b4c45dbcba88cccdb33b962f5fcf19f54b6a41349f2e6725be606bc89aef7ff6a8e19d01459e007658d5d9a1576b22edefcbfa1d3a58fd654f17d9737108db5851f7bc3712414df1490ef7956ef109138214bc1f167522949c33b7138a9df39cabcba58701be56a2f9faf9b00c1d8c20fcc3e5188580a4cc3b1c175e2ef9ccff2fc1feaf3fced006502e732102d4f466e3c67b2deb7de46d02b098bf633306f08b78726c420f8d2a879f9ef7fe28fd09b4933a21e51b9264caffaf819f90dfe7f8b08698429833628bbde882f6efb266858ac67c297eb3c7dcd4a129f40714dfde897b996846c578c3515fb5f1a6047bddab51f6c3bb65bb4a7dd8176795a23309a3c79755138db59c4d102446114146b209103586d007292e8ff01eeae492283470fb8ce36a9862b476107e96c66f4422afdfdc1d9a9c5bd43fb29d20ab2b883d02713e7732dd58c729fe46b006718b69b264c13dc4096797a846e2c9e5fd4db0237801d9fed1ea104f46f978c6b040f627ba5cdd9e175d158bda4540eb9b775c17feeb5e2b43776ef351b649209ebc8d7e24caced0b68f6c83492405732c36538a706343f562c2a773d9045f6d809257f5a622772a104ab91b9819feb06a9c7c7689b046dfb6531bc46ca59af211eab34fc3a5abb0e97107178e33bbb9a5a763288a0eef707d6a450d399175f3df009efb17a10dfa99c96cbf5220546d280c43ee2bfab372e33fc7963bc9ba34fb9f249af84e10052e2a1fb3938f47fd464c6bc23b484ee240046841062b66141e9f791e5f4b7296abfd557947dd40c19404b03edf37e3574b2daaff918848f8e6e42fe167968a15c422dfc357d25825dae7d85921fe6235b64b2287df01686e469f11908eca1c79b0c0bf7dd852d959a89e33d83ecc227303eb6cb96d01e42aac20700f5b6772fbd03d838787c8124da272dbaf483ca6f74292a2b94c412a3fbeed8b027d4b49dd4eefc3c552bbcba74dd849622eb2c97340335dae7c58867e7f5b6f53a5baa4b5b27828916d74e1ef4a5cb0b571a52122c442fbffb76be605470c08cbbd06db2c829500bad3942b366108e2669a803ab88463702591ac552d6b20ff3ed8ae44c8d72bae401a2e4891ba6f68fa9ebc5e1c9ca0dea44a605da9a8977a5ef9453cc9a07b022726c8c87072fff9b5589a223f0c74707ec7e963e0487883a535d811cd8329fca2c8b536bb404761da5eecd4c6cfc8d4feab27340c29ae44b15114fcaf02a6bc8271383e697a1c8680b21ce4e22a961572da213dca40db8bfe68469afeb109ce524a0b906799dbaf4bc98cb41d5ce14e38320a9a3289f37e15dcab9dd07767b43447c6c04c65004ab47b4a03e652287325d313cf8ae129a40ff473bb472719feb37255707599d8b5b0e52d5ef56e0f4858c15fd7cd53aca5a36e77c3523e4c4f8028541770058b5d446091e6e67f6054fc11bc0b67ff07c2e8b3eee1953c70cf379a4344d1ff0277d0c3cddc749b6d92217d0eeea38c669d27ed521028e342daff82a5efb66b74c4fc65ff31c517236f9294b91ab8d08525ceb6f4f7a2ff6f812d75218337a5ce550131fb4bcf00a600f2e3e5c09709f6c801cb93af2da05601dcc73e47b6e46cfb011562132567a6c91362bf9db2710bcfbad097e81a3e35e3c53efcfed080760d93b3e0dffa96c4b16cf72ddc0d62ca91a4116a69536a22afeffcb7b1dbd79757f340fe7ff7e721044153e4e5f353a259d8e1546a98b7da7a039332c4118e0196a31c03077adb6b764fe9b34eb31b35f983248556fb5744d40e090a955759709df56a1e469431a510351f74c30a638c82b37b5555746ca1eb4176b1ac8ea8d6fa8f9cf5441d670d3e0347976be0d524b2b04c6657978c5eac4f14bd7520434e7082cb17edf5df97810497fd1ac5992824c8c52be2dc2ff130f3de8788a6a2aaa843a040592e268cac01a1f9bccfe30d7906af9ddef9c35435b1f18446c6a1221f88c904150694cfb01764ffb020e3a76efbf9cc178264b4ac5fb532594278e67daaa06e5f968f177a4a546a4d424dd4092d1635e9220c60d608dbfd55baadc6864a519ef31641bccc870a5bbc8430c779911b171e1e445f25f2bf79f14eda57235e2bf857d301ede525c8b5927b05f9a745e4ebcfe85c0a69af2a6639cda72c75fb1080c24cf602b16f7ac7c39f5c62900b5a7c3e3c864d6ab7d0acf6c03c16c75db3fd9064b67de88ebbd335b051ada9c5fd1c96d907c58adfc3a9e18d7e5e5ed50ac942d140d418c3697731a505e53923ca12caf0b9323d12df0f2bfd4b1f1d6f1534e55b6d0dbb94f3e74b710f6bf1cdfff0cbd6af49de716d89da6b136c88d8ea2ae82f908ff679aaa2c294dbdf5ee5ac73d0abf22a040238314eac35aedfebd49cc52f6f54c9ebe8299627ec1058cd82b99a0cb269852ddc8d9c520bfef9a339322be240fdc58d8b7eb2fd38206729255e2d5174e3acc3c88e144d039f25b6da38255a587d16be6929c9cfc2ddd08a6bd41a6a3e54bc3571a1ab1b2e2797fbfe4e3d469383de2cc4de2e0e6bfae99d97a936e1d354c92f93be90131397f35384f2889db4e949709a00e5703d80361c88321233e2eee03fdff19d012967351fd7610d0b0b38f21116ebc46abc56d7181e7dcbbb10de6479981ad536d9d9b8a817511f949b4322c20f0b40600bef17fc572653a1a14787a2042bf1453bfc0d9aa878ee7e1e5842be2d51803740e203d3530791b0ff6578904f90f094d06d9077d6488995cb37f075779b3c3425f3bb8fdd2be06ef877a730faf45d4af78e1c5b537f089ddfa9b19d17ec8a3051a1165f77029f2b03634723b24f7dd4cadb229f59c6a5fe15e1d07c582909d460f34ffa275838b0bc5dea8bfd0b95ea75ddb1732179120877064a2b91deca0163b96059a66467262e0544344681f547dfb6ea22828a8e18def5527ef4603f3641954da0d7554a58aac51b4898505413f84e2d0a387d86781370642ceb069a9451f35590fe6cc5edb02df40a11fb494c0c5e9c6d9690f699e1486ea14e053b6f2fea5b44bfe1488ed8ccf51614780880d22cca18494983f8012669a829d565a5652bbe2132d1954815c038e9a34abedc940aa10e3088a659300000008c8f1e9392a53c8ce2ea53d83626ee04031d76b225f2defb2dc8e3d78893e9a6613e02d1d2a36e2d9a8bed878ed678d74890868b489e5d9d1304036211350bb64ed0c11784af90af64dbf003dc210e2976fbaf867a9a2cfcdcabac0e9c4ae2a48e086855d5b3d6b28639f43a483bb27d17e883a1150b9ae2fdf1be6a31059182847f5d1e4c099750b3c7f3c2dd28d85ef383124d035129b83bfa588a507ce81514671f67958d1647240fb164997ca028b0630d6468898803d914c64376b22d1cb957c7b0d872930fb4a1820ce0a9928dc8896dad09e8f7266c4567426a909e1c54e39cb9cbf3a4fb612681e5e263e3350dad995fac91f22730d7d57bdedc09f1521b807f4e51f306b9c7af27c55db874f9b95a7c816b954d169ee4982963c0c7f3459510e311bad9381889f3b0a8b61172cfb8f5e787b8a956fcb9717aade60376547e8cf44e0e8d6e661078f63d5708ce36800ac3579d6dbfeeaa70c95e2a92b2e59e8ad96a2535054bb72cd58882fdafa350cf342d73e0e39a449e97849c61d3367cf7bdd18b0e7632f7d00a12ebc44c449f5941bd4f5751f429c578173dde171efdffc750a4bcc9cbe1e038a8b613a77c22ed876333e69b8e39742d11da0fdc014058741156912771c9b6687f6f1d37b2265b49ce914950fda134a5e90f7ad4677b0b5f75536837cdb8871383065333f6b7417487a99179280b413a7636917fac9b0300fbeab9d50243ab02cd3c45432fdffb348abc206e83b3bd85da6f8280c488909e487df8fbb592bfd1850ff2b06d1e520d4b460b5815d1dda2ae095f694881f6a8b49f2284d50c2a4d035331d1e9bdf5d3e7bbc4839aba234453462ad4b8b00b463419fac10612f07dbf2e6d036cdc4fca84f089055ad4c734ec411e4 diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W2.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W2.rsp index 46b9405c33..1ddbe2f50d 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W2.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W2.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H20_W2 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 00000000000000000000000270cbc93eaef8347f7c263187859d5aa45969e78fd83aa3da69ea10802942af0cb7d0a433a5b0e39993a0200f7da84e434d0111941b43ea8819da913e0a955d7dd4c05fd2f719ebc987363dbac1f0db8bec4daf210f9aca23e68e5419ba0a0683c96965703529950ec0b563dc7616e7ad0feb9c9098c41ac82352f8f23b49f9c063fee47599a88d2580f3618f95b221998ece2324d10f5c9aca92d0b9b065d29051e41cf8242a5a6ce2562d28e3e8fa29823fb6ed5df3da56195bb01f5fdd7c62a07a3234e280cfb7e855890d7cc6423b1214155683b6a30f7a85dc2eecd4ccdf230899c31e819559786b81b1f7ab30e8a288b971eaa3c483ea0a13e5447fa0c0de47efba3e67e5759608702b094980b13d9a53852c8de6991101310fbaaba8c7b74ded0d53f47005dcf6dcdfe1d154e13308543bcee4e5f91197d9ceb9ffc763016b2a683f5b180990c126dbed2ab5d45c391a152bc7f3fefd088f76777dd6f24b12f3b9283d7108ce1b1d1ca1fa540f7100b62bce0cbfccd71f64f34d540a1d35056887ac069b4f07bde01f07eb2d2603884e396735e91aec35c93bef29fd5201db70e047e938e3ffa307dde005b7803f0699bcff5c0f9b56da1f13f77b6a239c7dca93be5ca1b5eff0534da3a6d22dcbfa312a95769c9b6894a32b5308f559a51e0eb6287d6ba51820b1b2c57fb75b9c073830735a173f3449356d11f4090b6f67c471200430a7a1c6d05158397c413be214ca194880484eef3d8e6072dab6a3e649194979b90e39e1cf243958b614a401ec578b1b6a2c0542a91b06021491c7524d9648dc9d4ff4e8590a2c1cbed9c8be58b29576625488f0caefaffef05f9b47fd9ca320d5338ae59391b24b981c492614861ed5a05c3dc23731d363b5d0a4efa8cee7f6b809ba89d6c3bcce1ef5b23b47dbec62d76cc30e7402b93954aa3ce710413a45b810274fb7a7ce5044fd4afb87706616997ad853c5bb0a2bc202e4b1f252cd2e5ae72742906bc36c2a8d129718678535b0bc9ffb269e1e74d5f2a37931d49add7bf397f4d62013fc7cd0e5af68d3df77eb74128119ca903f6ac8222d0492c1ec7f11f4220eaa3f1164b7322951ac2983397b11de0fe0b915a236b70f317c28e9ec458956cc7d62157f7fc7ad179cee31a6e0c07d09d99f65a8d2b1bf84a9b55d085f84aa94086d80f4045c11a67f8df1646df47735ad026b6db5ff769fb946caeb02829e3e11aeb0ed3e1a16be21cafdc66fb5d3bb8b133830209db4ad5b2c2e9935af16618001a714a098472d291f9dcb8949254a7529d654fb4460c14c88e55b966540ec4b22a19513665f02f00d560f586d08242a63a0f192832cf897e4a1587569de114ae85ce9263ab308a3a8fa2a62a0de24efed2193953c53c69d710e340acde7c1851dbe371954a59da03543f854a84f7aae5a3d50e2be068d0584199bdd81047d7adbc975d021202f97032217a3e4dc8398245b2c0b203845565c4f025df5eaa6347608a09462c81a134e32d5a0ef7cb4c464f8ce2ad0aa5cdb0d26a86ccae4bb1960b71eaf7075a402addbff18d3da51390f28f088fc3b0e8b625cf2bd082177ca20d7421fc38b44bdf73eaba440fb272850ed0461d544022807e79a45de86accbc3695d23d118a43439afe3e4f116bb306deee09ff7206e85352aa70b5cc8eba70f259b22c90d3084722ee4fabc67c92808140d1892439691f9a0afe9c5f3a2dedaf6ab211c5b29ef0e4fa9825ce11568549823d0ebbd36a4ca2d88f9344b2d20f7112f836768ad31ffe694419dbb35ce1a304944ea05ddfbb33f118290313a9847031e6f8a2b51ec3379b66fc4573ed1b2f6091d24156b44220d5fabe5b7389d7f8777a51c74fcb314c8a9dced4ddb0a551628647bf1d1a0ed665abe77dde46976e101cd7802b803035175ea7d4b57c1511f258b1878d4329d7530a9db0014d35d3b03339947a529ec16da327f61bb22994a50f1e274217c606f55dd959893cce0f0c471e535c2376437c72192dd783ea73cd7aed94a3120bfd0f315d61891a716fe67dcf44c5a50d8f82dd4edbd21c0fd5fc3e4a9ae32ee3cf138a2b9646eca7ba7fb5b1814a0162ecdcfd4b93d8d4d3316dd99db0df390050423b100edd5dc4f478fb930bb9e1ce7e85b62794e99b5f46ba96b9b734397777f1274998ec77817d704abbc6195283165b961d730e55c2c44306a6753bc42bfaf25939d22b3a4ac307c16ca28e260ec83615b934eba5a17a58bfd1be8cb4e336a68613b56ea8fceaade54afc2f87b2658a7b3a8e0c9e9bc76a8a012f2e15ab6ca59c9df0463fe2bbc594bd756f2516bacd04a423d219b22cd88144c0a4e4bca914a5c4e575a049dea608411afcaeae51f680743610b5d6d05d8fba39e5126ca1f0aa3a0bf7283b46099cd4f9337f354ac730f020ccaf0e33644807d72898b726ebdb20eb5078288800b3204dc58679b4658106fbe45b9324fe1da13239189e7aa068bbafaf36f6bfedcb6846464939ff03d0eea29f1464b90502bd4325d49c643ad5a4d51e7892dcc00d0f7d43e57511d2556424adebac0e2a0d6a053d0aba09bd7351638a05555c6fb7f91a5262ec8a326bf0b7b4392e06e479a87662b7b3b2bc5066e689aa2917509a07f74983714731e785104b81e9c5ccc734f3e47c0980001e1befca30e4a447ab317c7b139cb88f3e4c1819600713b4a45d3c292d2982a46be517dc3029a739e65dd107bdcdca86a6962f8fa7e5de507e4352938942ab99b19fbd95fadbfdad169807be9f8d9c9dc1c1ac4a530965a6abac63baec409b6d834ada0fcc58be2d3ec519d649b13502a98705535b5f841f4011bebd87237b2ade344a2dc63142e5390fb620e24b1f9504ca78fee0d2432e186e9efb7dbc3aeec617e3af88492492f6a70ff4bc2006e0ffa9020fdb386dc30a576f3a06b46cb43f8d5b4d6e2f691b7a7c471ec7c6f5c047595a8c5acd8d6194bf5fa500e362697266ccf0ab2621983013dd2984e8d7ef562a77cef437c1d68b22a522eb887fc39874d3579a262baad48a69a54f5523180d46da0a5c30ac87d79fed8a3bb1392cec27eec881192c63fd62f3624145a69ef54ff95979037c0bc9dfb70cce5b73ae6da2db0411d140c244d148532f02eebe97f4b5259dab9c01bd84bd9660d854a3bb7cb613725ce9e8224b14c1dd2325e8f44d30929700f0c95af1ba875336dea67471f650fc77922f3c8c49be00669506dc94a968c1f6ae58f5f2e61fad22760eadaf1bc70fc78fc82221ed6d6dd029563713daf4cc64f978fbceeed2d31113399922c48fa071297e44659484b2ccb98e0ad94735dfcd5b4acf7a80953b41b6c0d9c865cec6c5decb3669eeb8611b24b806ba7578074cce2299eab8fca8254841188fb9f06d0326009f13694552c34e9e54d79550362fe49ba7761385d3a4d092b77e20ba3bf1d1413c2fe0ffb29693b60f97643efd05a8a9e5165e13a9caed226a3a14ea37c7c54c37eb0197da7aca429da04a62cf4832702937d447c1a32fdbf3bab57727ad87bd8352f6ee1ed94b0808aa9de1feb8ed3325c53e1a440674dc7ee3ba523645a605d484a3909f83ab6651eabb5a5196ee9e9e1350af9370325d11a4f9c6a4cff9821435a7fb6be95dfcd6ec25294ba847cebead8d3cae3c388d58c04adcf545db68b983061962d2865bc9217f4c3b4890e02ecbe4300c55672c3f31ab3ab86175908914f852570d84dcacd03beba7eb379727dea0e117a5e6b33f760bd219e1cefa584a96931c873d21db1b529960d631dddbcfb799775d411f2c81f83368844557405e4da95a849eaa73da7b1f433a117ced5880abaf8f3b37e36e245ada21af768a4598572d729dda11aa62eb4af07cf1b467b954cbbe7fa1b0d0d92e1ca25e169189a144a9aebf1e1d13278fcb0ab4023c7b086acb5aa8aa3a948c189564a7ba8e3d4409fdb2f4610e9d16c44e4fcdc06d1a66dc96c645698bcaf4a1d2da65c5bbfa47d05f6e5234154f53c38db9af4828c6310e6d72469b746443bae8c5c37374b1626b842c46399508839e6b1b208e47e749ce6722e0dc966783944ecd8ae9bc4f959a704252b05caa70d4076de26f1648badacab530ad2920b5627fe558c9cbbdc4d583900ea33afdb995444adb283ef80979ef6dbfca07fb39b965a4c6aee65250d43460acad5547dbc62693993e9d28c91b0267d9df93e1cf375b0807b1f61d538c1ec089532f873c3dfb723300b8d3c2ce9189208bff8b0776a61625e639486503b3bb850a950ddb940c6161f67f904c482b423f5e63f5f9fa5de88204b2eff2d719a880bec7c882765918b33393f4bd3222010ebc37fd1b7c0c674ef850653b22f205d2a9005ba6bf5d9a33ca3fe0d6eab3e19d3bf4eb28ec5c55e7e9ea7c4e1b036deb668fa4a352b5f9ff0ab8f42ab110dc006b6c75249e3fd2f089b10423d592e8959cf275f2fba0f6dda4838526b81320e49bad5dbdce9541beee5e70377e03b54eab41fa04d65a2141d763f3bc3d2dacfe013b36940979d82070e4f3c5e6fdcdf4af93939f9af71224d3a3283dd21634a2062f98f4c5522ae34aacf773a5611fdad906e30598f51e27c052411e6ce1c7a755fde2dd530251c1f4de1164ab285658bb5a674951767e5bab6eefbed65de00ba4a5d88a2d30234215e73035f2a84d4468d827d3dff51aab1bc7e85e974b36268d139a0b9ceccf8e91c3301ac1fc31843b0edbf62f31306dc2e4c5104bcd6b7243d6578cec97f8c60e922a45e9f1a4ba06b20a0f2c49f8e7a3638ba6f6618c3f56d3425eaa8f14f76bcd6f7212a141aab63a3af49da3dd81f16b247ad36aeb7f4deb928c7804d1be0cd1721c0e0451dbf1449a52f82a0adb64e8f350117bf1204820c99d1046a8967034730cd3fce7302916a945b5bb6f373e713465130fa3ae1a233f0a412b890a47fa6c75d960894064bdc92cc570344eeda7176a238972a24e0297d7176d6f37e5878355cc151e9f8be423b3ca74be8b46cbdef22aa205c40d03e1d75380a32db764ec8feda089134ca7ae016c92d63565af09b66dd235c0d9148303b5924d44b8b854943093497224c350b112c7a786b4e085a9d7109ac33dc89a6c4d5bd9c9df514c69cae7cf226fca6de7eccf075521f1c929e3416f0ec19a93089d6888b2647415d8cba864ae643ea11402e0f685d1f047dcd43ff8d42e19430c6859aa812c477111e96521f427db2cd8c99c47d1d5c1de91f54219881bfc6e4cea3b4a844fc6180ca622dfcce3dfbaf4c775e3b27b2aaa021dcb99a7e6bb48bc14f969794d08656f7650091a6c15ed9880170328421bb4735205bc20267669fa89ea2301f508c81bc47104d320ea8d754d55f08d88ddff81edd342b7430a54c3406bbf843712137f13f78a1a951d6f4e4277ec4e9c66434f4ff0bcd4095a9ce744d969f7d73336847abf76dcd1023f2e5d92580ea275dc25df9a98165ba863ac31908d3466b03386e5abceab01b64dadac6237e1fab22c59e887ed71716c58e5ca8e88f1fd9f1cbdca0822c9dfb0101ee45fc64744f5a8f3e2c12abe7057e20121eb0141ec4f82a9a917242d4556a59348001243e8df4d272c1d455d05b4e792f8f522f8e5bedc5999bd0f0b79561e85617feba1af0875ae7fdd4f3f9761d279b34b9bc378c1c8d2df99aab19829201a3fa2f13b2d5516a8a3e8104021244fad1f5c13b6ce010b47410542fa9229bb4f7505806419f14764691b42ebc0ba569d3eda081a1f9ba3a6dc9bbedf66f85738eb574fadc183d5c6ac554bde82915193744fd332728779ae0f9ccdb6f9d43fed0b3bba36ab60027f8c29c035b2b50b01768183a288de3caef3e5087660bd1d10eceb17f0daeeb8778f234a57491fa439e646871ebabbb008886105d3ed601b5dca431167c03ee66b5622c9a28e9b415c4d03be006b0f7733a57380ba346c50c8370180eaa179339275c7147afd3884f029af75689ab5a1a7ef98ebf1aeb9fa612f5cacc1530eab1cf4de29cedbf12a1b21cfec2aaa453ef302066f05bc3ab318e23d9654cb86a00000008fbacba04e2608ce5de88939ed3cc5f92631b7a435f695253dbf8e35f0e92dc089d295724a3753e2a821aa454712d3739dcdbad73af25d7e4ac14cce109ee1510d75628951cbed855c82448eed4846e440f7cc824f0960f9eb6452fa955225b2ca657acc7cde4fa0b5057d407b37335492fb69444d00b89eca2d042bd0f839a7de3f0d236ce0fc52bd2ee6e7a10ee1018f47e3f3b8e7fea48886ae18144e5395f16528b67f3d3393ef6390d85c857fc497da24331e8ad8d11ccea2bb1fb7dbcbeda700058268bb61db029ba43f1602c90890222d07c6475102520466dadf30a1955898bab32c91f557534de0c7954b3f4effea63d64d16d2ab75532b1b8010c717106219f38b04fbe7c083e1f764ee72063154cb0042661f48c385eb9d5b0e3f20e002f0757655039feeb3add3517fd32b40833e81466a61d1270297f03ed65906667e0b19f862b37e2d02d98cb563aebadb65e967a26fec2d873b467f16c142b5c4301a935aa25a2011d7c2660b6cabb9940a681d1718944337472a9fed2f24f62009e568d3d7f6dbf2869e8e16b13dd36eddaaa4a7d198d1458351bed134d69c60bf516dfd21783a5025260fae43097e57f2054739763fa9dde8f4f088764facbb54b3547717f8c43fca90ee96b53a6af1fdd143e69031da0d2f76b2b0c6a356f5c15c1c8189c1fe397ece30ab2ab9d68509a234fe2a93f200436275164e0d4ece03dfaa8a3f0fd476f44f52f34990b938a86c07b93950c98d041f3fc68fbd4cca7026e213febc5cbea40f01ceb4e8c6be31f1741c3f708125b19ef3a2df2194e8eeb7d443c19b0731e44c05316f86f0b573378f7cbb30e8766598cf472175425d874b3967453dda75c4f795d8342bde0fd7bb97525a65ce0d7bcff9cb86182 diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W4.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W4.rsp index 0d461a43e6..50424b9e17 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W4.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W4.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H20_W4 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 0000000000000000000000037c43ee18a5df8fbfd9e917f1c48edfdf3bba8def38735c8467489c1392881b827fa292e35aa39f67ca2a2ceb9301d7a592458d8bb115f78241ae487783e50926c43c04ae72ef85993a9a2d8db2139ae7cc95eb1d1cc04840713e0e867f0aa3644179e4411498d0f50c3e149c8849e03979ab92e726ffc2e3be442cbd4d1c9eb8605678e51e613417f33479ea18e3ac3e864c8219554629568da7f5b8ba9d4f3dfdd7f63b4fcaf606467d1f5b326e20c36e45c9f251c08b0116bcb01e3e5cbaa1d5e154ac2ce0e11ec42e81e105244a020773ed094262ee3d609d668b2948a0682e96ec77532d85e899d5f7e07e48b99b7416f27f05408e8704d36251bb5df5568c53df8c3aa7a0b14a7e311f0cb63752610127d73ac0b80733144c93d6de013fdfda6ff4693fbd19e6c7ecead046f1e2c937875f74f1428e3f1f54996b3b47fde49a07b34298b678d0753b9e363ac9e8a777148cf816ecffb458d829a440d983ab9b0d435bf8d98ae71a81a37b7d10f5e001fd0c6a3ff033530f0eb1f155fe96e21637dfc82c9e802070b1c4e008998206e9c04cf3a38f89108b275b5afed4d58b9c34cf4b7d94df20ae5a516e7da4557d53750ead4f760ba82a8e7e217c048acd6ba2ba877825522cdb72e152b31993cfc0fc1df21934cdb80fa088011c62e127b3799a498860108e5f4f8cd6e9fbaeab60b7ea46e84942e354e4065391a6c7039125eaab29dc08cc5bb695ee950bf37cd1d3d83030ba994f280b00d22d48269f05c56ffc54e43c45311bc6dbfb4b53a1df6ee4920a370c894c17fe90e521175bb5ed8bf39987d343e59fafe785e9389daef38de6e863035a3fb630cc2755b58f0d4952cdaa83040c84775faf0314a7d84008ff79239b7f77e3627afd2e868aaf5a73cb3d92f697eb4b880557cfa589fdde3feac0336c7814cd0bb962d96ab5a9a3737cc465e605ccdaf5162c21de0feebd23b6cf9cb0fccce7a1645a66341b7314df7cbf24ac1256ae53d5ac9952de184c1b026b9b2f227591694939f95d1480243488e5a26ed84a628dce33aa884460c0cc3535b73be0dbf4b01608866ac032c19fc1ddf288ee7e2b955c1fc80c1761cd6ce0ed9d6fa3a66723c1f4bfc67b5c2b36269035661a8f10d20dbee8712322d93f6d70c329b5ca914ccc91373f2b809686a5a68ed5bce241112ff1274350219cd10208c51f1b1ba415b61a1bab437e6a75d422f635584a83633ccac0040215df734c6d5e654874f8059a26893183a3d1357e01f2f5522351f945957a0d14c263d5da7602b2168c786c66bc419eb941c1b029ac4ae53b89fecfadfb58ee1aaea9e71287152c180952de7f553599aed4adaf6a6741fd358f2ae0968c027a1f5f175acd951303059cea84a98b70b7ca986709bc2ea405159ac9d50665f25eaba56e0ce2fbc5439df6e5cd08d10d4167030fdbade6eafac433d37eebffc185c9333411d3abe34f5254f1451191c7541352f7daafca626b26716663fb25726e77aee9c1c6ea2de33c1f28c2b6d15cb7addca5bc422d6b06c0e4db832b9ab0f08da4530218d082116a1a0ff9f4563992302b2ba889d04c1375bc15fda2510aa034963121af0cb9be12a68c99d76390c126f6fd7df89f8a38982e7edff991e8d9318a9429dfdab46a54aa9a04018b634079d23a511350e4b0162e628605ad852f0e589730d0f8e09222716bdae6151aed4a62dc3d50e417e9a8817fac017ddb0da99ce08723bf420b6a70d25abcb2914c3997361b5be31e485b4c621ae493729c7f9efb00e5e445f4828629d61d532459f08654531b4bd5da5867745b58a9e608a753e568c931afa3909da2a5dbede3ac7cd52cbf954e9fa26f510476cdaca57fb014b4d9f46cbf4d2450e2c5ad020d189e5d32eb49aec0782de2556403f51ed8ce5f519c2cbd451233f1adb9702918dfad4031ff5604376384a200fd64bc0bd80371cfb896dc56f379b8f3c964d2e57998bf67fc2fe12c88d23ed3bbb267e0b54d1603f833a5588a0458a04521b86d90a56c7e9ed3a8beff5f13a49517a79f270d245fb24fc3dafb1ce0f01f6f15b8e230291d5f6d6f394572a49f9f85d1847b990cb2060b09dcdbff555eaf9961fd5acfbacc64556b77139c177438b8e7a86112c60293eb1c583afbc17de5261eca46b76de8160d5068764c194fcb6a9243396ac5a7a6db9602b3421f8f4f425495d91d5da88eb9aa3036b5749a670d0fc8b40af82515f296057210751d49269d6e86e7cede47534b7b307b39c6ab21fecc37048f4c911112f38ae2cb01a5fe9a2379d37bdb4986a0e40c2db67f529cd3903d41a9157224224661414a9092f906e6fc7b6d60a68d311159107d22d2a15d757f0b4aee8d1a453676f26ba90ba8862b9ae5ea403e6ebee935407d468bd84107c8913592539adc3c65609f859f57770f72d202a903a63ee0778a321e402e036fdcfe4b62d78a67e3330b71efadf9bf2678fb024c75d9ec9591f2c58c08e6543b5fb5427177cda74ac3c0c641308c0562938e30455799bc555f9c0cbbbf12b9b1b7ad907ddf838c86634d3ae4f3b9f9d5d4dea929c75c5af465d17fa96fe88233fa8996cdff1e1cbe21cd5ee75fb3ffbee0f0f15817923588737a6b1647324b9cad29c33414b5f87c7db0b0280bc27dab78b4c8cf137752169d65fa5b9d374fceece83acbfca612847a147a66642d2b25bc19c4e7e86118efef57ef08eba9fd9bd36854f96ae47ec1b7ba8d4e53f97553386d1a117fd6d11eead3d10e58cda7258ab8d530c47d33321247690dddaa770c9dd6b5295e164e2a0b9b815dedbb9654517be6691b3dfc739c9d470cfee8ea2117ab7a2c2876a21e3513911486e00649f98aaf9ef1a32b63000dea1ecfecb9d433b51333781262053f1096c884fbcbb3187b09489fe1da7ef9d3eb14ec1cd91fa1e09bdc2a6f05ba95bbcc583a86fc73daeb18ffaa7802e671e0641331813bded68bfc6f284cf44ed3cf810caa5e6103208bd4c56ea670269e04f96a5627ce77b364b50b21b38eeebbaabed9b311bdf49f46310be5d19aba8b76b5ff276f90a784850000000863db9401ef22c5a1bc3ef9a0894c875e66109f097575f50f8feb4e2c18ef1b3804d41ae1c38fb1dc4d3306ab4cdc3a0912ea0d70983212a10c7fd15f9eabe503251cd8e12103dbb3d5520a22bb4f758ace010741d5eca7d2fb972e70abc782243b7639d486656e9c0bef7a89c6e64ecc0bdfee8af27e24349e9cbf37ea13c9533fac0b57d5ad9ed89b7af20991dd140b9c23a01f53eb3f1e649d8b2d6d941948ae30c64cdec7cf05e17ef2b74d24445ff0c108a240168aa5694336f1ebc3f9577ecf4aba3fe7494eed663a8fc01b85498206a6e87a435e30a3bfa64558126e79e440369683bba29269d86d8c08150286a1ff69fc0a4eec0067e88542a2dc03fbef3d11681fa55c18d9ce1ed722755012df301ad7082256925a5fd0b50d675913a929f7cb289ef8abfc5514815a88397a1be657ac0f5a3a343e18d56a8264d0d52596c561a22a72d18a7d6551b001af0ffc60576f54829d36515e4b9a5c4069306d2c3511f176d2d74c092c7e261d9fe4b8ef9b1d2f1dea9663795afbc7058c147f1fcb977f80f98fda75a7c8821fa226af50fe8d02b9f8b9a9ab58d6f498544e4c8414938f106891bbf87d215e42a3b3dd82462c9ee5007edbe45379f89bde29d86b485af81942fc8a71123b51971ecbb49ebce70a85298ef1eef2226ded1b68a16f525be1f074364084b9aa50a2f215e9824727ecdfb536c3e2f8254b2e37aa81bdd106ed7669e5085774e49ebeb7683554c867c6aa891d6f02ba298fb5bd75e2af2163e211cf09873ce061f20badfd14743a9088c2fcf756c37ebb41d3a437857a85abafd33d57765e8619429abeef65b6a532f5b2a8ed9892316f3ed951eb32a10f51edd95d7a5a0e5eda591a481d081e124831d297cbc44c233522ea9f26 diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W8.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W8.rsp index dae33fafca..de889b92b8 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W8.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H20_W8.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H20_W8 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 000000000000000000000004c77901fbdf3723a0e739e33dad60d6438b3a33adfc72c33f3e1a3e13791a362aa3a1cf96aefb864bcab9cf5714de25794d8d59428eb4585ba22ccb719b12dd7301bb456156130d9c8d34e1624025b402dca6c4d2d5462ef59c5842a9aa242c72cdf29daa26527f5f529c01af89066ed129477f2796f7a2bbf91233f4bd3a9f658e995fcf6221a40547c442f3f5dad46aecff3a4b061bd72c2bd725af87940805954d9b9cef4395fe8e914c736cff67cb8f481c5e9842ddfb95a4c7f9f1310c3bdf951acc06337ca482b677992f207e11fc3520c923d69fcf8b863bf113531e0266246adbd818300bce8ab72b081d453f109bb298e72bd499614f9e609a12bd1e7171187b65e70e9f175b7f03eec038f2faeea0a6c13058264f3b21ef4cfd27c3502eccaf94c68060a468353f1e3c111226bf3baae1af78d783c91c32a344ea5b1e3875f1571cf381e4a142f154c749a572ee587395b1bc49df8c979623dd8b4b09bf1622d7bd1846bf5f65d7be5f28f69a40eb9cb0f25cb30b1090205f85b067870d2abebc20f7bb67a35afe9eb9e1c8f9d90d32b18728b313e055c22671682ae85de2277aebfa94380bbc7ca11c090430cc519695f3af0c5667a3595bf565e7b1114e069d9343132d36adc42043cf0ff1d075f82147d4f8baa9e38e68ba8aa9170c855f3c6e3be4840dc92f65cb5f2e1e24730bbf6d4f73349c3d85e4507b8c4f39bc8b07eeee8f2fff240b07858d391a9e24d34d7f219bad1688546106ecdc177589ea3cda62c02b3c862d7ec1e995e6555beb0d2fecb6d6d86c232dc76f063fb90b1bb4f20116bafdd7436825a53fcd26d1544e71a1feeb0b154ea298948c3ba9ba0adeacdd46860c6d28da3630b36acc8913ecfbc1288417513b8988d977613b93fe7c5c883a4df6096ca35875f24b4e2f7c6c5cf715aa9428069b365e1a121323556113a0ed9a2b8c1cbb944eba56e4917ae1dd6dca34dbb4098a52651af8a8b32a0416b85a9ec8c3e305268c518f713edb977fd6b17cac7fe85d574003bc5133b590d117e5b471a0abe73f96a069b0162bafd492a01900cb3c9bf6ffa6c30f11e9d1ce0eb5385187990f54387a1f66be91b8e9cc09acc5cf0545da67470ffbe95b856f90335573b14cb487787a1440166a4b5249c8108b7d7e07f340f2a30f986cbc2b1e3055cf425dde138deb3fb12a9bb2cfae7020b2503ff50840ad2f026282bb9725e82e310cb2c32a1fc1e7291817f7539055d8b61335643d2a6754033df4326da389ed5f83a6a1c88125975548fb213a2fd7287d98e8d815f42524e10ad9117cdbf88464a8354a96e6c1127167f7cf00088440501d660e670bf98e174cbb5bef986899bd2ed23f0051d1d776e6f4eaf6a8b4c973f12fc85b218c17d346dc8e8f820f71716219165fecc90ac1101a58d0325a586e9a2fed1a2ca2a96b86c94892551712aa032e2a474315ef6e0aeabb2d92356a65e55ccdd371f79a5e6f59e902667731512f1faf7bbbc3ed307927323b1a51f52268d696be32066cdb859662fdb69f8e2a718462537a612987377552f3e34919ff9e044ebfef0f000000088688c398c528e063a27c2654d8ef6fcf86cccf6111384367569f78e0c5544ac0c32f502398b9fb43c94ce6b0c2fdff387ca058d8b3d70edf444567347c32180e5f579935bee605d8d59580c7092b374ce27758f3fabbdc1210c52e7cdea694281ba308427afff30f71588a9280f7ebc56fe9b80c84ea65867cbe443ce760d0dfa3c7889846873ca76dcf464c7ac41ce082605d115f02ac350289557bf7afa58157cbed69a0dee6991af022ce6cd54867c1a05e71949fef85c941fca240e0cb67ea053725b7fa8de0ef248b9203f3de202fad5415112aa621ffaa5504fe4d20929b4f761d9b8621a63726e079b36c2e04bff0782374e2cb103c54842768c164ee77668753efebca2f6f075f47002f7dfb3689e27f1096236cd904645108e7ee25a0f6f3a24ca2db67b53a13a5e9c39601d526b5bf1658c9e9ce2b80f0a6eda7ddeb8811c6458dcea902dad8c1e0da485459d01a9349bebc7e03c7da4366fd53ed29b30c7bb9d28d758c5574f7347cc02e1becabc07964ef20bb27950f4352c92382eba52126a33d4fbe947a1a70dcc622115e4a1e61d283cb7e21a26d43f5ef2317acba85a2aafd6fcdc6fd902bf7821de2b21f252d73efb0f632e46097ed8b9d7c859175c8b4c54d7509ed221131702fef73ca28d9f25f7e1e915be840ff3e56b8d09323f93da0a6a041b5fe66a1910707f5a06c805efe8cbbbcef36a20680cfbbc4d793bf7ba9be868e290e4fe99c1f44eff6f1444775ce1f2c2bf2479b38db8029024f7cca496cc0c1d4013f96a1791e73b72d4220d649d7333761aad155a45e23e00b83bf3c80848c4c3bef451b33102338b11e4fa27c0e63800f1fb10c72029c3034e04d606bed563c0a001f5ad8c718d4056acce6076a1a652b28699928 diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W1.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W1.rsp index a3527abf11..340436bf29 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W1.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W1.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H5_W1 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 000000000000000000000001a5b1fcba390b752269e52f24ac609acf4e5f1cd5c45f46b26f6177ff23e3502f959bb3e4a9995e7337dda0dcfaf464974ca49ebf852abca2643fc8670b9428dea973c569cf1b6efb10b7aec60643882bbb57b84111901de9df43ff8b84941b85aae106b431995a6cbf103758a727cb4234cbf8b6e3f659aaa7d72286174708859e0e153c5101dac9615e1b9a43426433ff250df739bb9bc3e8e19723199f93564690801de8699bfbc5c966286a1d58936a50d2346635e4da1047576f1e97f97056975d2ff57baf59d88ba3459050f049b3a74c6fb82e7a8cc70c121ce1c633afc86093af3426c5bb2096dae2f40d68024928c28aa3b371d204194d22616413bf304548fb1c93821e16aa0005ec8d14cdf300de7a841b925731319c19b413594e3b2db5e74a913e70a1cb89b0bce8175c8856b1e221d5a07bd2d3a2d106f9acabef321cc2ef36e5ec9e60240956d5b9533f45e11bace27017bcf6d74eab81e3a55e10025e954b510b1b7909956f6d0b2188bc62dc05251114b8e878dba723f8cb9aedcb5c1bc2fc47b3f1663070a23ad908adb9abaffa2fb3c4fa3b8ef5305d979852e1306f3b88bf826ea086e9d6229de20cac880aaa32a0426fe9e0e5e283d055a298d3749721235ffaffb1561bbec3321d96c68140371ef7a20cce5987a9a37e9a3dddd45707e181a855df4bd29a22e63995c92b22db1919c7c1882d8e91c6764506dfbab529319e49dfe6c32a9dccafdcb387a05704938a20c786a9d413bcab3dd020ab8f8bd5a8b6821902c028e19b3ef75726dd5c6f546f25a820976f3d6c6d30ef4d42b06a0133d8ae43b97e639863f50310e822c568e4ee523f354feda584bf549294140674e5756c248afa342eb60b9e0873a1db661b1184371f752ad23026cef236855d3e707eef88b5f7b72f607c1a47db31cfb51bc346f20526f4f5b696ba7171a65d94e536a361863b67287b040860ea3ed4d25af0051581e135ff422243e4346896eb58ad50517b3b63df6d104176b02bdb5e2a6e8af0ef52ac4284c35b2561212a2d1b0b9f16d0f08378ba0368f0e5cd031cd898d21d0d7df5c81241861623896903b1115a0a61e4aed71abafcb609344eaf227af41a0ae4c3017c8dc7f8dc99aa679fe0605a800d6443bc27f18f4de198f93c4553836cede5f24de328319ec49bd203e322e4c1b57c2504e087b042824e11dbc6ea13207cffe3b0fa1fb595052e80cdfa8fe7ecf4be060b8d049bf52da0bf09a24b5297c2d7720ba7f9cf8264cf1397a5550a39206dd98bc5488cb7f5429f6327f643d3eb49c31cb66e281bfb7488777dc0ef8c18f9670e29c1f03d08cf405c263dbba87f5fcd1f1d365abe7dcdb087449618d3f0ad10b3b663757f8a496f24d857a61ad952984e13e181c31a7c39440f37ef23ca77e1a95264fc784cc53a779ae92cd3833967a8a7bd8baa57cf98be69d67f0d540592fbac6990d1b11b01facc7c570d267480f94ef5bdcbe6558c70b5e23d4fe14625e45439784601d0cad002b2f541f65880d286cc279f0ffbb0bac3a1bda18f3f8dcb3210300c843ebcc349cd59f48eb8763d901575158c77f6b1494ad63b2118f78461e773383a0ea685008d1bcca28f6dfebb445d2e82a90ea8f4856d1a3343bd00cfc8a73c0d496dba865a7b0c232f0a79bb0be78263ecab7d273db90219abde2deaed1e82c1ef3efe5d0a2fc826a396fb4121abca045898814c8b63bf70f584cbd75481eac9dbe9b13f5e50c95871bfb5facf07deb4873c2d8ad81b3a212195de3110be065dc1694a84fee5b4bc80b143a81e6055e3bd26fd4b487c7c27b73079449fe59393ca2ee06d51bd9902f5bff9c5bd6d0793a2ab21333009cd9efa6f64fb67f97d5775110be4356c20600188458faa739ca149796f5a598b05f46da225b969a297947b75185d0e9c8c32221414ac4ea886209b8e4dcaee07af50bc1a995fff0d5b0ae01a6a36c540f65642ed3be1d1b6808df18f575df9c01e1d2150e1ab268355d3fee33eeb7fd6dfac9adb0d9c99aada56e299e9e13a4c37e4c902738bc92b684d5ebde5284944a95cbbf2f5119040e3f8471b6d572f108415034f574f13dc417686a3a92306f0ff22bc9e253c5f04b9a96b9105c397da197ee587bacf961c71d8787cacc05d12bd14f8ec2eca4d8b11de8810d7d31cd0c172dfda21f732eb6a53088d11db3aa4b9080eda3230e2b55bb339b4aedc9624c32d5e6eed1110bb61373fa10d98255ecd9c073f374ddd197c4b9c208771d963e93beeb263c7be992ad8bb9930725303c9e5b8b2eb40fe7266e3c1f26f6150da42668021c9bb2ef8f91c76a1726efd58244f0aabac9d958f320fccab4e4f32898be68a83dbfc15f1dddf63fef8b3ce05d8f8d1765ed7b2d3aa6a8941c94600c4e177d3f0a0d606dc2a55b4c46be43dab0380fc96784b5dd0ed9dcb590083682aa3a7e6b32c90612be44d1082e3738cf5ca4ef581497c3ce6d7eed774561c86177901cd67cb7fdce4ccd81586a5a3d0587d8099fa7678a43f095eead13c98976481ed4040529ce29145436157b0228241634faa5a43c0d0185ed9f2e07eec3ee3aa95a62b127e45ea2902f97d024ff810968fdae1c1fc6c851b51b8829dd1280d2cc3b6029f0097326d34f3c350d6501a05d7a333323d23839931e947f5a7df7274098025a0041e4d5e719a0ad3480b3a16c76486d119a1a4ba0542fce25777e0cbaa44936b540c5ff91c013351e0ccc93d3413f9b145c551c2c4d302f000f2c5b3c3dfe5642ffb9e5e5978c323eea9ee7e012dac29f62af9d57f0b5dc106ba751900604c76573eedce79c4c06c8c055daec35e2534ef7c2eb6aad9c9c4cba215ae520cd87752ed32a4dd3916ce38c302a13c3e1dc613e754480bece4994b28e900a9be004a0aab63eddc3e06fd05bd744fc43f76487407b6999d9fa65d15550a1cce8478e55860f614a2f13d0667e98763788802a95c2fadab792928d397dd8e2e3a2691c88681574e1169642e9a1d637bd3ee8e0494629692ec9b1d0560df3374c53b33ef8a1c13c105daeb538b7fd65de27e2223255e3dedb08bcb8d3d18447a61948731d30a9358c3aa61169bf679ff24aaf7d0ed19a82add52a6ad496baf24934c3d991274d70380c8a9fe2a520272106e2d67d5a136b9588c0dad681d7b11fbce6d835caaad3dd9179c594be9e4c58a9d294b85353974fdecc6075f7dfe1ffd1cbfbba7b6f0d99f1f9b3eb3cd22f0a75e4ee9361025890de6556c2b450748dde7c200092a0a52ad85ea5e1d9c6eedd274c05e55cf42624a3a2477ac162061803eb176ba5747559b1460008b9f55eb5a3c55a575342addb5fcf0be3334aac1e0ed0f22c457a2c1f4b1dc0afc8485905ff537360060b895681acc58cd5f23eb587edd60b2e33c2aa77b1b07bd4090a3f8ea627dd1351fc68aeddc50d51bf5323ef3055f6a16bf2a6d1d97f124ffa7c27faac2a0e765a75f363faf715b0452e2719cf3e13b2b10d890a7c66aa3202760ba41874d14ca98709005166f7bf5f93de9054f31ab4d9eaf5c97e2db07c9b6376eeed1048dfb6c26242e5de8a46bd308b37edc9a9acd3a4beb04b084ec9e1325aa02ad58af47f264cdbe5fb49d4d79cefb6badb8e2afb4c2ee7db16606f0166be7b2acc848dcf51ae6603d72ac4c1be1b8e4cd54de4a2fccb53a42b83e8750c825b4e1b0052a5faf2f5bdd4581a557834c6571cae4e05d47e71efa27b792ce9596d2605fa89306942699d126f842746190a36c5605d5b83cc9fbf3133ae752ba0a4c42b474d30e6fd9127b306854f92d0f0e29c8a734c468e0837b073bd622319c05b00db874b63c2e6cc152bd0fd7e5107f168c897d80efc7d943f3bfb2a64a108d84506c2895d1a0cc6206ac92f9d274757e91defc3612b2c6868937fc02d45b0441cddc7969fa0dbf0df711a35b6c43ebf8b12a3ae77b941367175fa8795241002cfb3262cd4bc9857e1fc6420c9f7deff319bcad70047cc9a24dd13b19ee95a96df562d36c5eb010f45b0e0fe353f95fab81a722dffbaeeaecf1e169e8ed774048b34f9f35df7757438e57f157f83507382ad7bc169c50186cfea182a6e402cec92b4915f8447ba1b96a6e2fb16634241efb103f1de9184a62e3c32ac1fc4e3c5c7142d9895ebd5b80954cd141856dd2242a42d760712a895aa52c74c52a0c0544ea85ced655e74725944f87b9c1522806e0a6c9b8dd7a1f0f92ba06c9fb002de559cf637fc139abd90d0a836360be6fa4c0bb8eb6b797d4e64af3d4316e402c59e432f25d54220c50b04ba0f6a6e4b7f349090d5eaf205800cd6feb6f5459554f03cd8e3557f6132889f3d33b91a8a56190d9b552bfe99b0b3b3f260948ddb14e106a22b96ada2e7459adad648117dbc0c4944bf46db8d557fb3a1a997d963debf89e542f43e6695140eeef90f93b06a378b2f4466eceae8ba6d81e5019ebd2baa6d28a11a8824fb17fb808b612e36225d7c1ac798dc49faba3210f40fb230f9ba0d24549ba5eacfd9f8a470b83cedcc895347d50bee5fb5d4602d0294a5d73332b03d2800ed5eb21c6f7288e01a917da98e6c9214372d9139fa2bcf82912df4c6e9b4537f3ca9a57fbc55f20483b99acbba555f9ef4c6e6bc943e24919215854b902fb2e5497b22e6aaf0f5b0d4f3cb338f94c24ca9d53f87b98ecf391e27df19ce311598ccdb09f5581111d77c1caf8aa8d163a485c74db922355924ed67db075c2bc0dd29b4efb130e7869aaed5f20ba740cf5ad4f47c64c93fcc9e964bb0aabea679d4e17150658a3d97da9be89ade5ee42d52c36379d5bc2520b344bb269b0cad9e2e0087de976e121cf0f0975ed9051ff8fc0c7eca3341399f14b8e62fe5e0cbd3f15b8f3a18b10473a1b253d645815b0205841a9c4d7c493d4eeb4e982a4b5ea723d29c8ec06083dbd252846f119aebc07fc9d568b2eda28db5ad905123dad39d02c012186d854e561443b0fb73b139d632f2a102e33b52ab2b94c3993aa8d8713b141379c62193d3464a96529c75676fce6451482875c33a4d699bdafab582b543399764102820ef92837d3bce37938b6ffa46bc7a0ba4ad3cc8e7e196b12df2ef03748b8bbe1541613c693d4a02e54cff8b72438fc9cd36706422e327b5f60ecc0e7285c2cb3ae37a818fd9310da196ea7bc87ce42f358570032a1ff791a471fea3f5dededff0439d98ea5e49958e3521c646bba4f1494c9734b05f2758b81b8cc590cecf09ede5d69d29a388cfb04dd0d20d2b0e4bf6616aeccd45df4682ba6a93acb83f33d17ed8740bb26f6676519d29a96827af74882140a88603c0bc1cd98f0466f8a9952de5c9f8e58869a2783d4e35778fa2407522005c5666f70273d55f8901a5459c2e2c53f484ee811516a5a235b5575787acd073a944b29d5ee4f8a3f9936e0dde8570c357a990c49c05eeef2dd604c8ead74541d7593dea66125d19d2c65da11bcb7aeee7fbb35ecdd7f7a17520f46e17ad0c3e68bfde0d459d8aa9da2ef6cc2ca2c90c9349501312778adaf1948624ce0250e1254b443a11a0a1f5532a0576123d2bdac0be59e9111bf7dfae21859ca219760dc4f6dc5ad73782138084a48abee1a8d2476d44fc22aea93b99f3e4b94da17282cd2bb8f624a92ecc5d24f5c0096434e4a6ca1ce474ea3abe8d658cbf3ec5a9c9ab563bc68043c55d92267cd9dfc5bb086a0dc9b800849c675d5179e60bb6f38385118ec7b2aca937d54e8ea99bc9736fe94e614f2e584f203892ac14cd2ed24067680ec94d0c1d8dfb9cd0cbedea7efd865c32fa1e2e6c8f0f7e86dbca875dc0d0e83f1edb9ff190f463fd57b89ccac14b9142d513e6c60ce226cbac592a3aa47b4b062844b6aaf3976acb6714f9d4080dde568c29de2d710816693a31e2f0e4fe61608395f67c0b4f0000fc4d3eb46bac57251d99188969116864fe0593bc60f3e5f7c9f9ad0964194b37b897431acc14effaaeff4802753093027caaf6ad88e20cdf6ceeaceaf681a2edc951e4b6e4d49239797c54d87e591ac324a5718fb62338074330b1febd106ee389b727346b581e4b0ac8a7c40d7b56574ed506fca456838abf7ed3f789e55de37051c07ac02b610f0a8d656add1fe9104b0243a29ca46093f6292e0ae152e4976e7c5c8eb6c18e04cfeb11a3163a14cbaee778e0967936fcf76ddbbadbe93794a98ed8befffd0d182b3a96a8a0217ff1be9fe8377e93a2c5f4d75f83df93eaa3e2d55574851dc3e0d096685a3b3c575d6c703a41807888ee4222461e1753ebf1862e39f29a5bb321bcf111a0dbe748fe337e301ee9ffd1b7de24b90f815bbcff5ab6d1d730f4795446a5c5655fa4e99554fc9e461d9d88c26492b28d94c7bb32e5f99ca567705536b7c3530f3bd4c0db0eb984d15a110417247caadce1afd28cfa5cf9f7998459ae4461637aa5db978db1bb15187bd7606276d720be8a4a421f0b4fe049c0decf60c5cfaf3afecefc431ed8498ced36c88b20f417e4ff5a5b871df26e7918ddd44edfd04caff5870e0591cad7d085102dba0a880fc0b456535211cfba89a5b45fcc58d6d996a32e39488821b7834ca4ed81e4fa77b37a9fde7f4309531fae3988e0fe2c2c5cd390acb4232480b20896bb5a136b66b95c2728474d91acde95dc61b86f18d719f183aa1b47aaea4f9d7ab9ca0099f3496c79b203edc277b76a00e99d287aff8ee2cccf5da4725643f97f0aa6c9658c4a2deef1c5e09278080e035343632e3212f72d82e09d672463a3471af578c7da9aef1c727238626c8c76aac5544626fdab7fb15b620865db86cdbf3718c076dad60779186f13f334a0546ba457e5b33b96c575aadd2455139b911c3e69a14dcfd8c85ac63f1f9159c2825cd8ec8ce9c7eca54c3dbc8c37128867508e0b410030444cc0d6acc1e9ffdcf3288889710dbd95524333be72257d2dc79af0eefc4d0961ac720640af06e1d15f5da49664ab3eb1ba68c5767794e9a79f595f70626365a47f4e53d31229158270ff4b9a3ba2611a4a53fb739c87c7e4f9ef88b6d5ed6eed8d11d345756c867e37e342b48170236f9fdb11c4aa49d534daec9cba8bbf1b0a7fee6c1673175ac2677c4cf1604a8adc2c6d37df26f102ecb2b9f9b7a493767f81eea07fb60e319a5d2c5c239994952e56974900798cc2335de0790dcf706e18a563942aa04f32d869a97f9a6a30904a71164ede9a33f75e5d47b94e49ab6931092e982fc2635b83ed8e085cdaabe697bc26ef3611f894c97dd410ddd45d41f5144360c1a96b332a583f47e75ad4afb74ac27ae97bc0a1f05a1a780d0a0041f9416a1c5631562c34e0859d5e973400c9d5acfaed302364f11e65c47448bae7271dbc36c00c494614218f04585fff089d0914b3840939817972bf6740b7e6e53be78ba98d50aa469a965f0e8fd33857f5aa2ab731a7ca7a8eb4f000443eb6e436057debed8441c8dce197de6e9e32c646fda78feebcd0fb5d0ea4471f5dacda99f20e89657a6af993a5320979ab45b807b9f756197850d419b5c816662519ebae7fbd17c3893e753cc8eec9d7fc3910b8ee0277b78ae08eaa4dce23a64139dd9800a173e047d447664ff81f5689b164590af784e6e4859993683b747602a816d49b34405487ff12ceff7fe7ac0990ba49130295177d1678f783867ddb593e55fb3f49dbd7d7092078296852fa9c9f02d1d399250fae993c1eb51d32df789e75590657d25ae633ec882c896829f861375a8139b824775b8bbeafe72ce20a7b55a8d187cca8a8554b4a8c314c8c4d8cbe8124a7ff4d63a0ae11ad6806e9cbdc4b8c2c824579960b7c49a4b6bb3cbe18b28c9e64909ce50fd5d9d1744a44e016b0433b66ebb5eaeff9fac286d71d80f04c8e78b898b818cab7dbd2b701045d2cdcee907e3171408318fe0a4a5f86fda1fce6398b78854598e287bc0594402fa56773ad8cf53b839c84bdce861a20efa67aa3ea38ed601687f9a9050818b3aee87e22355e62bc5978979c98df3a7418e468d7ff33b15114e838db3b39b0f5e6bc83a774b84210a2642b9c56c8691e2796f7d0bd72c72035ba327ff33f220380d6a39cc1a0322e8c2bb5a843f6411652f4792f7c15f4c0d4cf87c484a89fe45eead455cd2dbc792a2c840e3be5278feb93a988c6426ff56529b0185520443f2c21aa5f6dc4c03f96d6d30d778fb9dcd685ee6e3ca5eeb0c05d300806dfd7ac94fda5118e115d2df3f8bb8bdf3e198a06d5e876b202d391ebe92a633fcfe2f8315d6ebb2c27a9cb7de232ee7cb12069ace3f58fac8a7ad8c628ce28a757151b9b690fe70ca8fbec03c0212c91e96a1efed549d46e379edc255b66e097acc473662d079c393f00177c80c0528240eb19e74378526eabab965d5e2f433191d0fb7eb3e3bb8c1ae32c8ed2ceb8ddbda24f8f06a8e64a2cf1fde2c1044a7f6d55d5cddbc8208a39f08f9d712aa40aa1d8223e3a42d866d8bb8925fe37291285d4aa71b83dc4072bdaaaf9f02fe833310014c050808a24e70830b6d0014fe3750dfe78515bf135bdd47af71258ecaf59cbb3dc147f55cc13274e8c959bc594a8394b690dcc1d98f564058f2ecf0097beada116507d9062394eb45164dcbec53137ca226043809bc44b9477137c99e79d483a523e60d29e35134cca5f589b5b1f1d5e49c971fc2e5ff224b53e0f19745d39c93f212447ef0fd0fa70856c1fcf86dec2c4583ec2943566353fdcc139ad4b87e4b4942f87f74f353bac1c9097818dc6796feaf1829bfadaa7dd07cf6b2ec95c0acd49f26a03616caf2a8ec2b1d44d8891b6846965cf0d7e6b08012c4d2b98ef86ad9c30380d023ee096fc749b94712ead24e2fa2e78600b3ad4ff5bf3451604c9a9c44513a1c18c665da883a5adfa8ac42d445c6572e30bf63324b94052342c671c1702e9ccd0da5abd1c77017414832ef16f636015a653268507f0e8fd186b83e4aeec1da71280b31393ce0f5a776cd8ac1d221ecae60617fcc3a36c53839043df0d5d94391f96c567b9659e94415f7c229518ff2f675eec0c97090146355e02f67ff5c42ed2b29dfc541b3e6fefed4d124031706b319a36999afb787740af4cdaa1da253bc3cd2e463d603b059dff4b5c6310a876b0260fa40d65300ca194bb590d599391a7e049e76b10e62b21b5ce6a83b4e92682b25dc6ec68f7ecf1e69d8e1db07d3837d45df27452cf4d6c26903450b352718f4d3ed7adad608c377c1f53e6414a3282d43f78b348c496d8603e762b909fcaefbc8193cf277041082cb9dd36b8810ff8221d956de5e0ced5635bfd261bc4c32de67fe1648f2b5d1e01784a288df133c2f8a803718bea3160b207f9b11c5dfa9981dbedf7fbdecaf5117b65760708045f8fc1e54d54f53c37995a367e3a578c876086c96bda438c9a8daad35ce5e8def882bfdf0a0d65cda63a7a9e3ea7fc91a45dd02ca9614263e6ac1f62d28c70922b81fcd98a5a966ea56beadf4ecd25aa5a2edc6f8a92ded720d8e062077db026fb845b08bbbfc9da7f6ac48eac5118b654cea44262e53db291d0cf4b7d4925e7115372aaf4164bb86d1fc5e52690984c74b055b384a91405ef626e79532917f8e26c63a4e8882372bd6c27eb747a2a3d1c17845b7ed826d2984947e8a299d718cc274e6c1bd530f14853656220b508c0dfe96e4cee284a60d183fea3b5c8d39eb0615e067633376acd5852fd447781aa5a288a5ae2347152a1830d72c5ce1f267157166cc33fc0ac5150b00db8f030ea63e51e1ca1cc1fbdef61fda793f29394d3a8053f04bfb2f182aa9060273b76a129e232687f2d42d00a3b9dc67c28c10d1c561c428aaf2e21bb290d66f7d73add81ff98cedd69f34875c84f30d4eb48dc3b882be8965db6c23b246cefa9c94c36c52c4979b464bb4592e422b121bc84f904acc48a04870d42e6894a12eb78b849b6ad26c4d637b8f870b25360542e143563efbb2adf39e8001c1b958ab1a04ec186a1c5748fab6d3bbbdd15bfd36300bb986044caded761067f841a31a4e95ffe9caccc1fbf0d51b83945a29ff1daa8d2d57630c7976e9ee730c5b2441330513e5fd21b234a5e9b65e36b256c3939d1de2730fc4c2a273d702e13dd3f8584d47ed692a730c82f5ccfaa8acf077b722ba2fdaa5c246b2209e897da9972c4a54b7a49e3a14eaa592a2ddcc9e70a8a7a8121a1ceb33d22dd0ffcfb7cfd76688b1ffdf6ee63abd623d30854266cb534fcd420a578437282a37a1deb3ab51f63c4c600f011be09f4ab3840caad041f87a033cb958cd4fa0307c8e33ae224fc85d8d332051324d2fb277874e1e17998ad1338843bc0160c31fcaf90c4fe87df89a48f14882f797e54c9a62702c8750d5051b631810ff0c01a05867c02346adcfe2c446db28c0d07e5dec99dbb508bfa0838d914ba1bf69b79c9b5eaaf46db732b57f315cedb1a050059c2e94a1b337bf7c64fd07df43ca7933827b6dc9fde538b53c3e8b8f579db106a743deaf31592b4697222f6b64d19210bd832207002690366c68291e641fb7c9f0877601de2d1590290ec3bfd8bb2e433f3c94416890e5bbff624c8e256d636994b5a3d1813e4334eb8f4f221333b1772dd15d280554c188fdd75063581362107d59d470dea5f3616be025b41ae8d00130f3b3357d6e7d5d9571cd6b801982fbdbc12b2f29aab5b9b7085a223629767c97e0f21d1040ada264f0c6a6e4cbe9690d2dfa58a52dbeba0db545a8a023adfc720923cd1b616bd0f60e7e3a9c3d08cd070faae9e7fbf5d7b8bfe0fd8c3212367db7fdfc9b635e986cf138900acf395188292be5dc88e6bd158eb637d8473ce8e750e49a4cabb6635d31da466a3b253192f633bd7125210d1fbd266c6c3d93701f888152ee1645481177d9981fe4b404f977004f6771c92049755d9d629eab760421137ddb63b778157924930bd5d239c2ae90fb5fdb8c8015a788cc45dc61a207ed4605d28a7cbd00caa8b97cd3b62a0e2278a76ea2b3d5bd41a774f659e196130fd4539ae8ff20fecc5b24a20bbd39ed7cdd08348116446ddaae9acdc320de58f63397b29c77199fc60f42f31ea467522ed446f4596b9917e27135bb7b73d1c5851aec57f763568d86b1f1340ff6acab7a45bb9c746a7f2a2f3faae60e4a598d37f45088d9d1250599fb0fbf68e45d2cfb28eb02215879ff74cec3b38f3741f64f03611ff7fc17b1c49c02ccfea56f2dbd13185c8d77f42a943ff5ee2fabe4e616d722ccf66314e8da191b67cd16c04aa94d19eae82c40d0c3f2e13ead51245e9fa9447380c597ea4bf26e90ed235e59ac2f783c681d21fe057b79e4bb3899fa72182892431c3c66dd3207b178d0d3a973123da3b69bbb2e73da6bb8d71a86fd501cd58ad5c72cf56e9c26387ec3271306cae768e920dd88eae06049d360015dc9719a0b91132bc0f55a005320fde40505bf18912817346ada67f36424907d7b6d950958bec05944a9b55bc93908a3cf1a9ae8d709ac366def39d29657c959d6a72b2cd1c57277d3b8340fcb9bb9745a0f003278ac104346eb655e60591b0e341d57828343b3fb6b8ba2ae24153cbdac528861fa30bd9b54c7d1035ddb4b280fce1a8a069d9224753cc449decb3148c111ea658601b59165f6374b010dbd343703e4a6cc5c8efba4ac7f420511b9150d13af80184bd1f371b64bc15e289268faef39b5eb7825dcda6326897dbdd9c6f37a3d5653b6613a37af51e5b74d27ae8b344baf8f47347227f201af58403ad59f68aeed8c9e3e1662a2bf2d0bb567fa22814cbe36b533ec64cb055122962d8725cf132aefda54f8ee290a51e53922e39abbf1df0439acedaec5031ecae048cbbe4a291044911f5b7097f98891f08ab729086e6fc4f9142dba686732db6f2b3044e4fa327284a1845fece6f59ef2ecca89b8d5000b2b1b21cfc690b557a54c6f1514d85fbccf269e8eeae79c4c2fa9d33965f46934324a1cc97c648cba1d5f6befe5dd06b45538689f146e28543b41c5c9b2de6000000005a83e68d4f50adec31a352dde617fa8ff70e9028362d2f20a9b1e9ba99a4ef0e0a8d6edbf3799ce086584ec56e2c3d9f8819e40bd62d4fe38e0295f2761f8e55d4da91ea2d2130a4b5b88ec92108b8b02b2967b1c68e4c467c8e3b65880f1dfc3b4fa3c1883401b6bd771d0147874f16d3635ec192c5990486ab3604f9b754229c837a959aa1847e50c6e05332d252e8f8b92e3db1d8b43a71a61c01e485ba1c7 diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W2.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W2.rsp index 488997fed8..436baba31e 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W2.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W2.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H5_W2 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 000000000000000000000002150417e62d167e4676733e92d1394e814545ed6b9b5bcdb5abfe12ef0d5e14f418017877e0ae217554001f178e1fbb78c6517a7b91a4768e2133c5c0ffc3541c1c957502a004405cb29dc9f86b37da393939e10c6050fc178853f99a31f96dee2893a203398e3cb632d761c2552e0f181eb568ce5984b89658da394dd4138df820dc6974ab9baae3253756c4c90e329464b5663e5b4cd00ec4efd4e3d4224b2fd0d0c6e0241fa222e9ca3057d903c958a9e3bba381d3b3e91406f34f368be3f40f09a4d7ae479944113e69709ea4a8eb3a0dc3c02b49822f35deaa94bf1d98335bb0a10966eaa9fc19167d9d07956f1e2cb1eeaa6ce5ef1d1860824911d8d151aa133eaa0974823d9b0ebc6218b5f1d3d39560832c303c99fa3a73f4a5c983cf80937cc18788a162e025515213225f357dcd2e2d8a9411fd4abb915892461db7d02e15c4b7f774837ca87d764d2f07e8c437465c53152691e39c65e7c6649e83ddb3568e2e31c661c649ba174f9829351817456b4e527ef6e2db153033becc31af7ffb1ec040d7f4f6ccfad654a34d7041a854cddcb8ab905356d37e4332f5632aef346eae7a49d6d3f465d3a918a532e4efe3f458bc3c2a17200e18e71bd05730f44d1d3b9490fec0e4a52d532bc987c7f29b0c4d1a1375b302a48476645f6f9d938ed7c4b9d874b496488439a299e9108be95b2c695e5049e739a9a3d14684d88b064884ea5438f2e009c0126509541457c87a3f06af3c75da61373ecda9a693b980113b22c34ba15c95696388c2e66d90b2fbb800a97a1b96b31a954e411229bbd86cac0fe668990a9c15c6181f847f2a1db288e995257b2c525e049609ee143555eb36649e119c0f427c998ffb45592ea6faffeff2a9e498428b09b6f1d3fc3a0c8b62a749c51b279be712be38f7b323455b50ac4e325703cf564025e2aa1e5876dd56a7be2ccb920dd22e475be7db8b3ff442711e9d0f3b392eda27da8a34cae12cd4f99fa17d8364d5a2a1303e996621b649a6d7105343b0a5af6dd65f2b1f13d8f36545eb65b99b8b6db5f022bc702e8bd2a1ddbc99b64a291affd1e2adcf8a01e9dd9c117e80e32f874beea046b56b44ee8cc2240d03de68c90d9f4d67e5f3aea949cf6f47d5356a6232e979329c10422193f206c74cbe2d06d290d40fb0ffcf2bafbca374a7c327006cb1b21608af282955d3259a4f4b845ac2d9b386be83e96eeda3a84a64810ae3c81b709fef15078424298917b2697d2bdd3e7f4d365b9a84bbab07c0be4d0929be663a06345d1a67360141c03c3f37891f09c24776177e34a9093fa62005187511268fb2fa80740cb751f5e9fd0d74b0f61b643d139f8ccd040c9a9a32cc740b825a2e6a5beb28a8915fbbb1bcd41c9694fcc72ed570b1e96cafaedde8adf8d5028f80eead64f9407e57ff5465da3e5e341e587cbf091f2f5bab89e95666a3fb7158718afcf685df10ea4a22ae7fe55c8f70d5d5a5973f3dde9c80f2a9eb13d58ca3485268f6e380464892f4c3c3598c81fc3d77d1ce0d3d9f50c78be78b88f6a9e17d6ec4ad9e6a86edbd5a4e5e17219fde097f422498c171ec1d0f6dbb6a2a49d34a66ae854e2650fa4a6c2833af5106472e7c787ef2da06f28f84f0f1197c7b4c4cff6ab3ceaac5ee819809ef20ee9b535252c23117da43e31ce778abfd84bf647875573217cc79c088f91ab07adc4c930a4819b936a98834ba2f9b034996d26bff2cc901317536b5481431656c083780d774b686ac5b0abd7ae2e05981c39726e6efb4ea2507b20e85cffecac815d6d9f84fa86240e6ded4dcaa67a2e2f944ac6d38f986b7268f2c240d8f5eafc0b2b67dfc11992e305e64264e19e021fd29b72dea8be8c315e3aa5f02c49fb9e77a34c48c58a28c4340ffaa7fb5b5d0c8a4aa4abd7bbf3955a0b71cbff160c5dd9a6a4ddefdf00367f414dad1c7ec0f77c1a777ec1c726a1049a2c4bc01554b95665496584cb13b28dafd7c668baa7d0c1e425e5c8cef9f75f21819a5708db01e5a5918df096424abcea2d758d4a8c5fbd96e10ba91bef727bcc47930bd45bc7d6851b21c7daf94c016e8cd10498f18ea44c6474d865a8841800dd19fe3d57611660c3729b5c2a2f1d1765a1237db7b97bcb6af56f79f275677bfee3c37fb1a0d7c2b453feea1f7adc60892a95a7e00421b4fa320ea25119fbd6af73d9049c8e109e2b1b683f5bf83933d63bd552f65fbfb806f346db3592e244acc0878c450962956f4e47bb0bced88d1ee0d18f93acdaf6bff6e6d9b451db35755c1bbb547dc4e098012823874546757f5aa94cd0bd294709da538e8c8675e96d47269451bb63d35b6f027d68aa0871b23114553e883463512890d489286886a93227ad5ba80c53f0bb4d383f15f607091a3ddf07cb199a7d8abee54097371c8ae59b354a8f86765288dc635e4f5a3f1bed2f0998f0562755035f39a4fb0f69618ebdbc3427f1fec8d1040aef11da99c0d3f0864615b1283fb2f9e66b957cf666ae08b2e11fc9153dd32b5fc43736758f65d896d253dbe16d7b16db56130851b7a0935d92d33fa75affb9d509ee73c40c9b61359ff814267e962d4aa80f6fb0ddb76dd4cbaf49fe65ad51b406a2f33bbf698a6dde309a7d7ce95f7c68ee5bccd1631f1443f0b1e823af31b2245095afdf073708fa9afa0c3b1c4606d5428cfbe3799003437b74b136b1d0d2f80848a1e5ab14fe7e9ffe02a09e21bd5d9c4eb0607bb5549f0399c2336cbc76a6e55c7f80fc0ee968c696beaa803fb020438a9ca6c89ef1e8823801e91c1cd7cbacf09c79f128f22f29c9d49355ecfe470b8df5edf9a47bdc781a3ff0ae8e5596e13bc06c610bab6121f85d54ef764e6a82a290a4ac3db0f76820d986ffeb5f19460db6246b59aa659afe6753093998876cb961b07fac8b0c0896d0931bc5843c4f545263a950523b7ad8520654564e27d0661f1cbe60812ad232b458ca36c6439750ed12df2f5d89b12f584e0023a2b8fa39c2a13da2b7497a968189f183f65bb37c5999fd6187f9979f39ec459271d67676ae157271b24ac7b3d3876840c48296096ee2730e14adb8af5ae11666d02e441f83c859aad9657c1216a9c8116d660abfb5e061f2face2f11088e661ab2046b969e72c3d23c6410c951ad210572e3cbddba77c5fb81c7594e60e1a4784d3d606b254a49f05521a0289dd14687cf8efb78a2eef2211e6021aa14f2a3d2a5a0d5013282591239e7df7991e3f44442b544e14ae382181f0790d4901b30f659f0cf9b3080a113d2bf869e44149667438b194bca40f1ce542ef7021222e0d6b7bcf40b8631e9a23b87dc1b97cd6eea407d3f7149e250c70a021b3614b5f68c065eccba5ac481fc4435f2da541a1e368d69259bc179338e641b9b14e77abe6762ae8db9a980061c85f49aa161aa92851f6f1e6a38152edac3f121326e517215cfab5746db3e026ffa2b5b4ea41d297bc4bf91f1d07c866b21425e022f0081c7284fa81c0b6b43bea2ce4d61b910aaa539b5485b79f0f766bc704eba870b33855a589ddf7525cbc07c828cf51e687f6d804e4d43535820171d38a67a8025486f0594872c996768b56177a916b13bdf622ea4d05ac608bd1f9220420733fabcbee129a4e89b243bfb4cb7cafebdbd37b1b505014ac3b9419bb51e274f8aa81f82725693341424df75c08ff6acdf622fea4988d0925ffb33466489331b00dc3432d19dddf30fd64194d4523dd3cafef94bacaf6c72b68665d1731edc8c2e9933d9302c61d576160c3c98a9fa393aa60a843238acc975f5af75532b5088a06299dfe395bf4ffdd4ba2c96ca3c7536c6986d34bdf61e01004e537748f427a7cff650918ec3c0916cdc7ba3037d078c1f96d1d77ec7560d1fa3a55443a8b2876c882a7ae2ddfeb611af3806be2f02e39a82e734728348bd90394b732da8798ea1552925e36a8ae92697bca66ec1cc4f6c2d0d60348f81f74ddae919516cb53455e4642f0782acd678e0f2daf973f866ff0f5576517038ffc52301bc53624eee8cacd1d9fdc4c74bf2afd75bd3d0c7a8010ab8d082e6edba64106cff64b5a9ac166f02b906b9b84539361a68703e43c74439306382964d3f2245a1cb9699b9aafe48922dcfec3515cf9d737d72888562b4830e5a80594ea437556ca1c7921629438c620a439196d194a862dba078524bbfd801d2cb33cd500957b84719352baae64d8163ff85cf8236c509ba495633d4972ba8094d1e293b07f7693bc939ffcf4e3979c1f077e48b6a7b2666360759b82adffc811635b860062fe55d70b1397d6dbebe2f73e722fcb90af4d98a55d4043edea799954e8950e7f6744a1e3a98b2fd48f2ff685208c8ad85becaac5ae51e187e75beaf6589773d23367379a6b46082761f247d79341d9498d210a206424d07bb88fe5018a302f4bbdb2d0ceafd4b25603fce716eddbd18ba669fd0a18c93112082b2941924ba80c5a50efaf1f391e6e0d7d6e27cc991c29f4065d75be997762e4032b62bba80be85d4c8ec05ebf54354ebed5c32ffc47caf0e7c703c38559f125521ba736225d9284e33fbab9d32ad54e3ddce4a79a6a0adb2fcd15c57281a9f150a38d8fc96a27c751a888daa65c4461b54efaf2dd2e0d3b5a6ac12027e3b9721f6bb1a32239824faf8574574845a4d649820b1a003cbe2b3e6466f47062356432d3280edc53b1c4fffc63de4fac290e4525c151ce05314c8a8b0c744acd5768936f93a7421eea8e69522ad6d188f71f4b285a535d84ca72c965bc4e40f03b09703d534b6de536b2da8bb36704ee930f1252fbaab91d5974a9d89e1411c5662d65328334a3982c31d4d0588000204acb1f5fc359302d931d8844dbf24201483041dde064ac06dc020768f40039ab61e8a4b893a1a782a49632e38d5a70120aa4ae391d69c9fe11aff5c3f4fc55153ecf9bab047e130e4585e5de2fb875ae4841d21abc580a945e4738674ee2423a237e9f03edd0bf5e395760d5ffffa1645846019fac8a58ca6741a221ea52c0c3020ca6590a7633388da3daed3ea8425ad3671f235420b00ccdaa006a0cee192855a6d8f6cc17794c4bb1da3c6d1b3b2269572bc2f9d93ba886fe30cdcdd2f105536472a580d0e9ccbaf9d2bd091cd33a2243c816da0fd4a3e8f1c01657dc236ea26cb83e05f1c6c184d9c0391535307cb945f80f9329800b39dcbb10e1ba5d13185a3050772d694429e17426136db817cffe563a77703666f1dc827d81790bcc4e9ceba15c34a28c420b6cc7df34cea563d48e9fd20a208497e0cb5a02eb25c3f67095f3f3a63d62d06ad7953ebfddbfddbb613c676394ed866622ba3323d6b1ae1b1324aa41e99170ee1e66560fa78b74051fb172f9b82e53a02be5859ca2d59a133551b7f1cfde0ec524b4fb4aefa69df632a385db308044922dce6258d71b36b14cb481e82928fafc56111ebd5969a3588ecab557b8c15654cbd559f0792b6caed5413d750867d00ef53aa597949fdb837c468c41bdeb081aae58040a50172cbf3d075a9263f4ad7da16062e80e5fe39da2e05366b79a148ae181c465aae82ecec18e98f696649bca24931a702c338f25bb2d135b95bddea4f9f92a2f925f31ee784f195d29eb4003a5b9a21cda79c6a35a579a470bdfa05ce3ed9c2a693ec92ac559691cdf22e5b074c479f58ef2395781369738f7de2c13de64090dc6575920c28a2c5164c8266e9dee906ef55c69c73fc932a64549470fcfe4da13bda91672870957d0cc002998510826d6452f7b400d09c47925eb3e4bb8f53bbd3f657d2afcd7eecc992966bb1ea7774ed15d22d931dacd5bd45993151ce89e173548d0d9324ef74be4c0cb89a1d824f1eb164821249116274a536b1b760846a4f6d1426f946d338ef04f06494a8ad0e3a59fc2269cbd411b0106e8b1245dcc3814ccf330790dd352e68a675736119d839155378f573524f5071487329e2b30405d2b0f07ad82cf2a7a3514821356f126349668f35350f3f3b71045bf60f1f608da2ebb1b067f0e9b673a1e6bf221eee8aaaae8000000051c142d7004cafdc21431a71b81e6ddc44a8ab75a3a2c8fa3a9a8cc4a781d9079063f7a97bf683473a44e5ec3877cb60d400f6a6d8a3e4fdcb02f51160f6d828ea4358ff1f2fdeb78042387d9cf0452ad8653f511d53435401a55c32b0c03a76b0edfec3b1fcb0b864da0ef3663930feab4e318cb7c271ac7b0ee8f7fa2c67838b293d94a7bddb92e05b5810f88ac6eea3182bbe37704a0190fd4658e268be368 diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W4.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W4.rsp index 7e4ae977d5..222fdfcdab 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W4.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W4.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H5_W4 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 000000000000000000000003aeb14a03f55d830d64ab4981809d932f48f8371887e4b52188d67e9e77d296b7699c4267b07320535a32b9fda668fe4d64e126e1190851de8400a1eb29b6251778dbf3fb6e6c2d4ed9cd306501ff53e4b3e2e6338d8107537ba3bfd14ce795cf8f939e9ea6add97df60ae591800014cac041bb38857d29a479ece3289240b926b02e7079af6ce0bd239fd9c9c55880c7c68d527abc9210cba38903c561130e1cf88e75ac230a1ba6591edf39142739e8cd16d5c744d49c6dc9318927b3f6a2f44139131b5a29635a80e5e4ebde27570727e9fcd9aa18c7e45293f67c0a179a7a159574908c1a43de083e69aead0dfe6ae356367da1de7bc4007b45483f3863b045a047ccad8a88c16ebf45aa2e76a40a5806225bfefcfce1687602b204efd87385308a2a4d4e0378714ce5bd12341b1a71e8d155b2cb2e08616d5280c418d355987cffad11b65e2032371a211269943baa66907285e4968fb4bfb271230809365dbcb8fece0e66a6c23ae94a4a91ad6cebea8c2ed848ac76fd43935db8382731ad2188f556519b87efad901b656f8c5b533a772cdb1f59b2afadf46ea3cacb9eff1eff51ef73cb414da18f188880a67d6a2dc70c4aafda7d2d65ccb3e870033c3ccd2e16116b4f685ee45194cb8ff4415768a22ae5189ebd2f5d2a0bb796890b85a01979536d5ca3ea77994cfd530bf95a039a7ce635a6db922baa997a6c26ef45e12018b58cd2cbc7b3b3d0d2938b28ae7d0779369e0f8889c36ad3a20e6cac70268428eb43fc660d6a2a293762aef9df55e5873304141ec87a96ce4d6a7e20fe69d66a70e872c4f037f32b5317f51a602196c8e443ed0cf80bc2b7104b2b5211cffd650cba2de1777268b1e015556e55f3e4400e61abcff383541594947f4ca2394ad26c43d3301264d05cae9a38d4c70b7b6edf50368f2e30842bd619387961c258abf34181b0e662af0db9ddd8e444116e28d1959c4e56f5e32322d51b772f6f994e971c49869ced203936f76731787fa6e8d13dfc533103ca0c3cea5d8c27d8b3b05f9ac81b30b9ec947cf39299972214b6e058f3fcf58ed982efb02bd1cdb6199264183c82853ae04cac67f6d2baa37f725dc77f08534273e8cf070e9383d8f4ebdc44bb2f4a48a8aa9ad9b8c6ccd1a718fd9ad8716aece437630a5294ae83898d44392444bd7d26fa0705fc37f384b9b09b94ef0ffab639b9d01758d286a8ae14c933e746459c64dc31d609716e928469e38b36e563ef68e3644a7200a262b1688fd8e4363b57d42a64d0866e19501ec91d83707067fd37e1a3b42453e75afa9739e73030180ad38b687230b6bc8ba02ec2bc300a87828a1de3a8cab63fb26d30099f960dd82b7cc65923b0dc380d3513cf0c74e671e50ba668b8b0497919e260cd8c2755de8ae3455ab3dc3c378a789b8c84dd6ee8641a4feb06ac3d8dd80093e744ca7f44e1a3bd0e1d05870841e13a6744530cf89b887085cf8031c1c713d9167d9e1ad5d5e7c5d6ecce0830863f846d423dd76a91be60aff65a72f16e71173609a46f3bbd33f46d8d1928fe620a646bba75325dda0e8dbf1f95ca9bc02e891889e6b3009cbc944b9aab65fa30cce224ec1856abf23556ac570f43396c61cab7f458d5ff1fe7f83c0764e78fa0f9f9d75fa9e0c518379a3ca746205fe03751231ba269e19b579b90b1da30d8b6315ed7a4e54ae88fbcdb15a8fbf24fee6d9f7b95dceb99d330b449f05a53974118989ca9ac1bcdddad5a43b882db01cd27d72236c0d060b2b6120ecd7053820a5cfa84dc672fc2c310067cffd3f5a8c3bca13077fc1d44e99c111d4f95cd68d74bf827849277ccd7245166950beb19f33297a00838ca21b896073878f2b509bedc6d6ae8295dbe1a059cf3ebcf40e7790e0530dcb66159a8c0e0fdde36f1b6374e42eb331b92bfa9061c6f480bb64e73c539eda7ef879730904d5843ea1c5616798adbe21d6c5fc4efebb60c45ccb30b7b1fbe673e754717ac71f5ca272dfffd2aca2eb8cb885c8a8395800f70c90271aba676239abb86c0708301bbf643028e55b9dfcbd338f2e22f5cee5c4d0fa163488a06fab8f15337dc219292f53325f98a4ce0f3f931b2961483d165a97e19d9d1408a156c7d35eab47fa5edf71dcf862e68a37787a1203c35383047398b3f305e1d4fe19d8dddbeb07990c507e8d80b6992c5c996c14b7cd31f65006585dd6bdc7fe43a893e96e06daecbcde583759f8138b3461341ec115ff29f1ed2eb72ff45d29e674dbc27165c9c2ba212455264936a9b8615ec5fd6cc26390dc45e1bfdb9815c8026ab9744af6eedfef8d2b2e73adcc50c52593ae3750dbc880c19dd627f215a49b044f87f866098c14e2716a055819ed0314ce687193cddc15773a220c1204b81dbf11087019ef723f0e14131f638cce5224bc1c73626a2811fec0becf91b6e39674c16c31407289222bb02eeca5ccb6a195c8c594d5ec984ac7fa1cc266f40dc4c6ca0724a94da0e1c8ac89ae52ab5c35ab2dfab88d9899336b19b099a71d0564f31ecfce6c582446a37e4acd62c62902afe83d01b977d61b31e4d03efeef17e381891c5e96a1043da0421eafacb98358ec2e98986762add3036aa1a1dd9f3235dd9a6f991e935d44337a265755aec34e819175e140b51079662ab5905073e588c785647444c4a3484c7f5643056b49e4fd0927cbfdab1b4c3101484c20a673b5322fafba8525d8c76f05e2cf522f1bd9955b86ebff690c02bbe96f73247396f50829f12ab26d21f082af26fb68cf7c4edd47602955a72eb29fe18a22131a8ec9b33936e816da6ecbc78b83e7656796dd756eb408a462df7830a67371d088b4e3aa15d4f56412cc1147338ca3fbd759ec61c2069d58ef9e84fd436eadaf2f8a955bf86c1d336830e9e8e8ae5374827cd801f0fd92dfe10043e8e1776c6ecd0cb7b9e0bfb6e326e8eb0224203575ec16007008dd284836dc7b4425fd39048d3cd2df1ef4fe18d6499abcd55d38d44c70852557ce09c3e3f45234cfa94f417600886b9b8a946a24ddeb19726c8b0a0b1a41be57b203c310f558daa000000050233c68da9d372a5a75790fd99589f6cb07f2c9cf97325a28c59bac5ec87e8eac10877a29091357b9b12611d2ad4b6ebb92f2a92cd0efd4a80eba5fec0eb6f95d1d9ddfe0b6e9eadb2420921ab517eba102bb8fa0402cf463d7b7d3122e161a5b18959390a8a38d08706f1ee4c2a7cdbbf95a642133e504791cb5516e1ccf2915cdc752a2a6cc023632112bf44115a1d97fce39359885b203307721151e4574c diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8.rsp index 57369ce635..709a37263d 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H5_W8 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e2e0a0a sm = 000000000000000000000004c15445cdb0955e650d038fe369128bb41dec49c85cd58208337d27a63c4c4c613fa669e360606b31f1bcbcef9540a8babe0fb27755ca9e444cc7e3b2de51f4f63b9fad23b7a334003a45ce9919f223efa24d1e24ccd6b7d46f645834ae72cdd32484d1db569f8ed1b784ee2aaca9645e3fb7b0c68c1c8d22812b6903176e4475f307e0fad497f2134462d94f51c63e1e29defaad7bdaf03e49da1ea7086c064b3e536c01c4cc435d5be073cea199da5e6d1c3fd3a9f6d5b32f5ae2d974f07dfef21994f9e33999dfc0d3074aa8bf41c73d1b2f106ec5624badbb6521a3d21bb59fa5c28e8f02788975290248ad126ccec0639da4b0eb2e1a09be522dbadac2fdf2643c4cf2f905a55e7181542ce391f9ec6e3023fb3f015a52358be92385d6fb2c5ea84ed630622c872fcfcfab61e90b94b0307b31fab6df36c43c3d8907ff7842573d998b4e66f629d37681700c8f8d0c4da8ff8ab6e20348e817ba9e818de076ebd99d0b8ce672c12459b5955dd714b40a93210050bf54c8bbaf22840c2d007cd1f40a000cc55c745cfd3316205731818b93cfb51045369a4ee88cbce94b77544e64861d62dd10e711795d6fe3d4ad1517ead72967403c1a6a308bf834d224da53c2f89528c480bf294ca41e9018f129c0ba6316ea18fdd6e9d80e0593333c668432cf8a9505659fb63fe309b5ef348bef9e19fbecc33af91790b1c4531a85cad51af236ce5efdcbd77212fc0b642dcb91f7719e49a38ddd5afad688ed9ce5fb48d98f5e2c08f06d743d92b005e4d013e4474703f8c8f5b085f4f479896191f8fc9e9d6fd8b9c529ce2a7e8d1fcf614078366943deb263455843a31d16be42aa8551185315c705e90afaf25a06e93a7c7ea6696cf6f3cb496c674e3366e1fd6c1280a83900d5e62de9757e3383feb324728b32a496b97f6356f30ab160611ea04abc38b21cc7553901599ea4c590f9a4082e6341a9c323ea5dbf0f93180ef5bec182694c44e3360cc4ba3be21aed6958da7a6d8a75bbd84e24b40d88a2cd477e319933ad193b3072a987915edd7404e67d67759b31bfca09c6863e3230ff1e8731d1d8611bcdf31d5c5e272f674eff68b25933555feb2356b7639b7147961e3d8405e42f01bd6710bf64e896658d3532a78f67dd99d047060e107e084141ab06ba38124224861d6ff5e356bb43f90ca37b7b119ee2a06665b1c9f5d913853cc27f20b539727957ff17c07de0b9754d49f3ea1ea6da022112015e82a477e719aebb35e4c7e680dce407e3919832143ae3898ee14cf91ceb150341ebf5f767d2e1581c41751b8ddee365491e69d4c3c9ac548d60b8105b6b6afef80be691f1a766c59ad94ddee2ac824e26a3341b4409050486fbc94a1d95488446fd58595465204a0b7baeb3654c85ad124a6a42d6bb134e2bb9231a9f073afdfdb9fc6f114a99d08a685587475567cc68df54376fd13acab6b83b06628715e5ebc69938154c9e7c14c7cae80f78ccd41a8d07f2a65c09f5be027cd8fae674059b48d9d720250fc35160dfbcf520f89cce57af12415ea14996e85c6eaecef30319642839d4ce000000052c26f6dbb703f8711854e896635d51cec418c2c01df5fa5067c3a3ec08b30d042f4a08bb5dd156f17039c6eb9cbea8cdfbf46e64c6e345edc8aff2dcc7ad2ad911f2fca9853978b696cab99a0d633873e5f36f7e3faae37e24f8a27451604e9aca4a6d3549035e7a4e4527fead4920e658bd66d06509eda1841f843720016117ef0a66c52e26a12b719480cdb6055127a1601bb7110772341f1202e54ac90824 diff --git a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8_H5_W8.rsp b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8_H5_W8.rsp index 7e8dc7bd21..57f2155e3e 100644 --- a/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8_H5_W8.rsp +++ b/tests/KATs/sig_stfl/lms/LMS_SHA256_H5_W8_H5_W8.rsp @@ -1,5 +1,3 @@ -# LMS_SHA256_H5_W8_H5_W8 - msg = 54686520706f77657273206e6f742064656c65676174656420746f2074686520556e69746564205374617465732062792074686520436f6e737469747574696f6e2c206e6f722070726f6869626974656420627920697420746f20746865205374617465732c2061726520726573657276656420746f207468652053746174657320726573706563746976656c792c206f7220746f207468652070656f706c652e0a sm = 000000010000000500000004d32b56671d7eb98833c49b433c272586bc4a1c8a8970528ffa04b966f9426eb9965a25bfd37f196b9073f3d4a232feb69128ec45146f86292f9dff9610a7bf95a64c7f60f6261a62043f86c70324b7707f5b4a8a6e19c114c7be866d488778a0e05fd5c6509a6e61d559cf1a77a970de927d60c70d3de31a7fa0100994e162a2582e8ff1b10cd99d4e8e413ef469559f7d7ed12c838342f9b9c96b83a4943d1681d84b15357ff48ca579f19f5e71f18466f2bbef4bf660c2518eb20de2f66e3b14784269d7d876f5d35d3fbfc7039a462c716bb9f6891a7f41ad133e9e1f6d9560b960e7777c52f060492f2d7c660e1471e07e72655562035abc9a701b473ecbc3943c6b9c4f2405a3cb8bf8a691ca51d3f6ad2f428bab6f3a30f55dd9625563f0a75ee390e385e3ae0b906961ecf41ae073a0590c2eb6204f44831c26dd768c35b167b28ce8dc988a3748255230cef99ebf14e730632f27414489808afab1d1e783ed04516de012498682212b07810579b250365941bcc98142da13609e9768aaf65de7620dabec29eb82a17fde35af15ad238c73f81bdb8dec2fc0e7f932701099762b37f43c4a3c20010a3d72e2f606be108d310e639f09ce7286800d9ef8a1a40281cc5a7ea98d2adc7c7400c2fe5a101552df4e3cccfd0cbf2ddf5dc6779cbbc68fee0c3efe4ec22b83a2caa3e48e0809a0a750b73ccdcf3c79e6580c154f8a58f7f24335eec5c5eb5e0cf01dcf4439424095fceb077f66ded5bec73b27c5b9f64a2a9af2f07c05e99e5cf80f00252e39db32f6c19674f190c9fbc506d826857713afd2ca6bb85cd8c107347552f30575a5417816ab4db3f603f2df56fbc413e7d0acd8bdd81352b2471fc1bc4f1ef296fea1220403466b1afe78b94f7ecf7cc62fb92be14f18c2192384ebceaf8801afdf947f698ce9c6ceb696ed70e9e87b0144417e8d7baf25eb5f70f09f016fc925b4db048ab8d8cb2a661ce3b57ada67571f5dd546fc22cb1f97e0ebd1a65926b1234fd04f171cf469c76b884cf3115cce6f792cc84e36da58960c5f1d760f32c12faef477e94c92eb75625b6a371efc72d60ca5e908b3a7dd69fef0249150e3eebdfed39cbdc3ce9704882a2072c75e13527b7a581a556168783dc1e97545e31865ddc46b3c957835da252bb7328d3ee2062445dfb85ef8c35f8e1f3371af34023cef626e0af1e0bc017351aae2ab8f5c612ead0b729a1d059d02bfe18efa971b7300e882360a93b025ff97e9e0eec0f3f3f13039a17f88b0cf808f488431606cb13f9241f40f44e537d302c64a4f1f4ab949b9feefadcb71ab50ef27d6d6ca8510f150c85fb525bf25703df7209b6066f09c37280d59128d2f0f637c7d7d7fad4ed1c1ea04e628d221e3d8db77b7c878c9411cafc5071a34a00f4cf07738912753dfce48f07576f0d4f94f42c6d76f7ce973e9367095ba7e9a3649b7f461d9f9ac1332a4d1044c96aefee67676401b64457c54d65fef6500c59cdfb69af7b6dddfcb0f086278dd8ad0686078dfb0f3f79cd893d314168648499898fbc0ced5f95b74e8ff14d735cdea968bee7400000005d8b8112f9200a5e50c4a262165bd342cd800b8496810bc716277435ac376728d129ac6eda839a6f357b5a04387c5ce97382a78f2a4372917eefcbf93f63bb59112f5dbe400bd49e4501e859f885bf0736e90a509b30a26bfac8c17b5991c157eb5971115aa39efd8d564a6b90282c3168af2d30ef89d51bf14654510a12b8a144cca1848cf7da59cc2b3d9d0692dd2a20ba3863480e25b1b85ee860c62bf51360000000500000004d2f14ff6346af964569f7d6cb880a1b66c5004917da6eafe4d9ef6c6407b3db0e5485b122d9ebe15cda93cfec582d7ab0000000a000000040703c491e7558b35011ece3592eaa5da4d918786771233e8353bc4f62323185c95cae05b899e35dffd717054706209988ebfdf6e37960bb5c38d7657e8bffeef9bc042da4b4525650485c66d0ce19b317587c6ba4bffcc428e25d08931e72dfb6a120c5612344258b85efdb7db1db9e1865a73caf96557eb39ed3e3f426933ac9eeddb03a1d2374af7bf77185577456237f9de2d60113c23f846df26fa942008a698994c0827d90e86d43e0df7f4bfcdb09b86a373b98288b7094ad81a0185ac100e4f2c5fc38c003c1ab6fea479eb2f5ebe48f584d7159b8ada03586e65ad9c969f6aecbfe44cf356888a7b15a3ff074f771760b26f9c04884ee1faa329fbf4e61af23aee7fa5d4d9a5dfcf43c4c26ce8aea2ce8a2990d7ba7b57108b47dabfbeadb2b25b3cacc1ac0cef346cbb90fb044beee4fac2603a442bdf7e507243b7319c9944b1586e899d431c7f91bcccc8690dbf59b28386b2315f3d36ef2eaa3cf30b2b51f48b71b003dfb08249484201043f65f5a3ef6bbd61ddfee81aca9ce60081262a00000480dcbc9a3da6fbef5c1c0a55e48a0e729f9184fcb1407c31529db268f6fe50032a363c9801306837fafabdf957fd97eafc80dbd165e435d0e2dfd836a28b354023924b6fb7e48bc0b3ed95eea64c2d402f4d734c8dc26f3ac591825daef01eae3c38e3328d00a77dc657034f287ccb0f0e1c9a7cbdc828f627205e4737b84b58376551d44c12c3c215c812a0970789c83de51d6ad787271963327f0a5fbb6b5907dec02c9a90934af5a1c63b72c82653605d1dcce51596b3c2b45696689f2eb382007497557692caac4d57b5de9f5569bc2ad0137fd47fb47e664fcb6db4971f5b3e07aceda9ac130e9f38182de994cff192ec0e82fd6d4cb7f3fe00812589b7a7ce515440456433016b84a59bec6619a1c6c0b37dd1450ed4f2d8b584410ceda8025f5d2d8dd0d2176fc1cf2cc06fa8c82bed4d944e71339ece780fd025bd41ec34ebff9d4270a3224e019fcb444474d482fd2dbe75efb20389cc10cd600abb54c47ede93e08c114edb04117d714dc1d525e11bed8756192f929d15462b939ff3f52f2252da2ed64d8fae88818b1efa2c7b08c8794fb1b214aa233db3162833141ea4383f1a6f120be1db82ce3630b3429114463157a64e91234d475e2f79cbf05e4db6a9407d72c6bff7d1198b5c4d6aad2831db61274993715a0182c7dc8089e32c8531deed4f7431c07c02195eba2ef91efb5613c37af7ae0c066babc69369700e1dd26eddc0d216c781d56e4ce47e3303fa73007ff7b949ef23be2aa4dbf25206fe45c20dd888395b2526391a724996a44156beac808212858792bf8e74cba49dee5e8812e019da87454bff9e847ed83db07af313743082f880a278f682c2bd0ad6887cb59f652e155987d61bbf6a88d36ee93b6072e6656d9ccbaae3d655852e38deb3a2dcf8058dc9fb6f2ab3d3b3539eb77b248a661091d05eb6e2f297774fe6053598457cc61908318de4b826f0fc86d4bb117d33e865aa805009cc2918d9c2f840c4da43a703ad9f5b5806163d7161696b5a0adc00000005d5c0d1bebb06048ed6fe2ef2c6cef305b3ed633941ebc8b3bec9738754cddd60e1920ada52f43d055b5031cee6192520d6a5115514851ce7fd448d4a39fae2ab2335b525f484e9b40d6a4a969394843bdcf6d14c48e8015e08ab92662c05c6e9f90b65a7a6201689999f32bfd368e5e3ec9cb70ac7b8399003f175c40885081a09ab3034911fe125631051df0408b3946b0bde790911e8978ba07dd56c73e7ee diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp index ea0bef3312..e48c4fed28 100644 --- a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_256.rsp @@ -1,5 +1,3 @@ -# XMSS-SHA2_10_256 - pk = 00000001B901B8D9332FE458EB6DE87AF74655D0B5AD936A66FDB6AC9D1B8CF25BB6DB8404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 0000000100000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94AB901B8D9332FE458EB6DE87AF74655D0B5AD936A66FDB6AC9D1B8CF25BB6DB8404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD09000000000001000000000000000000000000000000000000000000000000000000000000000000000000 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 2500 sm = 00000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA7010C534B0D4C6FFDF4DBFE00E72405EFE83BBCF19AA2030A8CB163808482B6376FF8CE01FB8090F4842896A1EA5E9282F35CACD245A4B9DE9FE84E9315851D68A72B3ECB9F440937C8BA4AC3F0429246CBC2777E8B92D84F4BA49FAB89465FCB0FC8017E582746F531B4697925154A22E2D6A0F1B81913438000C295153D7ADCA8F852C50D360F65F887479E9631A2CA30FE3AD92E7BF648643835F4F8CC081A6C951B83B77608A08C021821DA61962CFCC8E97D75441921D39C5AD537543EFBAF0345DC70826E6E950929570C72E51619600C58D932A72657B19AF163E0B8F7AAF2949A5EB26C517909E0E663E36753491182975206009107509DFFC898D308B903E84A8B29718BF7125397AFF5467D53CF8F36EB945B6B98D48E81C0174A0E03541D24369CF8EDDA4288FFA615D16FBC7355CFC0966BA9256E5B8A44DA95760DFB61301B10FD3E82436E267DB089773E43B984297D1E0D395DCC77FCFECCEFEBD4B80B3F241872EA251DA466CA6C5324346F4B5E6886654A86592641A8C32AC554261B2D9130462C976B039E593F873AD1712820FF3E723FE57F137751AB3CA8B5B20D28D1B9384DF1D710AC39FAF699989418B7856C2034C695A693ECC336EB472DE5049C743089529695B028F2F72BE0893E59169E9A2376C64BC5CCAC5482E5A6E9C88D710A3FF8F23C206B09D314BF50568228B1BACF1CE330D529BD3793D7C7CD9EC770C111D9681D6F1B97D908CBBD436444853FEB47F234D31F5E92B9E0465D67AC0FE48859126BEFA7F7D121A67C2C2970B37B8081B4E73C5A21A41F60160A61FAFBD48649A3D2032C1679A67F348E3E25275FCD9AF650937FEB0A30F25878CEED7D6CA693518B5A2F5418135EA9316EFFDECDB1DFFC9EE3A62EFF0E66F3D05BD9D5F8679B536BB6D39792B28DF2481A6EECB9BEE40B11A10D39A90EA1AAC47BF956FBFE9B0427B599B9BC024F326515E71615419423FEC3F19F621D49B6EED59F129A6B1411B7B1AFCF073095D57B03F25A16F946ED716BF705F567A151BE85B8E8195CC2F070BFD482702182B8A4A43ED942F6BD3CBF9DE7E8AEB17C41E1C009C94FF4A2050E3731088B75474B38DC52BADF53C7DCD3FB98D023649FC4799CE060ADDACEC7CD4E656074E631C1CB8AEF88EFEE0817C2E3D79E287F4510E48DFB7E23CB49D6FCA39A1E0F471F16A8BB65AF02150D059036D00386DD287BEA4D52FB263B57AE5ADD901CADE838B1D7347D9E47EAF6456148C6C4E44B0FA3DFCF5C9CEC2D80AD509A65AEF0E3E663B7F31BCA437311BA799D4C2ACC138F85D73CB40792FF03F8F20427D951444990CA3976A71368A7DC1455E880722F06F02163BC712E852A914F22E5675EB9B1C6C8B7FD20A8880AD2EEF97982C065C937BD3639357E4C7450CBDA0B51CCA8E3E078DC760FD99EBF646B82369576539B2BD5B2C866ED5AE94423A5CE18C685352398D01C983F080D7BEB8A9243AAA9AC1DDCC1B058B92BEAD301E8F3B8F5EF71EEE7966302B44D2E26D2A02393713E5D4D3FEF42196FAA368274C78C2932D22840ECA6018CE7D16B19A0727CB1966EB28B57D137C5264CC2E627F24A3BAD50EA4F75C7BD8998709C01ED5ACFFF0891934E94DA2CACCA212FB48BE3F9EAA310547E73C388D881F36AE21EFEDD23744F6B07C5D6D2776C191ED41E607316F61BBEF7A20E1A03150AE833D18952AE35188FBFDFA55C12A388836717BB2BDD97E89121C56C3B53E8198242315C9E438512E0C8354A3E599CB7217AE688647A72985606BBD0720F6FA5C5B6F70E88234EE54C6DB0A41106C866564650829FE4B232635B06B18240C9F86369C75B2F7D237211A380C43F95D362E0680D9EA2CA47E1DC8C49703E22650B765F847AD86BE25A3B7630D640A0097632DF13F600E8A025DD9A1FC67B0EB09C1CA9FA3923896927DEE1E3CC0C81F4B82E43B89CACC69C9B8ADCA1670F7D4E50DB7BCD94C2115E75F2BFD2336DA5A304D0F3455927360BF5040E95D1454106F2A8A7CD27D5510E7B5BE7B5B9EDEFDC3D4249D655C51F4C1DBA0F359BE4769AB66EDBC802824E9AB866E8EEAA2FEB1CC855F0A745AAC84A610DF0238112C6519F8E7346C45331A6036F84D5B6250F4B5BC0A2A6A31DAF9C60EB13C20CC649A18E27A6C98B82F08E21706A8BDF338CC69C1679D25ECFF733A721211C1F6DD28091AAA9C93B047EFCD2C8A55F2DA65E616F07DCC0F44081D4E359C1688A00F062EC925D24432862B547BB70F2AF126A3DABA5C918B224DE444B8733E6FA601B3D349307E94583D0EC976AEDA2B90972324B3ACE8C7B79A67723AEA037E12DA9EFA9CA9668A4F5FDADFB9EEE13398921F5023E354A6894825431DBA7317E6A6F69F0E77294BCD02D7616E75AC31EC528FC070B8C34027C4E9CD0672903412FCA6B723650D56AF562069312FC7EF1891A77E1A3F29D810C205EE212E75863F3B8B1ED216DF888ADD07AFF45F1B5C01196329311414797CD5F67FFC54AAD04C803FF7E83C2E8BA224CE83695BB7916AC42B1861F5CB527FDBCD82DBFA31C5ACF981D8414203837504263C96A0015841FBCC721F96D50A86D6E096AB54AF9980F06CEE6341C78D6583F6BAE8081B3C44B0F10FB7300874B5011FF0F97C52F975A31355884C2F12B6FFEE20E8371D38183C9D04977BFA037C9BD4DD7F7CE203FD7FAD3852B3C2AE9D078ADEC70DB1A7140EF1114EBB03E8DE03237E0A27FF510015AC76FCEFE4EBD4C3A1B6C67DB2A82FE2B1BF18723DB0F29FE4AD47B2EEF22AC3C6661CFA7DA7476D23B470FA2E0441B6473EBD291791F09B4ADA70A5286EB05167BD59BFD8C46427413D60692382EFB7882F60DC53AAAFDF2014CA7D27F8FA93C187A8371B41796557AE739912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70D3DB184EABED83E30C11C9BC62F3340923A0082B987EC45CC7BD1DB4B2B15E8AD3EAD74E96D8C20D85617BBEDC0BDAF8ED48B7EE8D7C42990028EC0669AFC0861C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A remain = 1022 -max = 1023 \ No newline at end of file +max = 1023 diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_512.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_512.rsp index c56266bf30..4c5d3081f7 100644 --- a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_512.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_10_512.rsp @@ -1,5 +1,3 @@ -# XMSS-SHA2_10_512 - pk = 00000004E219A0AAB2C8F4054939A56A419E39D2B91371C6A2A485B21D749DC399E0E58275A69ED6A400A7C1EA5A7B4EEFF0DB2A7E742C062A847DDBA24680388DDDBFC14D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE sk = 0000000400000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A4E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FDE028B6F5724BB039F3652AD98DF8CE6C97013210B84BBE81388C3D141D61957CE219A0AAB2C8F4054939A56A419E39D2B91371C6A2A485B21D749DC399E0E58275A69ED6A400A7C1EA5A7B4EEFF0DB2A7E742C062A847DDBA24680388DDDBFC14D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA7662A4DC4B05165A87B8D0064114CD7836FBF0E8816843C48A8FCADBB6A7FB88801F98928A5E5B90C63DEC0EA0FA3395D402190BCAD7718FF534030A15444CF7658E15BFE22A447F3E23F7CD3B21642364F858C75968120262406989789AA6381C6C7535C2EF461B882A555A1BB43239564EBA5E7450722069495EAF1D3A396C45CA714A94B1C38E13E94E14249A8CBAEEDD0EB6A1F867221D94D164CF5D47DB5C759708AE19D193AC01ED5DD678BBEC27E908CE04E5F45B13648FEBCF66AD7181BE682028A9F3C137E962B292AE5A1D8A661085461D378100FFBD3737C4FB6B436A85B851F5F823A0BFA2F981E2C0379C626F2F813B3CA1708CD9D844A8044A917DB24EAD379D5A34E90E3546AC2D9121365D162CAF65B3DEEF566ECCDB449B1CB773057B21BE4F54E6036E1923FC486AAA69AF01CE1E29A3C89F78DF91A71F1145A92FB5C12BBB2D4E43210A60286263F56951307B13956F7BC1EFDEF3C8194B815692D4B71BB74DEC510CB396F1D903FB30BF8FA8D845915B74A537CEC2F5BD6CACC6E0896A10B7FDAA6D1412CF1B29A2669A3BFBED70CC9A6D3F8E782C5AF72DC54E3D1EA0F88BF2BE93E0EB4479DA07ECDC18885ED58D555F8BE63A483C6E20A875928081C31DC62E49E550D608A6EE22480FEBEC0A3DB64056A63C772DD0C14B1D2A8EDFC0D3A799B008B5D7C63D42D1848C06F43A974DBDB5334F237E6C21481E12170947B7CF9EA5E81D7400F79936FB292C1E1910F016AE190BC1514559E027FBD2C85DDB78A3230443DF8D1F35FCDC73FB189353361C7A4C819D3FFFA3CE11E6237664C8FBD8D0AF7AEC9C2C47D0DF15B588773520C10E0285F00299584CC25D5BD18DDE6DACD091C1CCB8318F830C6051D181AA29F3863B0859000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B589FD94AB5C37762EFFA44AC2093812248300D072E964594FDE1E5EBC7987B59EC36D4C0C120E76872FB77366F2C5B18B86B9139DF28EF7D44E32FECC4C804F010000000000016B410B4BEEFE73CB8F4D4C3ABB7DF62F132C01D90F410AE51281E0C5172FC3762D01221D015C100F93020CD106AB5DC052522C419A0FD67AD1A5EE9D5FD62E180200000000000121D1E9B1C034C0E95BEA3582EBC57F8383D0F6D1DA068D3ADB5B2B6237AADEE9A89B9F772A990889B143707CDEFCD05608317F599099BCDD2EDCA4B7CF410EB403000000000001C23E183353CD7FB42309F34D450892A84D2E250627D82E72E4A582BFCA8BAD10D4F5A2CBC313BC02333F65E8FC8BAB87A19EDD304EC7F7F85AC8078CFA3ABEE7040000000000011E2BAE00E2D34A2B2CF6745FBEF9D552837C3DC63720847E7DE3094B58785B6043AC7DA8CCBB7CB127C7B0C7A974607349D30D61CD7F08BBE092A3F9C7BD0FBC05000000000001657D3C7D66C12770C0BB75D4F5214C4B194F841F23B240ED784A12295B734A173AE89D8EDD857516ABFACE192FED90D2CBF6254B4DF0CD8C0D3F7CE520B0FAA5060000000000014567D4BD416073A25CDF242C18DBEA42908A4D6F0F15266EFF60569D4C458758BFEC8027BDB07730ED08E3A23D0540D8B90A140E06A28CBB64891316084D93FF070000000000017B8C7C4EBC5F897F112AAAD0FE18AB8CE4360565BAECD1075FED846955A14048C88B6B5C1A065F92AF55BFCBB10C7C46B114C80E9A36CC3BE6A245F466351B7D080000000000011F81CA34F234A41958ACAC3BE7C53450FCCB7E4D785F18C94981FC721F4CFB851AB0550BEE14A4DDC57D2A9EA06065395660BF32D43B71FCE388DC6F33795910090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 9092 sm = 000000006686539E267711CC53D8B185DE1BEA3A8484A81CDD6B6B0E46CD6568189E74C033347FA34BA7448CD4D56964F49F730BDE52ED29F39B1CAE52DBEDC90A0941564695221F5431496845B1E75D26B6B857E2611A6451456AE84936147AFFC7C7B2D2C1E333FACC759EBED3AEFBCB300486A32BB292A7F5331B29C4CA9D53EA76525BF71D5A3E48FC845FBFC5425860C9A12823F207A63C137A2F354B763989905F589D19E88325E04DAB387A43728A4F541C50FD01DCC2A7D84C6F18B6E97EBAB3CC292356AED4291FD4B69C3D557CC1FCD2964C9CC149D630EA9C2E77275C448894615FBD360F62B0E244B1C000F1975FA615DD6A6DD56929E69F80F1086F533631B97B3061C60CB3CCFAAA690EC0F4D9C3A99567C975C87A589881F548C5F1BD93EC0217C975EB40B2A715F44E2A70068D27B8EB36A6BEFF81E312438EEE5813EF919C7FDFE95C078BE095A07A41E468AC98C8AA215C6C976DC94AA462B2DD38EB434E35A03CB016FA3DC81C1D8E91E41FC43F71CA3BFFF5B5ED792DDF10BF542E2E0161113497B31AE7D795C0B9DFFB62E809F587779B6FD7B1DDCB38EF48A449BE87FFF3D39854CB01E9F97B36ADDD4B2D8C4562C45AE61E527AD277EFAFAA5E69FD57EEAC4828EE99DBE12234E48A253102FA3FE6298ED6FB7572BA4FCE73F55E90CBD9F6F0D111DAE055BE32913F0275722C5EF30C2A1E10D6D6A783C2AA2838C5A6192CB37077B5A1AD2074C2A24F21854C91973F186FCEEBB536B6EF677311DDDDABCC839947F681ED60691910FE67C017A449B91D4F2BB342A9CC5DBD62C2EAD8B2DE02150CD5B0D3327B7D2BEED3415167D54F73AE24BAB4BF906C1A056A1392B078CB74664CAE461FAACAF60FD0C6A7925CEDC5FE1DA590D0C52CA558F6750C7A75A8F66C221421F154A3A0DB9542AB5555890176CE1345DB286997894FC57EB5C2C3EBA0A4C6E8C9D7C637C56B034057C364C66F3EEC2C6DBAC1080BE9C26B16610D007F303C4B9B7A329D17000CFF3853EA3F9D56A5315BEB2313265CE888B790F4F6E16E53F6A75DD689FC246F6E9675748F56FC883F850EBF452AB50D70A21F6ACA9CBE83C7452B8A05EEC284B49CB92A4FFD1ABC8FFA72CD41273B4D0A0E91DBB3B321F507274EC896231A24B3CA654405654E449EC9F0ABF7FE8182F7098A6DFDD2889BDBECE91F5E86CEBE4CEBF8EF098C05A5895040E89A2D24730373D42A05DFC4E9DEFFDEC1BE8EB34AD922C94F80075F0BC540B1587AA961E1B668789484624BB34E0F1D2C6E163EE3DAD3E9D8A608F267D2BF7CD4CA356915B3792EC7B2956CB5335E1630ABC7EA438C7131FBA2BF91E4E7E0E54D3DE82934C2A711F4DAEF7D4EA9062E659449D207EE702945ACBA58A9DE4B8E9514A130561352A04B1923DA060D90B0EB3C654C540507F745F0F24065FFB8D76C0C5B326DA7C300F3E2BDC6DBB570C85850C88E0996753DB70B1C9201593B3A8E6ABC9D581604EA41D9C7109959DB8E8882265C7F8D12F24702F9BDB9BB4AF388C55C02FB49B4FAEFB98A25886B558D4C3492048BA4DABB55680D5F5BAFC70BC02492283183BEA8127ECDCE84EBF441C8AEB01082D07CFA9DA4C9034C8F4A509FAACED436450317A7DB7DAA434D927BEBD2AAF917B2E6D434511237E31A7B04E7F3E6C5FA38087E274E5B6BDB334F9D9F6ADE18AA9065FF72F09CDAE4B3BE7FB1CA862C78B0B8A9B8031297629CE35DAD8281075CD7D250557ECC3581AC93F62001020264F8E93FBA0FC322245747EC7076288748AC8D13F18AC5A3AF4884FAE075042FB85CF3C0DD3449575E0066021BE65428A2976BDE033407039D548D9EB6DA7D02B2CD6556B12362140950B80E378D44E4B1AF627BF715B7F36083F6B899B4D09FD639E47CB04541E6A306894AD18BFDE42AFD2BDBF2B61A78E98DB066BE125999FD687A324F16E0452119E9B7085799DB594891A9D631EB4A955B5B0F4F4773C19006EB10BA46D8445640074FECBB51649B6FE90BC1C63503018A37400CD476CB166A6A2782EE1680495B2E11F5EC5BFFA5FF196C739CFDDF7430331E71CC5686366E753DCE01F186ECF2AA9CC1BF911670165C06319EECA4D406145735FBAB797A794C3C58E998827A076E23DDCF473ABAA62E2C5BDDC6DDF55DA550BFFC23BC4895F223F904064AFFD5D5E61A7B64E29E3FAE23CD6FD9619795A1314587D124F3FCAF3569206484848932025D8F638102A4F25644DC1F62F13AA1262C5C55679AFE8E1F7BF340ADAEFD97221D46FBB8702B2BB5EBA511066C8E9F159F52431ADAFEDABB476DFB8E836F153B08F3BD4643B9FCA0A954DCAEB7194661EE8EEB97781695D64EFFE2301189B28BD7C2F9E64C32E263C99C6BD804AEDB9127A60EC8489973F99C782D062679F3F604ECDF2460383BC369DE103D0736DF1A0868D6037F68F091E0C741442DF88E14E8EA615F5E8646A68EE301E551849F580EA63BCEF034B847C47B373602465E6FBAECB948374A3D64410717B19A240DB023B16B6BB0B7BCF1D63987106F171B53DEFCA63A7E0652FEAD5584FD17F54F50AF85E1D87FFE5CA116AE1664CC9AD25B327362D9857CCF6169BCFF97A95B1583B8E20B7BFA4814BF5D82F00F07961107B6063E8CCD453E1A622A7BDE9C4C6B97BA3A41057AF2D7098CD4E829C34A80AE24846D8BC92BD7489B854831DC7A4956D010988AC9B2135917188810FE4D94FEFDC59F6954EA289C444813ADEDA9CB435B6C470C0037C21024FF67B7B7031E87D8F8774CD6BC926318982544BD6FE38C09893B929C9F8B7487D51614D1FBCCEDA56C1794C943A36E54225B729D63855471F2AA9A514D567F61B9E9B4AD4A327E6B113CAF5C0A22D26F74A507B0EC1A67965F0978C608B70E7F6D1646E7F89D2E70EEE62852C69618ED8AA136DB1E75D4A687A62443A82802EB270F1C91E97074F3A12C63FDF3BABEF882F934B4BD0C2468C66B1C6E37F8CDA8FFCCFE109FB291FF10163AAD73721CDB57A5E2CE8CC41467CBB125E3B525185F8ECB34C4F4675220CD92836BE2E420F24BE023F22594B5E3F5AF06CE056C8EDFC67B49808AA9643FB1160DB9D455C38071F49555D3FE9A7890DCA5E2047BF23E904D07641140BE0142DC90069A86D98A280D45A88C7E54B6B0660656A5C40018C9AA955F5CA9F10A10005C735C90F5B2941043AC88271B241AF7EF66218B4B74E41579BF64C812F9502DBAD602FC7894000F3ED41946FB81DBA9DCCD666125E9A4A5AA7DA1B8E5B8347E1964D36F6D0ACCAFC14DD8B5DF301A3768F5EC7924982E1B57D37D019914A01EA0B7B1652EBA5C15A6843CE712C34A1AA8842DCC9FA570A6883857EB260BDF01EFDD4F233551D18F89B585993A92A3DE64CA9A0EEB74A7D91DB9E0FF5FE1E035C97EB8CBBC796E22302FACDFF89231FA3F77E72EE189894071B376D0113BAC1EA0911D3A5E24D638CF8BF0C8B92B0A321B7E4557CF465B88102F98645EA37E58DC6664DFAF870E024A4D9E84C8B913EB467D8252BBC8F86818EB2F9D03EC70B4342CEA881278C516382DC79E27B4EBA9879AF2DFEA6CB914AA98593C52CC7857A877371F871CEC175AA5E72285023F1A59BB072D9B2912D974A26B4B57A6B772F9CD7334A3A66DA86DCED932119C5D57106FFDC51D4B7E10B6E94C343A90C9C15D078E9D5A66BA252695CB27377607E0968C93D529E02EA881A2AD58DB81863B0FAE8B45252AA6F742E04D310D82FE58B7E6BF2D0BF8A7D714F7352BFBFC3EFBE050F75E60222CD694496EBA04C85B7DA12A33ECF4325A392ABD40458D087DBC638BC65270E6E7E5719F14AC7721541610F2724EFA0473CC320023013DF549C8DBBD5F5691450E04C26202F5666F5130154012204FBD584E84D821EBA36CD2FCDCAE1C4BBE8BE5C9AB1983526743838548D107810E014FED68387355106C3B39A9539F2C24D318DD5F1B0715E853E168C809BCE684671411C783A766B7307675CA4D04B0DD86442B1744ED1B8EE018F83D9D68B4FCAECC66FDEE75EAC379E19D0DBED5C3473089EF153433ED2B5587C22C3299898850F7A872BCD7A064A7F8211AEB8175668B1402E79729AFE8F4EBB2F147DEABD1E0234E5056F5D1DA522752639E200C12C166D5A442071F190DEE7670941E2F0C59C05F1F1EE8C6449EC731082CF56CE8DFC8DBABC019420CEB0975CC90E59F165B156FDDE09152FA049386C57EBC64DBF0ED92181C6605B0EC442B5CC242DA32C1716B2FCAB0F64F6C94E7E8053CFFA1B5329D7DB924DF329BD3AAC38A29DBEE3454E1FE3D79A6EA6877DE61518DB7D79BE808BF2D6D12AE400E94866A8E27D2F4FC70D9CB443F8DCA23113E32C1497EB0E61AA22594817739E8F954A39CDE8B6B1A543CBD65286E2DDCBD0F5FA3A6A28B28036210ACABD9EEDF4B006B94DF3631B68A824824162C1A3A1E3288924B834F21568605AD9543CF93919467A90E61C49F5EF5EC30DF4FFA1EF2C8CF59A7EFA1446238D9E23C3B5A42809BEC365038F526DC24D81AC1DCEAA429678B3A019C12A772B3AB24DF707A1E9D83FEFAC76668A9E234FDFE197101FA2F74EE80C9F0CB50CE2EA40A19D618EB82699E032B417810765366BB2DCCC2B41081699F01563DF24D65E6FE0142E9AFBEC6366C1C027864ED04D3C3F1EABCD974A2C842C640E46024FCBC33B5C94494AE26FD0CCDE2A62DCB2C63D22AE6F0CC2D107C78B1C4B0E54CBE78573B38785A0CF94839C6DDB6218C234CD351F3813E119DC05765C450DAFD64BEB915E7BC6D09FF6B756949615CFEB5518F19A7FFD3C36078FD18CF782D5FBFA41AA86ABF35E16079E71886A63077763203439B75DFE4E5CE50F97EFC93030C80ADA63754D8096271224D1EB627E3FDE3F54E2D566535C5D33F2485E686D4B56B0C674BC5D6EB60C81488344A32BFB02FF5A309FC45088769B98930C32B2A9F269EB83E3AA3E0CB0FAFEACC1EE2BB5366C6787E89D46155687639CC5B02EC4681977761B43191E5402CBFFA0573D63041029C7D14F33BB2BA687208F18A91AA8E22AAD4E86CE927DEEE97256EC3CA81B71738B4BCCF072234047F5B32E44D030FEF18D9509CFEF94B447ABA3CF4878DCF9C0FBDE9DD7738D91D5AE94D1583504292E5495945E3CB6B202674261F4D1911468E9C95B6BAA96FDE0EBE07EEB47C5BF9ADCFE3A276F79C84CFE48D3A5A9A2BFB656C8A9A87B76A602508018DFEC14EA398A05022C87D8FC0969EC627F4FFAEB1F8242D31B82CBBB11B4959307B3D5DD0376F3E7AA40FAD8E2FF8DBF5D0AC1C9F90405B943879D5633041A05942A6BF60B89DD7ED5BC14F1C1658C4CF226DFED57C8AC5C825BF5409BDC051F8C83506164836662C94CCB33EB665E90735DA8132850BC22BCEAA581A42D97E45884C03CBDA6113587454CEFB86EB828BE506E20FFD3A4BD3F0BEEE7239FB57CB8EFFE15B421A049D5A654EDFB06F17EF56BEB8B7E9F0FF2FFE632AC59DEF87DFD32129479284462B108D604B665EFEC0D25ACC19CFD6EB6356E7CE960EE78553A56D622D3B2838F49510940221E87EA2B308F4DA54915B3D61C95500A3073A2E4B9B34DF59C8111CFC5F6E03B86E339C806CC0A4128A7E47F6340737C8A3004A2626E544CAEAEBAED62EA3C45801ED8711715D6B0A85A4C005CC39629D894C1C590BEA60BF5AB5B02A9B76728A6E7F72F7C746265D51FA1771ED9D2FFA4184D4EE985BB95235DED9FC782DBACB8AE478797CA856EE48A24941059B4CABAE9D48E1C4AB18F419EA94224485ED860D056AE7D5D0D00E9AC97470A30D805CC2176895F3F80F1D8EB9F914C6F86C6E870EDD24F0AB9D0D1BC03B4A6CFE770CAFC641B4BE6222CABB3BF68DA88AE2822BC27255ECB02085C7E19C4BAFDBE27C05FEA7B8E3AEF255164A84697D9C7E4E540C01F6FFD4E7566922FED1EB49DFB029E350CAB96EEAA30567500EE1C5C04FFE0F2564098798446351894219168368642ABA593001A47584DF43742D652659CCC1F1BA0FE7C21797859AD752423033EC5871F5A1703D0504E20B458677C4C4740D9181951412512D0C0B5A32AB9C33BA1C9AD9CCC303021ADAC2091500382D42149A0AE666ED8CB8DA412E52D2FBA633AE5525EA0FE81DF7FFD071C39EA7AD445C01F9B0847226C84973B024F3A69AA22D64F477E130DCA563037B7CDE81B11498EBA5850B5C31E2873EC2A4423741EB539B66580DA833E487A3ECDD6EE957143534C156407EBACD74408888066EFBBD69441277EC843C45B39B3E0B6E2F936D2F8EF15F45075982618BA5F983806E7919BD4D59582282C16AF1221980B5510A38DBA62A587F6D80F4080ECF7819B5EC949B2856FD2AF0DE295274718D859D64FFB280C63546D27C98873505F49D23DA88DF5E3052769C28FDCD40E0FF72893DA4244E492FC2EC940D407344A1A4EDAC677EFDAA1582772990C3DCD904B3104569F93989FC13FEF43F344AF7C75621FC14C448FB778D681F506671E5D03D24016424B2BF10CBDD9495E7352F040A48F46FB33690DE20A30C0ACCCED872430F7A277B4278BC83939E90B07B4B548E4D541491EB8B997C17825EAF3DAAE1F5E308099617F30955E3EE32AB8B029A6D72EA42A2FCF33077620AD4FC58CF7DDE2BE8D6A62B9466291BC7286096F14E8BD2D11C73AF7D92D2CD31DF9C18307AF432E933635CA06153A8DC47870BF5FE0183AA8AF5687D01A8DEC21957E57EA27DD4BA80ADFB48B2ADE869BD76D11BB4FAC2A74984397FC8D65E641A8A0DEE95CDE25AAA04EA13D3007A031F80AB9AFC73BB27C60F256407715DA96071C8197A8663CDE5DC9990FB29A1EC9AAEE667BE58C4EF1017534D07C1CF9028754AADC687D760D6410AA1FE5E2A6A4C35CA7EF3BB3E5B4DEF14FFD7903AE3570175C4C75E65C09DDB262724AEB97ED9735CDE139B74ACA9A5D7B1463D6BDD900E73E8D1AA1AE534AEDC0B0ADC0634D6AA682AAA4C8FC2EBFB97E98478FD918AD4B24B4CAA246D328187047E8958756BB05E80E4CAFAC794BA6824CFB30EB09EC7786BA7CBDC468A7ABD66F6D7D62570D7B2CE612D4A781663D2FB9C5BA533F6931FDF374D77681CDBB92B2E0ACE313023857010DB8E401FB36365BCC03E91E78F4959A0BA59348BE988805AC9585172CB1AC5749644900832A67D493F54E0D898E7606276073226B5FA8036437067D193C744C0115F5C71E345A48F96A4A7B10E58D79B9A0EA10C545DA202CDA1B4AF08A968B218E5C43AB295740FA5D36D9B611932B9E0682A1EE6D5DBE228FE90E9C7E169748261E1C566EC82308884DB143C3A8F199B814F706CE6F7C612B26EC1A01ACD713CF758C1682D15262280F0CE056A2FE81D6A4965B6E66CC8CB01C7193C9AB5B17159724D0917AE84C28BA3525DBA96691397BD9238483AA3DDA24C3334AE22EC9A47FE426B3B08640E6B6347CA91AA4384D1B27B323C8C9B363A162D27BBAFB8EF81CDC90B309DE38FAD663F00C0343A8D8FDBFE6F3455BD288987C3443AF79DE32D86735339B9828478BF5887471663B2D20CDB0C92D87F27833CF08D628DC834210CD7A9C852B58C14B894E24C21B380A1E44937B6E831CF0DB2BF88799A2532A3383C755EACF3970ABA6EFAE0D5825B7DF122F6A7B536CCEFFD000C2E61A519412B6C60966D4ADD9DE24F94F771348E043EBD2A25599CD72233B9744EA63F6C94424A4AFDC10B30EB857E423C4B19D41CEF442432E433A6AF71629EDB05E7809FC011FE3DF16FC6A56B83AF09EC0169A6D17B318C27BB074DFDF0C4D817679551F0080E7A8D1D9101B63FDDDDB2D1CDE21770CCE0A0EA5ED402AFE65311A48249D2A49D44C10B7CFDAC28583C67CB6430DF02EE9F84E430C88522CF1016242CD0677EB43F077842B5267A638C551AEA6931D182D2D3C631598B247FF93964C59B0EABB99C4C9941E641B0023B8AA5F3F93C17FD684B3F18996E30FBB8D3D7798C37BACE0F096F04BF1CC4446549B49931107D2F86C66638AFBCCB22CE50D7390CD38311EF7A9D50734A7021D872B87E8B60AAD96B0F12748F7BF4EF8C9BFB515A5B017191E9079956DDEFF3CF016DAE35C99D3FBB755BB3A79E69EA78F4576B9E05F35DD7CBCBFF369822B9322BA2B05337A17930AF87975EF0CD380B920CA86B6C4B7C4238A59F6F03E8AD55EF1E6AE8FB04663D7327FAFF924E6EE53476C449AB25A236C98523A7067A93EA0C54EE9468B9F79DE251D99A95C1AC1D7C78B56FDC43369418DE381B78CC9C9E478E64D904391F368A188444E80F3C001BDC93459ABFAC1E229C7905DB266ACE93C2AC4614AC777663E448EF8DB336AF6A937CA13E325A2043BA5514C3AF9CCBFFEF3FF635658808CCC58E2FD1CA58802FFC72E386E777328A79D163298E1DD66603E0396DE534A4AD7D3A19C117E7873777EC8735A910E4177B0442D9294C4EAE3246E87B95F437335AD6930D4D1D6547065756BEC9EF32188FCD42043BE04249D920335B6E34D944AEF7C542F18333280557DE060C94CC2F93079741811FBA2930F038CD4941BEB47984CF3DB2F3E721AC15B1AC979CD933EBE8EE073D129888C9B871C87303889897A8B9FAE58999AE9574C53F3C024F9E1587DF95A820B3886A4DE641EEA0C2A17DC347CB16ED3D4BA5BDF45EED7222F6714DDB16F4343AB65FE27E27A47D18D82CF8003332F59DF37976DDB719AB48035169C6AF53DD2EDFAFD2512CE3B73D53859455B456D756CBDBC3EA9E1E869EE96002CAA7EB6ADD8D9C0201AC3E88332A531D509A861A95BF04F0EC5867AE4CDC1B5B0A056DA596BDA426545829EB5C2773AE19951D346A9C62DD6EF1C031A4D659FEE60472619BC1DEF82F9183B7D776F5FE30F625CB1F41054C522E4B983013203D7F55294B79C878B069A9A86E195CE477B71B53EC98B482F5072F9B442C32316CE3E6CCE64D0AB79197D439D4169FD36BA3A30A9F150821821B395695B7179D8937B264A6AE4506A9599F73998967C824F444CEEBBFE3CB587412FE39C3F5F88CCA164CD050EDF18CEE52BF1FDC4B33A2A347E82720B49707737278348DCB509A488823BD2907C60F0465CD2710DD0041B53BE0D1EEDEE5C6F39A02226BDC3FA56409AA98990C1D6E62C324797D910C79AC06DF3D956CF6788EEF1F70B267348C0E5C88645059E631E17EBED5D365A0C16BFABD6FB9DB2BF9FC078C7DF6187EF616E236D4DDC816332D10DFAD1601979D4CD14EF177FDC5D93DDCE075E0CF0081E5EE900E00B5B58820BF0FA5BCE0FD9CA38C6E2CDC456376DC2326E99DACD54592756C2A5F651131C084ED369C94654F44669E1A950F16FEB85EA106F752BFFE23AC4B089F37A07D3DF7CED35602F57DA407F9D60DA3B2D110005D0C27927967B61A3D3B16F4F0AF9EA887D9CC9FD812132E60254F1B3AD778202696F7084388AFB30AF25D61DE9B7CD3D53044524A832BE78D058A68B17BDC981D4773C5FDE404362A368272CDF08070EB738D7AEF2B8B5519BD005BA5140E230C2AE07A24C4FC0B22579FF144DAD576466D6CF76C2CF3C663F5E8E1F423C2F516954B1888096333826079EC2743C737824220E68221A15AC03DBABD6B73BBD6565D9B3B2FAD2D107ADA8759030253C4B7EE6721FE96850B07E962322F6D47BE10711FDCEF278DA39B6588EB45FEA241875C0BAD85FEBF38FAE94358BBC673D57138D1B09437F963C20A764DC35D73FD7CA0CE1B44F28E4FD2731FDB75B9E3001E63A4623811141747F410903ABF5A914DBC9D60ED5C3E59443D569DD33181B33869F1E00ADB57C61FF5F74E5F3F8C0AB974F7D5E9AED105E35DC112F50FF03461C19E2E456FFA22C3DA25491396837FE35064CD5AC5F8BC453E0E86736CDBCD997913BA652B281B814278F7772ADC3081EFAEDF51946AE741AE63D3863CBDDF78A900AE829F97F63B4155EAF0B245843A5962C62707A5B57157747BB6D20054DC9A49D0AC4D1E5EDAD0FE3303055B8667D773DDB4DF9B72F6FE2E2FA58C2E7A4C3D6C9053AC3C4B7E4E80A54AF105F88AFB441106E38D3143B7AF5B70447D1F96AE8FBC7CA4D7FF9764252125C2739963273D2E139640DE66F878AC3793DAECE33FB1D05338FDFAC98E051D2613FD4A4817ED459FA7B05CCD6C90A6110AD8A01AD594EFB2FC2DAC88AD30737A55C475149505C341E9D77B3562DB46347DFFD2A9DB8A68124026D9E9D9A9997AF40D70D3A922DF54D52845B387DD8C2E4623CD85659FA7F25ED157C79337C99BD9173FEEC9D14B0C8D18881BE0BD2D639A7D2F3BC5628F9574E923D74489CA281CCAB138B54F75870855923206B9E8BCFB6B41F46B7953E3BDA5A8E8A233865593A41F393C05594FEF6AAD0D21D6969BACD767AF83E2C05A524E0C5B2EFC01609C5F7AFDF6A2CD90BDD871475B703544AE98A4DDF412084B0A8CAA4321007D12DA982338FB3311238E26C35F2D5C7EED3E4BD6F5F932C42E0A790B17BC5C974BE06113B70D9B34D7BEF5B5D37662A698F8AFD529A703EF92686C27018828D114A1DA99492698BF66F2A801E8C97BE82786B458429DBF7FC1D90390B438E6B91D021FE8DCE180BD28F5204F373CF45BBA390AB9E3977FAC6AA1B680C49832F7FB649EAEB80058FCBD1E4E67B7F4A065E7D80CFD90146B2D0BFEF64ED0AC34E4FB1AC2F1CDD51D1A3A10F99AFA145CF94E374929C139BB64D5B143C1FDAF309B15BA0A57686F2BECF7FF886CBAB80A3886D94B2C99BA026E1963C6CDA0E50D4242A4F78D4C93C171F47A8457FCD3BFDA4CFABD771E41015EF13D6479E6FAA1EE63BA568E7DFFCC7DDD98EBFF25C16C53DDD3122E1F33C3A18C6D4081076324D50EEC28549F3EFF9007726BD7CAA24004C778BDA91B88DE6175CA3A9D26C0074F3ECBD8A5E980B41CD46E571E1A462596816A711E816DAA1F373FBEBC98461A05E47E3C082FE88DC300C95AB4112CDA18BB7956FD530E68CD8C916457ED0CE6734CF72560A8B675C0AC8AEE7DF585994E5FCCE96917E2E034E07D6EF7114C74BE2F799EB98D1BC78725FDF26AB22CB9FB25FDDF7F8A7B122827564563E400EFC7FFE34602E577EE0427892BE8D5EC42BB4764C4CDC0C779FC057F7CF8411CD966F45ADEE37853B3C988DD739FFB5126C760323D83AE1AA97D979D9DB3080033208B5DA3CDF7D98445D336949B28BBB27C282F9B0779FF04AF813E5DD203E0EB21C32D9CF2B825F150E853D4906C960CB624EF33820290DBAE1EBE78E60888DAA2D72B865EA952BD21DD234513019551BE865506BEC1513A187682186BD5C482ADCF0AADEEB83D05601CD570CF0E406E94F557A3F8DE99EE903CFBBDBF2C50B3A33FD6BE722804D2D64FB91D6EBDF5BD762D78C86D1AC2976A85CCFEE7CB3CA718E706C41AC8BB41BFC2888AF84E7E3A6088087D669098AF90EA6D92E9BBBB37EC26C1C9A705B11C71A442D32ED65BE2D79FA73C2F99690A21A627891F2BE7FCF340477AFE57A6FA2E827D05FDB3A4AF6A49388FC062D7F24FFBAF8AF61503124D79EF179D32CB6F717B854F11B401908C700B8E4A38337C3E76C33525A93525845C614F39C5B7310BD07A88D7FA99558DB3292B3B5036F85A046FA38B040544ABE58C8DDE9F86362D03557FBECDE436683C5BBCD58A497AC07F7E7F3B62B2AA8BBABE4250F4C418DDA374DE6988F843B7F71517B385A9A1CF02931A0D9DADFB417722E17910530EF488309474E6D9DDFF56A5DDFFA3859354FE34B93FFBFB0E7B1822C832230DB644CEBBD319B2D8C4E2F689642852B34F2B1253BB58EE9B7C62B757E6382CEBE47BF5CD1D26F0ABDFB5AE5356F0944F82BC00B52BA61EB5C603B7BB0EE768D763B8ACABA90516914D5C73FFE5908E753F498EC7E28BC3ECFB69D8EDD76D313140FE218F3AD55BA76F3CB73E331BB762B7F7F92F75C2CDBAAA7662A4DC4B05165A87B8D0064114CD7836FBF0E8816843C48A8FCADBB6A7FB88801F98928A5E5B90C63DEC0EA0FA3395D402190BCAD7718FF534030A15444CF7658E15BFE22A447F3E23F7CD3B21642364F858C75968120262406989789AA6381C6C7535C2EF461B882A555A1BB43239564EBA5E7450722069495EAF1D3A396C45CA714A94B1C38E13E94E14249A8CBAEEDD0EB6A1F867221D94D164CF5D47DB5C759708AE19D193AC01ED5DD678BBEC27E908CE04E5F45B13648FEBCF66AD7181BE682028A9F3C137E962B292AE5A1D8A661085461D378100FFBD3737C4FB6B436A85B851F5F823A0BFA2F981E2C0379C626F2F813B3CA1708CD9D844A8044A917DB24EAD379D5A34E90E3546AC2D9121365D162CAF65B3DEEF566ECCDB449B1CB773057B21BE4F54E6036E1923FC486AAA69AF01CE1E29A3C89F78DF91A71F1145A92FB5C12BBB2D4E43210A60286263F56951307B13956F7BC1EFDEF3C8194B815692D4B71BB74DEC510CB396F1D903FB30BF8FA8D845915B74A537CEC2F5BD6CACC6E0896A10B7FDAA6D1412CF1B29A2669A3BFBED70CC9A6D3F8E782C5AF72DC54E3D1EA0F88BF2BE93E0EB4479DA07ECDC18885ED58D555F8BE63A483C6E20A875928081C31DC62E49E550D608A6EE22480FEBEC0A3DB64056A63C772DD0C14B1D2A8EDFC0D3A799B008B5D7C63D42D1848C06F43A974DBDB5334F237E6C21481E12170947B7CF9EA5E81D7400F79936FB292C1E1910F016AE190BC1514559E027FBD2C85DDB78A3230443DF8D1F35FCDC73FB189353361C7A4C819D3FFFA3CE11E6237664C8FBD8D0AF7AEC9C2C47D0DF15B588773520C10E0285F00299584CC25D5BD18DDE6DACD091C1CCB8318F830C6051D181AA29F3863B0859 remain = 1022 -max = 1023 \ No newline at end of file +max = 1023 diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_256.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_256.rsp index 299c00ae9b..8cd3c93b7c 100644 --- a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_256.rsp @@ -1,5 +1,3 @@ -# XMSS-SHA2_16_256 - pk = 000000025E84310CC01CAAD0B2B1E010C15F6691FF24977EF626465F5CAC2B015342A52404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 0000000200000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A5E84310CC01CAAD0B2B1E010C15F6691FF24977EF626465F5CAC2B015342A52404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD09000000000001D5DA3370DA40FE4B2AA8D93A4C52E009ED16134083746A63365266ED868E33160A0000000000010EB7A75A56A1497F0FC1FE5B3F6B396014CC9357B7FE8A6D2BA1B553EE3518610B0000000000011B23B9B57C09E7B440346ACFAAB7028D8821AF52CA85D5CEEE66FA4E95B45CA40C0000000000016AC8FE7754C3CBB4F71F8514603EAE30A764437F404409A1283CFF4B7159C0F80D000000000001CC6FF52DE53BEBD4E1D3DD11D0BE5FFEB977CA63FF2ED1099705AD3D5BEB1AE90E0000000000019B6C3951BCA1748DC7B89630F962DEB3937A4F8D15BF5634741113C38D2699F10F000000000001000000000000000000000000000000000000000000000000000000000000000000000000 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 2692 sm = 00000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA70104A82ECC99EF0F9172F36D2B461A6515DC13666B7F1D917746E7086F99C8F1A63E1C7E5A339AC394788015AB12B3532C7ED27D1BCE2B1F25ADC96165F6104861C3DCC2B150E1DD088C95AED7DBA928946BCC8351DAF6136F7335FA45EE8F4651CB9A6E98D556765100FECE8CCAE704D7AE90AEABE735C2FF46DC9FB302D2A1F4C33F371ACC4FA552FE83C254761E140E990474A10D5D2119D90AC9C2736BA2992026D11473619FC9D1857C50BD2ECB693FE0DD9C15EEAA100015D58F2D8F936E154B5C932078BABD1E9A3E3D7B876174311282D3C02D8463E268FB1542D967EEDD01DA7D0ECA0E3257F84C2813FD01B211B495B9191A48E3CFC34E056844855BD1EF463F5D1F9E9A8C7FBACBD29E2726EC1AFA11522536678005155E1CCC5562A8C0D1AE450EA842EE72F236381AEF42F2445DD5B9CB2A791B1D95240D10FE14A3343E73C5FE2CC524A7FD21FA547675C86F6C8D4EADEB1AE29060EF687EF65344A45A5F1033DA0B50A5529AC43435DC3A8BBBC986F1ACC1AD60CC13F9BB26A1F99DF207BA4E2C7B1A4A0BD8B5B9529F705C1C323AD93B7F67D735958A454CC7D6927CB165E25F6C4811F8D486A34DAC2C8A920D506682D747BD6496258BB4011164FB8F12A3E984085401E73A96C5A0B7A661F6D9288910CCF1C1101E0BBB68646191DCEFF06EAE14F3762FA5C231D3D57770F230802C2188D108FE326778A10980AFDFCCD50CB32C844771C1B5DF2054A7F9D19FA28F461E81EDE49B2D780FB3FCF424A28FB9B2E88CD08E4D4BCC31E1BD06481E817980FA8A40E74D0CECA78B87452100271944681A77667368E04F077001DD9B1454DA4614F631A83335A8C5B1F83087C603CA6D731A4AE32346FFBF5BBBE7FFCD206304CA468789748789EA6620D7C8AAA5D10EA029C3EAF78675E35C29A598CB5624FF0ABCE0548CD6C9DAE3CE9BFE4665EE57358DBEC0D157880889597F245FA042D00FFB56066AC873718FB1BD12E0428923AEF51F55928C8DA0D632382E3325E4CC5C6A3EBC4776C9F6520EF2C6960F0129A707F90315AC1AB035A7BA0D293A6400C30D363DF000F53D309FCB4CD455AF4290FE44F8FB76B6C32ABF15BAEEF44136CCD739D96CC95B0DC0EC8186125075F21570A6440A5967CFB83836BBE0FA463C0B6692A9C6D673038D17D343EF79BA50ACE3835F6216C3943470012081600FD81FE5B31B604E946A2328C40E977558DBDECCB8D643E07A573A9CB5DB4518877320FBB4998BFDC59FEDF2EFBDAEA4058725054A1317CA755D3BDD4780AF57F3B76649B3675DD9DD95A16F5CBDFCE00CADC229C2DD7B4E32D6EF82B346C5900BD03164C1896A4640F8B79FD7241614D2FED6D1E2E5795827F146C2158BE0A39E9556BCE1B08B774531FBFED5012C3F1DDB0C27A8503A43AD652AEBCF8E6F904EB09F30AAFF35952227395C3151F2927727015BE31E6A03C994E8011B555AA21C792E806511407B653D1CFBBD97D1D4CC87BEC5E436487DD454363E2E87AF3C2AD4590B98E9597885A533623BDDDA308151FD4902D8BE5EA43CEC046E62DE367D9C21F581AC2EF46EAF0F0E10438D4895C49FDD3049A23E32561BCEAF00F0C192BB9B2426CBDE0CC3E6186C3228990D0C0703BCB923061D0256CA76F9A75429F35CF416D6A93FE80E8C771DE016EB671CCD86B9B221CAF0C521F58D8BDDD226514234C6D44554A5943C782FFE265FEB6309F643277F09495ADB42B4C362E1EBD6790AEEB0C5329F797809B1A99E617BF85395C38D7B367F2C2AB5E26A156437E7248DF2E9F2F6170493DDD3FD0A0CFEFE8577D87D69AA8E668F66279BE02DEC2D05BBA330A504C68A7E81709454395DB2C55345262308C2443E6D245675277291C8E6718B222332047A841B2EF96801D464F6EA1053BF96F6E69F495D45535AC3FD4411C27FF7DEE1A7BE429B3D9A386E40B99329DE24163911705BC3137F0C728AB5848532999315D7DD980036E8107AC3A68691D840FD37C6950FED7E43C79CED8DB06685476979EB357AEFCBB1CE969D9C37505FF2EE6B27F8FCED566180664EAA36D867E2C702C6716A8EC826FAAD00204EE915AC2241D72BD22B8C46387703E5005F5A2FBACA6F84D5B6250F4B5BC0A2A6A31DAF9C60EB13C20CC649A18E27A6C98B82F08E21775133C937E715F8EB13518C059EDF4585E7446408D2AED56F1AF125187E172DA47D9A150ABAFCBBB6BD37E68B51E1E3B76A88186784096804E0CA23134BDB161B70F2AF126A3DABA5C918B224DE444B8733E6FA601B3D349307E94583D0EC97649EDFF2BD44402B649537B4A3AB06D71227E40BE5A484B47D7364A839A4730A09D12310A297840646C5828AAC63A9C3D416A375BFD3CE0D4A35C24762B458CD70B23AD28725612F5FB98FF740AFB457915740084644120ADD17B445078AAF541C08E140C4F0E8E005322F8AB6BAB5DF2FEF6DC1EEF9555B3FDA2C9354130A171A704637AD2E628163EE49D33FFA1530ED03F0A3E771B74CCF546BEF58EF21DD1522538D7ABA7F4A83155F8567A89BB7E052994F9E491025A37F3229BA80485F66F0BFEB7D77B5227DB43AC1360C86DFEDA86872B28FA47CE1C78A4DA2508F2144D5F353F6EAB57CC363587735255342964CCE7ABFB619A8072054867C554D4474EC48C059D2384AE7E36865F8DDF0CDF3C1B34C9783169B23CEAD96903024CE5D0B798AF6C9717BBC5DEE4C9150E8B271E12B53D2DC24D62BB1B522696BA13C595EED0091E7B3E7B5E50DB3DAD2516992EF120B950C8A22C5D1DC1959D8A6DE0E31E568B1B105DF9711B589CCEE0BF0A8A4597AFB9D07663D1FA4FE307488CDC692382EFB7882F60DC53AAAFDF2014CA7D27F8FA93C187A8371B41796557AE738D2AE42D887D10EDBCABE6AAF951E0A070D881879332064C99F8527A5EFF252439DDC6270CBF5906FC144DE1CBB74B260E8615FDB2903BBACC7A30DA76937CC982BBF293AF6DE61315DE00A8D15148487FFC0BA96489AB359231EF31202AF53CC22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B583 remain = 65534 -max = 65535 \ No newline at end of file +max = 65535 diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_512.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_512.rsp index ab807bc996..062a0f68cb 100644 --- a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_512.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_16_512.rsp @@ -1,5 +1,3 @@ -# XMSS-SHA2_16_512 - pk = 000000058AA2D66ED8FC46C0EC0504C56F35B897EEE56E6E022C0020BA1B38E675296297D99CA20060E4954AD137D640B279CD2903DE768E1FBF6A412EA45B5A33EC55D54D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE sk = 0000000500000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A4E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FDE028B6F5724BB039F3652AD98DF8CE6C97013210B84BBE81388C3D141D61957C8AA2D66ED8FC46C0EC0504C56F35B897EEE56E6E022C0020BA1B38E675296297D99CA20060E4954AD137D640B279CD2903DE768E1FBF6A412EA45B5A33EC55D54D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA7662A4DC4B05165A87B8D0064114CD7836FBF0E8816843C48A8FCADBB6A7FB88801F98928A5E5B90C63DEC0EA0FA3395D402190BCAD7718FF534030A15444CF7658E15BFE22A447F3E23F7CD3B21642364F858C75968120262406989789AA6381C6C7535C2EF461B882A555A1BB43239564EBA5E7450722069495EAF1D3A396C45CA714A94B1C38E13E94E14249A8CBAEEDD0EB6A1F867221D94D164CF5D47DB5C759708AE19D193AC01ED5DD678BBEC27E908CE04E5F45B13648FEBCF66AD7181BE682028A9F3C137E962B292AE5A1D8A661085461D378100FFBD3737C4FB6B436A85B851F5F823A0BFA2F981E2C0379C626F2F813B3CA1708CD9D844A8044A917DB24EAD379D5A34E90E3546AC2D9121365D162CAF65B3DEEF566ECCDB449B1CB773057B21BE4F54E6036E1923FC486AAA69AF01CE1E29A3C89F78DF91A71F1145A92FB5C12BBB2D4E43210A60286263F56951307B13956F7BC1EFDEF3C8194B815692D4B71BB74DEC510CB396F1D903FB30BF8FA8D845915B74A537CEC2F5BD6CACC6E0896A10B7FDAA6D1412CF1B29A2669A3BFBED70CC9A6D3F8E782C5AF72DC54E3D1EA0F88BF2BE93E0EB4479DA07ECDC18885ED58D555F8BE63A483C6E20A875928081C31DC62E49E550D608A6EE22480FEBEC0A3DB64056A63C772DD0C14B1D2A8EDFC0D3A799B008B5D7C63D42D1848C06F43A974DBDB5334F237E6C21481E12170947B7CF9EA5E81D7400F79936FB292C1E1910F016AE190BC1514559E027FBD2C85DDB78A3230443DF8D1F35FCDC73FB189353361C7A4C819D3FFFA3CE11E6237664C8FBD8D0AF7AEC9C2C47D0DF15B588773520C10E0285F00299584CC25D5BD18DDE6DACD091C1CCB8318F830C6051D181AA29F3863B0859EBE1763192D55AC1F413982692F909485720BD4F9B15A9EA968A63EE3F4A698AC73B58112D644CC2E1EFE05CAB29911A95C103284C83290F67B83587BBE7556294C5225374477D7ECAF9AB5EC9460765E6A40DC75A84EC417263C50D22FE5583FF9626977B8826C06E160772D6B0506861A86633446A807183935350D91EEB5D37414CF3BA477AE353761B74E05BB6DC167E86FD20D1EBDCF5C7F6AE3C16116BF9CBB6B67BB564009B597CC2CA1B16B7B3B484C6B172A817AC71985522092AEC980B2FF393DEAB2A375CA8C894A68CFE3DDCF7CC0D468B43C6531A58723A8BB14E201B277155AE268D6A3D15933778611288CF4B0BF3A33C30C1A77AB39A8E6770125995651FA889FAB2B28C87DD556DD7260ACB83D691E2B9DA5880BCFBC2EB079B0D42F673A8064710EE9CAE5913E37500A2BF7FD4B6BB409F511117323CEF7EB39EF1BCD8096E4EE0F5605D58361BB74E6656935E7B075F389DC49BE4973B7C6EDB05DD051E120406EBE62FE8A1DB88A91CDF152BFD790E3AD2308C12B755000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B589FD94AB5C37762EFFA44AC2093812248300D072E964594FDE1E5EBC7987B59EC36D4C0C120E76872FB77366F2C5B18B86B9139DF28EF7D44E32FECC4C804F010000000000016B410B4BEEFE73CB8F4D4C3ABB7DF62F132C01D90F410AE51281E0C5172FC3762D01221D015C100F93020CD106AB5DC052522C419A0FD67AD1A5EE9D5FD62E180200000000000121D1E9B1C034C0E95BEA3582EBC57F8383D0F6D1DA068D3ADB5B2B6237AADEE9A89B9F772A990889B143707CDEFCD05608317F599099BCDD2EDCA4B7CF410EB403000000000001C23E183353CD7FB42309F34D450892A84D2E250627D82E72E4A582BFCA8BAD10D4F5A2CBC313BC02333F65E8FC8BAB87A19EDD304EC7F7F85AC8078CFA3ABEE7040000000000011E2BAE00E2D34A2B2CF6745FBEF9D552837C3DC63720847E7DE3094B58785B6043AC7DA8CCBB7CB127C7B0C7A974607349D30D61CD7F08BBE092A3F9C7BD0FBC05000000000001657D3C7D66C12770C0BB75D4F5214C4B194F841F23B240ED784A12295B734A173AE89D8EDD857516ABFACE192FED90D2CBF6254B4DF0CD8C0D3F7CE520B0FAA5060000000000014567D4BD416073A25CDF242C18DBEA42908A4D6F0F15266EFF60569D4C458758BFEC8027BDB07730ED08E3A23D0540D8B90A140E06A28CBB64891316084D93FF070000000000017B8C7C4EBC5F897F112AAAD0FE18AB8CE4360565BAECD1075FED846955A14048C88B6B5C1A065F92AF55BFCBB10C7C46B114C80E9A36CC3BE6A245F466351B7D080000000000011F81CA34F234A41958ACAC3BE7C53450FCCB7E4D785F18C94981FC721F4CFB851AB0550BEE14A4DDC57D2A9EA06065395660BF32D43B71FCE388DC6F3379591009000000000001FE9BB64389A416997D68A9C5451FF9E3E78396632F38598E5345173954CBFEC8673FBB2AF02559E05CD20C58416401806095E8E1C2857DDAB16D1EE0F3E190DA0A000000000001614A2C14DF18FC44145D5BF5D800B784E33E3A9CFF914651EC186AFED8DD7B7BE9DF850F296C864358A76F3746114A0E8C77DC4275625349967A30017CB236F00B000000000001F9DB099C3387CCED2252727351924A10457131B3BFFB25244647716F38397BB534828F09AE38D601A810D11DDD56B5EE1DA23E2FE2DD430E40465C7D6B2E0F9D0C00000000000105E33C911412FBDBB9E20A3ADC0B7252641A464D05EA7033F487C212AE41F3183BE15D981076DAB6BE2E3FD38B92902A67949DD0DA273D580B0F486C5A66B3E80D000000000001E66DB2720E5C55537B360D0F774F1CC73246C4145690C3EAB8367194A83269B7AB01804478CADEC9A748FA6B2BBF7F33D13C61CCC88F19A0BF16908E0B0BD12C0E0000000000015F9CF8DB14A3F181CEC637BA72FBE950458F42346F664729CFBBEEE0A492EB07BDD134095EB0CAB4FA91B361999C9BE0959B55087B34DB128EE3FD6C02D7E4FA0F0000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 9476 sm = 000000006686539E267711CC53D8B185DE1BEA3A8484A81CDD6B6B0E46CD6568189E74C033347FA34BA7448CD4D56964F49F730BDE52ED29F39B1CAE52DBEDC90A0941562F22013107A0B9A812D3763286B6DEABDD26B7D975D267CA8D98F7A4EF9158E8CD7254464071BC8456847AAF9C54BAF4164E50E45D0417F3E9C05E9C1FE81AAB153A5F0C71B1159C1481EACB9BDB9EB4DED57C56BF48661F4775A35225DE9D2EE101EF5B13D4DC507EFBA53E65FB539793ED8C45E5FE4763F0CAC9A29C5E6685571D9AA4D3365B9B1014A1927E25870871F9C8C0EA530BA455B0B2360C24B1839019549E1862D3AB46C728804F06859D2E974B49FA858282D752079D80E0420A9C94EF9DB7050E9D83A8AB5B37763812080A80FE3514AEA7C767AD2C637E7DD267A27B2ECBCCCA482C11CBB111846DC6EFDF105181DA3453CC3342CCDE25FFB2890779D5F57790F1339B680C95ED5FEA0B4E0DD7B8071149CD9432E9F2DC0D451735247973EAF1F284C8E0E4E09FB49A659505338C62CA09DB6A820D9AE34C95418FC6F5B22273C55A5A4523C7ADDAE31CF57D12C4F7A8472A5F3292A2AAE44AC57E22D3F2BA2104EF47CA54788A1D754230DA125501428804B85AF0D296A8301278114033F8B9FD1BBF20FED474C486FDD6598A5480E3F3C46A5D432930C1DCB43711B63341E31CFDC262F53BB4E355678AD71FBEBA8D6887D67E7CE3ED994B961B8EEC3659BDC3251EE7E92BEA91B17A8302ECE53EFB4571729FAD476EC91E2AEA3EAD3C30730D3F9D454B44C843B9E1859F8E420119B153F83BBDDA898961B77BF6D0845BC513419C529B3CC2EB61CD813633419E80C461B9F46187ABFF24D359CD067C1792B41D2A7001CD548F8E6BB1BAFFCACF72D29D5675356238BBC2F0A0AE53850FE21ABA0B9912570EF03454D3548411E9C2E2DF47FA81A08336CB05044958E94D96006B6B80346FD722EFDBE4509BC4C27C779EA9CE3FA6D4540A5A30852BAC3D98E69F92319B4CE434112B9E046E80AC8C98AF74C0F75C80E0E55FE0F54F8D1BFFA66BA2FCB3B39BF957F6C35F00BE5735481503B311BCB51F8085303054C88CE780A72CD3A41FF87C89FC0C0D19B5F14555B99B813EA0046FA9D421287C14472602EB5836875B43EAF674E37D971DC563A89399440960BC748B244AAF9D8744E1408EC8E0818371808AC6F10CEE8A4CD6FC25B5F616B4152BDEB86B4AB037E4E1BF59F6AFFD7EC15A55375111D8F8F2FCF710941DD0CB532FAE810F87613AF8B853FA559F4B7F61024A9D73E531BAE8FEAE72AF55A282EFE6108AD2DB94FEC5E3D9C6E052B9B67F5AF7C4469E00A21A91BED53DB2541037D72C1AB3EC8C8933E6D65A458A8A5A57744583949653BF9E771695B7C8D30EB9A1B57D15BAA3F89D28315138BFAA88DDD261EB3AB17EB6F3C4A85065934000B2F7915B326DA7C300F3E2BDC6DBB570C85850C88E0996753DB70B1C9201593B3A8E6ABC9D581604EA41D9C7109959DB8E8882265C7F8D12F24702F9BDB9BB4AF388C54A0AD6AB6B60641551B31D77CD08E99048ED64D16659D9B65BB8ACB3895948EC2B7CF30870B25E4381E550CED893B3BA2713FDC8F14C58EBA6F2CDB2FE3B2BB0310A51F954624BFE8A8139E9E37D329FDE86A56B1E3DA98EF9C3A6F654AF4E2E89E8BBD2271ADC9129C21AF4CFA132B4196FFECF5700C963268928C92BCF513CFC081409A6714C353C36A5540E163F57AA0A57FE68E2AFA78F331AB752173F3921B49E17CA30FE44412A904930D1BF967E9BD4BEE04538B02EA3058D0BE461FF6641F3A5E2B393972AA0943DA5DC0DE745567F22B02F60798D647A71A59A141E675EAC27961F95BCD87FF5C196F08766ADDA7F43E73EFA570E51C89D0A596D861A2B1731FBEA4D5D953E9E699721BAA76F564C39EFA91B1DC10F78BD396643AC730C45519FA0247B58ED7A0A4FA11342EC4789348C4FB12CCA3608E22B7EE96173C19006EB10BA46D8445640074FECBB51649B6FE90BC1C63503018A37400CD476CB166A6A2782EE1680495B2E11F5EC5BFFA5FF196C739CFDDF7430331E71CC7383F41DE05AB125B74D8F25C445B975C4BAE944F94E73A60D62C87EA33D60AA7F55DD3CBA1947848AECF5F01A9F253201356E02722D0531128893FD2ECB735D9BD46B778D1D00C245F38301F71B90D96C1359753921556A9AF55478B971B0FE8D8B284964A625D4322E90BE82C9067445E5469EFBFC33FA904261072CC196842470BA810566F2D5B553E7291CBA9A4FF8CCBAA223BC0D0E8044FF34795ADC85ACD048FCF710D31641074EF233CCA6611603F87BBCC47E20A9348CC567C7E23FF84C766A49B7BAE6A59F59AF957721AFF84E83539B8C683149A5787CFC4C05EE82C46340E64C486217CCC83C57C2C9226EED64EAFFA9923877514B46AA08FCB446DB1D731C742B8A17C6A652751C94387DDEF68C679D1ED0845026C68DA6B7F3E36CFE1B02898DF0EBD98FE88EBC2F3F569CAF8F11C2D66027B4C4A1440324843622C2E7D450E98C437BC5E66F02D3524F0FDA9FFC063C7DC91B56A48C2943D7D04B674EF6494105BD5F4BF79D4179031580E5FE9974E5EDB124493EBB0EA947119C50C4EEBE1A7E9EF3CF77C2AEB05E55FB902A867A353A635AF798F74BA88B9A8996964BFA72DC73DE5290966FDEFFC94EA8E767F9C977BC27E50290F3E0D9423F3BCCE545D594CF0B4ED7BA966F0BCDEA0172EF7CA8AE732BD24AAB99BAEF03CF970D3877DBC1F7D9F82FF63F316D7547463129BBF08604F7F21DDEDF5A3758EC8DFBF104738CF062F712D64B6F653484DCB6D8601C5FEF58EFA234BDBA6FB052F5254BFA7B7212FF8D6D03A03AA502F797E100790A3499185CC8BDD5BDEB0978C608B70E7F6D1646E7F89D2E70EEE62852C69618ED8AA136DB1E75D4A687A62443A82802EB270F1C91E97074F3A12C63FDF3BABEF882F934B4BD0C2468C6A036DDC3493F2311294F01D09CE5AA36E5A7AA830672F45EB2894A80E5C1937BAEF259EBF97F61780A84F31DF608E126ABE26038708017FD2588656AA416D24B89D52D80739EFD42A8FBCCE76C155BACF1B514C8B8C3F7276424A52CFB8444E548DB752EA947DF2CC1DAF29490FE79A42FF2D845E7A491ED6861ED64AA868A162C70ABD4C04B0C8B1BA523AD0B6E8E0EA210166D6213B94CE1275CAA2108DEA7BBAE6017963FBF7D5F7801685EF6750F6BED988D0C1FEF24FB9B75FF7C95A8B6A9DCCD666125E9A4A5AA7DA1B8E5B8347E1964D36F6D0ACCAFC14DD8B5DF301A3768F5EC7924982E1B57D37D019914A01EA0B7B1652EBA5C15A6843CE712C34ADDEDE75F42A117A14B1A9D9EC75594333A3BCC41D95099F30B7293AC6A76B535FC09AF856FA8BCBD2CF72770D48120A3FBA021BA64D685D58072257FF93A7331243A8A7C3D6507BFCC58E7F76D28FFA3EE36BDDCF6E389E9DFCDF813315D720773AC005EF78E77F093FA5E6FF281E647B4BD982AC33591B40BB2F2E2A37BDA9CFFBF08B0A1954FEC592FCC0A5C15D07ADAE82739FF85CEF18025B93C6AF3ED72D63590D8FBB6B7CC0EF87DD769819DD5A6E60630EEECD4BF4296F27D4F5058E20CB33E5B172442509EE7BCD817CA7C67F263D4F3BF41ECC6851986D74E49C1AD0D2C97008EBC070E122F1B19DF8DA264BA46BBE734F9B08A154167755B2A3089EAE043E9D1A4ECE5F5D1C0C080963C1DA98AF78A665FE477338F3F0B36FA7E2AC73992F509EE47C11FDDA16BD612DDD81FB9427C5DA2587154264BAAA4654441B46400F0481AEBE3B8A744B973169CE5A06C78071821E8E644CD5B66573991C6C0390B2B553534DB4D0748FB63DA09112D58D75525D6F73C94BD93CE121BE678FFC625D9241222CC785131D42D8B36BC5825654BAD71E7896CCA575E3A66F948EFDD54BCB2E574B39E456045BF1D8CF7327100917AD670336BBDEEEC25277E6DED2BA4B77D91CEBCBD247B5B91CA02888E208498DFA03EFE10C25B94C8F5BA3BFA5CEE079E1AA8A07F109B4701706A3F96BB3C049382417EE0E08605EF08B06D62AA092592D816631AC7394250971E2E56218B0320FCCFF0CBC0B670237D1D1479AB655780CD7E41D2D1582FFCDE1528CAB79AB734DCE747E58483C4BEC989818E91AB33D5E8BD6E080B8EF7437B9D5C7ECEE65EE24E6B3940E4EF18CF7D5A9B217A9A2C058A900BE7129B628E81E009F3758ECB3D278E456432D5B6A3EB800E10BFF7DCD958501CB055F8A20F5579DA1421F43F593B7F2F8BBCB6D90805AA9A9CC5E2456F530BF522FE5FEF9E38295AA45D6CD8BEAC16D5152B9505DB546924DC43644753A7A151C5711E00D534A288D662FA4EE5C6DE546C203D4C37192AEC06F52A9A1AF4DCF6A86A32D78F214823D1F0EB76B297C1C7B3DA933AE8D6405E3486C1284310237BBEF96CE1620D8BEF7C4035D1E01CB1A67AA4E613EE471CD9ECD14DACFF64C986CBAE45D3C39C1E2C36EF9DABFAC020014AD281DF4673F2F4072047F9C881CA03DBE28908646872A48667042EBC119D9D162C5343778C99858950287015D6128C884E4F335E65D7FF03B6FC7D954E7413B5619888474992800304D1C9CDBEABBC7466200AE6075DC257698C454A5C2DB560AD172FFA64E38BA5A8382129B23BD52432D10A2977683DA4A91546AE242CFBB5AF9B24978C4AFC3F2CA44543DA40D27EA7CE154844F48EC6C90684587F0EE3BA0654F8530D2A47182F6EBBC44B5585BF16653D6C81866C6C02813FB92E9E4B6D39D1F022AE14FC2B55ECD93DAC6595BE2F372A1516D1A4E6131E72AAA49019B359E4035C864F829EDF26EE08A45E9C252D6F76AC45DC63EABBFC641E80AF149DBE1E53F1EF85B66D3B813C2BD444D6E0DCB5C59E2978BFF9F4A60CB9C6AE0A9ACEFBCECED54ED592EEA9C9B0F9BCC9356A3D1EB7271329EBDC30BC8F8EA72969B03FC5AD6042DA3DB87C36C00A7F0CE9F28305E2BC72972239C61C973522DA519EE286B388A0C6AF3FDC3A09BED2D38CDFFA16AF6A517F6B73621B136C2C2D8E67FF6314D2DB42C6A3FFB19C74C0637BC530A56F8DF71FE105DE525BA2B24071A2CAFFBB0D37F8F5C3EFB5B34FADBCBB9DD2C092A0BE9B4BB0AD03ADACC8D06CAF6A980C8B66DB154F07BF689C3E9306A6CB6694AC8588CFB5F42105214FB51C576EE777608A051D9FD3850B22CFC2EF1F4C3A8D659AE6F43E74A335A14459F7ECB60CAB8A90294D51571BBEC69283E957B055A29B5BD7616510E8D782B7C25327FFB042E9B00F8793BC7268C0B92411ABFC2830042AAC561786D93178C6DF6051E5B520E8BEEDB629509B0B3581BA16D27A84EA94D05A8DD3F9CE73EB75027CF29D3AAA5FBA10F88CCA732D15352AA09E04E0BFFF2CFA60A41207D7C9D07B7E3BB1D39D93C4127454CEFB86EB828BE506E20FFD3A4BD3F0BEEE7239FB57CB8EFFE15B421A049D5A654EDFB06F17EF56BEB8B7E9F0FF2FFE632AC59DEF87DFD32129479284462B826A56E7F957C82037D1D753EF996155A8E13D8E4213BBCCE88B3713A079FD4CD25E611D857F347639367B25D9771969FBC13BA2161D64970695977BE8EC125927FECB9DC34EF4097CCB154B41C3098637CFFDEE46DACDD83A51DDF20CD4F2DC12582C937BCA1F33E311E40F7A35A98A14917AC8BC2934F2F3E68410C893E2B02A9B76728A6E7F72F7C746265D51FA1771ED9D2FFA4184D4EE985BB95235DED9FC782DBACB8AE478797CA856EE48A24941059B4CABAE9D48E1C4AB18F419EA945395F3B2530ADA8996D2C6A77D18D7E374E994BFDE761C04FE235DD6CF3AAF57E1FB12CD0585A74E02147E3D4814634EA9D82C5A746E8BD611C05EA798DA659D03F5B5F6D77BB8ED9CD99CDA42B176351633FA4C06BDEADF1867B2DA7D68D5BD5F915EE4988A16C8472450A47EB217310E79327FDB829A5B2DC0878026BEE398EF0E4CC70CD96BA57463A5B596FAD237E47C4923DB8E3EE9ABC263733FDBC34D05B3C0A133681AD5F50D817BF674486B8E3C3CED4654D4D93E2B8BFF92AC9FB6DEFBC1982DA0F50CB14F72301A25E3855602A6E8BF915509E4005AC69D7BBDA193AAE56A95B72774D3177A0988007CE34C97B4F1DBEEB95EA966E51A9FA7EB78AF76F7CA88C869459A5837D3F05821C7C5BEEB0508738AACA46D0A2FF361E47538429FF845488A14653D34B4AF836DCC39E1DFE62EF9700D7F6D01C3C5EBD31C87B03605C0A6903C8AF70AEDE6BBA5238426E92A7BC99C68B2601F25EFA92A72BB89C4BC86297EC8E67FF2B3E6BE96D11CD7C500F380C1E3EB68F7EEC1C16195ACB77CE9FD9E7E2D48ABF0FCCD27B1A058CD74E969DDE90D004128ED790B2E40F78BCDD3F630E4C01424EBC58F5C020A92BC81D6887DEB065B6252294B5B7F458BEACEE6B6B8313E23653C80C4C532CD2E515931E6452EE883F6B124642F9657328FCCBF300DC2567E2118B7BF394143C6D1FDF380F92EE15C07BEF9C18A4054EBCE1ED59AAE8318725EBDD388948BEB3BAB282228C743B3B0A62AA7B64C70141BB187C77852C4DF2B90387E4E3670E2AF35E3D969E7A516D2FFF28C7C0799396E5A7FBF936293C3633ACBD50BEE1BB396E04D228D6BCB5F1CE8FEC6E54069593FA0DD244B61D017DEA5007F2ACEEA73C208E7129912849B398D318DE57405AE4D82CE8793AAD854DB0755CF659AA3A0EE83EF6AF166D81383A3CE1D5C0917074517C9C68002E584C47FA0B6188BC5C9263933222D7E106499F98B42B39973A65CF611CF5C9DE267487DBD9E19529A4C02321EAC4794A43070D8CD97E7732EF97E53621D203A5FBE0ED3D3C5DB794083784744FBC4E66D7114559BD343A53A582CAE18A8451122F93BBE34429E7B2284F1274AD7933F26ECB2A81C8D5DC60BCB98C9BDFD7D6170585D4813E93DCFC6133EC18794ECD9BAEBEC7DD31D80BCE151B61CE42DF11EFD55AE81A115D073F7414119EEBFA05E73D43A2D8FCF1CEC1D7FD9F0D3A1AAC4E5945A1D8400340D7E8B3F1701DD57CBD4261AF00736BC25499356F02E5BA7D0F19475F7397269186697D33A9BF4699F1EB385E08059712615E3C1F6A03C0BF8959A78E3960F7F2C51C6F0530B217879721431260492C1B3B7F9D074DC62E722798C9804AA83EE2779C73715AB5B78F8639D8D30F9D54671023D8331EDFE4718C78D79980A446F533F8556B16BCE1A1C09C607C2626525052986F3818BABD08ECFA78D7C11FA71519AA2DBE8A3B34EE82AF05ED10D089F7DB006F6D92AF90FD0962F8EBCFAD63D5BF41D3A51AD570789ABB8EC53B37C3904D7C914B83FFA8206C968814F82EB25DB9893FD427DC0A9A584270E306BBDB4EB6853EE37462F4EF562AB2A26B6B520A18D52489C566EDDC1BB61574D20E2A17B55D142A77E3DE415BB98C6E39622DB30F3EE02C62E405A5DA0DE9B07FE58A72B61B60011C752C01FCC1245DC3049691A145558AF755BDED22872431B0FFFBB7C2A09F61885053A19EE8589E76CF218A1CEE5710D962EAEC8F9C463936AEA8E4168407CB8AEE787A2C5FC3DA3B9D7F2C6985D1D812537AA348E2403E5C0A2451854B4619F634EDC83A193EF6A48921EC9BB4DBA821C890659E2ACF30ABAA37D70483F3B808A8F64F477E078AED9F6A87D2BC23D2AB079251AC645B75BC1500351F100F771348E043EBD2A25599CD72233B9744EA63F6C94424A4AFDC10B30EB857E423C4B19D41CEF442432E433A6AF71629EDB05E7809FC011FE3DF16FC6A56B83AF2E13E895AFC2502186964EB95D68FA0B39D11F78DF7D4C5D0B65DE97B352BBF256F41DE84DE4E399ABF4614713974D0364349E2C465C422BC09C779166D104BFAB82AFAAD2001C6AB97AA598DD9F8D9F17CF2AE19802E3DCC3542A04FD158A8A4961E7333AF64127F6A08B378688DDA8B3BF53EB0DAC1146B18DBC3FD1718E3E7E07821A83F6AF9534809168DE9C3D4EEE7283D4B012B18D119051D0A942C19B79236E427FE1027A46E0F1FDE1A68F45E36D4299E8DBFC690BB470457A854B8A86F9A235E8257F66A1DB0A704A39A78652E5928A95FB4C1889DAD77CCD4BDF90A6D330D0E6067C3B319BE5EFE2D4DD1B562413394A983DF3B4F989F74D0B3EC7D8A11865F3AC62F9D84932886D24FE3BF135E66D7F0A27D00EC010F88E0951A2B67F0BE92BAEE3687DCEF1AB008CE6A289560E90D41BE20C1E9E83C07D04F073938EC45416626FB219C7CE32DD9ACDEE512CD1E2A64B48B2846D97D3F57355BC68A8BB28336BCE8C1C33267BAF2EBA5CF9623FC4EAA61AC506148214DA6AAC02C8CE3441C8564260F3374E4461799C5FFB6A67CF34F7C1CACA39591D0ED86F6B1B5BA45ABBF6A4488E669B281B5058F92C89023FB0C482E0B245052B45A63519CB6F30486343C8BDA9F47651344F15C876AB8CB40FD8E694C24CE5318773D6BB148A67F9EF7722A9F4E1833CEFCE62C4ACC89622AFF50CAB1101906402B2F91BA0C4EF9BB59FE5F49C65B2F993F999C212ACC148CF04AAD8D5910DEF892441A3F91D5289D0F2F5166506E6EC068F2042E69746BF2C20F0463BC40F0A4DF6AFB6577666E4B60E5DBAB251340BDE082420A0BEBA2D3BEED60D17EC30C7DE6304359ADDA83E9E86A9A5DFAFC8AD72256209A8C6E34DD0907BD6BABD698F7748A908534FB2A986BA65B1DEF141CB0BFFE420545A293BD648836D22C4B072EB60FE3C1E4524540495B5D3BE99E170CFE6C3CA4C3B72252A0D4127A3BCB1DB74818BD259F0293F161FCB8CDF54D957F7AFF6118452CAA20F38DF881FE306C2E918BBCF4D6E4776658BC27FBA1C88DFD1FDD80D72A4FEEFEC07F78F76FAF76A3B9803C6FB8BD0CB2588D1766F4A930D9DCFDA7E1639FA0ED56E5D7742F6F55CE9432C57685DB5B7199BDC12756C9BEA29E22A6F6FA3B5F8BA2B301FB3D9E129014B757F21155079B3FF1C5478BFD9E8123B9565F9AFCE4C0E75C7C4E19AFD397F2FD5F9CC2A3FBC7447AF54E6BA8051A0CF5F35DDE7E4FA4238909B202C9134D36CD7F5AD05EF5D671854F39030784B7531B757E8F9F4F710A4E714E2A97AEAADD6FE9A1DEE57626BB2A360383D014FDC273C11A18DC52A59D7D0E7C756D6D48F1394E25A5CE5025222471AAE0AB79A9667DE5CA3D97D11E2A8455A77ED842744C5CB5E3E810B543ABE67063F04E6BA5388C61B8D6FFF48971E7D16F1D519DF56279CE71768AA7EEA14B23A420FFF3761968279CEB896460ECBECBE5785E33AE248E1B309CA20B7F7E70AEEA065888A2C20088D0C686F7F566811FA6D4B0747786D5EA1F91AAF7901F6185EDB3E0F21C611C8E084BF7594C3AB0837429DE9ADAECD98EE324708DC1CDB1EF927F13463472253D413863F7E89DEE36AA8CB604CCA4ED03030551A1E448EEEA671C8FE8C7A9A88C3BC7E8F0F06FC9202FA988E04521FDB25ABC209D0A134B0D2A84032F503B1B0FC206077349A35AF71349AEC444427E398BB33F4DD668A709DC6704CBB40CC126683080FD9EBE5822333B72D71B4BC4E15F7A17634A5E414932DF52EE6EAAB1E2CF2119C0F4D11E8D38907F7B3307E655DB30087AA2901A4CC6EE4D15F72CDE62F429E2825F5B7C70572D98DA4ED88F56CC1DDEE36D09BCA15FE29ADD81EC74CD0F9DFC2AAD2CF50D71454AB4E04F3A8763E3EBD3F31FD22656A0A846925DBAFD0DDD107D9A86AB28D8E7F8D127CA642BCE5D010562B3F2D5F47014DAD1A88DAEDC54C3547560EFF5E764A20966B860273D35A686FEF539575B8898C3ED6984E0BBAA6FD5E8BA596CE548EB72CE5F7A7E53022CBF8BEA53EADC6EA1F4D4EAFDA59807B939E02E8417342CCDF07D00DA329B3FFFFEF94B61BDA2495816C551AAFFF946D2E3C0B6721584620FC264CC0293316411AB56EB337F613326C456F2D59318D45CE4C11B42A08F2644940EE91DB6B709E07DFF670EFFB7D6B5F74089B44DA284571AE0AB361E233A76A099DCDBE955CBBEF8CCE129A3CA380E8C45D3879C65DCFCCC928F0E4233B8B6BEB60C5EA34D691BFCBCE45E469510F3FE1C5A37C93AAB390B352790849E7B17A36B420E9C8AEA845EB671A2C9649264425B9F2A953114FA75B2161D9EC058132C4FBCE3587A24BD8C2671E2B8A1D29727C283A43B88D270FBD9A7978D9FE6EC869F4D9340321B6A283891010F801AB780927F7688B5FB73728CCF39291329C6B97A445587C0A1B1AF2EC8CD86CA83A912B6AC359F9B569988CDBBC22F5591F81FD1F97C205BADC0E62C390E8426C35AC602ADB498EFC1E8A589134349F2D901ABC7637793E2DBDB6A84803A6A5516ABF3BD2C4076BD44F7E8927D29F5D618DE1B5CCEC5A16C57D4DBF5741EAAC41008312B14000E27035FACF21B175075FDB9B0CAE9904FA41AE4F19320A1981B1D4D092F62F84D404AB8688D0A614D18AE93FEA9C5211B9BA81C573C4452A405771D7A88EAC32F7AD29EA64622EA20C9D9239D4A064651BFEBD64F9938961CFB26E832053F17FF9D6DD2F0F463E2BE1BB92BFACE323B15DD68927C4365A08798728B1326E43CD8496D30207B0527AD68E02CC16E56B8BCCD23DF0D7C5E3047220BF7ADDA607F4EC540F47A1FB0FF28883070E2CCA49A42D364646D826D34131B971378C26081B861AAE59EBB9B714FBBEC97F5A3E0622D02BF5704FFC48AF154DD5A952CF43830C8C9931F2F0DA2DE2F94140717D3C9B427889D2FC2394710F501E41FA5DDCC509391FA97784687A115574E60F723B9CC83A68280BE41B5014F02A3486C6F5F249C430C1E1DACF9A03C410174A386F6275CEA5E101D53E7025971E7226693DE2CD39395EFC763A9E52103F00E7F0CCF2C7EA45AB213D3F37608335403E6551D2D896621EA9678C68EC2395E86DD2011EF70915CD9D10AB88C52AF27FD0067630F7AE9BD0504951C9316504373B2A60F155EB1E49119480746B79B4D4A67A5BF39912C69411737D16BF3CF8BEB29CCCEE94D309979F2B757A07C440FA9F53BC9056ECBF6FECE40CC20AD9DFFB3CC0E16B0E4D7BB9389D610A965E9A351F03F7B2F35E141E1A67E75F1DE81A1C941A41D6605D0EA8F1D9D47E93D2F65ADF67D96EAFEA77342095E82BCCC81606908AA41404CC36B0F58FD0943ADA9571259C253236973C1BFA8F82A519276089219706E5092CD4A940EADDBA5FFCF52D699F30CF5CB4B1B6392D9C33D00CF632333A06EA1ABCDB2473F65835BE2D3E703DAB2E469CB78A0095561589EA0B114A6BEAC3B1EDEF9764E2A4159194E0D5968FBAD672332FFA3E6E3A82FCD08E8F7443230F2AF4104C3D8537E1FBC1057691037DE846EBB6426354B80BC635C61BF2B9411569BF5E339AE82276D400EC319A2E575A39CE1A662EC3581E428D4E74D285EC5E283FFDABEEC19A1130AF54691E5479D4BFDE9E5DDF4D1AED4A8BF69411F9F6720542BBEAB7870B8E1BE43361BE2C017AAD2C10915686E506E872523E088B80E0CB5AFCF340477AFE57A6FA2E827D05FDB3A4AF6A49388FC062D7F24FFBAF8AF61503124D79EF179D32CB6F717B854F11B401908C700B8E4A38337C3E76C33525A9356C31A70691496A56A0AC6338ADACA88AB590597E016D913CD21A91D07AFCCBFBC32C6BE8B19121EE42FF926B8F55106D15B7B6301E6B0E456EAB19366F057C9FAA8BBABE4250F4C418DDA374DE6988F843B7F71517B385A9A1CF02931A0D9DADFB417722E17910530EF488309474E6D9DDFF56A5DDFFA3859354FE34B93FFBFB1CD2F2E1B4C72CE4A762DEC2EA1B0CCEDD01D81B69DBB663DEEA0CCC04E0CA9017162A72F288BECBEDA8D2FE3B2C31859C3C4B7E06ACE1543A1A8277C08BA6E0A5EBB08E14CFB334FEB3AE84F99538DB994FFB3DDCFA5B7DE509FA096233A13EDFA21C59A49C3B33420E148701403C7FFA694CF5C5B45BBE6CE596E60414A6EDAA7662A4DC4B05165A87B8D0064114CD7836FBF0E8816843C48A8FCADBB6A7FB88801F98928A5E5B90C63DEC0EA0FA3395D402190BCAD7718FF534030A15444CF7658E15BFE22A447F3E23F7CD3B21642364F858C75968120262406989789AA6381C6C7535C2EF461B882A555A1BB43239564EBA5E7450722069495EAF1D3A396C45CA714A94B1C38E13E94E14249A8CBAEEDD0EB6A1F867221D94D164CF5D47DB5C759708AE19D193AC01ED5DD678BBEC27E908CE04E5F45B13648FEBCF66AD7181BE682028A9F3C137E962B292AE5A1D8A661085461D378100FFBD3737C4FB6B436A85B851F5F823A0BFA2F981E2C0379C626F2F813B3CA1708CD9D844A8044A917DB24EAD379D5A34E90E3546AC2D9121365D162CAF65B3DEEF566ECCDB449B1CB773057B21BE4F54E6036E1923FC486AAA69AF01CE1E29A3C89F78DF91A71F1145A92FB5C12BBB2D4E43210A60286263F56951307B13956F7BC1EFDEF3C8194B815692D4B71BB74DEC510CB396F1D903FB30BF8FA8D845915B74A537CEC2F5BD6CACC6E0896A10B7FDAA6D1412CF1B29A2669A3BFBED70CC9A6D3F8E782C5AF72DC54E3D1EA0F88BF2BE93E0EB4479DA07ECDC18885ED58D555F8BE63A483C6E20A875928081C31DC62E49E550D608A6EE22480FEBEC0A3DB64056A63C772DD0C14B1D2A8EDFC0D3A799B008B5D7C63D42D1848C06F43A974DBDB5334F237E6C21481E12170947B7CF9EA5E81D7400F79936FB292C1E1910F016AE190BC1514559E027FBD2C85DDB78A3230443DF8D1F35FCDC73FB189353361C7A4C819D3FFFA3CE11E6237664C8FBD8D0AF7AEC9C2C47D0DF15B588773520C10E0285F00299584CC25D5BD18DDE6DACD091C1CCB8318F830C6051D181AA29F3863B0859EBE1763192D55AC1F413982692F909485720BD4F9B15A9EA968A63EE3F4A698AC73B58112D644CC2E1EFE05CAB29911A95C103284C83290F67B83587BBE7556294C5225374477D7ECAF9AB5EC9460765E6A40DC75A84EC417263C50D22FE5583FF9626977B8826C06E160772D6B0506861A86633446A807183935350D91EEB5D37414CF3BA477AE353761B74E05BB6DC167E86FD20D1EBDCF5C7F6AE3C16116BF9CBB6B67BB564009B597CC2CA1B16B7B3B484C6B172A817AC71985522092AEC980B2FF393DEAB2A375CA8C894A68CFE3DDCF7CC0D468B43C6531A58723A8BB14E201B277155AE268D6A3D15933778611288CF4B0BF3A33C30C1A77AB39A8E6770125995651FA889FAB2B28C87DD556DD7260ACB83D691E2B9DA5880BCFBC2EB079B0D42F673A8064710EE9CAE5913E37500A2BF7FD4B6BB409F511117323CEF7EB39EF1BCD8096E4EE0F5605D58361BB74E6656935E7B075F389DC49BE4973B7C6EDB05DD051E120406EBE62FE8A1DB88A91CDF152BFD790E3AD2308C12B755 remain = 65534 -max = 65535 \ No newline at end of file +max = 65535 diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_256.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_256.rsp index 5fb1e18f1c..778c2c0169 100644 --- a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_256.rsp @@ -1,5 +1,3 @@ -# XMSS-SHA2_20_256 - pk = 00000003A7FBDCA19FC30ADB13F35C92F71086094413263CD71A0570C9C2F250CBC2842704562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 0000000300000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94AA7FBDCA19FC30ADB13F35C92F71086094413263CD71A0570C9C2F250CBC2842704562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5832CE029A1A95FFCBD5C8B157282F7364E680C60B252C49483FCA03529693B074E0D2B1F6DFD6463B974DE6829A616F20C839B0D2B8BE5405623B5B722EF22F7A3BB78E91315F715D9DCDB0C8639CB8A90685BEE7969671789047083CACF24FBC4B601B1B23B2E79E42176B2438CB405BDF46369F4DE5F411B2ACD32BEE3065DF9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD09000000000001D5DA3370DA40FE4B2AA8D93A4C52E009ED16134083746A63365266ED868E33160A0000000000010EB7A75A56A1497F0FC1FE5B3F6B396014CC9357B7FE8A6D2BA1B553EE3518610B0000000000011B23B9B57C09E7B440346ACFAAB7028D8821AF52CA85D5CEEE66FA4E95B45CA40C0000000000016AC8FE7754C3CBB4F71F8514603EAE30A764437F404409A1283CFF4B7159C0F80D000000000001CC6FF52DE53BEBD4E1D3DD11D0BE5FFEB977CA63FF2ED1099705AD3D5BEB1AE90E0000000000019B6C3951BCA1748DC7B89630F962DEB3937A4F8D15BF5634741113C38D2699F10F000000000001F21F01A1F02A9D105C71E89A189791BDA7CFB7BC89003D2EEB2AC6E7DBC26814100000000000019CD3ED9E3D49C10FE36B3813045F452DD0B3CEB702EA9FD3DE2289FEA46C9E41110000000000010CD4EC639F5FA5159D505EFD1215E62E35B38AC9A8B36077EB263B10F5BB4B741200000000000111A178357024706621EF264E4A66422A6F5B9F4C24A35579CB17DC686277D05913000000000001000000000000000000000000000000000000000000000000000000000000000000000000 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 2820 sm = 00000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA7010C534B0D4C6FFDF4DBFE00E72405EFE83BBCF19AA2030A8CB163808482B6376FFD2CB50DDA1EDFD708F002ABF07D0001C3357A70F6511884C4185790EECECCC578715C21A26FC1E7A951C54A30ABCDB7EC71AAD92F2662BC900F9E9A93054CF39B9A6E98D556765100FECE8CCAE704D7AE90AEABE735C2FF46DC9FB302D2A1F4C3C0901B0B16F96846F8196BA6E2E8BA4375B3F5FE010A02661EE3374C1B28A76A4A8879EF91C329714FFDF118CF5669BF7BD65CBDB738CF6A8636F20F399855E5BA4B0955661EA3FC882D9D64954405502E2BEF7D3063D36F993460D2557C7977DACE2D6D7D9A77DEB151610372F7DA0C73F7B2A737064A6C62DD0CF4B69F1CE4D9BAE3589B525734E92F3F8D4D2AD9091B6C82F7C0189D3780AD854BCF3CD62ECA5F998274C2E153FFF3CEB473D81B551AB5F85CA351B4BC225D7942733BC8DA6EEF78B8184B2E355CC338055DD2A26DD02B1A0740CD15F6CBA4EF429254DBCE0CC4F4B00DBFFBA622360B091DD6AA817423484ADF53F5D8A30E3D4164F539899DF207BA4E2C7B1A4A0BD8B5B9529F705C1C323AD93B7F67D735958A454CC7D4290DEE03A74DB1B3A62D2EC10EA3C3EF2DB3375893598133F36B5B8F2AD5929164FB8F12A3E984085401E73A96C5A0B7A661F6D9288910CCF1C1101E0BBB686FC03DC302429EA2768093BA3B43C542F272E93D15A190426830A92526E5251912FE8153DDA93C92A1195701DAB2D2A22C9F380DD4984645384692FF8721D549A4CC74ADF8A5C2BD5DE48F6A923D8FD37E36377639AD73D1C7AE721D0152DE0E73844FC867FC8C029E657271B738EFCC1A39C2A64EC5DCA96D89BAD4C407D4F0CB226B913ACD451E7C65BAFC90021E665C24A2EA208A16D92E9C27BC18B9D59B7FAA8FD4A12AD43A403062FC7003ECC756E3E26F8B1BA47801DAA46173063E37823CFA4B1481DF4C88093941CB014F54D73B5058ADD52B6A0638C8F3341DC13235F18FFADE0EA5601EE831BD587A8EDB72F96744AF8B08AFF190BA55D0B25D47F33F84F17D6C15B50AF1684C8F4044CA7BA2CC196C7F3CC9AC2603194A9A536347F33972E57BD89F4E3AB7977CD3220C0D5E54911F17007973BAEB9C8B3DBB95D1483FB4C281E8137940969814A5B6FE7D1057E1DCFB7AB61415E94AA4338F0635813AC5FC9767CAB6C9B71F63D372BA40AF511C7259875386539636DD45512165EB3E72F1046CBFF94254043D879CA0B64F7BD7AEC79F5F87C11DE3DE80756E9FA3DFCF5C9CEC2D80AD509A65AEF0E3E663B7F31BCA437311BA799D4C2ACC13818BDA90266F7A362B61CFDDE0523BEB8866B829512E9B625A90898DCA3DBA0BAD32BB3F2B1687014B418E277BEF2F73A6CFC6016578227EA1A56E5F7655C68B27E3B486B3D2D5EDAD5390DA570BEC6613D901E5D75A913978DF9002D8AF64A9B4E6BDB7388057A17624FC600F3031D016E61D17E3E6A9B2771E2CC466B2A17C425E4F21F65131B4005AF392C685BEAB2FF1E5E4E886E1454DB240AFA0319449B4F3DACFC2FAFF74844BF8128A3B77237211ED11362BA8A6F87C6D103A23A7D6628B57D137C5264CC2E627F24A3BAD50EA4F75C7BD8998709C01ED5ACFFF08919C609F8F74BF5303C281E4D8D1488EFB7FCBCF8AEC5C4B26330A6CF6E4D798C1FA4FC6DDFE7FBFCD3C4CCC352F28FFFB9301C08B0731F472F6CFDED99EFFBDCFF23AD4839258197D6706C3551375B3F7359C6A8403C9BA07CDAA348C82E896416D74BEB3BDC53DC8CBD2A281340B78F7635419636A3C38E9D5515CF8A035A439D322FAC7F9853AD29B44EAFA7AA9A4ED2471B0BC91B4E1FDB7E6A80056C0F264CD1E0837F2ECDB1EC864CF6565D6F9ECA34C9B961B278867E8ED627C1CA3F0E05A841B2EF96801D464F6EA1053BF96F6E69F495D45535AC3FD4411C27FF7DEE1A7BE429B3D9A386E40B99329DE24163911705BC3137F0C728AB5848532999315D616AE1EE474D3F1C1DD7BC7F282E6DA92731914758830B8AF74345719259AC8366C65C61697E08F06B61AAFB4C247C6FC8412F815114AC9C3D9172C1B5CF22867D870CE2534C0C2A163DD971EFB7226AF5B9BE4351DE6AAA45F27F9B2CB0831FB8C51B0C6412F36BA064FEA5ED935CD8FC498C92D651E2C9BB0A294D35E87BE8B94C03E5893DFAD17EB8A15E5B131E62A0924331F3888CD95D68D0541171EFE3389CBEC636344A6AB01468843A94F56FA7FC1806448C09DA99219B5B3FF5EEEC1397B66DA61A963FEAFD805408782D911B79206BE9A53D04EB1ADDF69988D97437FAFA9FE1D707144A2290523A7D25AC1BB6206AB824556519D2B909E4D04DE8D8D35A0398398CFD1A6A4D5B8B9BAC3A42A27B05E91DC07C8AE10BB4636D08A9D08F444A61A465254F464EBBA190A6B09EF04567EA727CF57713F381DDD9FA8D431BD19121BCE533E07068AB0500B15488F2F60DC3C2BFE4CBDBD849C873D2036743E7CBED5BFC1F8511489AED9E0CCC0FAD5D9F1805544D2A20F56AAD3E0058522538D7ABA7F4A83155F8567A89BB7E052994F9E491025A37F3229BA80485F6823B9A3781C1CC42488414DD491B2F80FD91E049E56AFB0D3823E66A6A3FCB1660641E4368990B3D05CFA937C51BE7692B36F007281321B5F317242030B2007DEFBA495E0499587494A9B6E4974C37F5C006A34FF102A23985FA9F660326DA39E41C65227E6F51D5EC56D93D19E1D3279F668A13A2B3599139B265111473D5F8F0B23E656D7E2729177C18213323818435F2951FAF7288F66F9B7B6ABBFC9617B0191CC9DA4EDE34F511E0849E7C27115FA6EB6C43172DC2FD4CB1AF4C27A4A6874419356CEE67CFA51989ECB77328F87F18629E63A6732C5BEBAB4DB4BEA3E19912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70D982818E4AA66E926983B45F64AA0172AEB48B28DD4994F24311F28B2577791EF712689DF5DE30ED5313C773311EC605B8E44C297ED4AAC95D3B1DAA8631F7786C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5832CE029A1A95FFCBD5C8B157282F7364E680C60B252C49483FCA03529693B074E0D2B1F6DFD6463B974DE6829A616F20C839B0D2B8BE5405623B5B722EF22F7A3BB78E91315F715D9DCDB0C8639CB8A90685BEE7969671789047083CACF24FBC4B601B1B23B2E79E42176B2438CB405BDF46369F4DE5F411B2ACD32BEE3065DF9 remain = 1048574 -max = 1048575 \ No newline at end of file +max = 1048575 diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_512.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_512.rsp index 92b345dd0e..ffa415e6a1 100644 --- a/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_512.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHA2_20_512.rsp @@ -1,5 +1,3 @@ -# XMSS-SHA2_20_512 - pk = 000000065711A97061C93B4FF7199D48104CC42415C4634EBA3647D8E51BB1ECB7D4C455418BDE977F20460E48826E531A7A59E7DA8746D7AD5D80CD059D8007C2E890304D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE sk = 0000000600000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A4E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FDE028B6F5724BB039F3652AD98DF8CE6C97013210B84BBE81388C3D141D61957C5711A97061C93B4FF7199D48104CC42415C4634EBA3647D8E51BB1ECB7D4C455418BDE977F20460E48826E531A7A59E7DA8746D7AD5D80CD059D8007C2E890304D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000AA7662A4DC4B05165A87B8D0064114CD7836FBF0E8816843C48A8FCADBB6A7FB88801F98928A5E5B90C63DEC0EA0FA3395D402190BCAD7718FF534030A15444CF7658E15BFE22A447F3E23F7CD3B21642364F858C75968120262406989789AA6381C6C7535C2EF461B882A555A1BB43239564EBA5E7450722069495EAF1D3A396C45CA714A94B1C38E13E94E14249A8CBAEEDD0EB6A1F867221D94D164CF5D47DB5C759708AE19D193AC01ED5DD678BBEC27E908CE04E5F45B13648FEBCF66AD7181BE682028A9F3C137E962B292AE5A1D8A661085461D378100FFBD3737C4FB6B436A85B851F5F823A0BFA2F981E2C0379C626F2F813B3CA1708CD9D844A8044A917DB24EAD379D5A34E90E3546AC2D9121365D162CAF65B3DEEF566ECCDB449B1CB773057B21BE4F54E6036E1923FC486AAA69AF01CE1E29A3C89F78DF91A71F1145A92FB5C12BBB2D4E43210A60286263F56951307B13956F7BC1EFDEF3C8194B815692D4B71BB74DEC510CB396F1D903FB30BF8FA8D845915B74A537CEC2F5BD6CACC6E0896A10B7FDAA6D1412CF1B29A2669A3BFBED70CC9A6D3F8E782C5AF72DC54E3D1EA0F88BF2BE93E0EB4479DA07ECDC18885ED58D555F8BE63A483C6E20A875928081C31DC62E49E550D608A6EE22480FEBEC0A3DB64056A63C772DD0C14B1D2A8EDFC0D3A799B008B5D7C63D42D1848C06F43A974DBDB5334F237E6C21481E12170947B7CF9EA5E81D7400F79936FB292C1E1910F016AE190BC1514559E027FBD2C85DDB78A3230443DF8D1F35FCDC73FB189353361C7A4C819D3FFFA3CE11E6237664C8FBD8D0AF7AEC9C2C47D0DF15B588773520C10E0285F00299584CC25D5BD18DDE6DACD091C1CCB8318F830C6051D181AA29F3863B0859EBE1763192D55AC1F413982692F909485720BD4F9B15A9EA968A63EE3F4A698AC73B58112D644CC2E1EFE05CAB29911A95C103284C83290F67B83587BBE7556294C5225374477D7ECAF9AB5EC9460765E6A40DC75A84EC417263C50D22FE5583FF9626977B8826C06E160772D6B0506861A86633446A807183935350D91EEB5D37414CF3BA477AE353761B74E05BB6DC167E86FD20D1EBDCF5C7F6AE3C16116BF9CBB6B67BB564009B597CC2CA1B16B7B3B484C6B172A817AC71985522092AEC980B2FF393DEAB2A375CA8C894A68CFE3DDCF7CC0D468B43C6531A58723A8BB14E201B277155AE268D6A3D15933778611288CF4B0BF3A33C30C1A77AB39A8E6770125995651FA889FAB2B28C87DD556DD7260ACB83D691E2B9DA5880BCFBC2EB079B0D42F673A8064710EE9CAE5913E37500A2BF7FD4B6BB409F511117323CEF7EB39EF1BCD8096E4EE0F5605D58361BB74E6656935E7B075F389DC49BE4973B7C6EDB05DD051E120406EBE62FE8A1DB88A91CDF152BFD790E3AD2308C12B75581541C17666CCCA89933F0BAFD5A0D93CB983D087BF3D1D8F388D22F6B09BC3418FB7AAB26A5754CED0B1F20E1DC38A0426E818B22F34C296DD19DBEE2F1E048C65EA766F8B9EAF074792D83B2C35D363CCCBC4516C9F0FDAD4B07A3DC3C44A9D27368A57F7C52E75500763BAF2CE58C0B9520E1CF94B584D0D9223312ED434D305314718BBBF41BD80668F2D6ECD82327BBEE9FD960898BC7227727341B863F9664701B3F77A1E01155063FF685D613EA39DBD04F12F9E72C840A286A1DB44E63C1CB55527BF3238DBDEB31328477B9089683B1F07A3A0034660ED39487C43D1DB76757D3F0A1D0B52C26E6713D66CE20A818A113D19E5A312C5127507A3C410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B589FD94AB5C37762EFFA44AC2093812248300D072E964594FDE1E5EBC7987B59EC36D4C0C120E76872FB77366F2C5B18B86B9139DF28EF7D44E32FECC4C804F010000000000016B410B4BEEFE73CB8F4D4C3ABB7DF62F132C01D90F410AE51281E0C5172FC3762D01221D015C100F93020CD106AB5DC052522C419A0FD67AD1A5EE9D5FD62E180200000000000121D1E9B1C034C0E95BEA3582EBC57F8383D0F6D1DA068D3ADB5B2B6237AADEE9A89B9F772A990889B143707CDEFCD05608317F599099BCDD2EDCA4B7CF410EB403000000000001C23E183353CD7FB42309F34D450892A84D2E250627D82E72E4A582BFCA8BAD10D4F5A2CBC313BC02333F65E8FC8BAB87A19EDD304EC7F7F85AC8078CFA3ABEE7040000000000011E2BAE00E2D34A2B2CF6745FBEF9D552837C3DC63720847E7DE3094B58785B6043AC7DA8CCBB7CB127C7B0C7A974607349D30D61CD7F08BBE092A3F9C7BD0FBC05000000000001657D3C7D66C12770C0BB75D4F5214C4B194F841F23B240ED784A12295B734A173AE89D8EDD857516ABFACE192FED90D2CBF6254B4DF0CD8C0D3F7CE520B0FAA5060000000000014567D4BD416073A25CDF242C18DBEA42908A4D6F0F15266EFF60569D4C458758BFEC8027BDB07730ED08E3A23D0540D8B90A140E06A28CBB64891316084D93FF070000000000017B8C7C4EBC5F897F112AAAD0FE18AB8CE4360565BAECD1075FED846955A14048C88B6B5C1A065F92AF55BFCBB10C7C46B114C80E9A36CC3BE6A245F466351B7D080000000000011F81CA34F234A41958ACAC3BE7C53450FCCB7E4D785F18C94981FC721F4CFB851AB0550BEE14A4DDC57D2A9EA06065395660BF32D43B71FCE388DC6F3379591009000000000001FE9BB64389A416997D68A9C5451FF9E3E78396632F38598E5345173954CBFEC8673FBB2AF02559E05CD20C58416401806095E8E1C2857DDAB16D1EE0F3E190DA0A000000000001614A2C14DF18FC44145D5BF5D800B784E33E3A9CFF914651EC186AFED8DD7B7BE9DF850F296C864358A76F3746114A0E8C77DC4275625349967A30017CB236F00B000000000001F9DB099C3387CCED2252727351924A10457131B3BFFB25244647716F38397BB534828F09AE38D601A810D11DDD56B5EE1DA23E2FE2DD430E40465C7D6B2E0F9D0C00000000000105E33C911412FBDBB9E20A3ADC0B7252641A464D05EA7033F487C212AE41F3183BE15D981076DAB6BE2E3FD38B92902A67949DD0DA273D580B0F486C5A66B3E80D000000000001E66DB2720E5C55537B360D0F774F1CC73246C4145690C3EAB8367194A83269B7AB01804478CADEC9A748FA6B2BBF7F33D13C61CCC88F19A0BF16908E0B0BD12C0E0000000000015F9CF8DB14A3F181CEC637BA72FBE950458F42346F664729CFBBEEE0A492EB07BDD134095EB0CAB4FA91B361999C9BE0959B55087B34DB128EE3FD6C02D7E4FA0F000000000001045B70F509F59A21D1A0FD0A9F8005C66F7556733966737A4C549A1C0AD12610A16CCE4745E8352426D85C4E0AF11B546CA400B2996B322C29C2A698955FD3F910000000000001D2D4342E8FBEE48D2E8AA9E243D9DCB48B35AA0EE43D40CE90B89731870E68C17200FA64C7A187130A45439DCFE40F0458C394F8C491F2041C1BDEABD782BD2B110000000000010212C4441F454AFA1C1AC6665B123A752D82426D32EDF0E05020D303C645B0A0BB63DD21C34037AAB34EE80578496AEFEC17A3FAFC11CE84578D979D73201B0712000000000001CB1D49A4FBAC9CE0FBC7E45ED2DE9B6B0A55CC9753404E56FF1FF2AD8EB2BF64224ADDC0CFED6A8C93CE346D9A653F16C3560C18A078D30146DBFA378874F62D130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 9732 sm = 000000006686539E267711CC53D8B185DE1BEA3A8484A81CDD6B6B0E46CD6568189E74C033347FA34BA7448CD4D56964F49F730BDE52ED29F39B1CAE52DBEDC90A09415613AFB9FFA4CA8FF0A1C2FE2CCDC30559D5B553C328CB7D274CF36CE9104C96584BAA8EB576112AC8ED1BC3C20B09B7985E5CA1956DD1C3DCDC22628B1F901162153A5F0C71B1159C1481EACB9BDB9EB4DED57C56BF48661F4775A35225DE9D2EE101EF5B13D4DC507EFBA53E65FB539793ED8C45E5FE4763F0CAC9A29C5E66851528A4BFD1D6DBA65C7F404041CC51F47969695388CBBC506DDA3E940F9137B1E47347870006F3FF7DD32743538EECE9616E083B98BF9BC4A12CABD07B8755D2FF35D87FA3535E4A71CC53671EBECE3F0873B101013D42484FBB91435D6F763FD9817383F1FC1DDB9D7C26D23BC278FF71B1B195699353E0645FE1366E41F5786254F1A42BCF162BEADC23571504F690F39AD1EAE858CE58DA432C62AB78CB8641B1C66EF57F7EF37F89B44838292B438697FE9BA3AC1E689C59771D7AEFBDC6E5902C14AE10F94B511BF3F258EE81D8086942B14FDFC7CFF87C4570E508E7CA7B80723F5A301E7D5B757FF97878807C0432A1B22A76696C5DE9AA94F4A1AA8F5E69FD57EEAC4828EE99DBE12234E48A253102FA3FE6298ED6FB7572BA4FCE73F55E90CBD9F6F0D111DAE055BE32913F0275722C5EF30C2A1E10D6D6A783C2AACE4B819F5F9B5940B6C56D2F81C7B3BDF64EF04C81DF8C57242836691287201D11D4986E783547912E7F6A1DF5013A440DF63C1DF428F8810E0D530E691AC07820BDC33A1971F5708A3E7A5035049DD4944B8295F801582C73A9CB00CC39D1E6081038A0F2B3ECB5C6AE9C4B13997320557FDE870FAF844F8A0D4BC43DC21A71E38F14ADCBA7F3E9288F3E2612D22B8D5249E91C3F01A1F977032B7463DFF8EF72327AAED145F179E94886D5FB90ACB9004C1411158CE2F663C14C9C6DC9EC143F048F00B7F0F0979098489058E3D6AF2BE145603B827EB8B76F310D28461B13C6958BDD6EA91274779E59A5CBB750BDD51C002E808093FEBBF4CFE94EC5A51685303054C88CE780A72CD3A41FF87C89FC0C0D19B5F14555B99B813EA0046FA9D421287C14472602EB5836875B43EAF674E37D971DC563A89399440960BC748B916D898728772B9F5878191B66D626705194D259D9E1F68BEEC1B9B8895C4245571D88C52268928B51529E0099A2D8E7D49A9F766E903238F35011D0FD47A1E81039EB665108E4C6C7B4C62058F09E406FA3474A1741AF851FAF7B23AC344D791E0C14C685CA29478975828AB1516842998ED710FE128F48FB5FB3A63C08155E232D0100CF0D50ECB21D9049F34764D8724DC4E45B70E456820666848D0303384E8461D36EA162296ED6EEDE9BD81379F7329347521E4E40DF1D7BC30E0A8E41C26531333ABA5FFF195127D0DB72CD0AF27CBABF5D058CBA7DACA16C469BE9040312B01372C0EFF86F9731D10414F293702EA83D0AFB09741471A25543A8D091793D9AB64F89827A659E3B3D515E1A7DFF6D9A1CB220D1D2351B6C724383C4B20F9131D1886FC3CAAE8A853FD29ECBB19780181ABD830CBBACFD53C98661883CC31887868910F3406E821BD391C401B02112D41C31535D4D767D7AE42DD72CE68D8857D66B1CDB42D3E89EB6BB9BEB9834B5391850743E2FB46C8AC0BE0F98E5FC081409A6714C353C36A5540E163F57AA0A57FE68E2AFA78F331AB752173F3921B49E17CA30FE44412A904930D1BF967E9BD4BEE04538B02EA3058D0BE461FFC2AEA9B91AADF42AA65DA4C547EAEA680F4E5E5E6D1956AE8081CAFF8BBDEC475447D7BD9A9E8078BE92CDAD1AE866B55B593FCDCBA9AD2CF989F833D15550971A2B1731FBEA4D5D953E9E699721BAA76F564C39EFA91B1DC10F78BD396643AC730C45519FA0247B58ED7A0A4FA11342EC4789348C4FB12CCA3608E22B7EE961E6C7461E30DB4CBC9BBA8A29D722B9AA021D162ECBCDC90AAE91438D78CA253CA4A1394CAAB5F60D363BF00BF738FE348117CD26DA9452E1E4DE630074D61C1489E5DB6070417D44FE30D08926DED0EDA454D7514A29BFD8754A4399E440DBEE6B78C0F4F6D0D6A8D1F51C7E0F7D506EE906FBEF6E6ED4D2E1DD0AE58D55698A6E6B717326F2E997BE7A0CB55BD4E3DD913EC26911B595BD6331590DA242751DBA012FEC296B5DDB01F9779F939512211DBDEFA51795892B669773CDCBBCBAB4969FCA853F3030D30935A08BB3FA4CBBD318889E9F2AEBD3E8DD9428522FF3734E77B3EF92D382809BB455BED3E95E520AA3E54B7B6F5776453E7F9F6D821DCAD970FD27D1583CE527F20E0237654130E185E50CF4D62A3034FF82F32FC67E60BA74E2E6AEE1C547F81A0C38FC23EC9B8F60FB49D998448BCF6A43A995B44BD169B93D688E52DD7B964A5022A1F3117C0D0A61EE2C1A3793262BF105EA52544456FCA11B4F0177AD2BB56F4A7A5EDF483D6C04DC69E9EF95E313B526BD2CA11FCD81149033684A733DCD232E2A280492770F6B264923F975B7DC8C8A5774EB2CE5EEECF7835FC6860E7AEB14EDC3E1CB2700B6160DEDE5DCA58855A70B308E98C5B2542A5CA6A7AF4E94C0A58E0C3CF905AAEC65CF04897BE10A426A359BAD9BC70B5B9401AB423C9159EBD60965674BE8A2B3A8B0DD37547B80E62840F75E4DE979B936E321E02F42EF615C780498C801DD99F0B361E0080313C3576FB79C88749DD8533886B110FCCFF387D0883035C0241C7F568D9666082D66FDE31DD16B8A1938CAE11FE763128D2C973574FA48C24E1C90A37CF221D830A9D1712DCD3ECA38D6EDA822EC3EA2FCD4ADE875CCB990076EBF4F224A82AD779C97E3B593DAD7CFD440D1008F122F0E4BB6A201E7E86258E90E5B2F212A2B348B9E1AF78622BE875D2293505CE6693D26BFBF0445B63D0BC1C25B24593B2B978E711C3EFF6B5688618CDC5EB5BB11A18D6488FC0C70F7B1DBDF325A4539216FDEB8E392B8C1034BA9B603EF6ED6473C8A53665C9D1A1E80B96EC50C9D5A20BA05EF423806458F7F9B9FFB0C407A2861DDD3AB3DCD110A34BBA2977C9630543A13A226CD2F66AFE92228D79D91AC8A8E64AE8481E63A3C0C2A97757C8ABDE5D993691ADB3C308698A6B2869C1012D60F6D82CC77243095B8EE6C3F38155C5CDB3C314B8A1F16553BA0F3AA85FD8611851C57E1AF1E0684F05883F772654825F16F8D27ABA3AD42EE7BA3369033B20A0BAC878286671A43373D0532B4FE562902FF31BAF65A90413A0234250A9C24358F1E8A18845E2B8BCEA3FCB2935D39C7B81551EA055339EB2BA7CFA2064CBE3911FA3216ED6842BC4656448871D9B70F73C74D347A6A78CDA23A0CEC7164B5CD5A176617435A1EBAF7A98E36CCA820B50F6A0FE07F09F4BE1C8E86C5C583B001A3BE7CEAA41994109A967D84FEE131B5ABBB38D730D79BB77A49376EA5A105C711CFBC0F7FE145BC3D2067C050A13AA92D7F0F1B312C8FCE42E4DE45706FA2481375188D3F10659514E97D5A5E1A54024CCC8F19654DA2B7E5CF571C13F525E39C117CB0E7C4DC5CD27B44263DDEADC59DDAE0EFC10BFFD525B0750E992D7EE6B47FF94D0C6B5ADE35DC9CC23A1B8D464DC765173947A8347AB27C679B5CE60B743AECCD58BBA4BDF44657EC8832E02188FDBF2B6D9D3B18ED3C27E503AA3BF2517DCAF9D6F937F34FA3C6BEB756C7DFD1BA21FD55F87C399349651BADE09B047F53932D36CAB6D9BCB2D991A3224602B857FAF27CDFC3B46400F0481AEBE3B8A744B973169CE5A06C78071821E8E644CD5B66573991C6C0390B2B553534DB4D0748FB63DA09112D58D75525D6F73C94BD93CE121BE6789102B7A65B60A4EACD5C6680A6195A3038EF74263D961B1A24FAD476D6697E4881E0F7B70AA830E2AD8B52954C3574A46D50AC6EBC5E14BA1FB2C986007CEF0068C809BCE684671411C783A766B7307675CA4D04B0DD86442B1744ED1B8EE018F83D9D68B4FCAECC66FDEE75EAC379E19D0DBED5C3473089EF153433ED2B558785E0413821C2D80E4EE91C2DBE5CE074B6FC405433A00EADDFBE023E8A4C4C221B36DABF183FAE588D0333871DF98F13D6C6ABFC73783BB250875C432335D094AFCD4375BC6337DEAD712E837050FB0C9ADFE917B176BED05D90333CC981DDB972D03A1235787233D8342DEFC761A8942302E07303C19CF338856596F0E7B57869F823161FA631F2424B8C32E2A05F45763DAADB4D6502FC794B617D6A6591FD7778BCBBE2AAE927812F0361953A835E716192A3C77C4FE7062D2210042D190514CAA2C62958ED7CF63321963DD1F310F0237C988B2CF0201223930C55CC0E4BC917410D50F6751E80684FE22F1B64C46F54197427616762D8E11E0B644A20A18CFD68FC2BC4F12E00D0945696909464CA8256486CC7FEA84603F8C612A7B0EB6FBCB1FFD250D3E0B78DC6B3CB5AB69D60C2E8EE5ED147A571322C4FF0B72EA8E0AF97B46A366AFAF27FAD33998C8B7C12083969AB0743EEBC91AFC80DC24534B3620EE07E0F2B062ABC74CD98DAE3CA6875E2F72D74D4B3DBA97A2B93D3D855598C89F13BE30E960F8D7EFD077C1CB5E7D89A19EFBECCA33657C639CF92F8EFB0312DC8A2E69620F4030885B002E6F48686DC28455A44B2453A89779EC8CC42641A1E8FB65D371C2C71AB4B54631F2F6F7B7C99E37B623D1BC55BD54576817B80D864BE46D2A2E802DAF1B0148D77F9CE21A3881C23DF956737D29FAE6E052D9AC14C5F6957B801552F2749A6FDEE111A2C5484610EFE230126A005D2BD1D759BB213F974B243797EE9A20713513FE4A32883C0D1D319FBDDE35C498700B0E8096271224D1EB627E3FDE3F54E2D566535C5D33F2485E686D4B56B0C674BC5D6EB60C81488344A32BFB02FF5A309FC45088769B98930C32B2A9F269EB83E3AA316C1A5DA65BFC5C28E26DD1CF6617F5D543319DE20054BE65EBF5E4A3C1A8E39498C519DBBEBE2974AE52CB322CA7647F07F615743B1FB9F8CB2354FF4A19406D59AC8615CE015A50ABB6F308B229FFE6D5FAFB71CC6F745131BA7A449B3476C7FE7B49EAE4CBD3230C2BA977BC68E6C13BB0035F79F364E480FB36B2BC032A2E3CB6B202674261F4D1911468E9C95B6BAA96FDE0EBE07EEB47C5BF9ADCFE3A276F79C84CFE48D3A5A9A2BFB656C8A9A87B76A602508018DFEC14EA398A05022011B056386BB8FB9F62AE55D7110889D53098A6E17DCB74EB2AB09AEB036A236473A939D5C3E3C42E7C54DAD4EBF48627C2A12BA56F6A9653B7BBB68A591C6B28F8E64681C3F925B21EC850B49EFAE3CC6FFF5CC5BB741FC4F76614D9746FFF59973214609723BE5D81F250291EC4340AB735D957B6315A88A54A1E34901740EE82FCD7B181F03708C1136DD681D1E75012CA308F1827001625E7E2DA5E183EF8D5EC42C6C158D567E8CD1C700CF8C77836D9C1FBBC57A1C24CE4DCDE060E084F27A6B6EA7CC0456807FDC54031FCB8B8829D749366D1603A5DEBE435B76AB7A47DC8F9DFBC4C594F668B17E2B91AA264B024165BABD302B3D5084A723DDD30192BCDE345F2C5016C2F9DA6407B5559728C4B00AD4A45803A84F74E8DDF421FA6D838B9097AEDB9E3AAA05841A22CB4FA5FA9CF5A69B9D592AA7FF2D9ED3B86B2F9F517480DE548575F0AF25B1A567E38891A9444E997942D12FBA7B901D1A8A66967EC85D539327194092B2EDC62631C56634C1FEAEEA62CD2F32310D41DED0D89B0CE73C6E973DAF6ED7306E2C06FF48D5F4AF9255F0A4E4378539EBFE6B40A987E4F2BB93BB3E2D4A5967C918D63FF56BD89FE3C91ED40F4969D351DAC55C03F5B5F6D77BB8ED9CD99CDA42B176351633FA4C06BDEADF1867B2DA7D68D5BD5F915EE4988A16C8472450A47EB217310E79327FDB829A5B2DC0878026BEE3989D15481FDD1527A6D9100A3711FE95DE06C769E78557653CC4F713FFC3F5E7FE129C80C30860EF8D5D7453E6AE14576AC95F1A18D6D116E4AA170E023653B391D7D13CB1463C6E6D861D3D35FCBB8218EE5B5ED0455E20FC7F87BF1A268DD767AE2B17E2AD3552D6A61722F7FB75D69168C09E62172A500C0B93377634E642D4F640330DE54AB18893DDE617236D9182534900361C2DCDA629BCF6FF71F8BA270DC68AA4A984A72F2A36CD3C63BD36662115B9AEB160DCE73AAA32A112761BB3378DA1DD28F6C4A5C39836BD0E4ED8A0091537190D10F84165906321759025675F7C19164B148F4C86ED0563E116F62ECDC327160DFB11BDBC39364268F96DB0221980B5510A38DBA62A587F6D80F4080ECF7819B5EC949B2856FD2AF0DE295274718D859D64FFB280C63546D27C98873505F49D23DA88DF5E3052769C28FDCD7AAB51122FF764AF782FF548DBB5E2FA136BC20167D03193146DD5711C0063C868376E114F8528159267E167FD17286319B743D488CD77F374B8A2FA29FE4C5E71E5D03D24016424B2BF10CBDD9495E7352F040A48F46FB33690DE20A30C0ACCCED872430F7A277B4278BC83939E90B07B4B548E4D541491EB8B997C17825EAFD7DA17D01DF34EA9AEF82FFB981BB743985F0FCD454D651421DCC7ADE9649559401CF7D7E8812642C1ABB88EE592A23D253F8CFB7B3F1001AB8A68DE52FAA65A44D75418DB889DE8D701580E2C7A9E96E5D00D7DFB65577EDE71019B3D2FBD83D275BD4E3AED01D19D40338F720CCEF2676243E67B125DDA3460A96FA4E19ADACD506BFBE751CD3F3E039473367EFBE4C6F88BA0A749DD9A6EB07C40CCF69D3560F08C7EA7AE2ADE605332EDE497369E08D04ECF303A30025C2973BADE39E4A5C391DE0619C2785A646956A908271FB7F9201515F8952B287E61509B3939CC97971D4DB0F146A2B6CEC952FE8E215BB4A4C4505ECECBFAB113AA354C3445CC9BB61CE42DF11EFD55AE81A115D073F7414119EEBFA05E73D43A2D8FCF1CEC1D7FD9F0D3A1AAC4E5945A1D8400340D7E8B3F1701DD57CBD4261AF00736BC254993A9A7516C849967BF35BCEBAD46ACD20EB2C4DBA97718DD21A269EB831E429CF863474CB5276EFEE181EB1AF88E6C1AB7B26C6205A8178F006AA0029F7E2D835D4959A0BA59348BE988805AC9585172CB1AC5749644900832A67D493F54E0D898E7606276073226B5FA8036437067D193C744C0115F5C71E345A48F96A4A7B10E58D79B9A0EA10C545DA202CDA1B4AF08A968B218E5C43AB295740FA5D36D9B611932B9E0682A1EE6D5DBE228FE90E9C7E169748261E1C566EC82308884DB143C3B5C73674360B0302F946C4B9D42654B52C36DC38235179AF6149A395787727F630E454C76CAB55DC551D0A84A679223D10C8EF900328582CDC82416A30F344F42A77E3DE415BB98C6E39622DB30F3EE02C62E405A5DA0DE9B07FE58A72B61B60011C752C01FCC1245DC3049691A145558AF755BDED22872431B0FFFBB7C2A0994B3D48AC1EAFF5EAB329675498C77ED7B9520EE3588A35A48319B7AE6566F002BEBF7B39BA6A194FFB695D092A26E35CC52A2106A391178F000C931B080577CF88BF1498BDFD153C8CD13C4431966F9F4AB5A2046D5D6BC3E1758C9CFAF8DA5AC283A1AEEEA5D9B3DA041653047A088F4D1AF809549AEA457D02FD4DEC195454F12E6386D28E54A26A4F0D180DC2C86D7E892E82E29DD66E252EE56EF1F0F9E5957642BABE1DFBCAE474EED94D756CB59DA77C4848F75A96C16C5F5FA4F162DF12295985B731655D9728699598D2DFAB4E66D9A4B2A8F8B6A20FA28A8B50F256FC68626BC83637BC9604E518DD6386CD4E2593D63AAA722269475FC42F22787FB75FF59280A452633564FD89CB9BAF7C03A59EB278D7E02B382FBE98F1326CA6CE1DF7A91C6A4791BEC4EE328A9DE2C83B771A939F7069C5E2A39AFB6F39AFF4AE266C4AAE3D59D99BA1E9242A33EC319CA09C58F278CFB8B394DD6336E16F2452E155263728BEC16B81117A4CF98935F50767374587E4B7C82606AFD0CC4D2589A6A725D4DEB5EAB7F385E02099801D4C35FC384D5DB22E9C1E42361C7D10E82FB6919E74D58671F5F80EF98A29C800051DC8733A31E7D0F7B5199B93BA4E8B86543C9BF6472DCF27DEF21D432FA95263F5415E91766A1A01350C69519E728F1EA767941BEE87370EE8CBB8FAD0361E45CDE8412F04754DF98B94BDF12E42B6870169358AF2B12A0C99DDACDB7BA6F6E5EE0D8D81425E363B1947ADA640ED116E397E51955ADC8943E5435DD39E109EFECD67D7857B9A90D5344ED690E74CB0E074D499381374345BE36FC21208808AD9AA817023BB0515305083295E88501AA64A55EED1CE2D9BF856B6E3F8B7246F796F81628E623FA38F935EB2ED6194A40AB1FB08C82F794CFE63D7B448D9A6AE1183DF1DAAAAE8F4C4B14AFD727E5267714E7C731446F9912A567AFF9CBCDADD513B09D6C10D8F509EC9E42CFCCD6723B66AE50E8343085BD970267BB98C3553BB0C94F12169E87485123493623FC4845CE4D048E0709CCB3186107127DF0B2344DBA35635DEF2C2667808BC835D534C17FA77403DBD6549A9BB1C209C98CCD745E552786A268CC3E9D1BD62A980E1627F030BEF0FFE7947419AA8F702EEE5FF8CCAE5DACFCDC8ECC89670BF8E6A0563AB65FE27E27A47D18D82CF8003332F59DF37976DDB719AB48035169C6AF53DD2EDFAFD2512CE3B73D53859455B456D756CBDBC3EA9E1E869EE96002CAA7EB6A7CA6B786652E3D4F796BD25A912E159DB9EB8DBA66FFD815C61406CE01E494D29B96CDC5E4D44D98F13BC42BB696FFC90BEAE60F325B178500898B2561AF414B06C1603DF1D485686A419C4BA076AF518BA6A9F1FA808C75800BBB85CB28124A46364495B8617AA0D089B1BF88C681E73E9A692178DCBFECECBBB429323ABF29CC39AE714620F2A44C766360D51A25271F419FFDE94B390CC7018DE603418EEBFC3A0F88277FB9001CB9217DB8E44175CCC3AB8F118BC90B870BC4D07E656F74984AAD630DC431888301214C77E5468B0377D87B80D9959FE15BCB075BA4B99C7E6B265CDC537223BBE9C17A5A67B4B02ED243AD935FA8C76CC9E287052AB1473FE17BC4BFF23788C3FDFA8FF286D1EDD9EA3DD9518AF14E4D44DF1521732D0025E70A8AF60C121E236047EBDC5A26B287CB844DB787FA5C7ABE6A06038C1B17F40B75335772ED71766511C2A23CB2A1D82313BCF0D5B852207248219D195CE87C6F4E0A9D7E1B35D7475BC5B0FB5F4ACE00838CEC43F4AE4A5B6C4C3AD49D6E83244265626747EE6ADAB13649E7FCFD9D572D0939B348FA5ADB0B2F9F2B90F0080F6A60473ED136BC0FB14DB1DAE2AD08EF52E2919EA92D6AAABD880EB0FB3700D6F53B7F0F01117AC44533815B47041EBCF2DB565C908AB57DE7F980B5A1C53B627D423395C168A4201FEE645CC4AF4455AFDBD4B234160B7040E51834BCE48272CDF08070EB738D7AEF2B8B5519BD005BA5140E230C2AE07A24C4FC0B22579FF144DAD576466D6CF76C2CF3C663F5E8E1F423C2F516954B18880963338260BF4DA12E7928CD6FB411F972C86929192624854B7BFE2115FDEFAFB79ED3C084E7969DBE364FF5E57D699B5B112B4DD357A120665841C35C3B9A53773A341BA942FF09979C2E9C9C01F6131784168814A10871B63F3BF9677DEFA6F559CD700DFC65B95F6592C0AE664FB9520FF7CEF970453BE1B2A86FA6DE1A445BEA10BEA53F01345D227D25F2C8C5271FB0446B8CD5B9505FC5528A96F05FE8601AA06BBA137F9CC5251550A1BA82FD6F8409102F9510878DB871D537C67788E5D4DEF101154318C52142BCE9C779696A70D710FC247E7C8BFF58B36ABDAE37EBFB1AE8D5A5E2BF466632ABD26A05EA4BCB0A5D93B3AA47AB700AD3942938B4BB272F55B6C36B46CE3C4C39AE24B775C8D4CF174B5B30057FEB10318B0FD88B576B3408B22B49224D6E438AC84FA0A6F34D0AFC0B75A9102CD5FFA0ADFA1ADFA11422C450ED66C55C3FD4D062F978EF277E5204F434FDCFD5B6AB953DEA57C7461A62F631BC72928B16CB3E906E166C0C1ADBE398D0186C6376090092C1F12ABA0452FAB0FDAB00962023CA033195870C5AC2800B0CAD8BEF1CCFB55137D3C5D3EEEA247FE6391BA4FAB13D7A55BD3EE5F92B8C79A6E9AB6C24F5BF992964D69C1DC6578D8E09EF9FB298FAD5BFCDB62BC2665F2ABFE6DDAA0A1BC5D8351AC1E7B83F7BE92AAFBA85D519B9F6196A4D3778E25A9AFBB2D0780F416F3B90E68BF08727B9956CAB6CAEBAAA12C2CD0D6A481EE770AD66ED443DFDFF76137A5EE278857AEB240E44068898CC4083FB758D173017EF9A6A58A21DF0E11ADEC122926F68B292DDC91A9F8DA849946B52E50D682ED08666B90EAB23BAF484DDCA47F051EDE5E1FC1C67A4421B40598075B764BB78BEA5824AE7C71364AFA6A73D9EAB7792671614749FB76FBD9585F333003BD5C18BE3B6BD291237C7E315E463E225D5DBE624D2665A5A81AED53432BA48EF2327F375212019F174AA2412DAE46F7E1BB4C2E002CC480522332ADA06504F1A8331EEB21718BD62A41DC79AACED15EB077F664851BB4823454F3FD0E1747556539FF3AE95EFC2CEFD22CEB477A7B475B5EE1C200F0425E774D702126A7DF653128B09A0677D4E2732E2F8D4AC9CB50C26CFAC734B17D210E994DF9E54F70946F0133B56B520A1E184CF9FA3CFD6E930729A8653A899DAE11EE1820ADA86DB0785079EB8B1726A0339E8D3153F989249A00E2BBDBA4C1A887D41ECF34FD5A7C217BF70B47A733B5DCECC55865DBCE89C4DBD665365674327F4197D6EA82E2BBAEC16EECEC6C193921499A3E5223332E9AEC043EE5180ADD4083EBA0C605A3A47E717E1DDAE6FDA44A762E7E676BF231AFE77C234D1C73B6F9B690C08FB67B34920E5115D8524D900923025F033880359B0FFB842647E589216BEDDD1BDAF5E76E73E1C2D80EA2FE7846490793EBF8108BBE66E70D534E5C49D8F1D06DEA168F39062E92CB996EF6BFF72D6AEF92FA97FE18C8ECB177277CF35B5D021DE16DAC6B4844DAEF9B2AD79ECDA0E95A6FCFCE4370F4C3706EA64C7DF8070D1513C499ABF8CC4881FEF756053DED9329AC96A534AE5E50F9B0F3844A96C5F6CEE9DEF4BA1B29608051FA384B3912F8602CA72BE17BBC5CAE71B6189F9E6F54506CF27EC4398E0312503071DFD5D5186571B24A980DC95A24ECC889E478712BBDDFE6059F0146B2E0C3D38BFDABB019D304395C9A38913E6443D4A1BC47F8B9FAF7438A1E6C21A1E6CDED75C75D3A285AF1468AD83870F16C6C95AB3585EF0B888469887358270EC3E39D75F6540E77BA2EC7C63F9435F4D91A718E706C41AC8BB41BFC2888AF84E7E3A6088087D669098AF90EA6D92E9BBBB37EC26C1C9A705B11C71A442D32ED65BE2D79FA73C2F99690A21A627891F2BE73403F0F7919CB63F96A2BAD0CF275511DE2A3AEE1C28E83386C2814911CD0BBD61608EF9D562B1F251DF188D2E40803E3A6863D6C00D67D8869165EEB55D977A6C31A70691496A56A0AC6338ADACA88AB590597E016D913CD21A91D07AFCCBFBC32C6BE8B19121EE42FF926B8F55106D15B7B6301E6B0E456EAB19366F057C9FAA8BBABE4250F4C418DDA374DE6988F843B7F71517B385A9A1CF02931A0D9DADFB417722E17910530EF488309474E6D9DDFF56A5DDFFA3859354FE34B93FFBFB2986795C3F5D858E00B8CD6D5C30330BD1A0283CD34F28ED1B4F4832AF142579299FA4CB3DF35540F247D9FF92B7E9A53BB8F72211627E71646A7545424C4A9D7A37A1D8F98574C14907FD23DA45F811CB5AABE618B3E1FED837A80106779773040FCC9D37EE5715DD26CFD151BBCC7BF045B8672EAB87EFC08A36ECBC52FC5BAA7662A4DC4B05165A87B8D0064114CD7836FBF0E8816843C48A8FCADBB6A7FB88801F98928A5E5B90C63DEC0EA0FA3395D402190BCAD7718FF534030A15444CF7658E15BFE22A447F3E23F7CD3B21642364F858C75968120262406989789AA6381C6C7535C2EF461B882A555A1BB43239564EBA5E7450722069495EAF1D3A396C45CA714A94B1C38E13E94E14249A8CBAEEDD0EB6A1F867221D94D164CF5D47DB5C759708AE19D193AC01ED5DD678BBEC27E908CE04E5F45B13648FEBCF66AD7181BE682028A9F3C137E962B292AE5A1D8A661085461D378100FFBD3737C4FB6B436A85B851F5F823A0BFA2F981E2C0379C626F2F813B3CA1708CD9D844A8044A917DB24EAD379D5A34E90E3546AC2D9121365D162CAF65B3DEEF566ECCDB449B1CB773057B21BE4F54E6036E1923FC486AAA69AF01CE1E29A3C89F78DF91A71F1145A92FB5C12BBB2D4E43210A60286263F56951307B13956F7BC1EFDEF3C8194B815692D4B71BB74DEC510CB396F1D903FB30BF8FA8D845915B74A537CEC2F5BD6CACC6E0896A10B7FDAA6D1412CF1B29A2669A3BFBED70CC9A6D3F8E782C5AF72DC54E3D1EA0F88BF2BE93E0EB4479DA07ECDC18885ED58D555F8BE63A483C6E20A875928081C31DC62E49E550D608A6EE22480FEBEC0A3DB64056A63C772DD0C14B1D2A8EDFC0D3A799B008B5D7C63D42D1848C06F43A974DBDB5334F237E6C21481E12170947B7CF9EA5E81D7400F79936FB292C1E1910F016AE190BC1514559E027FBD2C85DDB78A3230443DF8D1F35FCDC73FB189353361C7A4C819D3FFFA3CE11E6237664C8FBD8D0AF7AEC9C2C47D0DF15B588773520C10E0285F00299584CC25D5BD18DDE6DACD091C1CCB8318F830C6051D181AA29F3863B0859EBE1763192D55AC1F413982692F909485720BD4F9B15A9EA968A63EE3F4A698AC73B58112D644CC2E1EFE05CAB29911A95C103284C83290F67B83587BBE7556294C5225374477D7ECAF9AB5EC9460765E6A40DC75A84EC417263C50D22FE5583FF9626977B8826C06E160772D6B0506861A86633446A807183935350D91EEB5D37414CF3BA477AE353761B74E05BB6DC167E86FD20D1EBDCF5C7F6AE3C16116BF9CBB6B67BB564009B597CC2CA1B16B7B3B484C6B172A817AC71985522092AEC980B2FF393DEAB2A375CA8C894A68CFE3DDCF7CC0D468B43C6531A58723A8BB14E201B277155AE268D6A3D15933778611288CF4B0BF3A33C30C1A77AB39A8E6770125995651FA889FAB2B28C87DD556DD7260ACB83D691E2B9DA5880BCFBC2EB079B0D42F673A8064710EE9CAE5913E37500A2BF7FD4B6BB409F511117323CEF7EB39EF1BCD8096E4EE0F5605D58361BB74E6656935E7B075F389DC49BE4973B7C6EDB05DD051E120406EBE62FE8A1DB88A91CDF152BFD790E3AD2308C12B75581541C17666CCCA89933F0BAFD5A0D93CB983D087BF3D1D8F388D22F6B09BC3418FB7AAB26A5754CED0B1F20E1DC38A0426E818B22F34C296DD19DBEE2F1E048C65EA766F8B9EAF074792D83B2C35D363CCCBC4516C9F0FDAD4B07A3DC3C44A9D27368A57F7C52E75500763BAF2CE58C0B9520E1CF94B584D0D9223312ED434D305314718BBBF41BD80668F2D6ECD82327BBEE9FD960898BC7227727341B863F9664701B3F77A1E01155063FF685D613EA39DBD04F12F9E72C840A286A1DB44E63C1CB55527BF3238DBDEB31328477B9089683B1F07A3A0034660ED39487C43D1DB76757D3F0A1D0B52C26E6713D66CE20A818A113D19E5A312C5127507A3C41 remain = 1048574 -max = 1048575 \ No newline at end of file +max = 1048575 diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_256.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_256.rsp index c684aa186f..1c1436e12d 100644 --- a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_256.rsp @@ -1,5 +1,3 @@ -# XMSS-SHAKE_10_256 - pk = 000000077B563C8B187847A60569B3A0CD3049A5DF6CA3EA3B446D75F99F8D37B940AA9604562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 0000000700000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A7B563C8B187847A60569B3A0CD3049A5DF6CA3EA3B446D75F99F8D37B940AA9604562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D93309000000000001000000000000000000000000000000000000000000000000000000000000000000000000 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 2500 sm = 000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E651324F8D245291EFF735334671EFFD85F3A823D972D2D49DF408A2AE09590B24CB219D4BA4FD030544953AE56AB3CC426D1E89F8567A33D4ED495164A01434E617E01CF73FA1022A8E19ECD580802F2A359A6BE287236C711249E8CFD26E81E0D962E4E6007A684AF87B096B9034966949F56D02660E2B7279214CEB93E62073BCA7A334E8928210CE101C948DE9105A5FE3B87AB9741B4B4185D7EE42AFA3055430682E22AC918051D97466B12D2FC559413DEFAAFC677C8351565ACC58D481259F0F41EE4C3DA4365AE4ED4094E4B7406AB6963FA3883037750A6ACBD864F56826811C4DD77FD89B17FB35E2EA7C907A056063335AE03884B54E791EFC5B68DCFFA47AB17563DEFAC3A51C0C7E96367FD2A5BDB6420DB2F8E1FA8A1E04E02B5033836AC23BCDF359C659C13E9237867828AF0F173B3F932629847BAA0FF1658833035CF78699FC249FF331272A068D55590E7451D2F1C118B8DFE554FEC7D2B2E0B494B145F9033007E7EFF53151299DA3E5C48DD1F35C37DE0D832D55AED0433B04149A965F5EF8A804F0E6EA4239ABF28A694648719C1A4A315A4EE054B04CAE408D5436A081A948E75B7EF5914E0DD9A9D01018918CBF37A224824D0B936F9E659D7C7663EB4B63FABA90515F2700301544682570E6B3EF16C59082F949173C93ADEC1E111F387845B826C3523FC184B5F1D1D830191C88D1F9F3C3A81337495F73F2B992EDD1E9D930F098492BDF4DE0C16A604D71CA275176A5C2148B151E1961C11F7D8CCCE4F08E9BADDA88E17BF2DB02A6D1E1D2827021DB46592168223ED5CE3170858485437C132229DB3823CF7D727E8DDC6B6BF00983947D02DA1D6A0C82EF62F0B0A9F1FBC427D200F636E66DE934401583B67DB03BB8492A21BE921E1C2CC0ECBA29139E304A0BDF7123670D3FF614F1F0E22C7C8E161E91E90EBDABC3BDA8347463B052E4E97DBA22481C772462763AA738E424431E22FC0B8441A43735869308C228166FE2041FE782E25EC9ED80EC9994EA098FDB0782856925994C9E8FDF09EC353677934D465C348E01FEC000C30ADC8B85F0C19844A4E6B4D0E8F6B2040D9CCF85DA7C9522BD571EFF09D5B1561225886FFCD6B788E6A6267ACECD693E42C90E4730F2EBCF73204F7DBE114540F4AD0C2CAAC6D0565C6DCE9F7F1C5542DD0F7016BD1C976AC68FC2C45E702D9D428999F9041C8CD89B70FA2A90286D7A5F6EB267C45893AB7A9C0E9F75889E64F9A24ACF8963268ACA48B903DA92B5D86FA1C5E8DA5C12CD2C030F11A8F670E028AC1E3925B5D70E7EF6E258B5B1C7F64D767098FA20C976F74949B4BD4792A13DE3CDBAB345B43C1900F6F63F45D02F6A576D8E6234AF7631821A82C758CB0FE7A920EB689186D83BC6D34D4FA579D07F899DE605C6B6C53BB3EB5DBDDA07747CD49164C54A9BF8A9F6A9548A58E119830C4A1C28BDAFB0F94E7539D5F73E2043018B8FCEB218AD24D0B5AF139DE4BF0968A70B206EDA0FF3324096BDCB13A3DA1C550639C0606527E494572744D779FACB63A81CBFD2C18FDDF4883B35F19FAF86B48D5CD2DD9177065D7380AFB479A59205262C98995C8EC3B26E648E01252E75EE3278581B71C84A6F9F49B0EDFFDCE1DBC2AE84F1FD849E3E1D049EDA6A5EEFC0E5EFB68199B40274DBE381ABC0C1BB6336975F1CB08EA7A875241CB911B9853025F7CF48F75D4FA0ECC39C94887E71903538BE9408E8DD1AF757ABC63097ED308C7F0EDF784DBDCE94CF1B52C96E524E7179C8ACBBCFCAB586CE6CDAC4FD71787904D4D19A3C95963CC8A0B0F4073965CD5FEBC875F971ECD647F269A6365491CFB0E6F0908347A384EFBE009EE5ACD512C88DC34BB54340BC9B1C0CCA389E8BDE6AF14B3DC4672459266931B482AAAC2ACBB4542B22D3D25E2E279700167CD7AF03866E60B41CDBCDFFF1216F45CE0741C53B57059C2F55F8D2529C6B0E760FA3BB04A38153913A2A372B5CEC76D57348A81842EC2A2BA6D8D23C976F3CB9F3D349A8448C04962D6B064AB2B8D48AD48F1B221B7BBD9612FBD83C101B7047D793FBD30262FDB21DA3610060FCCE410A86D46779A61C7122F5BA45A814E46224EB6D5969EB9FEE6EDCEEED25B698E4E83CA574A8AC2896FBE20E91DE3BC759FB39137FE7C26A9201D40914CB387223C9F8937FE6F5503D7C207C9330CEF1A170F355484FB1A3BEEE3253FB58D7B532C7885549593BF2984B3D6FCC2E70105FC34A1CD9A85B5D7EEB3A3EB4F07F2E7E0E649042A947B4F9D9A5149F0D57913A7EFE5265E853091C4EB95FCB9EEC69656DBF47ACD54F0045644E95BC75168F17C797F9E54C42DA5ED4E72F3CBDC54D20135C64F39492E2F2F577EB888047FF44CC2528BDCF0F387DC53F045523D40423CD4BA0626CF907312F5314FD59BF41A47F18186B517A59C7B9BD07FFF6433631AC5C062DDFE499E0C22DC5E3A10AB8D8D0C5D9A098331052A74A72C2599419F61A78459B45C7976E43E96BDC2EBA3AE45FFFC8766D70CAB36512C02951240FD5ACE420AB2C8CA931E1113F541C8439AADB13BBD01D08553C645E1E8AD6AC0BDFC48F9179909E135B6055FA9CBA44BA072D2A538BE604D931A5E3273F4F5BEC1CAB03D56A297B5EB5AF99C83F60C70873CB17A1ABB1665B6D7DAB0DB36359457BE473FBD9078313419BD89B3B947A46C2FED48F0CBF057F179016B6DA9B9ABFCC164E97B4E56278799D669385C5F0EE1BC47C9DF611F3C69CD4BA07AECE7C31D5EFA0A3D8FFC137CAE208E806DCABE99584F7EE28086E4A338CE9B8073DAE5D30A9571B807D43788E72A7A499DA5589B7C5BF91173A9A93A386048112071548CF0A71C9991DBB3A11D93483E3716D9A8BAAF62BC5BB58B991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EA6E323ED6E8A520C761F371CF760445A3E865E4B2524DEC48F47386A1E6CE5561FCD200F736E4CCC848CF9D69404EE753B6CA35671A40AA2B667270FF670DCE5AF0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD remain = 1022 -max = 1023 \ No newline at end of file +max = 1023 diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_512.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_512.rsp index 8cb2fae6cf..2dbce6b683 100644 --- a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_512.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_10_512.rsp @@ -1,5 +1,3 @@ -# XMSS-SHAKE_10_512 - pk = 0000000A28C42CBBFDE2F32EC67C1630DF460F62D15643A6B5FD3A53D78B5A0011F6621D645A874D43300F9F334AB1D6DB08EEE382C34931E9EBEDF37ADAA8A57A37AA404D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE sk = 0000000A00000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A4E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FDE028B6F5724BB039F3652AD98DF8CE6C97013210B84BBE81388C3D141D61957C28C42CBBFDE2F32EC67C1630DF460F62D15643A6B5FD3A53D78B5A0011F6621D645A874D43300F9F334AB1D6DB08EEE382C34931E9EBEDF37ADAA8A57A37AA404D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002AFCF3BD5578FC5A469B5EE30687A6686B9CF04E9AA88815B89EE6F2D170BF84B0BF845A75B2C303B3968643511D4AB568552F4FF6C0243725F291341AAF654E72DD805C798FCD5214B14616E7AC9F3A4EA6C211B319FC9009536A1772156E62E666788121874F472FA5CAB32BA174FD0B2218F50A3BE7BDF448263F84CE6184306BDB40D6AC6EEEB7A009144D47CFE5121C5F44044D10B0776B575F883AA5CD63B5A577409851707816E4CBFBB13B047D3902D0C7916E4C9598BDADB732E82166F10149695106C8A9F3C0D2CF4349B59CC5A66177FC51A7B1098F6D30FFD8A5D016AD38097C062E0DA6BA3EB4C8FF851503B97E7A276E026DC8D92C68F979D53F9157695FC63A97A9F58D8F92140217D196A9778CD52A9074348743BCCD068B5DF2D5B76943651822D37F217E71EA6763CED121444AA3570A5880DCF44CE21FF035E8EA8107430E6116C10485E4DC7792D04A9B9717932D621B572F42221F1BAC60D3B65D93007913BB100E8658968B0CA77C533F20B9396BE2A7DB9B233028465E54648E3329BA2820ACF6CF00D46BA0CFD045C20C6BA992AEE34F57E9C84ACA1E95C45E9EC6D0BF500A7F7E6626D5777DC6AEDB370A4B1EB82BF4CD0F63DED9A4CCA567FCACDA440EC29CC67A926059152AD7BDB3F3EB06813BFDD8314C365E490C41C6FD4A6173A13F4C4A4E517037315D0EF14428275919CC61AD393BE23333F7D8A93C59DF7FBD4DFA8235AFE88803BDD881CB8E591A721E917CE44103EE38CD499655B666AC3536A1DE850F3FCA9C393454D9BD6F0C75B11822FF23EB22DBA69B08D3F4E92B8ECFE9BE9432A8B445A5BEE8757C7C53DD96FB2058A5370EFC4368FD6B5FC124FA0B9366074719377A0C533415161E29C71D5AA85356B90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016A30B3920D43D47945F47566B618719C38844032986568606F2DCFBD7104EEAC5436CCD86E9677E05985FA63C1B6D3E642D0F145B3FF637B96F2AFBEADED75F30100000000000197C186BD25DEEE5DC2CE5B760508549B1EFB2F3E0A34047232BDCCA39B144EAE820DB1F2D3C3159D012D7CAD7AAB1C44E15F53F4B1166E23DB8AA23ADA9E23AE02000000000001C5A2B2230C54CCBDFB5F42AD8805628B6B3D4723AB84E514035694195F2FB7E716F21EE8845170F30D1BEF79ED4468F2A45A72853F2D8F601973595098010E1D03000000000001C9E730A265A6F2DDC4B0F420CEC9C7AC976ADE4FDD5CEA3B6D5445AA2562772F76635C514BC81DA00E36681EDFEAFEBF29B1C3078AFEBAE3956D74AAF351E35904000000000001B661B82380E38D5CC77679867BB8FC1C94E77006AD05DE9576A7BD210641D25D011A056637775E72395B7643018E0BA023747219D875DBA848A58E0F9D7FD2DA050000000000019F3A31924919E8711F88BC45477356D330ACF65BDA612F6AC681F64C24FD70A6AF08B3FBB6136E4AF05B38A9205ACA4A2773D100FF79057CE6EF6C3F82AA9DEA06000000000001EDF9A31569FF07104E7B2FDF78D2CFC2FB28903D720F4D2ED95AB35DEB5EE579384ABCDC10CCE008B5BF753154B78207E452D4AF2B5646C42B89EBDDFA02570107000000000001BA911C4438781B45414444B18E3EEB1F0E57D33FB8F1BFB5DF1DC85D88A29371496D214B1042FADF9F17DFAC6215231DECB7D4ED1ADE6272BA7933403D3BADA608000000000001D85DF2FBED8348BA8E34D08202B5F944A00F91F1CC1F50C50D2460DFF1CFF490D84B84A1FDCA7A5E1760FF2E3A392D3F4ABB78116DDA6CAD29E694F9A4691E3B090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 9092 sm = 00000000BAA7550F0E617123968A7F276A4E50664475EB64F4E5DC6805ACFE998B45C1E0EF24208EC4F8C326F4E4D4B36902314578DB3668398F8D67F573F98468AC125AF0437077A8CDD3F05F6FB65D3C9AA15540627956048C55BEF5EEDD31FF57A3B38C0C8B079A22FA8C4F910E43F1C71E52AA4F621B8D4E9EDAD6BED5AA7B55D96F5377E4D1C90EDCF0E9101E4EADEB45DF369CCE46AE87D9FB350FD6F71FD8A4A9CC7169BC7BE08AF160D9C4FF4E17133E98C694EF995B78898ED467ACB68D301AFBC96E96EA6B4C8B756FD955337C4C558D78FDF7853E9519930416E4CCC396C092F2480C530BFCBA340E102AA1FA9501B6C985C9C00FD8711A216850F91A5267A97E57A963C3BB42C86E365E37A258BAD6901D1F1AEC279CE2F14E9E3CA316DE8DA0B086DB8102A746FC5C3EA9C99BAA79F74F7463F047DD6878FEA751585B40EEED6A775CCF99DA0882EA094FE37B03BF42D843B2E58EDD709D0B7157952189D6E05DCF84D7A98E006FEB4A4746BBFD556FA25DC5CE32026F4D42CAEE72DCEFCD6E085205B104F30EBBCE03D9379CE23E884EDCB5844D875098A851A999B3C01EBD13F4EE2C95ABE76E4658ADE75DE9E73F3F531DBFDF366773B69A422916B9E3B033E015454FA5A31DC03124ED69C91FA12B18C028EB56FF8025D46272390E2CC84274FFFBC61E60055D6BEBB1D24D0482C00A7240A1FA86C3B28CA8B25848B109CA18B5ED836ADE7C00DAA6B65C5109ACA7CED72AFF32B9DC99D1542F41C2726028EBC437EE5C8E3EE2326E46546C36C8F1E3B85A946A7790C59D4547DC156441C09982CB02EA2B28D887A0345D2B62A5C2CECCC3C4083C35E47DBC096D2327AE64DC84C822D511650FFA8155619193E70B2B285E98516A5815550C699FFB11384225CA719CB1AFA38992E7315CEB3BD02ECCB6BE6A1FF8D0FC74B2BAEFC196D6D1D839F16BE25EF9C595BFF82613857E6C9DD1707ECA4BFA3790367CAD1D28A49ABF2281522FE1D9319DC6A73EA986345B69D82027777002B40EC9BB896570BE4B1E74DE3016325C72C876A9D93C834C936DF976F78F33D9407D4A5CE48D5A318F39B968154700FBD33EE81C800C09B7521098E565766EC58FD6F4DDC0E0D11BBC4AE0F8C7CA5B75C3D9A3A11429120BB71A44DCA86DCAE5D9C67C1A1189587D6753B7A60679E76A6BF91AEC1A1EB2FF181DC1BB11DD597E55F3CD9D90811B3F6FDCB01B351BA04F56B749C356AFB5656B4329036B44C961EA89F3E47F5A33EBBE7E3EA6140147518E42867D2B820117E6F7BC5D685623B4557D03BF5FEE5914FA7B01D34E14B398AB4152CE9A622851DD8C4009EBB1002B88C5AD6B75B35EDB4043AFC721310C9B3B69E30EC11597B14862B8A3AB7240FFCD4444592207371036AD8A221773700BCB0A643D295C56BAC055CA672FB8F9BB7C93A62A46646A59D1A8ED7268DE772A86C557C5CCE6C59C5449069A2DABFBBBBDF7F84C221BE0973847615C4A5C770264B54F110D2FB213FD8D93C19418666CEF1FA23097234B4DFB4F8CBC84610E6D1E65C654046AD37AF98F29EBBCC67B2A3D68BFA0F1541DC569F3B755BAD59BE5A6BA5AA01E674EE71E759A8CFBA7A139D5809B3EC21C25AF2F153E8FBF4D0051B455429C81B226A21F3F4DBF46E08143B20DE9CBF9D6DB13D5C0F51C9707565ABDF0666923B99E8D488D8F35FA68D02AADBF7515566B4A2E1F80A509BCB19556DCC4DC4849A33A16D12DF9C3C686FAEE401EDFD7625AB1EA6E122CAC4755FBCB1BEDD4627A60AF9396C950F9A72FDC7337066C140AF7F26A36F27D1840E4A93FA77DE018E1B1DE1F08319F6AC6FBC4146A9663E83B2427AD4920BC3AE2AA7077EB1D2A110201928A68FBF341E11BADB18CDF00B6C24FBDCCA114E870EE6272A5F186263C7E5AEA1EFE28ED7ABFFF79B369BEBC70A98F62C8F8734BB6D068FB2051CDF4DED516260F1EF5CE952529DDA4DB8EA91AEBBBD8BDE4AA50A2CF7CD1A6DD8C0314794CD5C5FCE66734368FE141CA7D4781445B16C2D11CE41AF9AAFAB28E5A8E067FA8224D487C792EA08E406A6AD7DEDA72DCDE3AACB4ED3F7E987C750A437E4315F7CEC44A5C6556FE705C289F2BAFB0B99F61E05E7D4D88448E69C9CD8D6EAC8A2E4FBFE862F98C78AA5B242E936F2711D3E733903E6AEB012E0E27F6A7C82627D8B8E82F371418B5810ABEE5ABC94F8D082C7F3301AA3C2C4E794BBFB5AF1144292876D83BE465B4BD50E677D7A0E2E58C02525AF4213BEA0FEB8749FC24D827E7EC6071C77BDA458414AA7A7C8DBDC876734BA2FD13137B55097D940F04B04A39AD0AB325A77A358A7E574C2D64E0AC794E13ABD793C43A7F561EDA57110C63D5914AF56EB4009FC4ED230171BBB7E8732A79E3E417C235DEFC0E67E2A233B8438EA0127F6B69605E557E7DAA8F63FB3D4BDEB9DB92A0AA5014C6D7DE78C198D4AAC70C407D913C414EE858795A40D73321EC677E002A0ED64E28831C61D124CC7BDDF561D3486155286432CBCBA1024CA40204016C95DCC76639423EC073F74D448D0319EC5EDFC78EA4BB3E54322124816F87C95C17497536F10E88BA7805B566A4CFD1650525D00278AC57DAA1840D81128754DFF3E18F558F0A1A64511A02E9B48996E0EA33A994D4B6BE0D16FEB008FCA38129221A016BA24D49EC85117D771C55B145A17607676C2879740ED02395C8494C515BD27A92CCDB65479EB8A2F2D8FE303AAE2050BE07CE0FDF0DBF8C14D193676960FF278BB421D184DEA70E3ABCB6655A05347FE032DDD578F14DA40F036A8A5CADDDE1DC293925F7851643CDC02BB7A12DDFFD20A50B50904E566893F127A01089FFDADA35B6ACA4EB4D175D4645F9478C6A8DBF03AAE51AD153CC4EA6A6AD03D60915D838545A168F8191E2AD373EC5003A969FD87908B2ACDA7D1E65944A9D6A125AF9BDF078209BDDAF31634204F077F372AAB28C37E81E125484288DF6799EB714B8CA9E137BF722E2B4C5399991AC63336E7EE9E787E0F14438834BB9E5159700AA990A68730B289513DDE3FA5C824356674C3D1C08207376582695CAA359E3E888891A7B84294A2E6E99D311FBEC1F596B69080C0FEE7831E72C15FD534954B8590D68CD8A28FD20AE0CA8AE24CF2C955A09FBEDD94C5EC08CA801FAE3AF107B13352A0AE0E2E3E11BE3BF96C0D07F7FAEF067F7507F892456B3D3EC4B58873F6C83554175954E8A4FD2989F769F0E0D0ABE1926474CDEAA1E573D10FDBDAA4E588E5FE59822834B0B629825213DD022085ADCAD4A28F447CCB257E1D969B66E6F403F8509C6B94725ADCADE52ED635DC9B9E1A42B11052D69F4B131B660CD0917974902870FDE186BDF628B61856C9CBE1D04D2E80A91500E9CD68095E711F125EFE9E32D2AE1C91B1A0136C0F5422C83421D97470CA298B6C9FE37A5148F5B224496653A2B36423AAB5837AF52A131B2CB89E875FBB99D2E032D1389074FB37311A15EC81464BED81B4AC47047E462734B5FD2D192D539A4BBD39DC8524EABA99BB69925AF7E2E2B3FD9B520FD1806F90533FFDE3784390214ACBA48E89657BD5246A6B5F626C45574837A8E1691A539F978FCAE23E29D31ACBCAD633961BC741153B77BD76B3A3D1D5D302C18F9DC589039EF815C57B27C925ADD9C52E5F3A6FC226766B3E165522B344F4ED2E9071854AAF991F02D2B1AA83F111A02B017E9033A48144C34E89D9EF73B1E598969870E1A41DA9F6A610616544CD5B981255A9542295A082CDD3A66CC07FB9F2D1BB4B7B8F64E129F69EEC185C218D299B827F1814C9D5D54280FB9110198029B95C565AAE7D6295616275FA799F71C790283D7B8AF5CE60416B584FED823A46EE48289F37B55EF27DC4E507AB04A907467A17C6959045595F260C9FC1D7A02B3F364E033CB1ECD9650441EBD6B50F0E44BBA7321D33BC39D9FCA19D3A0C0A4671EA68C09057FD6705A61EF6F924958881AFAFC13DAA5B3AE9876352F6DB0ED78AA7E1EB8A5C56B9D3FE6A808741B28200C381C08BA0890530633FDF515AB52544ECCB70B1530EB2B2E39AF49264BB4864436375AE62B8F9F8E675A70AF44252999A011BAECF423E511A8B6FA5E7FB0C467476520694B36AE5C0D475D3F526CB3668CF76973985D2536EFC73711740BD5C05FD3E3521002E2EDC65EDA06B81A5AACBB7EA5C3569BFFE89DCB32A3B3CF3F53061308AB5BD1AE1C9F4C999BA765ECFDC379A2E4FABE8E6D7514684A99E198A53B778E0BCD70AAE29AA52BD4F8EDAFF89D60E846EA0305DDC8D368314248917C2F0C5AD6B107374A674100776DFDF6D44BC179C305EE7C79E16AF07AAC4BF858FD677916EA65213B1987680E3507E6C976683CB9FBBE0A223F7B2AE55E9CBB1B1AE83D8971500AE7AEE000660C989F6A3979F74D75CD1621B0D5A8751189C380579671CEA39D0BDBA4F1A975E0956077D8599C60AAE9192963B563FD8C509B2B3423FCD52F974B89C109403AE80DB6D82E5FDB28D3D6B62850D6E4EA7B71B982632C4B9067A21D3F24DC18087A335325EC49F747003438F8F088EB80861F6C1D9446EA350450C52438EF91E4A61B41BD6E74D8516DE54F6C0F2572FAAFA731ED95A6BC399ACEF17419A263F692AAF04136E62B36BB271F3D949667BB84823B00A8E5B8700FC1795378146EDBBF022F938AB6663BC1367FB1F937BF6085115218C5A3CBE7D732D8D62D2BCF54B116B7763B4ADDB6144CCF34A8768C1AACF13E1894D84082CD242E3D0ED236EB8A7ED4E35C8E72D9CEE34F89963577D0D0CA9BE8985C339B429417D816EAA396CFCE3C1A40898FC6A3DE5736891F81FE5BFF5A7EC9DA88F5123CE5126BE7F0D705CD2BBBA5B97B0EED10272D0A7496D81EC612D585F21BC5C3237794CB9E83506BA93D96FBCB62AD010ECC406D3AFFE514AB8607A1F8D9454061D760D417E210B89015C1DBD1C090BFFC39BA761EEA223D93774E7AB86F2B03B4B2A25BBF56B413E734A0870100C4F0F05B429FFC0F93BC98C45EEEB806A6444ACD5C61E8E241E93C47F73F244D38A0EAB2EE9C1F296981261F179F9AEDAB136B73950F2BD1F6A033C7F33B7E5BD902C5E9183588065D20F6C8DC3648B35641F3A33A81A430161483838FB206EAA89841888B93AA8FF8F5A3BDB35737997120E2EE9FF2409B006020641B51D8D8DF939B04103D63C099B73F2D2878246D1802AF9CE44723AB19C87FC23CBF7BF89650441837B72A1C216F7D12F687F955DEEAC751232B3745DEC50BD3E4C2575C1D13FCAABE57539AAB71694D548A9CB6C8EE765C95FA453F1630A014456FE25639FCC61CDFFCA8C41032617561AD3425C82F360320C1A63E0EC239915E2881B58C183BA66DE53330BF665C885ED53E52F316A445F35C143B80D22A999E5BEB6482EA903A3F1F76AA262A20793A9A1B2727BE1131B53AB699D0AC5B2982B9A24C590F92DA2A257B1AC570ADBF5E396D41ACCDCEC44048E7CF77A8A480360099DAEA1185A2A21C80DAA70B0139F3C3A18577D31D5A52C2B1121C25DD7C41E3735DBA3BCD4C0C94D296EAA93B096EC9918D5FFD60F23132D5B11687FEC66CA0442D6846FDA79C9A7D7D3EEC831E6B8EFF7BE7CE522821071971F4AEA58E062F8B69E00F8FCE860F995CABF7AA719EA893FD2BA50CE72ADEC147FF6D7A10633D197C52688945D36A69F80A1D1D5E1066517672B946B67D427887B77BE803C685B3CC17EFC2AB1EA4AA80052BC78F84D928F4098220CF7CF5A8B69C66AEE3744236091974DD9FCFC1EA3EE0F14BAD1868F165EC932E710CDA329D67A630C39D9EF46881E12A79E1115C35B78E47961F52AD6BD39BDC807FB7D57350207C32F439906E32702BCEEB64864B3B658D246C6933ABBA99AE14405177558C1396DDFAF20BF4B96BE166C47201204A10106E7A62E06261A5414268B4F75FFD5075675FE9CCA38593136EF843C39DBB514EC0BA5002A91EE6F375BF4910D8F818EDC39D119E650CBAF6DA563D563CA33B457C8E40B4F04349CF401B772FFF6D4EEB5621ABC1A857779B78623A2AC2AE038291C187F88352734DAEACC2D0D16F3AA45B06972CBFAC4730EDC26F8E9E093F58A35D2E97427360E5EDFF75C14D404524782DC542CB28EAF9F7E1CA0808627D7EE7C7CE279B81DB543EA575876E8A194F4B9177ED6F1B9FD89A3039A361F413AC1CF454DCF91BF014F7F401BB303F534AC8D9D54B9A6D38202B03E9A5C5412A17E210F19D433D935C2392308FFACD85FD5DFC13C5FA608FCFCD7635094833DED7AA22C0CAC4C525127B0057FDC2685EB9336930CDCFC69F1376B2DAD0A98D52CDE7E83F54016FDE66BD371C13026FC975454361626EF5A6E668028E1ED42E2F8C9C8A29864B42C665B6A44040EB470562E8B1A40731B0859CD19BDD6E82E90C73A6EE21ACB55B3A08714743FCEB566A44743E3CC39272568EC083A7CE4D7868EB12195300B224918B50C198399622704421CDBCAD2861E8E3D6C87AED11B2005990E7FE9E34C8251C777CAF4F613D91443D75C50B8C8164803BACBB4397247B943FB01F6C94C547DC9000ABDBBF9E182280E2334E9D630DAA178DF4F78D4FB0531F9C27F9CC28E269204F0AFC394516B58EB97838820FF609951952C5896C8BFFF81C4002893DE238EAB3708663A3B0284EA1ED9A04F5980F1750BBBB9010AA1E4A3DB0C96F1A71E8249B87A2E28B381341C57074491B8475204F2F67529DB15F0E54C6696139D55672BABD4D3B2FCF38EB0023E8543DDEEBF7FD8C2A609751F612DF37566BB0EA5F1DAE8A94DE5D94D39F2901AE84CB772FB59C958088F9B3BC446DB14262F9C71B963D82BC687ACFF2EBD69352F158D09FD12D232B70D61A4C61FEC224B3A47A2D18DEACB31C142BC81CB18A2ECE744A28843DF157BEDC7798FE1B4194D0EC0AA71829CA1034D0EBBD1FC49D41B19326AE664724DF88218ECD0CD6BE7410D0CF47F755B31D5E36B57E2E9294CDBF701888521B9E8169596DDF8D4A0671CBFD4BE464D6DE62BEF45BBAC3B6B1C21D873B851338771B667D727A936743B93943CD47092B0132C4CD09E7AF8F276B84F42855CCB3D56361072F23DCBCF57A490AD90C3AC8A2FB0253A65AD4835B97F3EE70C71EE481B26D947879507285F47A200294D1D58C5360E01ED774EB93613D94231C7BDA56983A055BFF871EC5C29CA34AA651FDCEF8D66F72AFF4B5BDBD0BAD54AE41C37997CFD725A9989B4992DB9F8EC6B94392D30B67220F20647A8939C61863BB34BB8177C106E32DA64EC6C3834E6C446C75258FA1CF17E0B727896A64F1A65083DC2CCD471C65977D5382F3B8F8862878CC120F6BD9CB29EFFC42BA91B9BF085ADA4B437840DDBDC8442A6FD660F9C92AB617D43FBDDFE0621A217F508AB4406D6A03B64895A5C654198FA0AAD218AAB250DE80A85295CA6944D32910ECBF9B47E5F2BF35CED98707E4F433F1958B6AB9C902C1F4BB2B67F972F29C18CD215BD3875C501039C1B677142D31F0A8C07CA1000E963FA4693EC5E7EAA929861E0D431997A536182D624D8426B74DDF841B513CBD2AC8A17397E9F591A5ED5DBAE478D6082075892CA9331219DC353F2C3563CA6745741C7A2F0C334E219AE1C0D1164DC4A81AACFFADB400846688F2982A568414F20220A01FF0780E5AD1C7E8D2E3C7B1FEEC8F7C67C9A85C3628136AC05A576F6091972AEBA9DC184CBCCD35BC61671C6B729E3F2965E7C119131864953DA34A8BB9DABF2B82EECE7455BEC8BD509BB82074DBC766F7CE25E1813444A3CD05C1A4FE28D32651B43DEF2D2511E7E64C5C7AA51BEA1133ABA11005D0DE317322A3E2095E5194B748467133FFA8CCE0CAFCFA8080A3280A231C090C7F5EA61A97E001C59E65E1483215FD96468F1E99350D24373B32136C201CDB18A81EAC0942CF8619FB636B755B4650A55489FB705E7432809E2393180D3BDFDA4E22F4286C0B5CEFBBCB9D9992DDAB4BF662E3037B6D4EB741BF66F0E82E90A6A65C71239A6C939EFA9E0B1B5F1E7FE6A4BBED7FCB163980C866740949CB298A2A0FDA5007F8659FBC18CD236F14DC5B71EDDA3C88F7C68A0833EB7325422A512573F775B87698FE54BDF14607979A04D2579CA552C22EB53AE43D21DB17E3F4618E9070F43F3E58FB206D1CBDCC8DFF1963C1F403CF207E4E9A315F0185B5CDDA7BD84D3E377439538427A5FDAD1E9FCDD5EFAE6A438299FC47AE0C5D622451447242E287BFB0D0584537C45649FBBDC8C24724EEAFE2E03A475F6DFAE4873BB35C11F85707EA90D16D5A90FFA59085F2C3EBBEABD468C69C5D4BE845D45ADE69C9A8D725CAEB9DA4FA48884B5B3570E5DA3BC102865EE9ED58E8EC07672817A72F009C9BD007BC4158C9B137E117BCE2F0255ADAA6A394E0E1DDC57DC3BD38761EE5DE81165F964F6AD48873ABB279F1A236B7A022D565089304ED57C2424213530704A052FE4BAE2E2B501DAC5E7CA411AE2124D3D9F1ECD8F2EF653554CE8B2CA9504518C21EEF67CE9A0142CCBDFDC782FD34C529A65C552311A89781307BECFF507788B97837E6715CDC96820AC849112CCC2DBE7C99C89F5A0D111E23C19BC9115EC8096B469E69324F8FFA428B81D7FCD0D38489820F83EF8DA083B401E75DE57FB7E7A88F4BA52E7B45140AA8F1A97A51C112B5DF3A562F0AFFFD87BF2BA9079EF8A5CE2D5AF0A510EF21FCAEFFF192DB398947D9CF71A2E80E3CB7C5F8E83FC0BCAA59939C5F29DE2411E5D9245FAA641556A5B15DB99A0F9A86715A28F5BCA9F58AFAA1DD0974CB899565DE9A33BFFB8F0E2C118121B8726B87EE872165241B74B2DD0F961CD47D24D81D2A8B0CE4BED4C9D1F22D88FB8311B4704034D73EC20BD63EAE3E6657B8787AC1E1CC4403A1CBDF168E151ED3D30FFAF78A1C6D1B0948F535B472FA7FBD5C7C4DD78F815CC0EACC685431AACC3DEA9A7A75D95CDBE650F6428A81BF0D21AFFF6989F64633E50FF3DA779C7A3E2157C13DB06A3B09C4F7B4947C3ACD8F816312080E7749371A621B39FDBA5F227E86C98F95FC4F0397AB5EA3D2FF66B3958D195CF9EF2F8B4D34096037CFD856EDBE0D65CFEC3F3DCC014A7E91E39AB99F4D5CF00DB910562E3F17827064826E641B0BCB2A147A0D12EA4B93A8EB85AC079400486B2F4EF1BCF288ED73EFFF3F10493AEE8AA69CC37F55CC18E0C3E1F9E9914D268B7E8101428DBDCD1F9992E4C52AC91F7C8C946CD795A7DDB6B794726950E72581306D5FF772A10F4D63276B65A26DA6198CE3C3511AE3407B7B077F978524D778C9FA6D39D27032539C10BAA82B4D9EF44248ABDB4DA1817C20C1A7AAB51F0EE40E2B1DBCE8537CC9820E3272141E23B5160C7741B39783A557F5EE9B28DD0395262473C8C5FA6BADDE0F079C39609B611C7CC402BFA755096396DB229EFEDD326681DDA81EA4DB6C7BFC873F0673900E9DF2CBC053C7CD90C86F39D3C3CC60DE7A0DF08E2CAF9436DCF06107270CCFD32618AAAA84AD18721E69F9A40D4A02114664697ADD364AF0372739CE483EF0424EF250A9D8B1868F7AF515151C7A82F57FBFFA415618720D9F6B74D26620D7DBEF6FB5BD65D21D3E23692EE7692B1AAB7144DD5BF9DC0D29F735447D11516A068B7E5E88D0CDA94894B3DF62E90B20741BA266A0CF5AF40A6B651376B3BEA1982B9A1D1FAD34E81268E178557B9D0099EA569BEE5CC37EE87DA8FB8E194AD9262017636DD3280447C7D47B4CEA5C29308EBDAB0DE6F71BE71ECB562CB68153E8657D18D826C846F51F7FF9AF0A0EE144FFDEAE4B8B4B86744ED8568131FEC11580FCD130FEF66B0F3B80FED72570CF8D05B5D0A0F04FBDADF278423E80A645F3A5950BA42CE8F5CA1AF452F8E17310609F673E8B194C45A6028856BA19525A1AF21DDF66DBB42867169293631C8ECE4248F6859608B792169A785D5B0AFA42BF20B127D0CBF3E6DBF9CA7F4339D46C0FA311E0B6D7AE4FAD7C7B7E95142670525AE1FDD8312AC7E4FA311DEB7DA2C86898E138A6A85DCA01D3907B257D870977DCCA7566BFFA75368E0EF1A5ABB4A37C1C7F479D4CDF7DA4E4F15306C250B844794A700467D10478C70ED7576CC7A47A5214E87EF2064DE4E8CCC1C79A77999B9430E01F0A96CB4596BC71157F5691AAE0CAB95A34F556364B81252BA1ED74D9623823BC1DFF2C15B803253B4BB945567148AEFD159ED587A7543A38498FAC6B9F4FA387F208FD346363E8F024B875765E509EB158959EE37CCACAB20699D2E3B93DF596C0E7858DD2769AA752D7A04DDFBE8B663368BB16BB5E5FDCA2A07BF19D6BB64D98117E7D2D3DFB0F52C5FDC84FD477FCD77CCDA54E394B4C33F3AD535474B32F4695C94B79C5412DBA1C5266DBC0F3BF3CD6053BE1F45BD6248FB43F64D2E85B2F7182BBADDCAF27C3113E3A028473065AA28421B7DD2A48D5443A13B8828909E77DE44090C2F8E173524AE3B80553479C5B6229EF0617C9D7A7E977F6308FCB273726B911CE4C32BB7862CB97B4AE20BF738E02A1CAFD80A16A60D7A34D1BF415B90C6DEAFCB3484C5E667908797D4F4AA2610ADEB56C653C8F185A7CAF56EBEF48A2848BD6171D22001FC68AC2FA840ABA5C431246FDC23BAAF6D0DF066E79526FE433EE580C1FE39DBE388E052E07284CEAAD3677383BD09D051B1805D54E5303637B33579ED70AC197F40096622FF037F212425585DADDB7463B98BA1778DF41BB35AC25CF70C28FBC38D8375F51558047B13C4ED023310CDF766B8CB1DAA02B1B636713D63BD1DC219C3BC6D503C849BE11768D1223BFCDC8334441B8F9B12B320C3FEFD135FF8570AD9A7CD41A94A840BB2BA24D5DB235EBCADC26AB29897D6FE8FD2610CFECDDE4B192191A68E65BC9220F2FEFE3A81ABB0B339B4E67616325900F15D2A08F5372598A78879243EFC57FB452D6546312B64B140014BE557F111C383E6A230577E71C0D393A5FF4A64FF24DACA82EBCAEE30D15A09B23B5A8D2D7969C7A722D759C2BCE5B4840EDCF138CB7DF66ABEAB6CB261C1C4BD58215ACD30F123BBA9B9341AB4D3EB73FD5D03AC61BA9AC088A2E54CFF758756BE0EEE2567F68BD7C1F82D320FFA0F6A70574060C855BC5AF805E6393DD72F96108C960F40FCA7FB3DFC2D6D0BFE282E47F5C5337E6E45D4D2E16B84FF3E5CEF4C234FCD100613EBC8E64B88972F76C910D3F670620DF511138B38CB2DFDF52E9C149BF2C735E55BA7E78D059B90686E457B060B430D210920EE1381B7A5D391439E8647983867DC109AB65EC8A1FC72F106B90E4AB58C4E94B1A3D1879C14D276612764132E3A83F5FEC46445A2FA4FAAD22DB92AC778226EBD0768EEF419B9B0E640CD728401106B5034EF589527DD3C723DD9BB9BF84D8B807BF5E44D9861CBD0FBE01CB67614FC637E59AEBDDDFFB2C942AF3B12025D0DB6A87C8FD2B11E097154B8926AA3C474269949F0D7527ECF258510170DD37B36E9859CB0817921D58308AEB63F82BBEFB3539949CAF754B9C49FC538016E6187F33B9E6FF1377B1B442E7C90381A15714866F555145414DF827213D9BA1379D345ABF1E5B42A9865270956B1193B1623D4086A9C9362D7AB9268829ED2E08431B6B86A49D4AE71483E00A4B881E6BEF7F3E2A88F012B3C06A7332E900E0791DB4730D1F9C8B2210824ED920BCA37246A51653BE1221C9FF9DB1FBF9C602FDD52D0092B1BAE8FBE7716635678161F1AD15FC55B651150FF4743FBC00C55EB5DDDDE5576F21B4AFEFB9DE8069DFE7B917653E4D180F6CE483BC229D37FC72424C4BE81F59B0193D2598C75AD9B818E84985DEDB445C4DABFAE5C9912748B32290F33C5169F54089F39630FF701B4EBD727B630EDA9752AD3601DF69693AEDE984E84B80D72FD9BD347545A27CEACF2B2C81DF266D320EDE2AFCF3BD5578FC5A469B5EE30687A6686B9CF04E9AA88815B89EE6F2D170BF84B0BF845A75B2C303B3968643511D4AB568552F4FF6C0243725F291341AAF654E72DD805C798FCD5214B14616E7AC9F3A4EA6C211B319FC9009536A1772156E62E666788121874F472FA5CAB32BA174FD0B2218F50A3BE7BDF448263F84CE6184306BDB40D6AC6EEEB7A009144D47CFE5121C5F44044D10B0776B575F883AA5CD63B5A577409851707816E4CBFBB13B047D3902D0C7916E4C9598BDADB732E82166F10149695106C8A9F3C0D2CF4349B59CC5A66177FC51A7B1098F6D30FFD8A5D016AD38097C062E0DA6BA3EB4C8FF851503B97E7A276E026DC8D92C68F979D53F9157695FC63A97A9F58D8F92140217D196A9778CD52A9074348743BCCD068B5DF2D5B76943651822D37F217E71EA6763CED121444AA3570A5880DCF44CE21FF035E8EA8107430E6116C10485E4DC7792D04A9B9717932D621B572F42221F1BAC60D3B65D93007913BB100E8658968B0CA77C533F20B9396BE2A7DB9B233028465E54648E3329BA2820ACF6CF00D46BA0CFD045C20C6BA992AEE34F57E9C84ACA1E95C45E9EC6D0BF500A7F7E6626D5777DC6AEDB370A4B1EB82BF4CD0F63DED9A4CCA567FCACDA440EC29CC67A926059152AD7BDB3F3EB06813BFDD8314C365E490C41C6FD4A6173A13F4C4A4E517037315D0EF14428275919CC61AD393BE23333F7D8A93C59DF7FBD4DFA8235AFE88803BDD881CB8E591A721E917CE44103EE38CD499655B666AC3536A1DE850F3FCA9C393454D9BD6F0C75B11822FF23EB22DBA69B08D3F4E92B8ECFE9BE9432A8B445A5BEE8757C7C53DD96FB2058A5370EFC4368FD6B5FC124FA0B9366074719377A0C533415161E29C71D5AA85356B9 remain = 1022 -max = 1023 \ No newline at end of file +max = 1023 diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_256.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_256.rsp index 0726254105..c63503507e 100644 --- a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_256.rsp @@ -1,5 +1,3 @@ -# XMSS-SHAKE_16_256 - pk = 000000088B4832442313757CA73F5832B981BBB6B72FFD8A75EADB03605950D69CDC5FBA04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 0000000800000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A8B4832442313757CA73F5832B981BBB6B72FFD8A75EADB03605950D69CDC5FBA04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D9330900000000000121C29A3D4E6C5DAA979424FCA26B0EBE6D3FEA8F078FA9A98B0F55503C2541CE0A0000000000015EB6FB8267689B81BC8E2C8950E5F59F4B43194AB167C4A60EC9BCDA7572E5980B000000000001F02838F27F104405AA4D9E111D3A0B1849F6725926BA5B3A6412DEF900E7259A0C000000000001BA1EE79A04487C5639BA096A60E3E17F7A0E9C0238FA049EA7AFF52FAF5890980D000000000001B63504B794C356EB44A98DE32960830E6B275526432F232A7729ADA72571E8D90E0000000000014DA82230B909123D34E30FE0722BDD93EB6D56243518275547CBA7C473744E6F0F000000000001000000000000000000000000000000000000000000000000000000000000000000000000 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 2692 sm = 000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6FE5428C1B38A2155B8EF1FB9DE8440D993A1F197229DF83843A1615CACF924D481D1478868BB902124AF51010672C7478B1AA93977097EE47375B6A5BD3ADCDB13077F648B8C7435CE755907418C55379857F06E2F7A61A232B67C86AC1352B9854E31EDDBFAFFD3992A2FF8D8B758452896E7B2D56A89B09055C2684A6FBCD2868149F65E73EF30210B36E03DCD6257185F671F78904B3F11EC67EAF994D1B9810B03806BA5E0F9C9F764CF3EFC1772C1624A7C8D63A6295339488C2FDD9CBC4D52F94BD09075E359134DCC1745B0B9A12095AC493DBCA32FAB2980588C131B31246F16CC261A56C9F1903B0B4498B849B4598E5F8C73A6A1521F7D75628427F95374C29BB0585B22A7421D7A01B07092AF4E6C0D03F0445A64110B93F814194F4EE29447A8424917FD3EBBE24F5128280697659EBE4569087D96AD8F0AC7B67D272DEFC429B7BE6E9F76ED4A60B42FF5F0CF9EC09791851E1E7D263EF374CFBBA724670050F31569813630709AB6A4E35D66684AB154CF647FD64DA3B2E5530B4ECA5ABD9666549F8079173D267642D94F9660C76FF6D5378E015B792B13BB773CEEF4C7B3AD10BC12FDEA7DCC1891BCBDC9CD83ABD7DE6012ED3F07F1CE676F9E659D7C7663EB4B63FABA90515F2700301544682570E6B3EF16C59082F949F388D9FDC43455CABDCD4AD51E010674F23D753CB00A62685205FAD8CB4BE5D5174BC2039A9D72F3887749FF061BAB898B75511280A6E9134C3379B1609BADF260A2F78C4C9863965A97BF5DA405B992E011375D9834FD1AA73799E97F4F701E1453388E6A2E01080743D9A836F20FC93663C7E4591849A616ACE98011E52BFD3C156F233100992998ABCDFE26F36A0A4191998EBFE07E2B4D7D9787DFB44F858B43CCAA440867C0C6B6C74E32368C7884B8860E5AD1B518F322EE72CEC31F5253891BCA1195D4B5CD305ACB28479FB1BE4550E16F85D9285EF98B1F325D755F2D43E285EFDDA4F0842A1727C2EAA123789C359DF0C696349055E452E7F27CC668814754D5F91CBC9BB551E5663948A692D12D054D90840580C1D66423931FC5A4E6B4D0E8F6B2040D9CCF85DA7C9522BD571EFF09D5B1561225886FFCD6B788B60A2740339A04956DC654E108016C69006BDE4C2BEBB3A3DE40FA45F5DD19D0E3F2D9487FC2287870964D9F328563E36677622B3E074A980DAB585FF96FD09B95A6065CB8246841079ABE344B55A1F2D367FB3CF72F1391462C45BCAA89EF4D623FDA3904F18B7739B10C9EAC71DCDBA418DF1E5DA13E1BA5A122000BD71E0C2060ECF72407AFDEF3BA54EC75F425B4AB32F564854AD5C39A2A1D9D06FBD74DA44B83F449072FE1E7F6A82B308A253FA60B722B0B949204E5931BCED17F2B1C5EF51D9A6F477F108EFC9DCC7F139617993D5362ED390A73955749EF1FF0825D95C689192BB35FCFF90B87519113376A44AE4BA207EE9AF82719AA72ABF543ED04221A9176561983CE0FEAE6C491381F6E112192272AD8C82CE4037BD968C1F4E7B693C41F717FEC260DC06486D04822DCD3BA1CEB89F12DFFE3534B51B107E73383B4DF8B367F2E123BC873626A8EF6142C485C932E27BFE6024722F5825CA4C84A6F9F49B0EDFFDCE1DBC2AE84F1FD849E3E1D049EDA6A5EEFC0E5EFB68199A9913158FD2FD0A1EB0C039623FA42CFCF6A0AE68C6B65B60D79C9987EBDDB191E271CD9632AA1EEDD35A437D3405B89CEED11D4871C6C1F9A9C33B15AC647845C27F1B5233F2C78E908DC396F097744D841C8BF1BD732255BC62E601A9E50DABEE504FAFD020889BD3E0335DF683D946334C147F31FEC61975DC21582CCD00E77AE099812A621537438D6AF2F1A64E98F801173C97B9EF4923BE9B179A94D20D64CDB799F04FA406789F34D5A04CE3FEA635DE803FA73EBE3439BA0238086F39970601DEBD0E7DEFA07933EAD357C796B76DB6E6F557222BBC9AE2F4840F608E59075A190F8A156CA92CC81F4F69369EF086D61EE895B7F12C300DA076E09BD43CBCAD6F5857BAAE18071F291C3D742C9FF3FC54A51D1CB8061D5A0ED4358E8AB70079EFEAEB3947276F612A4376555002FA7AC9B7EC9778FC3B4A6EE1025D4C73A8CABF27E1CC7B33448B947CD339BDFFC9F377952D6249911F099F535E6FFD1BECF740CC96822076C1C173E32EB8A2A1D282D8BFEB277B9BAD5906F6C8ECDFF4C980A4F708C8D83847A125F12D726A803911B7669FB587EDDAA13FAA92D1745DAE5494E4DBE639AA2B03412ED97FE1C1EFC391CBE070881822B2626AA473C605E9D16D8A4A44644D551C332240FC9CE25D8A9484A9F0A65B6DF11CE50A984285D2B583BC4ABD4A26907E5613CDD84BBC4B8A6FE153F5D50CDC700FA96C40B8F33F4F73F6260DAAB08BF5A02A2F664E62BC3BFAA6A4800EEE8423D93ADB908B28E1F1DAD9CCF410A1A717F2FAFAAD47C60AA96B100947EB6EDEBAA92FBE4C0AD2407EB3D645DB8FA4EEC242E907FFA8E6D5771F18739E44FF6E70221FA212F5755BD9574163E60412DC2DCC34F449167D76C769FC5D9D4AEA104824F0872C46D1E4C35F337D007F2EB9B832EFD426982739F74A14BEE901570011D4FB7F43B5069C64556087A248D8C09CFA5E34600B3BD6194649DCB093B3DF86DEEB4FB42EF65CB5CC3C3FDC89852BD57F34D20B9EB617AF516E372BBC4154AA94744BF2835AD2E71334279B019756795B96FBE4D57FFFBBD3D6E4E5786234FDC6E5768AF9329225E1BCB7F680B66729BEAAB9C5AC5A2120C8D427E349F364F595BC1D72874466844FCD43252D480576898E9037633A8424577B3DCFFA3AECFE14317B60F84E450247EEFBD497F4F79FBFD48BD99EA0CAB725A1A4F1CB10B461FA0AE6F5FB991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EA6B7E3BC14749E7C7FA2F28480EFC0784B9C5FEEE217946EF2D55F5FD2902B6E080431350D4BB60DFB6DC98FF57CE274ECF76AB7C2E9A87D99EF54D9B8A5B4481F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C remain = 65534 -max = 65535 \ No newline at end of file +max = 65535 diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_512.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_512.rsp index b3718c5f09..4385540527 100644 --- a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_512.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_16_512.rsp @@ -1,5 +1,3 @@ -# XMSS-SHAKE_16_512 - pk = 0000000BE63E1958AFF9CEC5CC26706D9B33FE461CF17B8FCF54E1B7394AA3E0B51BDCC89B4D854731B25D63C27019AF9AD43E63969A575E7C181079BC1207320A6658BC4D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE sk = 0000000B00000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A4E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FDE028B6F5724BB039F3652AD98DF8CE6C97013210B84BBE81388C3D141D61957CE63E1958AFF9CEC5CC26706D9B33FE461CF17B8FCF54E1B7394AA3E0B51BDCC89B4D854731B25D63C27019AF9AD43E63969A575E7C181079BC1207320A6658BC4D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002AFCF3BD5578FC5A469B5EE30687A6686B9CF04E9AA88815B89EE6F2D170BF84B0BF845A75B2C303B3968643511D4AB568552F4FF6C0243725F291341AAF654E72DD805C798FCD5214B14616E7AC9F3A4EA6C211B319FC9009536A1772156E62E666788121874F472FA5CAB32BA174FD0B2218F50A3BE7BDF448263F84CE6184306BDB40D6AC6EEEB7A009144D47CFE5121C5F44044D10B0776B575F883AA5CD63B5A577409851707816E4CBFBB13B047D3902D0C7916E4C9598BDADB732E82166F10149695106C8A9F3C0D2CF4349B59CC5A66177FC51A7B1098F6D30FFD8A5D016AD38097C062E0DA6BA3EB4C8FF851503B97E7A276E026DC8D92C68F979D53F9157695FC63A97A9F58D8F92140217D196A9778CD52A9074348743BCCD068B5DF2D5B76943651822D37F217E71EA6763CED121444AA3570A5880DCF44CE21FF035E8EA8107430E6116C10485E4DC7792D04A9B9717932D621B572F42221F1BAC60D3B65D93007913BB100E8658968B0CA77C533F20B9396BE2A7DB9B233028465E54648E3329BA2820ACF6CF00D46BA0CFD045C20C6BA992AEE34F57E9C84ACA1E95C45E9EC6D0BF500A7F7E6626D5777DC6AEDB370A4B1EB82BF4CD0F63DED9A4CCA567FCACDA440EC29CC67A926059152AD7BDB3F3EB06813BFDD8314C365E490C41C6FD4A6173A13F4C4A4E517037315D0EF14428275919CC61AD393BE23333F7D8A93C59DF7FBD4DFA8235AFE88803BDD881CB8E591A721E917CE44103EE38CD499655B666AC3536A1DE850F3FCA9C393454D9BD6F0C75B11822FF23EB22DBA69B08D3F4E92B8ECFE9BE9432A8B445A5BEE8757C7C53DD96FB2058A5370EFC4368FD6B5FC124FA0B9366074719377A0C533415161E29C71D5AA85356B98A138DD28D76BF35B6B9BD3AA30CEE5641266AA5B6E3476CBE1CCB18839B063A655FF7831A6B655D5DCF74C93369FC562827A2E93B53A295E86E9BF8879371A9E0A176587912D1CF344CDEA03DE86B587548FD05D775686D36B8A3B5AC77165B6226682EA37B935C9FE0E02A8FF9951E2467626865C6369A8DA0916AFBFC03DCFD599163BEE9F73F99E34A3F8356E5F193E76C4648053269A659E080A7014A3EA4D7D9766FDB36CC8919294E88D722D9996FA0EFAE5FC3DDA45C14636AE77342A5654D12731B64E40255DBB777CD68D73B7CBB3D8D1013CADE109F474DEE5565B1852F646002BDFCE39C736116E56EB8EC6F75A46F2A19ECE8F0CAD24152DFA63F89AE0C375E32AE637BFD43A1D3B027930461A8CAE0809D65E9B81DE9BA9D0D498262EF57887D6B892F149030F734B44BD9DE9A4C8E97772A50E7404020A9D64D6785059250DC03745A68353456A7229B21F0DF6AFF33894919136D210915581A525208E3FC16F1AC5BAD3908D4D7D7155929F32C5B790F625CF89B8AD926220000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016A30B3920D43D47945F47566B618719C38844032986568606F2DCFBD7104EEAC5436CCD86E9677E05985FA63C1B6D3E642D0F145B3FF637B96F2AFBEADED75F30100000000000197C186BD25DEEE5DC2CE5B760508549B1EFB2F3E0A34047232BDCCA39B144EAE820DB1F2D3C3159D012D7CAD7AAB1C44E15F53F4B1166E23DB8AA23ADA9E23AE02000000000001C5A2B2230C54CCBDFB5F42AD8805628B6B3D4723AB84E514035694195F2FB7E716F21EE8845170F30D1BEF79ED4468F2A45A72853F2D8F601973595098010E1D03000000000001C9E730A265A6F2DDC4B0F420CEC9C7AC976ADE4FDD5CEA3B6D5445AA2562772F76635C514BC81DA00E36681EDFEAFEBF29B1C3078AFEBAE3956D74AAF351E35904000000000001B661B82380E38D5CC77679867BB8FC1C94E77006AD05DE9576A7BD210641D25D011A056637775E72395B7643018E0BA023747219D875DBA848A58E0F9D7FD2DA050000000000019F3A31924919E8711F88BC45477356D330ACF65BDA612F6AC681F64C24FD70A6AF08B3FBB6136E4AF05B38A9205ACA4A2773D100FF79057CE6EF6C3F82AA9DEA06000000000001EDF9A31569FF07104E7B2FDF78D2CFC2FB28903D720F4D2ED95AB35DEB5EE579384ABCDC10CCE008B5BF753154B78207E452D4AF2B5646C42B89EBDDFA02570107000000000001BA911C4438781B45414444B18E3EEB1F0E57D33FB8F1BFB5DF1DC85D88A29371496D214B1042FADF9F17DFAC6215231DECB7D4ED1ADE6272BA7933403D3BADA608000000000001D85DF2FBED8348BA8E34D08202B5F944A00F91F1CC1F50C50D2460DFF1CFF490D84B84A1FDCA7A5E1760FF2E3A392D3F4ABB78116DDA6CAD29E694F9A4691E3B090000000000017C1668200DA615F45702477762DDACC68BCBDB862EDB8F34569EE898D80B4DFB1AA4251E3C3D1692C8C50DA2BD543C84A807DA4027BBEB6EA8A4093D5E560E110A0000000000011171AA4B7778E156AC8674A7522E4E47C54E7ABB917E693DD788D8782675BFF5E0108D4853BA609E9E9C0FD4FB0B8908D8D36F3CAB806CEEF40B173B740540330B000000000001AB4927F65EF9D6DDC2CF1B044B306445ABDD4629C4D63AE6278E049C96933D81862327AEC4B7D2C31B6C7509C6E45D2945E0121A0DB90076FD84AA9C5AA53DD50C000000000001F73CC84242314EBAD62F95C79805461C1902C40FD822F19F69C029997DFBEB840EE33A9905894B1290A75ABD10F4EE3BD6E75DC6CDCF69A7FA48735C08EF85E00D00000000000125A7E166681FE462663B71CEDAAF483C1D8097F57EE39EDCE104F6B10BD85AB43EA3C766F25F76C0AAD896BBBE825A8FA45AEF3C0483571EFA6FC24E973AFE4E0E0000000000013DB4DA57E43C4A075E6A8B417B395066BFB8C7291C42A04F1095A5F410002B3AE64DDC3633B2E27A4C28475C56FCBA6F0A6D5B730FF6320C89B39E55ECB22A730F0000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 9476 sm = 00000000BAA7550F0E617123968A7F276A4E50664475EB64F4E5DC6805ACFE998B45C1E0EF24208EC4F8C326F4E4D4B36902314578DB3668398F8D67F573F98468AC125AE12C99BC1AC30AC1C70E9F5512DCBB72A03F07AEDD114A5E2C73E994252AC7D8344377E0BD8DD7E5D8AA7C37A8350D10E78049E98C5354C298A2A97A05F1375AEF91919DF3C700D64569F90D0E42EA543393D5ECFC90F5E1ED1173810AF83E1E12445F5FB5590B3A00414C47D7419D2AA0DBE2E4003083B6294CABB043E099B1433B6322DC7AA17FF2A5B756F87FCED9FF415A70E5FFFC2794C974DB85E4737016041B8B817D20B986C1842F55C85CB40C06E274D6F22ADE5C49DCB27457A297A97E57A963C3BB42C86E365E37A258BAD6901D1F1AEC279CE2F14E9E3CA316DE8DA0B086DB8102A746FC5C3EA9C99BAA79F74F7463F047DD6878FEA751585B40004D9E5223780147183D48AE736A5EDB2D61D8301ABD2FAC1B1E60B5BD2133C25AE6158E1109CF1C3F9038E6ABAEF95BC0B8EB39BA412B4EBADED88EF612BCB5CD6E085205B104F30EBBCE03D9379CE23E884EDCB5844D875098A851A999B3C01EBD13F4EE2C95ABE76E4658ADE75DE9E73F3F531DBFDF366773B69A422916B946DCB72853EC436A574838038C65B859D520972AB0EF69714DA03A840EB9FA46B8AD366C3A3034C316001AB869808374ABF5C57D943809C2C11640C14DC9F550DCC7F5FE407E623B98262DE9618F71F36CB240F66418705405E0BA2D452296B522F1366C4DCBD16CCFC896B8DE3BE331CCCD48B291CDE4F1894B9B0AE51DF7D4FE0BCD0F86D8126430A4DEB5EEFE5AB35EB0679EE5F029BD0CA4F6E364F6F6B97D3BEF756880D8FD1F7E1978FEDE67E9068F4F52795C4258F0C001CE40F4C1B54BA7A2526D11D62E30D1D938D7B9475439E5A5A2E4FEF606A1E7FC210B415CD123A82B08539A2F9B9DC79ED7F7D75412DD6317D699A57214951587078E9F8FABB27BB02FD87E871FE65C3F2ADEFFA5C5BB430ECAC0694B88A5883710B97FCF72A39252148B1D304DDDBD9ABFC29054FF1AB375722D8C6705FD87A83E4BBE2EE1EFF9734EA129DD30BF7F62DFBFF2E7A511258E268F69A1D1656A2475AFE819AD0A624691C920445BF7C2658D34FC8AAB137C3C13ACC855A6CD66FD2BA32DBD7F5E16FAF47C8976C8569E330985CC808D67C4161399D64EA943B248C6849C3A91C0E38612AB2ADE4683B62E2F8A2418E54F8B1599331924FDDC3668DB783B4B422696A03800C9045010122E24B346B99C4A92514E0DEEE6CBB755E78EAAAE02B9F0B54AB3AC33799225B661D3F5729080FF9508EF12F2FBFE791D5819F0C283D9D4666B93C966147218BF5DBDA389086110544606F5BF6F120EA288696AB7564EBD704846D2D9DEAABB77EEC66ABE1502762C6DF1353DC29B95ADE5D05853F1C53E1F32519CCE7655A5531EFE89DC0747356D39CE8D2A52A35D7F82AF5AFC88DA85478AD66495150DBA318B7FAEC3D2EB99DA48EC9F9B5ABE09CE782A9C8FC854B53E2E5B514CA9C6623519C42514127D8D57C080EC7BA0A159BE9CD5C4D099CDA476E93A8D785AF6A303A3AA3B77FF313964E1B9E095E5634EDDA4D5BC8CA2C4333ECB93E60EA6AB7D3BE7CAAB2678F65B44991FB909802DFB0026520B1025A3435DA746BF4AC8D2CD5CC07DA809E5C388FF156FC159892D645CBC9B37B5E25BCA92AE0084379A77A4D2BEF0BCEF989E0317B0D82BAF54486B0792C312F8923C0B85E5FD4D5B8F86D9E99A12AE166F7E518713707BED5E140EF7C35277D8F0CF563CE49C71ED38C5C15D5514340457527590B9005E3C02DC8360E12DC702CE9622A16594AD89F0BB57F81BD71B0292F235EE0F52F8D5BC8317173675DFA09ABF4A19D71C21BFFBEF9B058C36B18F359ECC1A378E118EA577EAE122E71DE995CAD6048380E5A2A24F943F2468128A94AEF1CDEDEE86630F9D46155896408BF90C0FBE204D7EAA49B6F0E117BBC58E3CA42AAE72BAA21EFEF8B3C248F9C085A1B39D2733D451865BD9D23CE32519057EB3E345BEE6B5766591157B9EA7F57626EE4F9A94352646EEC8C35E41DA59ADA25FC38F5B35E520858A8E490B20FCBCAA8A487B90395CAC25B1562D77FB982C9DBEFCE6FE507841EC30E547B0C6D6E717E125450016F77CDEAEB8E6CE1E2AD4E6C5FE29C788FC473BB6A1A9EAA4CE83791D0B7A3426A2B86E5C328820E839F87FD2428F7C4A5F43477C48877F8FA0322107D10B532044720D001F62BBD5581247F6399DDCBC01CFFBD12C9D312720BC16A8BFFF3D7CB1E83D96547050B25B2881681427B16752B1F58F3EB5B8B4CF8AF877AD3E6B4EFA12DAA71D2FB9534CE5F4A6684B24956647386385D57A9944F3CA15E326CCF70F8403C62E07149558EE2FE2F5D7F015C88A93E712E3151E316B9BC4A8A031502F073DAA1F1AFCB970AB6874ECF40A3383E2BB3196BA7320A08AA644538AB234E8D299940E65093F353F0A78C01D93F58D5E70FD464E07A1B6C7E9DAD2985C8C5F9FFB489D692E482CB83F95A226F2C351763D0B1AC1EA2BAF9907F117FF3C5CA5303BDA839A3293A171B77E9F68414C5D4FDFE24129B59D15F154B984B79709EEEA084A07809697EC9CC748C2363508461D7A1F1D6DD1887FF96A2BA275E110740210E9507324C0E4DB1A0CBF541C9EBC2580D9FFB18AA03A1A1DB485552218B5F1D05A1C862AC7D0439C8F12EDAA7E7ABF2903E653691AB5A0C26C6B30BF0053E0629BA2FBEB8BC6A5A6C2315ECD6BF9F755D40DF5929F6CA05B4DB3F595E191FDECE614AA0408DB903B338EE8F2458A32CEDABDB8CC31C55220EB7EDECE225A0E0BA8DA3A4CC35408FBC8277E5F6B4BC0713B96A52EC914D4AB4100449B159127DA510E6C94C4BA751A4CCEE6AAAF7688D1AF7B8EE10B187FCF5E172FD997DF85F02771CA9C5432BEDA41F922D3DD9FC498425CBC698F32CF3C5DAB50279B204CA067735B54D33BD0F96280A1486F8AE9E692E9BD39C687796024CDB0EDACE00A83A5708EB72BCECC6A51A4D266B6C0902067DEABA6C0E4927A0BA4561A82635A058571FC30921F054D27574005C4D91C17ED8FD68F88DD71D763818AFBAAF0D6BCA51E2825730CD6516E6A9EF5C99D133A82F2D9F240AEA8AC5293C89C4228FBD398BFF0996E3AE3DCFB7A1D4BA0A3200827EA6573D349F8CC2771032A128D7A61E772C20955A3299E56D9E5B0F746555BB8C0DE252C19188DC3731747F2BEEDDF5E92BFBE630CE1A618E4E7BEAA674BEE4380456301B5D0578ADACAD2B685BDCCD8BB20A0EA0D330F284E5AA318FECFE8893138D179FCF67DA80DB5A5B0A1D83C205106555F9ABB6DC02309A8310654B736B879C5806D86994DB3F3B2076CAA13A7BD6291B0A5F18DB24A542E6CA65EA69141F5EC8726336236EA04305C638B19C6D97759361B2E9F1EF455A997BD4E48C7ACF00E1945A919C77B6DCBAFBB3C3A1ECF0178EC042C940B1D449D803A955092A32B0AD6DF0D6B22D9B6884BA21451F8430738F1D32139E4B450CED6BF244F0D6442C6D1245FB2024904325D1744CFB92DE691B5632C00AB1A333CE0CA6AAC2D056CE3AB2FF552E5AB8E4EB626E988ABF6F27010F010822710F38B85DA10A0115FB8D76D3DB3E79F27F8A5E472ABE15B46773E77511A9AB78CE4076087F5E46AA21F953E06E11AFA9D912D93EB716F9FEC1C913CD0B2B69643FA4D0BE4D354C34234F65A1358D9FF6EB3B686FC1CAFAE14EF43AF20A498356FED501E1267F3B9C1D061109288F43CE00F4E188CFA2B68CBE8395768515C48BA515A46F4E48F669786AB3D250F3AAB360214309179BBD7E6E4F36EDB424524E2E28A7C2BC00683997FEC38DA95CAECBF5020C5CBD4ED3C041D403DE200C93C0AC004E471BE71BB3EC729B853CD8FED9F22241FBA4517EA291BA9841EAF8453597BC7625E4CC78C9F9DA52147C1DA50F8E7DC3421F3F3393412D535A505BCB84BF9928F9A8F6BCB87DCF80FAC84D9A80D57879EB74D6FADBDF060F6B61A7F08CE7F274D7C365D36ADEA9DA7642CE3E9B55E7FC0F72237C02556F514DB779EAC2C89993A623F55F668A0E01079E50CF885AE8CCE63F335A33763687E2EC2A61E6DC571268B4A405D32BF54DE503BD86431B262C14E2D0B482D1D8C0516EFB1E4BC7C59A3233597BF10FCE6176F0E5F93853CA71A15EE903F51F01275C307059EBCDDB41662896327EF0CC02108DE4E66C4D3B5B1BC1C4FACB24CE6613D9DAEFB55A6B5D6C6DD925C5DEE1E43079435E6C3EC704743E7640E4C8F5FF2CB29AB5C223A1FCE9F2D4CDFCA8C9535338004AF28386A3EEC6581CE06F0B5ACF3B7CC4D11693D840746377A1781473F4DB2AFC1E71939664DCFC76715EE777832C29BE4CC0B10864EEC338196F4F38FFB2E70AD32A3C15D9082C9DC5795CD2B3C38957E03AD9261BF7B836F8BF1E50ADA19F026983B0902A37FA2DB926B1AF6C9B737356322ED3069010190286939CE20B380D450D6E4EA7B71B982632C4B9067A21D3F24DC18087A335325EC49F747003438F8F088EB80861F6C1D9446EA350450C52438EF91E4A61B41BD6E74D8516DE54F6CC50665BC5C9D9183F3195A7117BBA583A2EEFF10B57B778B7E95DA6BF8D18E2A1391112235EC64E7701AF5C73231EE6664305C79FC59BBD67D774C80D33B9CFB2EC5DD98842BC41BC3888DEAB4D33E74D3AE046E4F2B2E17F6037C4595AF6E463BC5E9F7C95CD26997F7AE62A388049D0CE33A8E9760EA94D8BC65A8002731547678F88CCE64974147E67E81052008549E3D90BC5E61C5B95AAACBCE61A75FCB4056FCCC93D91203AF60A730587960AFA8AA6F95E50E961EEF2F0A7506A685D8E975CC89BC67B777C530CB62430FF11C6508F338174719DEDA9A648D13AA86CED5936AB7026DBAB13D49DBAA5E575569BB67C0F5DE83A0452B567E8B7CE3C65F59FD12B442BBE6FB5D458F2A1A821DE40AD517559A24A8E323696F6F6DB7D8B16C5EC58E3A77530E4C29293A9DDC08F4A6D0E200D248E2C132E18C72B689F3C4D183866333B2A6CD983B4B47205E436B696D885088A5D5643ABD08F121FFB92A69470BDE73F9DDEDADCEB572A5BC2C2987493D5A832DB8417A3BE817601E11EAD608415358DB7DF5ADF61EA9864171437E0A9318BC9805C322797EE85FC7943577C831BC24072FD1F8E29241C240CC80215017D3FAB209F004983542258302E2618F67B99189CBF90FE1D3CA7A6B991E138D798ECA742954D56A43598C0D4B9D53B143A2FFAC61C96F5BA13BC6B2D81687D212DBA423675391A849225AB53DB48721F083FE5AA727A727CD1F0FABB2DE7C2744106CFFCA3E687F596DB59FC5886291AE4EBADE51171B0BBA5FAD9391938524A148BE1C9F5592B29C7C486B841975641B0F63C4FD5B60E4EE27FFF53700C77F52AE131E606BD22B79E1CB48969F4E94E48509AEDD1835044C391DA0D16C71C79317CB425A158F86AFF9C0C4F310554EE1775D1063E6AC1DF9EEC2F9855D6F9CA5D5717ABC6A03E3827911B025EE757DC6CBC8F0A521628274356F814FBE77BB65DD2BA6F24B8F68682089B0B4CCF4AB93787DDCB748F5D04F734C1F541B317C408DB77F9B6F3B41DAFA3C40C3C423A3A05B4D123ADB4A08B394FA626F5D80DB0F3E63906E32C51F6E79CAC4360DCB620AE869956C87CF448B0B012188077D179A6F21899B15F77ADA6D24062D14F8B2DC33E809F9916E4EDB68B3DC09E0FECDA436E314F6C1B9E75912DE2D553C04A63C904721FCE036C8D30E27ED04EE5AFF1DE11E9F7DC225F1852D1D66722A766CE5C26ACCC6FC379BBC0CFB966C521F50BAD8375FF6C48EE75502AD81039E7031386B91FEDABD23613AECFA6298D961EDB5D7EF31EF45398B454036593520790E422C9320569CA969D2B8228F13931AB7087849CB7743269965E1CA46CF655DA1917C3AE60BA1531580528D602EA592C9AB888ED4F5C9C0501AB6D229E3D7449650F6195B2094C91D771B7B2D237AAF3D3F1EB0A9B213CE39A9DE996B39C23A59BBCAA636FE5162D840F90C6AA6E28A0EB3629ABF902FDB60D8A6E20B1A9E5F41F858B2E35BE9BEEEF93F74CFEC0D60E6988F3CD8302F95618B11D3E55F66DA8A6A7544E92CF1F507B628D36D57360E31274AEBF3F77205FEA5CC9BF057BE026B7CFE95893F9D0583FFB15896D4FD9C485AB70D06D67C6D0CBC604BFAB9331F8F36375725D97D74ECBC95047221D0E09649C1C89D14DA15BB86CE74CDB0DFEFA89CF07C8C09AC7B78F5F8DAA070D6D3C6AA30272EC6EB5CDD6025166FAE7CDA5351A457FEAC61E5DCF917F264F61C944D6AB7791FF89B0039481572CD7C5D49098966F87801D4313C16D644DB8612DB934A7DD68BB172F5413ECA078E09E956AE5FF1AA1E70FCF82874644FE072AACDBF5001347E5DFE68B7623D21D93B10D2F658D98535E4F015C53A1292BE6357D295F65D285B0CCF9245A47E7331FD7B308AE3B0FE33F4909CFDB64F4F6A26D882B6772EED60FFC985C2F61FD3078FD2F59366D78B33C3973E40B63322D75C816F6643B34E75D00EC4D68954BC2F28A0033A541661509EB337AD0E47BC30BCC6491FAD1F664385ECB53AA091C209AE870A910083DFE4EA5EF73059803D256B4399E63E4B71D608B3FE571868760964D7C2809851E0378FDC63BF620F1363C25C30CD1B7EA77F281D50340602F9224AD5FCB34AED819909BD05868B218E233A24770D332950AF29E8B0DE35163882C0343E2AA8FF50324FC773EDE5C94319531EA89732DF779E23262FB9064A8A359E814642D1B99A36CB122AE6E0BEAAB3500F4F0D65BBF745CA24C7685DD84496DE72CE33027E8018104D3E3B8A3A35C2AFC4A602E8FA9C42BB0FBA7A426EFA9890C2AE4384C39BCDD612214254E8FE43C02754CBE3A2E2687165F0886FCB36E669EEBC3FF86F52EDF7ED16F6246816968ECB720055842C58627C7BD81D6DB051C00B993D0743B99776CE4A793654E36AD40DE4FBDBCC74F023121CADBD2C1D0C5B8EAB4A3BC583BC97B6F4E5D3F4B825A5B88025BADE3B2C04FECADBAA18DF3138E24BC55E48104F9908C9BAA96371C622F7702D6010F59894730D819697CC3EA8C3158D5AECBE6CA7AAB7FC1CB51E410831D81AF12F49E36965011EDD9110AB4936E70335BCA7142FD96BF7C7684D2C6F9371FB39B560E3DB53E2CF4AF28288E4693A45C457CFEE2DE2BBD1AE5DB1C65EE01DC660CB27746E98646478B27F1F5A6AB571E4568FDB14EE3BA815E895944798CD1EA08331F3FE931B48898FDAB48174659493B0D39956CB4828F888DF0C1E6E10BAF50D4301FC5FB92B5D1FE0D7B5491F6C750A8FB384827807273AB2E3EC3125F4C07994A12AF71C3F1D8B0BDCECB2598E602586B54B5775B292B06A407E4DBD04BE47DB9BD008421F0F70B177E71E3980B4CF2EBF6154B6306D99136E2C8B4AF2FF3604837B455A07D2732597846CA0C2AA9366D3598BD34204046428004686B881FB5F52A0BC6C244DC453B6AF4128E1972539ED0E98FDB952E756C09FEEFAD1AA03BBA471D8A0FC2F08D572AB0C5C8EE5FCCB6C40E35CAB030DD5361A86B0E30E20756D65DC4F9D5FDEC968C9ED481DB2D3EBADEE1E6741B2184CF68ADA3B04E2A92C190F01E8F43CB7FC5D6C2A7339FD09C8B8FF9135E3DDE85BA80E54F5EB2FF32851F35CB057793E912E93147ED00FFA486BE23653AA83DA8A5BC14CDC7319DAA10995F2063BD4457618802D7B8644E6F61E655B39871CC328CC62F1AA0701A36EC9FEE032B1595B0D8F3517FF85DC09678CDD9ABB313841B10CE8AA11A6DD6AEFA6CC3D876F90783173C141D0234318D679E03B07BECCD9C90D23A93A05B2281B63AB124B1DC13EB95AED53C4367973203DB6833A84B228ADD3EBA92D952795B5E6E095056C687B031CFEF4C8A9AF779E1B2ED16163C5D575E2070D7345609DF9C1DEFD133543C76A72FF590E70362F5A73C45597BA94F70A6742AFB3216201D08505147446DEB4A140958DD88504A979B25B2A23366C81CBD06DFF74E7A93B60896876B7B6276044A6C8FAA20D657C852F594EC1CAB2B148A6AB9C84F2267641FBB28BA4F867BE2B26BDCB93F558E2626065B39431EAADDCAE761FD53CAEC6FB5DF898A2C95A7D44CD5EF84E3EB1D83CAF2E5A63A02DB8098BEF89B61E971ECA06E07821BDBDEC22A8086B82F120D149F41074FC2620270462C6D23A09EC22F4BDFCB0C5C04BCC82FF67816A4C203D80B7AC18BB30710235F1B0A02DF94FCBBACC7A1CFB719D048DA86556ABD468C69C5D4BE845D45ADE69C9A8D725CAEB9DA4FA48884B5B3570E5DA3BC102865EE9ED58E8EC07672817A72F009C9BD007BC4158C9B137E117BCE2F0255A1CFEBC2BFD8C36EB534A1B2D9CD8C8F87905375BD8B802322779248174E5F15041EA7F546F1B0D042A53A93A253DB083D7F81FEFC70DD5BF1DA47596F77BBC6459D4A79DBAA24C05B2EC968DAB2D3D21A430B98989DB43169B3EE9640178D66B3A80694647202246DF5D090CF3F3222EB4A3817760F193E38417E9DF5065D379FF6481580DAEC9956337BA21B066210588A6F80653171297D3B3F516784A02A6DCD7DD23C9340F0C13A86C7B25F84E1893D166D47F134A082C2B2EE4DF7E1D6E6EC747CCA360DA11122815F448356BD4B9B6DE4F5AD60AA47C9C7DE640B428494673ACACD8FFAAA3D6E36D657425D8F1A60C31EE940BAF7BCDED624CDC0E4DAC6A9A1F8951B1A87CB4849CB5D37AFFE410B3D00E014D8425B4D74C3A76497B6A5F1C08A9FBBB3FA4D67B1D8DBC76306EDD94D6226ADC0A202849C65D7E1AE11C1E4D21E02F3C939F17FD1E066EC50C0C81265CE0C7733836AA43EEF5A888EF0A557C964BC1CB08701FD91CE0A166D1E2D8415CDF34647D3B67434EE76B89B6BDE6368D909747004212CD632D44A4280E0C92645C44C3EAF0C01B4FF14A52CC1710058A99FA7C8CB46E06588BA723CC3FE2BFDA8DF36A7582E3F54E128D1BA5E8BBEED00464387B3280A80E9AA5724E44ECCBE883CF15B07E593660AA01E853F18BF5A511D6640386AD0867475E85766E0220AF8158FA8E494347AA140009EEBC3D423A059747C621A148B107DEC26289F9F92CBC66BA9CF0CF883E53BD62F899163FE38C74FD9AF0874493DCCE34428608C4A14CE76BB1A7600CB5D60CE0AA5454AC1A62F02F393DA1E5EA3186D510D15AE626406717C81BCC494DDA9430E2C24DA506184136CD2CD06E4626822F04E56EFB5B93FD89195B4D6D7E0835E339957E2F2F6E66F65BBB512ED0DDB2B36C5C7FB039EBAD72FE891E6AA459442EAF99929BEF947199C08EAA89A719F8052BCD3EB273EB11F1EA1914133E6545A4D6B9A1D259ED760F90C5CF56FF6E3946E008A752163AD517A3C443DF600A8E5D83D32ABE887022437B08EA6CA008A2FE72B0E7E6A22903873879656CA49391B2968E7B6029EC15B1C737DEFF674BB3340BD24D435808B781BDECB2CAF2EACA15D01856F389E7E0BA887471F85607FFB4444A16CF5FC9740CFFB0F91D3CCDC6C27E9CE96F01271341A7236502141B41DDA4EA016970395026A77B5F068F62D4432FC0CA6B377E6C634ECFD43AFB4A01DD7AD33FE82DB3FBA3924B1A48ABF1E4FCFE9CDC0F8BD4595EEB4CCF0EADEC874E2822536177FA3AE9B4570DC928A7175068AB4EB8B44F5D85A98C6D62C7DC519788142BC08915A5C25B8AF7D57AE1535320EAF9DA27806E77CBCD36102D24A29486FFDB5B3F21F88E9914BC2C9524F9010B72217CD3E524290AE85841407C5529E4AEB4C9A9121CB89E28E2FED2EEBB3EB10AA0F04FBDADF278423E80A645F3A5950BA42CE8F5CA1AF452F8E17310609F673E8B194C45A6028856BA19525A1AF21DDF66DBB42867169293631C8ECE4248F685DDDD67C5F8132F2BE3400D02571629FFF8DCD4EB8E3455370EA9672DD8C9DCFA6D125B4DA10DE0C166920E025E423DD0509E46D86876A69B2F09D11CDCAD6F4328A2B59AFF5C51CEEE28AE7023E726120A24346BC27FFA4188AF834FFBCDBAE46CA3A56911854FF595CBE35BB2D25F9A49EFAD39AE131B60DB8825496709967B4844914AE127276F74E593B36D00D934EB3B59D791D9F509B9D00BC245DF26E76DA86218E33FD2DF4019EED80A7B35D239F09C07F99000A6D0AFDE4FF6E88E596578BBA2E9CF89D070D1FD3B220E7A040EAA2D365AA75616C844C1ACD07FB19F3B7DCEA8859289B01609A3C0D7A6B790776FC7E9A606EAA2E424C2BB7C5A1E9636BC5485AF0FF25D6324E13DD067C3F88AC0F509A3D90CFDB259CE19B3FE27C6951BA56150D2293B7A5C64E8F564C0BDA74FDB4B60D9A66585F053F0BED5AC7BBD50557FA874640AF8F2EEDE4199813DC53BEE2CF3D4EEA1FF20F99E459568F899BA40448EA614964FC2844B13A83234502A4962830E2FC0AB04AD714B6FE95FFBEBE2550373E8AAFC2E192B9EC1B1BF441C56B6A1ABCC562C51258D46D63F585874E319EC6C777B6EFA137E564B38600DDA185A20727B6431825575F1731DB56560041763020F5950375ACD5DF0630E6308DDEEB474C65E36EEA086E76FE316ABAC8DC6C9C9298E22307DDA9A4170DDB6027DA5FCC4C5BC3D924D4403BE7472EB5FD9DCFEB0B74B2C59F37263E622FEAA18EE65F29A6B04F19D19397B83E24EAAAC4DC4B89E1F8E8FE22DBAD71DBBA2B1E3E3B9883C023516F4070A2EF4D60C79986459920B5402C455B856092DD9834AE32E3F6B3B4419B93EFCF288D50A0272E7E657AA76D91BA47032F7276B98E7DB9C1C676C40C3D2ECB76A243141606300D18AAD44AFCD29E626BD50EF268E83EBFEE1254039E00DCFC1C9EF04D5D1C4B68FB6DC3AB906082296F3C5ED29907A28F3CD5AB4EDFE18FD93E145F8A22FA69243EFC57FB452D6546312B64B140014BE557F111C383E6A230577E71C0D393A5FF4A64FF24DACA82EBCAEE30D15A09B23B5A8D2D7969C7A722D759C2BCE5B48B8906C6F67AABC72FA964752A7D92474A8A5EF85B50AF508F6FE268F3AB7EADEC9210CCBB4005D44ABAFE1653F5B529503F5CFAFA171DC71A6B5E714D6DE20E1ACE60FCCA0CBE39808144826CF71D57F66EB4CD9C84362FD3024AE7C94C905EB0575070E29D59B8EFABF17B2B69FE4C376232D718644512C19B10B57C137168545A00EE2B08C511ECC71007AC5587A1107BC3A186C0BA320D0CD19121906C8BD489B683B846998F33199457B4BD9B35FB9F5539746E37C00D02AEC01EE7F689CF130231ADE5CF12620C5F3CDA95C65532FB0421DE60E0974045B9FF51F6B33FFB9E57FA4F33C1E9285C5B231D3F896902592A0FE2F750C782A72A11FC421FE34E30C2A3D25E11D8942F94A2880FA2F79ADD49E81156DCAA92701B6C69C85546B09603AA65EF5FBF3CED9DC6352F3FE826DC7CB4A4A27B69FFEB1435645D5AF065727A4D6D1196D4F220DA715702F8BAD68D2F53CF02DBBB753DF045F5612B4EA3E5E64402F384C274407B43804B0AC429BB9F41B422734B95E4663D62B22A694F51D409BB9B70881732B7ABACC1333B74384F706AE7F8EA87DED4F94678BD8D61AFCF0F7DBC46E1CF96571182EBAB284DDC5649215CE1AEC155756794BAA2B3AC06A7332E900E0791DB4730D1F9C8B2210824ED920BCA37246A51653BE1221C9FF9DB1FBF9C602FDD52D0092B1BAE8FBE7716635678161F1AD15FC55B651150FF4743FBC00C55EB5DDDDE5576F21B4AFEFB9DE8069DFE7B917653E4D180F6CE483BC229D37FC72424C4BE81F59B0193D2598C75AD9B818E84985DEDB445C4DABE5956646227A2354289FBABE2CF6EA9877DC08630651D69B78AFFA04446720B55738BF80B08BDBCE28A935B020DE50DCE55E56566C607D9B8901BA171CE5D8752AFCF3BD5578FC5A469B5EE30687A6686B9CF04E9AA88815B89EE6F2D170BF84B0BF845A75B2C303B3968643511D4AB568552F4FF6C0243725F291341AAF654E72DD805C798FCD5214B14616E7AC9F3A4EA6C211B319FC9009536A1772156E62E666788121874F472FA5CAB32BA174FD0B2218F50A3BE7BDF448263F84CE6184306BDB40D6AC6EEEB7A009144D47CFE5121C5F44044D10B0776B575F883AA5CD63B5A577409851707816E4CBFBB13B047D3902D0C7916E4C9598BDADB732E82166F10149695106C8A9F3C0D2CF4349B59CC5A66177FC51A7B1098F6D30FFD8A5D016AD38097C062E0DA6BA3EB4C8FF851503B97E7A276E026DC8D92C68F979D53F9157695FC63A97A9F58D8F92140217D196A9778CD52A9074348743BCCD068B5DF2D5B76943651822D37F217E71EA6763CED121444AA3570A5880DCF44CE21FF035E8EA8107430E6116C10485E4DC7792D04A9B9717932D621B572F42221F1BAC60D3B65D93007913BB100E8658968B0CA77C533F20B9396BE2A7DB9B233028465E54648E3329BA2820ACF6CF00D46BA0CFD045C20C6BA992AEE34F57E9C84ACA1E95C45E9EC6D0BF500A7F7E6626D5777DC6AEDB370A4B1EB82BF4CD0F63DED9A4CCA567FCACDA440EC29CC67A926059152AD7BDB3F3EB06813BFDD8314C365E490C41C6FD4A6173A13F4C4A4E517037315D0EF14428275919CC61AD393BE23333F7D8A93C59DF7FBD4DFA8235AFE88803BDD881CB8E591A721E917CE44103EE38CD499655B666AC3536A1DE850F3FCA9C393454D9BD6F0C75B11822FF23EB22DBA69B08D3F4E92B8ECFE9BE9432A8B445A5BEE8757C7C53DD96FB2058A5370EFC4368FD6B5FC124FA0B9366074719377A0C533415161E29C71D5AA85356B98A138DD28D76BF35B6B9BD3AA30CEE5641266AA5B6E3476CBE1CCB18839B063A655FF7831A6B655D5DCF74C93369FC562827A2E93B53A295E86E9BF8879371A9E0A176587912D1CF344CDEA03DE86B587548FD05D775686D36B8A3B5AC77165B6226682EA37B935C9FE0E02A8FF9951E2467626865C6369A8DA0916AFBFC03DCFD599163BEE9F73F99E34A3F8356E5F193E76C4648053269A659E080A7014A3EA4D7D9766FDB36CC8919294E88D722D9996FA0EFAE5FC3DDA45C14636AE77342A5654D12731B64E40255DBB777CD68D73B7CBB3D8D1013CADE109F474DEE5565B1852F646002BDFCE39C736116E56EB8EC6F75A46F2A19ECE8F0CAD24152DFA63F89AE0C375E32AE637BFD43A1D3B027930461A8CAE0809D65E9B81DE9BA9D0D498262EF57887D6B892F149030F734B44BD9DE9A4C8E97772A50E7404020A9D64D6785059250DC03745A68353456A7229B21F0DF6AFF33894919136D210915581A525208E3FC16F1AC5BAD3908D4D7D7155929F32C5B790F625CF89B8AD92622 remain = 65534 -max = 65535 \ No newline at end of file +max = 65535 diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_256.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_256.rsp index a6484c2776..ff52ff9d9a 100644 --- a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_256.rsp @@ -1,5 +1,3 @@ -# XMSS-SHAKE_20_256 - pk = 000000091EA51EAA13ABDB2B1A37732B47125C74B4F2D624F9145E295C560DF4FFD6AEB404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 0000000900000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A1EA51EAA13ABDB2B1A37732B47125C74B4F2D624F9145E295C560DF4FFD6AEB404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C7D176B37A7DC26214FBBF555DDEF8D970B6AA840AFCEE7B674EE05845118A6FB277ABEB1A792B61CA4D24646DBBFD623564F93B74C1277C1AE4CB326411850F0371D6A848ED0BBFB8B0BC3254398F513E630D075CDD277E0AE10D8D13EBDD0CC60AB0FFC61631C5D17989AD9DDF25BADAF0BB87FD0E32975EB673434812D58CC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D9330900000000000121C29A3D4E6C5DAA979424FCA26B0EBE6D3FEA8F078FA9A98B0F55503C2541CE0A0000000000015EB6FB8267689B81BC8E2C8950E5F59F4B43194AB167C4A60EC9BCDA7572E5980B000000000001F02838F27F104405AA4D9E111D3A0B1849F6725926BA5B3A6412DEF900E7259A0C000000000001BA1EE79A04487C5639BA096A60E3E17F7A0E9C0238FA049EA7AFF52FAF5890980D000000000001B63504B794C356EB44A98DE32960830E6B275526432F232A7729ADA72571E8D90E0000000000014DA82230B909123D34E30FE0722BDD93EB6D56243518275547CBA7C473744E6F0F0000000000017AD15652FFFF1B8B9E752AD4A07EA737B8D79DE25D7F194E19ACF003E62C48F610000000000001D6819E585CEA52B14299092F01E66E9A6E7AFC9613A69B89ADE061890A230145110000000000017FB1A159FFBC19461AD72D4E385722A08E9A942BDBC3CF8352CAECD938737D89120000000000017B2C7FC20B3305327D2F0FC3C4854B0053D00E56EE4E005E43CBE807A619BEA813000000000001000000000000000000000000000000000000000000000000000000000000000000000000 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 2820 sm = 000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6429AAFF05B285E06B6EDBBA11503F92E15E17C582FDE9CCF8FB0E5BDB90FCABDB107005759C1AD991FBACA5F12BE25CCF5A487CDCB35D2FA0415A48AED18AECFE49E32AF457F664D605D54CF42246B21C1B822727BF0869E79C2479B3CF7EF92B2D92D18C1A9520CC21A0A17908D121E1EA426738CFE364AB99172E83544AD0FEC48EF86066353B471BDF03374C02568B2ACA5D9787A3547B32EAD02723B86085852D62225D7554249CC1FE71B8CA3B01240808B769DC4154DB886DB5C1EF5B5CD1E9A5781AF0B8028EC1D1E1E82D6AD6AA45A6D07B244962F9CC5A5A14674087C37F5C128471A780F7E20C5F04EE713489718EA13D2DD776EC37B91AEC089A1CB652A4CA27DF77D2B59BDD5DB0D4657882E1C3D50D022B673C7E4C1DC6AA9D0961BA4254B0FBC7E8A37B1D610C74A511E52A8A50F4943217493F7EA4C92CF25FC55C8986FBEA375F95A3E2EEA5595322FC1079823D49731A6713DD270B3AD1DFA54D60EC4408C15DA7FC4B5BEC5120F1966279A400F0AF374CF6ACD439AB0307168092C3A8F03F4024169DBE782051501D6CFD53F3344F583668D2F25276D0F93B0896752FCAE3699AF03C2E8C8725BE6073251317D1EEFB497336A32C511CA3D91BA9C3CF4528D139148FFFBE43536D085EF62CA9EDD4A56A4127C96366A690A32F4705C98818ACAC9A62F3421985687FC5107199B035FFCFFF5103D7B169AAFA3F7873198C245BEA6FB442A5EA0710814787B60EF727174C29BA2DE46E283BDECDC6DB095544CECE9268232729556E6339B9B8A2F22FEEA16F32E6FBA5577B4CA665BE58EE459BDEA5C1765D63045C230ACB40DEE76D8FFD25275D33730D608B41AD8FCF6149DC8C5602305056A1E00EFD26E79C204239C69DEC416E8AAA98B43CCAA440867C0C6B6C74E32368C7884B8860E5AD1B518F322EE72CEC31F52CB0B5D16C7813F05F9578CECC287D621864B54E54836F3315642DAF8E0F3A61C68EFB4FCE7D560363BC9F3A5A0086D87169AAB81B9736674E598CB301F84E7F03D94EC6741B481B978440F93D3B0A5426121B516C7A4D5DDF078995BD22D0970A4E6B4D0E8F6B2040D9CCF85DA7C9522BD571EFF09D5B1561225886FFCD6B7884FFEACF7644B9DF10F6FF9F1408EB28E5F212BFB503C2F8FC7981663C50B7739E3F2D9487FC2287870964D9F328563E36677622B3E074A980DAB585FF96FD09B7A843E4B2BA51E42D964AF28BDFA113E2853EE1051EF044C34EE020DBC7172C1A1C5F71AF0F2B8A6A8F9C2E4C8BBEA834A94F34114CEE3ED19E514449946DAEF69516854BC502BB54F46086F5FA4EDAD92893384F67C4D1C11E826B5F1E910DDA7ADFB66C00FA7BEC717F2419E026C3492CE4DE1B568A4DBC25C6C592641852AD2D562A9CEF92CDA1EE295DAD0074EA1C01DC90A6831D3499FA6DC8D6B5D737C95C689192BB35FCFF90B87519113376A44AE4BA207EE9AF82719AA72ABF543ED8EC30C89BEF5ADF1723437F91863B0B6CBD2373F9638D74D6EF309D1B787311CA839339BB9AB60CB5B1F922D6C430FDF84A3A8A81B7FC0282C404FAD61A9AEC0E974476860D49A2BA734DC223B46D2C25797CC55E16A37D56B5021A9413F7F65DE41A840258A1A492267B8EA54C51DCCC1A4572023546321CE81E7F51B4DB3836B1E2CC30E6E7DC45BFDA37C100EB88E44069492CECC82E9E4EC8C7C2C9F85B0BB6B57713F156B0F0B1F2D50589DEF2CDB05E5790D34CECE7C22212AE889BAD4A39F127D0F88709DF1FA2D58AB09D249014EAD040C0934787438A1A5C7C9520F36D18AFC8DAB6866EA201DB358B45AA0CDCA0959B4F0BF7ADDCDB0CF61ECC7FBCEDD43D7F85EB9C9B771CB8EEA797E79F369BCE45087374A20BDC6FEB45871AF744BD1C6D91F72509602FDCA13C0F43D8C9C0EC8141AC267D940537B86335E609D558CB2D1DA9EE891F338DFF31CD3748B61CDE572EC77997A2BCD420E58ECBDAAFD9BDBA4BD815108B240DEA39524C501079A2815C04018C444AAC8AEC51B9207412600285537487F1C65E5E53B472D0836698B80E10F1F06EA466C78F7065088E07801C44DC68A93ECA841BFA02881FA3003878D8EC6E3CA1CC6590607558CE59C93E72BCDE6D87961B3185CA3ECD7D6A913D9F86EDB5017F5A1F28FBFF054D1BECF740CC96822076C1C173E32EB8A2A1D282D8BFEB277B9BAD5906F6C8ECDA3BEEE3253FB58D7B532C7885549593BF2984B3D6FCC2E70105FC34A1CD9A85B9B2A48FA806BB1FE35675ECD1BA10FD998068C0797A6874B02F3759F9DCD3B771041F74F76D99E4FF70A47B904C80118090DA4220AC717C36C588FD89EFC473084AB49FC4849D497AAEC8FA2A8C8DB244001F4348AE47425932E61A64C79846C4214ED25F04D7E07E38C51FF1B1B3BCF0D8D38B31CD3B8A69210C1C3E5A92FB8CD5BB3A57E03D5D9672A86589501558211537988D9B6FD2B248B4C6B39CAD3A41052A74A72C2599419F61A78459B45C7976E43E96BDC2EBA3AE45FFFC8766D70EF340F6C1BE587DFAED8EA010542245C17684A9944E53BB33C776507D940D6990B152898366FC0906F835ED4B9FE9A776EC249F3B7A73C8ADD42D2B17B5893634E68CEE35D6BFFC32B9C588DE07ADEC32475AE5AF1F29EDC5E4EBB848C5DF4EEFB01A405403F4ADDD2097729FDE708EB369DB19FAFC35528A11EFF706445E69FC3F47DDF27092C44B520438B711428B717CF2D19F31D996047E852CC36403C86BD4C2485B886668646E164CD67132C6D187490F3B18BD3A339FD5FB07DFA9F1F74466844FCD43252D480576898E9037633A8424577B3DCFFA3AECFE14317B60F573A7CB1C938876CA58C9DEE64B7EDCB6BACA85C9E20AFAD6B68054B862DDFCEB991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EA6E323ED6E8A520C761F371CF760445A3E865E4B2524DEC48F47386A1E6CE55611B40AFF393D6177502756D15DB5232BCD58ABDB633EFEA7390FF8BEA443BFB32F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C7D176B37A7DC26214FBBF555DDEF8D970B6AA840AFCEE7B674EE05845118A6FB277ABEB1A792B61CA4D24646DBBFD623564F93B74C1277C1AE4CB326411850F0371D6A848ED0BBFB8B0BC3254398F513E630D075CDD277E0AE10D8D13EBDD0CC60AB0FFC61631C5D17989AD9DDF25BADAF0BB87FD0E32975EB673434812D58CC remain = 1048574 -max = 1048575 \ No newline at end of file +max = 1048575 diff --git a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_512.rsp b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_512.rsp index d573423186..35c2aeb6a0 100644 --- a/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_512.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSS-SHAKE_20_512.rsp @@ -1,5 +1,3 @@ -# XMSS-SHAKE_20_512 - pk = 0000000C2A857867C4C12EC4296D971A38A242B9DAB9C173678C2BC776A662A1619B1B0149358B252995E4B17AD6593C1ABE2AEFE1D2A0E4FA52E24E73AFB0A4B61A3D544D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE sk = 0000000C00000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A4E3B7DCC104A05BB089D338BF55C72CAB375389A94BB920BD5D6DC9E7F2EC6FDE028B6F5724BB039F3652AD98DF8CE6C97013210B84BBE81388C3D141D61957C2A857867C4C12EC4296D971A38A242B9DAB9C173678C2BC776A662A1619B1B0149358B252995E4B17AD6593C1ABE2AEFE1D2A0E4FA52E24E73AFB0A4B61A3D544D3FB22591039B76774FDAF41CDB22A8B5C5A20F3BE5F9058E466D2A013C60E39DBA2EEB33B69D3A87F593F3D02EF134760D5BE6BD693833524E2A5B4AEA21BE000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002AFCF3BD5578FC5A469B5EE30687A6686B9CF04E9AA88815B89EE6F2D170BF84B0BF845A75B2C303B3968643511D4AB568552F4FF6C0243725F291341AAF654E72DD805C798FCD5214B14616E7AC9F3A4EA6C211B319FC9009536A1772156E62E666788121874F472FA5CAB32BA174FD0B2218F50A3BE7BDF448263F84CE6184306BDB40D6AC6EEEB7A009144D47CFE5121C5F44044D10B0776B575F883AA5CD63B5A577409851707816E4CBFBB13B047D3902D0C7916E4C9598BDADB732E82166F10149695106C8A9F3C0D2CF4349B59CC5A66177FC51A7B1098F6D30FFD8A5D016AD38097C062E0DA6BA3EB4C8FF851503B97E7A276E026DC8D92C68F979D53F9157695FC63A97A9F58D8F92140217D196A9778CD52A9074348743BCCD068B5DF2D5B76943651822D37F217E71EA6763CED121444AA3570A5880DCF44CE21FF035E8EA8107430E6116C10485E4DC7792D04A9B9717932D621B572F42221F1BAC60D3B65D93007913BB100E8658968B0CA77C533F20B9396BE2A7DB9B233028465E54648E3329BA2820ACF6CF00D46BA0CFD045C20C6BA992AEE34F57E9C84ACA1E95C45E9EC6D0BF500A7F7E6626D5777DC6AEDB370A4B1EB82BF4CD0F63DED9A4CCA567FCACDA440EC29CC67A926059152AD7BDB3F3EB06813BFDD8314C365E490C41C6FD4A6173A13F4C4A4E517037315D0EF14428275919CC61AD393BE23333F7D8A93C59DF7FBD4DFA8235AFE88803BDD881CB8E591A721E917CE44103EE38CD499655B666AC3536A1DE850F3FCA9C393454D9BD6F0C75B11822FF23EB22DBA69B08D3F4E92B8ECFE9BE9432A8B445A5BEE8757C7C53DD96FB2058A5370EFC4368FD6B5FC124FA0B9366074719377A0C533415161E29C71D5AA85356B98A138DD28D76BF35B6B9BD3AA30CEE5641266AA5B6E3476CBE1CCB18839B063A655FF7831A6B655D5DCF74C93369FC562827A2E93B53A295E86E9BF8879371A9E0A176587912D1CF344CDEA03DE86B587548FD05D775686D36B8A3B5AC77165B6226682EA37B935C9FE0E02A8FF9951E2467626865C6369A8DA0916AFBFC03DCFD599163BEE9F73F99E34A3F8356E5F193E76C4648053269A659E080A7014A3EA4D7D9766FDB36CC8919294E88D722D9996FA0EFAE5FC3DDA45C14636AE77342A5654D12731B64E40255DBB777CD68D73B7CBB3D8D1013CADE109F474DEE5565B1852F646002BDFCE39C736116E56EB8EC6F75A46F2A19ECE8F0CAD24152DFA63F89AE0C375E32AE637BFD43A1D3B027930461A8CAE0809D65E9B81DE9BA9D0D498262EF57887D6B892F149030F734B44BD9DE9A4C8E97772A50E7404020A9D64D6785059250DC03745A68353456A7229B21F0DF6AFF33894919136D210915581A525208E3FC16F1AC5BAD3908D4D7D7155929F32C5B790F625CF89B8AD92622A0B155ACC09CA4CDC24518B84CCF0C924388B77DDD51F3FEE646A774CE41367F983402ED44E85B679908928FF5F7522BF9199CA1A41A6B42C6CCE575A6343E512475A3CC90B7D0A456141E1C3ED6ACAA15C6241328BA1936A6F78E0D6BEE97827CE1E329F2CC6B58E311847B4195B396C8AEFCC5D9A8F08EE282B26B4CEE8B79043589828F854650D73A433E0B879E11C577ECCFC08AB67DD9FAC9C3E5128060C2F2695DCAE7520EF6C12DB22F74F2F261ABE6F9FC6244489B96ED9222803F635DAD7FBB43AF6C2913FF809E208C97D9379BF5BC7E4276CEE51C6509A6D13D4EEC779A04A07B3D80569AF1A325ACF378A219999B8F91DD48AFF90105FFF878F400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016A30B3920D43D47945F47566B618719C38844032986568606F2DCFBD7104EEAC5436CCD86E9677E05985FA63C1B6D3E642D0F145B3FF637B96F2AFBEADED75F30100000000000197C186BD25DEEE5DC2CE5B760508549B1EFB2F3E0A34047232BDCCA39B144EAE820DB1F2D3C3159D012D7CAD7AAB1C44E15F53F4B1166E23DB8AA23ADA9E23AE02000000000001C5A2B2230C54CCBDFB5F42AD8805628B6B3D4723AB84E514035694195F2FB7E716F21EE8845170F30D1BEF79ED4468F2A45A72853F2D8F601973595098010E1D03000000000001C9E730A265A6F2DDC4B0F420CEC9C7AC976ADE4FDD5CEA3B6D5445AA2562772F76635C514BC81DA00E36681EDFEAFEBF29B1C3078AFEBAE3956D74AAF351E35904000000000001B661B82380E38D5CC77679867BB8FC1C94E77006AD05DE9576A7BD210641D25D011A056637775E72395B7643018E0BA023747219D875DBA848A58E0F9D7FD2DA050000000000019F3A31924919E8711F88BC45477356D330ACF65BDA612F6AC681F64C24FD70A6AF08B3FBB6136E4AF05B38A9205ACA4A2773D100FF79057CE6EF6C3F82AA9DEA06000000000001EDF9A31569FF07104E7B2FDF78D2CFC2FB28903D720F4D2ED95AB35DEB5EE579384ABCDC10CCE008B5BF753154B78207E452D4AF2B5646C42B89EBDDFA02570107000000000001BA911C4438781B45414444B18E3EEB1F0E57D33FB8F1BFB5DF1DC85D88A29371496D214B1042FADF9F17DFAC6215231DECB7D4ED1ADE6272BA7933403D3BADA608000000000001D85DF2FBED8348BA8E34D08202B5F944A00F91F1CC1F50C50D2460DFF1CFF490D84B84A1FDCA7A5E1760FF2E3A392D3F4ABB78116DDA6CAD29E694F9A4691E3B090000000000017C1668200DA615F45702477762DDACC68BCBDB862EDB8F34569EE898D80B4DFB1AA4251E3C3D1692C8C50DA2BD543C84A807DA4027BBEB6EA8A4093D5E560E110A0000000000011171AA4B7778E156AC8674A7522E4E47C54E7ABB917E693DD788D8782675BFF5E0108D4853BA609E9E9C0FD4FB0B8908D8D36F3CAB806CEEF40B173B740540330B000000000001AB4927F65EF9D6DDC2CF1B044B306445ABDD4629C4D63AE6278E049C96933D81862327AEC4B7D2C31B6C7509C6E45D2945E0121A0DB90076FD84AA9C5AA53DD50C000000000001F73CC84242314EBAD62F95C79805461C1902C40FD822F19F69C029997DFBEB840EE33A9905894B1290A75ABD10F4EE3BD6E75DC6CDCF69A7FA48735C08EF85E00D00000000000125A7E166681FE462663B71CEDAAF483C1D8097F57EE39EDCE104F6B10BD85AB43EA3C766F25F76C0AAD896BBBE825A8FA45AEF3C0483571EFA6FC24E973AFE4E0E0000000000013DB4DA57E43C4A075E6A8B417B395066BFB8C7291C42A04F1095A5F410002B3AE64DDC3633B2E27A4C28475C56FCBA6F0A6D5B730FF6320C89B39E55ECB22A730F0000000000017B5CF3181D29B993558C7A0E3AFD4320F7B7D1EEFDCD2FB0A3468643C74BEA9FAA355404C1E87E21758F95A9550DFC35D65FE4CF5B7023C963E54A680F9B06E210000000000001C9E3EF53D631E6DFDC8C3AFA9A9587423B4B2EB4A98CD686B3C50BFB5C9C99D7D24DB39B7D9A2E75B23666B0B7B5FAAECB29A98E1A814408EBF10A7B75C110C9110000000000012A5B873804EAFF769CEBCCB642FB8FA833D7F189AD87DFE06243AA869FC10A204159BF0E0A8C197D275F7F5402AC39337575938407F162E20FDDEBFB39D018AD12000000000001982FC2AE47D7278B0DCDD6CAFDDFC61B07E892F823F5569457913E9E6B46D137BE1E39EE028AB4DADBF1343208EB64F9ED562CD46BC8AC4F3C3F71B4C6738404130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 9732 sm = 00000000BAA7550F0E617123968A7F276A4E50664475EB64F4E5DC6805ACFE998B45C1E0EF24208EC4F8C326F4E4D4B36902314578DB3668398F8D67F573F98468AC125A48D7968F80492509E1DADA7B6A244DB720657882BB29EE8EB5B2909CA2E050ABBF43CE3BDDFEA41964793A0E69CA85B0886938A7261F46A7DDD3AE5B2480894D524551F101A16B171E57FAED681E13356AE6949546E9B60D753BBC664F564BCF0FCCE0ED541FC5E2C3DCCF3CC35453A3AFB3250D9D21A5BBF905BA7A717F8383456EFEE4743ED451D4452861D9F91A7AF09714028A201BC2724A2F72037FB25AFC45938D425A5E3736A9DB00958A4B4207BAB54956B772C52A52AFEA8F831D9686CC4FAE8749A070DC047DB8BDB3008FBA6051528245CD1B3DB51AD261601361060C7C25138B342A815AF4EA2B32C3CF6F0765B9ACE46BCF7C20067A6F4BDC15FE2CC72B09A6F66E468EB6A056FEA2C17638BB4A642D95B9FDE18620C35DACC1D5A2CBA71FBA4C29D539F57F54A59056C422CAEF6C6F889073ABABFD9CD5F8907E6C3F60F38A328B2F2D51A03C900F4E38E81BC8E787C64F3185F2DFE129E70F8443AA8747B57914EBD06B80147A2CBC463C564D048FA7A3B2241F1850FA405BC98B7A42EDBCC38EB1B46F14C3E07DBAB10B4BB0DC090214FD105BF5A488D9131D2DE5C7FDB78CA17B03F899C3DD77E3C132D4512A6BC6658CC2ABDC229A207D3F993ADA9A1E6899BE1F550F6477A2CD9652E8298EA0ABFD3BE2D6FB92C913A4BD09BCCFA92A14293ECD9C7A7DE6BBFF45EEB4B204C66FEDE1D75C64FDE7647D580E99DF34AB555CDC3A3D5E325830FA5FD722D09F2F0DB129EB5BD82C9427587FBDF6B28E52D11307C468E9D1AC46793889EE6349B75A90D1834C05B5E914E225A5E7AD158AB48F11CF733F612485319E88FC57F9EE728E5264EADFEF56FCA94E7166C148548ECD1485A9A126B8339A457881CFAE65F87533765219D657592D28A49ABF2281522FE1D9319DC6A73EA986345B69D82027777002B40EC9BB896570BE4B1E74DE3016325C72C876A9D93C834C936DF976F78F33D9407D4A5CE48DB5879D08AF016B67FB0DCD68E12FB0770CE148944F4F4218C5BBACB24A8327E029AEBB399607EA3981BC7ECCE1978FB7C226F94ABFDA6D836F6B9A9C34B8648C29F71D9A442F0027B461AAD8E6C12E70782D89DC3371B3DC225E9AA57AD4E785AEE6D5C21DDD122CCD3B13438476E450DE59729B2A1A71A6A463AF30B4E62E7F33EBBE7E3EA6140147518E42867D2B820117E6F7BC5D685623B4557D03BF5FEE5914FA7B01D34E14B398AB4152CE9A622851DD8C4009EBB1002B88C5AD6B75B332B06E65FFBFFEC017F20C84C6670237479738DD67B0D49BC66A859051B65C42BBDC0CC4C91A15FFF9A8CB89266E4B177FA4F9A735B4B64A939C0F4FAF31B5C38A174F671F86DD21D6461D4E0B71F85F58E0F1D6C366C27254FAB70A4E7381790F81DC2BA72A96DD9738B5B8571AD2983874BEC370BBA303413922FE613DFDFCAF3E6201A69D246B10067AA141C6AFB35F79E7B8C8089145F07735986C77AF22E6C832C26AFD931648477E434B3FA47BE828F89B2FB1ACB5E1EBE621BEA0EBF225AF2F153E8FBF4D0051B455429C81B226A21F3F4DBF46E08143B20DE9CBF9D6DB13D5C0F51C9707565ABDF0666923B99E8D488D8F35FA68D02AADBF7515566B354D17A95F5787424EDC05E4739B1145265A2F7137C3D44CFEE8528520B8A98A547DAF2D8FC30E325CBA9DAE98682FC48AC544A2C7C8E4425744D7917C4B9A275238F06715D8BE40F2AE5ABE5C5594A080CC8302F91AB8B44CA0A445EE129B9A1F0D4CAFD3CD742DAA99327B2D2927E399FE9FF50D12BD3713C3A0D1843D953DAE68A90CE2435930A5A8CA8A852D12082C138BA64D31225E3901A2203EF75A1A33B64380D3C6A8A0D8C8D150097C707B4D2C6971CC79EEB8D57DF801401165627905F18017C394EB5953CC4976A022484803434DECEB76EF259C17BA424570C3DE4871A60564EEFD8BA801550ED0C8CDE89D7EEC693F01A8CD3E9E8089DB3116515E53D6747DB93DAEDC2ED26B37A1D32277EE3642C48DA63E8922672469DE0C2302DB2FBB9C5A84D55BCFE4541505370EB4984AF724A52FDCBE9ED53A634E4B9201DE89D486A5CD10CBA000F0032A954FBD69AE65C2EA4851C1C0EBD1A5AAE6C88546A21CCA42CFB70CA4CD8BAD566721249AC8D536AE892CA4E856D3042CAE77C9A15FCADA3FEC9E4A8AE7C6D63AAE1F06982258A0170F9008ED55498373EBDFD242BF018DD5810663FCFEEA83A9625135E9971F2E4943283A53D0A24B5994527BE2B7BD4EF8CF2CD51BAD59B01A2752BA68ACB92173059A0ED6E7435657963D9D048877B430DBE6DA6D99A4B2339955E4A62B7879B1AE0AB62B4718C40D0CF11000E959F9A99B95F650C75216DF446D8781EE8409FBF3D9CCCC795791621962BF96E063BFB23D9E781F4F21663871110172C46A04606DF46F57CF382D3465F1146A054C7E221B439DA76A2203491782FEE368E90BA6045CC4E0EF9CE63C69284BCBDFBDFB41FF1450FEF4BB22EDD14A0DF06A69F042C193C7823BCCB97797B50576960E352E73FF2E8F722F7A687CF296C8856863BD5F69D009D8198812F383CCC1AF142DD76D44578A50AEDFF30CB85A61333A7D58BDAEBF575A486A754F7AC60D88660EB148F3FB8BC31B6B057023013CE84EFD806FDCE46D0C2B359FEA6E4C77E358BA93FB2B71B47B0FD6EE17A4267797FBB9F11B1192941FC13992B67099757A124009EEA46A89579F361F19ED02D6F3A17F58DDF52AC0881F3D0B41B89603234CFED7DF3F4E20C1ACBD505B9EAF7A742BDA1DAC0732C1F37CF98C98A216DB63D6A6B79AA2FD02BF1F1688FA20558BF4C3F2E7CE7B054CD73495C2945105FE7A80DA396F953D456CFED09DAF45F511B1C2908A12B55EA575B23B9B104D58150D334FD0E79D4C911A845E38A7B30A586D2C0A1B72122FF85A09177630655235DCE989256B7064DC8018DCCE8DDBC1B824A71C9B3F920682CD8D522529AA613124A9DC598DACAA16A538159213D12B341AD1BF372A4E95C571826A6E7E81E87E691449B73E10D2924719190C26D394C42F015F4B581E4C32319F02D3428E611C44A86FB7DEED726826421BF21A9638C10A5E2F921B616BC9448229A71C30627C398C4257406F9ECE7BEC2E9F7B2AE1F7047E80746B156E0DA9F4D22D50731747F2BEEDDF5E92BFBE630CE1A618E4E7BEAA674BEE4380456301B5D0578ADACAD2B685BDCCD8BB20A0EA0D330F284E5AA318FECFE8893138D179FCF67DA8CED69059EE410D7B12BBA676297F731A568D53BE999E31F5F76B924C710B8C72545012CE23973E52D4FB9A7F9B934EDC2B6E27A7AD412F52D3840E70BC8A4F0DE5ED7A890D5705BC40B0732AEF50CAA5563E15310B5EB6E70167B693185124F828E88FDC6E147591CF31F0524F981832ADD6CC9D75DC323077D810A9AFB623C41245249AB508B6E84B9FDE68B70BBA0EBD51AD50B2798B2B0A3FF30BF17FD109D5B66C9D1741C3D1FAE1E33FA503AD68526AED523A0F59AD785FB6764E3E4F26AB8E4EB626E988ABF6F27010F010822710F38B85DA10A0115FB8D76D3DB3E79F27F8A5E472ABE15B46773E77511A9AB78CE4076087F5E46AA21F953E06E11AFA08EB04C98C285F1D54B29F4BA70F95758BF633C778F8A674B94AEBB68A470C68BB07CCE6E83BCC2AC6FCA5789D0AD80FEE6983E5AD6C0D877E1B378DE56C225B5E04B7CA6D668DE404B150A615F3AA81CF775C8A7087BB390BD6468E13D3C01F480ACC4E92CBE0AFFC10CA5A83BD8F800AF3C908CD95DCE85E42C6976B645F27F94BF40BC9F175B15F85E4BF965528BC226D1C56937DA29EAA5C6E37D2A73686D4287A2006FAD01878C9F18A519084C0B0E7F92907713A01060F545798F2D6DE67B1750C52289BC5A9EFC8D71617C6FC30AC2FEA0A3FCA3C689A6D7E0FF05BCC0777B60E1227D97CFE10042E03A16D18AA235D78E3991407DD87CF8E9E265A5E39AF49264BB4864436375AE62B8F9F8E675A70AF44252999A011BAECF423E511A8B6FA5E7FB0C467476520694B36AE5C0D475D3F526CB3668CF76973985D25367D037C379A06D142F39D41B86BE8897CD327A765BF6490DD33E809315C4DD225D109D978B972FC62AC0BE6EB86B2B5F49198E8E1D60BE1852F2CFF34CFCDCDDC207622E9A69BE9F363D5AEB8161D28B32116DF586770E65ACD5D0FC2A8C8969F666705D3FAFF3D16848ADF972E99AD4D8BEF1CDA5040FCB87897BCFA8CFC0160E16AF07AAC4BF858FD677916EA65213B1987680E3507E6C976683CB9FBBE0A223F7B2AE55E9CBB1B1AE83D8971500AE7AEE000660C989F6A3979F74D75CD1621ED0AC65FFB20CCB56830970F137D0014E7F334E957714A35AF3CF85935C7636D90604AA3F5D1AE5651F59456DDADD77340B873479C47A41C8480DC2D57EF6948521A23E73F677C3E78830BA27218421C098795D3DA41103F744C8A0A5A6FE6960F26C0F90C31E51A893FAA00C6B6EFD76BFA5E224E9CE76AD683B41C18711E1BC50665BC5C9D9183F3195A7117BBA583A2EEFF10B57B778B7E95DA6BF8D18E2A1391112235EC64E7701AF5C73231EE6664305C79FC59BBD67D774C80D33B9CFBDA295C483A7E063493FB8C96F915FD887E5ECCF96652AD374BBA9689BC8DF98B70B672943C21F5FD0D52D44811D76ECB7A16FA0A9DFA37D4759DAF65D69B2D84C0429F3A922A23734B95BB35D0C52E3C123214315BB9BD108C9350DE588FA5002E6A3536A4909B3924A3E7F8674D4F74C09380FA35982123E584F970820802F0E4B7561A54715D3D0A37850E879605AA0BC7546544827A8EACCB0772DFC330FF0356D34AEC0C3BF1BCEEB5B4BE7FCD9E21919F1EADC23C414ACF0599B0C9963DD2455A237B4C7AE8950D17829F5030BEE7B01D5DFB552678F0A36E9E1DBE1F0E4767B2C1820DC77C436BCC6DBA2A0707D7D8D8C9F3E754E717AF878A48FC83A89C1F296981261F179F9AEDAB136B73950F2BD1F6A033C7F33B7E5BD902C5E9183588065D20F6C8DC3648B35641F3A33A81A430161483838FB206EAA89841888B8DD0A9468616B40464A5ADF80E28A5E33E1D2CFEFAEE6A7A4C59E975913F1BDFF49B40479D4903CD92108EAE54CD4B7247FCAA5FCAFBA7E32A4C4DA1805362DFB72A1C216F7D12F687F955DEEAC751232B3745DEC50BD3E4C2575C1D13FCAABE57539AAB71694D548A9CB6C8EE765C95FA453F1630A014456FE25639FCC61CDFFBAE0A154EB7DAE4928F40B0AB881CF4D0E8A1D0725733500815124F1705DA0FDA52F7E3B270EB81FDB86B1C5AAB117032906CA96FF73661E2C707D64D27E45D9979B4DE41D64FC42DD7F8FFD0227E9421BE8D47131204A416E3B6A78BA749E5F0EA8E9902360DAF05ECD83A5D494E1E4D8D42A41621E263ECF9F6D6E01FB83A0F5CBD435C9D9B367AFB579BC0393118DF8FC3DB793A2C0D504CF5A484D346BEA86571177C4E9ECF80B77498D64305EC9B287CECDA7FDD9CBD1A3CDC3EB3EAAEF6F7236BAE6FEABC4E17F8E8173066E2AA77CB6B435A5E81F04E866262495E2682BF7E1CAC4986E7E63D6C350DF4BD4338288716B8E50E3A2DEE49BDE27FFCB8627A97941FBC5BF74E7B2811E81E3D51AAFD54C4512EDEE3069A58C5CCC95F059DEB17257D6B16F30C34D6998ECD12CCC24EDE44E2A6113DDA9D3D9B298D58E61F663070364EC4A1CED4B70676E87706D4F4281761B900D8E10B8EA9B42A1364EFD4EDB44231097FCFFF21AD515B93BCE77F9D26C3432593976AA386F0A48B70BC659FDAD0399914A577A401D24C88B971C60DEF61D30F36EA9040F301734941742B66E4D4E9C883DF71D6EE901A135E0E110FCEB8A24A609EA226DF949704925DA1917C3AE60BA1531580528D602EA592C9AB888ED4F5C9C0501AB6D229E3D7449650F6195B2094C91D771B7B2D237AAF3D3F1EB0A9B213CE39A9DE996B39C2BCB4B909383CEB2A32F361B71D6CEC12FB0ADF2EF59277E4DA927AA08D2B2354D2451E74B2425019A6FE8D29672B103F92AB1377DE4DABF8B9A03A33FC6D641604644A9E153AB0BA4DF62F4F3AC71B34BFD2ABA44C1EBDF9B1176A2139D5E8DB791C9AC2638B80F2B312731C8E9F0E01CF4FD6B1BFA84DB2A02ED6E4AB4653A167D3F65AA04A0FCF7C87FADFAD06D7A146063735C4E7BF2E981B71302E1575CF6D15AAD2C9F327C5A65712D112511376988387A3D62F90D878E3E7C8874FB439CB059979E86C18AA096BC495F516B01627B50A77009A9101E925716334B9BBA939456E42F829EE45B902EDC68E4768E5A2EB06670F2F69B2118619168D82B3418C8AE26444E3E43034A88DDEED8464B6DF093A48545712B8D86D3DB7EBCC586E589174EBBF66743E972D342EE1FB62BAE073961B6CC3264D2C6D09932AF46841964D924AC5C317BD2F4643AF98DEEB154AD6E1D6505F98AD460F35597A262EEC900BF6B0A1EE36F31D54FA32BAB6FC6C3CA6501792168FD1A936FB732231B1DE5E443EE0B5CF8CD64E7B2EE04FEFEF8A517C40FF0F78F87247C8CBE209B000C36D44DD313B226B09522D087B73C04AE187774DC21A1FA0EBD77B4DA23D067461296CD4D0FBC79B36396A3B7640212C4DC10CDFAA8643FFDFBE5B1A1D23A3D8A56AD621FEE0BEA5AA24EF6BF0612367CEB4DFCF152018C7DECB6689A94708AA9C151498DE7009EFA79D220DF6781107BF7B50FA7DEE57BDEC2100B92A493B57FE6233D87129D1602645BA18F2207A3406F7704D24C6CCB0BFFC9CB6122E73512E3CBBE36936032559E18272F127ED2313B77FE6321FE6063F8581BE30DCFE3E689E4098EEF571C08F7A38F99F2CB3FCC4BA0FBF52A07E47CE5928AAC17F69C83C0754D22DA22CD4077D9A8E8D7782E897B2F1F192845B9A334C6714AE2FEFF4B308ECF6922BD982D862CE33B170F17A1E8FA9328C63A70537BED3B893048CD8D7BD5F8447B037D153051CECD070240EB03033D416C4B765E3B47D4B2AC61FF18703D8317D400D0DE8A2B94A9D5A851E1834BD29EDDC78470C325AB8ACA665B2333712B846CFB7F65720AE12D74731181BA5A63396C1B1F5C3E00544F6B7559ADEC52DC827DEFD24C8F44CE7627CEF0759E2CC4271F7F2FB1B06FE3DFF6E78C1711CAC99350E7D5E71B811DE6DC8D845960E9E35631803E3683B85C82E861442A9F582D1565C104FB333B3EA2D86F87373BB9D0E22DD3D36CB5A6CDE4EA6105AA1B84FE4B49DBA80F67CAD6DA4535B56529EB354ADD5C31DEE3BA77D4382938734ECFC58C016085320DB34F7287F38BD74C73762603B2BE31ACF4FC6A87112E4BB69834287E01AF41CA41D26AA4F74DE75F9840439BEDDE6804AC022BE7D9104956F66E458EBC1C98B6DE4CB004DECC068398286F5F26CBF0414852AA46F9ED6B73D157274F9D62A909D4D4975923208738DBA0D55B64FD54B5EC4A1691A4C335BA8E87A5517FB4547035C995B76B7B8BAB6B990063B5C5D8A4B482E0C8625E0E1967CDF3467380F69B9628B864CAD2FA430D40180708493E9BCEA465A49B0A705DE89CBC3AA934D8336F33C86A308F229FEBDEF3DAE69416FD9A977DD92753D6801DB3D3D72CB55D60F047D1DACE7A7CD19B2B2F5BFE6E8CFE888855EB60E61D4D6346F5CB03EA0BC74119803FFA0AB111BE22B4A98318C7F503EC9F585C7891B598FA07F260D25D5F4B5E3BF38330CDAF77658BB4669E6FD54F4AA798E6B7CFFE772D6D53D2D8DA94BADE6112FCA7B093174E3AE87E0A66B20AB61E208D9A6DED593453148E4A9DA7E88B3744CEE26D19344347313172EAB5D962DF2BB9F01E6D620BB9672C468B6A4D422FCCCC1C30886C4AE37027E5D50F219CB67CE662394745B28598FB6C8E08428D00D7190D09625F02EF93EEF410FEF7546B621CF9E332E6F428D83EB15C665DB735F860727983396E43C448909A92419DC369577859DB56501B6371A250892E8BE86FB19F251307BB7F5EAA9354E73B0F2A45E316933747BB153D0700887F3FF4B76735C8309BF4868A3087C02A91F53D8EE4FCDD389C18028ABF0A74D19594A2C5B7637FC8009E7D5EC2E4C2DC1E133866C5D896E3BAA033265E8E243F95F952DC451A307A0114B4165868E04A59837708ED0248D04D7DDD886115FE37498DD905AE9FA6613689297A2D892672F0EA422F4C376107B5F07B1B033EE4E43B578D06A5429422768C6A27CCEDB58435A9D04C59ACEE99AABD468C69C5D4BE845D45ADE69C9A8D725CAEB9DA4FA48884B5B3570E5DA3BC102865EE9ED58E8EC07672817A72F009C9BD007BC4158C9B137E117BCE2F0255ACEA158E95FF35B2366BEEE9DD02F9E3909ABAD9BD170F8564E6F182655A46A54B927465A61222E88762C981C512E1D70EC65F5F7A7ECE82F760250BE2E6E65515AF363D99A7A2AF47A553CAD49732BBC49E97D2D5AB3248F79586DE72CB48FBA20A0F737D387A10094788A7F916B2355ECEF0BEF38AAD9C67DE08CF31A2F6288CC2DBE7C99C89F5A0D111E23C19BC9115EC8096B469E69324F8FFA428B81D7FCD0D38489820F83EF8DA083B401E75DE57FB7E7A88F4BA52E7B45140AA8F1A97ABE03F4E9C9852B58B450CD01FA92F0666B3F7FD89BECFDED69D3D70A789858143B8F521B2056EC817CEC2A0E61DC5E9D769ACC5A8D62893D32D3A7AD89C406BE462C460ABC57996D5759EAD97AFD5D382240679C3F2DB42A7CBBFD12AA735961BA74F1DC0235248F64E2E8F424276D0D66A54A5AE6286F489FFC3C52D4BEF770482358B4F679BD838E184C509497E99D91496193C5838A6F9A0C69853C2E645ABA8E0F0E59640642EB0069F2EB959A4C57DFE1D3FD7A64BB660906520A4ED133F1B0CF864780EC1E211B2B2451CD4F9D04D6060EEFED3B0E09DD4BD8D7639C35AAA4F2290EEB5464935509FE16C377C0161DD0AB95B3CF96A874C709802272763F0E283FEA8E53554E6354DB7E5F1C4D5EE09E1F6194C8CA78406278F5F41C47306DA5A81BDBC8F8466F32822EF7F585A5626A1FFF904F0C5F86930F9F5728232E3F17827064826E641B0BCB2A147A0D12EA4B93A8EB85AC079400486B2F4EF1BCF288ED73EFFF3F10493AEE8AA69CC37F55CC18E0C3E1F9E9914D268B7E810120DD18FF54527BE73929E57D787F167E48AC4D7887CCD78E4C4C8295939276EAD69FFD48143702864706D7217B1C5A83D233C0611077873C3392B6D209ACAAAB0713F38B758C2250950CDB8F1CDD9219C9EDFB0BF70A997EC0E7145BCA47800FFD7B09B94BFB24BD16B1F0AC0C7E6E4B6607E7BA1D11146EAD9B81378F4E0511CDAF8183CA4532A421AA2893B59A385B2C6C849078C3CE7F21C81B4215305C71DF7A9AF97D79FFE8EA57B1A147EC4BDE9F0B7A18797BFB7F48E641D043F9FD65A2F1A8B3CFD1CB637649CBE52E413F960CE2716CE25344EB7C67881263862BAE76344B5C11679FEF3CC8D06AAD204ECF9D82C785CCA36E8CE64D592B6FE14BCD941B204BD944D775AF18235F12478D3A6D195DA8034543DDF772388F1F39E994A99D78E83B45A3F72BE242BBF0B047B65AD5B957CC19C245CCC04607BEB897BF7E5C9E6A5BDDAE4684E52D065904DC71C2420EB4E8C28AC5DFA77EA3DBC314D547A2BCA9D8EA7A95E3452FFFBCEDE40BD7C73AD778525626A832B097B5F46ADAAEEF9C02B55D82B592817799FF2D350122654E686683C2BF15AF65893CC327B740F4036E0E7CCCCE6A60287777AA16E6858B1EA90D7F1BC3061C733F25DADFD612B72EBD990CDBD767665D4EAD421C4AE17815AC7AE5E959736FA4DD505E90CFCB188774C18880D264E71E1D043112C00C65E127582538CE792AF5B909015547F7BF244D66EF008BDC434CEE3AAEE28F5A7D6865B3ED85D08ADEBC9BB7A0150C8BA780ED98503FFFC4FA99CFC7CF0F3905355077761BC69BEAE276BDC22133256D2373E64DB496C9FA01809000EEB661D4098278B4A7BB06D3CD53F9CFE0D8A44E4560B0E3DD1EB1F36A57C00B8A0C49F5384BDE2F10A945E41AA4CB95C1D28E7EF2064DE4E8CCC1C79A77999B9430E01F0A96CB4596BC71157F5691AAE0CAB95A34F556364B81252BA1ED74D9623823BC1DFF2C15B803253B4BB945567148AE7662C135511008E1D291A603B4886202E9E9843ADAC01ED8BE39EF346B8AAE1A5B7FCDB5A9412235012273797811C7324255CF7B7EC4E1158B16DCB13D499A817743AF3B1F397EE3E060DF378FF06C6D9A8A0D5F4CD38F81A015E0754B3D8EBDE9E53E52A889E3E87012EE48669939D49E54D9E1B2159841E2C7D1572F52D4A4AD7D950B009967F7FEB07ECB4C861FCF6B037BC999E353F1B7C65AA3B0FD06D5CE6627C14DE5B489DE4485A1D73DD057235F1A68021A2A6A69DD0EB196131F05593178EA151B216B920F671F358E64A4DAB6977125DE0A7459B7E783C849B8FD4DF8158B3EBD370AD97030AC84824672B5EF5088E3EEDC909261D3AC83D617F29CF825EE12519A07CFF5F95F626A6484446B343EA6E02AD2ED9382293373B347177765B5316AD91F916C5D12DBFF4483337C7D819E02681A0B2672D14F1285E507284CEAAD3677383BD09D051B1805D54E5303637B33579ED70AC197F40096622FF037F212425585DADDB7463B98BA1778DF41BB35AC25CF70C28FBC38D8375F5E096E90D04A5C7A6CAB3AC340B286A730CDBD291DE9F88C472C09D494DFAC4463ACF0378F3C12D982CDBE556DFA2B61DCC65F49C453CEAA5131B2AAD1544DA7DB46C5553160EEC3A96D509E2BB0C80FC6D141EA7B730F019F0BD7ACE57470A9061047F19BAB4E8E88DAEE4A4F703BCF24CD75CC0930B02BC0CF69B640ED66FA9B99719330DE9DB8838CEC4CE696DF786A636BC0FE9714482A72491DC1DB0E7F3048FF370309AF7C2F3859DB9CC42C0A742419BB35384C0BD03F80FE006370A853983B376E904E29632FC9C56396E1E434FAC69358F814FBD1B85AC8640A6F64C90B79E1D08A03602880535556290E3A74AB0481C87A219173E3C4B47D3C3ED5328DCF97C1FC490788157F0A2CFA9BC1A920A972A21AF6A0DBEAB0577D7C39E96D66A1E1EB566A10F3DDACA296EC1B893002AC989F48CB64E2CA0239FC08302917406AE4E1F9CEF6A7DC96B5CCE0725F7EF4EB60814B4694F872D8FC56096FFC033340E794E9093FC9CC32C8A7E666A4775E2DED466473F2AA0C88331ED3D97630048ADBB3E1A652445E3AB583737CBDC1513939ECD3BD151419584B373428142C6E392BDD288C8E4D9B176AE5ED5222715C3A991933B8A497C57C5942232D34624AFB8777D190C621E71A3E55B650FD8860ECD34EC57659A17A3AD94A035EFD9161EB42DD9785531B2203F67D87AADC0A886602AD1A26BBDEDCEECAD38B844326F5C60764AF5085EF0E02E26E223907347A6773A1C9273C289168736D79C8F8515F15E62428307174C1AFBF16FB2B016861B05FEB38213833CE77990C78FAFEF51D409BB9B70881732B7ABACC1333B74384F706AE7F8EA87DED4F94678BD8D61AFCF0F7DBC46E1CF96571182EBAB284DDC5649215CE1AEC155756794BAA2B3AC06A7332E900E0791DB4730D1F9C8B2210824ED920BCA37246A51653BE1221C9FF9DB1FBF9C602FDD52D0092B1BAE8FBE7716635678161F1AD15FC55B651150FAB011DD61BCE11599B5AEA7C13DF99C13894897E44034E068549AA6DB284686CB1D3AA3BD00FD06ECACF21B3541991DE3F7362C01F95FFA9D826D41ACC2038BBBF859BB7A27A6F7525FBD906D0C6016A2A6FD9BB914832D6BB46D0CBAF2EC2900729E050028D722F67D59A1D811A5DE513BF9AB4174304172DCC0521FDB0091E2AFCF3BD5578FC5A469B5EE30687A6686B9CF04E9AA88815B89EE6F2D170BF84B0BF845A75B2C303B3968643511D4AB568552F4FF6C0243725F291341AAF654E72DD805C798FCD5214B14616E7AC9F3A4EA6C211B319FC9009536A1772156E62E666788121874F472FA5CAB32BA174FD0B2218F50A3BE7BDF448263F84CE6184306BDB40D6AC6EEEB7A009144D47CFE5121C5F44044D10B0776B575F883AA5CD63B5A577409851707816E4CBFBB13B047D3902D0C7916E4C9598BDADB732E82166F10149695106C8A9F3C0D2CF4349B59CC5A66177FC51A7B1098F6D30FFD8A5D016AD38097C062E0DA6BA3EB4C8FF851503B97E7A276E026DC8D92C68F979D53F9157695FC63A97A9F58D8F92140217D196A9778CD52A9074348743BCCD068B5DF2D5B76943651822D37F217E71EA6763CED121444AA3570A5880DCF44CE21FF035E8EA8107430E6116C10485E4DC7792D04A9B9717932D621B572F42221F1BAC60D3B65D93007913BB100E8658968B0CA77C533F20B9396BE2A7DB9B233028465E54648E3329BA2820ACF6CF00D46BA0CFD045C20C6BA992AEE34F57E9C84ACA1E95C45E9EC6D0BF500A7F7E6626D5777DC6AEDB370A4B1EB82BF4CD0F63DED9A4CCA567FCACDA440EC29CC67A926059152AD7BDB3F3EB06813BFDD8314C365E490C41C6FD4A6173A13F4C4A4E517037315D0EF14428275919CC61AD393BE23333F7D8A93C59DF7FBD4DFA8235AFE88803BDD881CB8E591A721E917CE44103EE38CD499655B666AC3536A1DE850F3FCA9C393454D9BD6F0C75B11822FF23EB22DBA69B08D3F4E92B8ECFE9BE9432A8B445A5BEE8757C7C53DD96FB2058A5370EFC4368FD6B5FC124FA0B9366074719377A0C533415161E29C71D5AA85356B98A138DD28D76BF35B6B9BD3AA30CEE5641266AA5B6E3476CBE1CCB18839B063A655FF7831A6B655D5DCF74C93369FC562827A2E93B53A295E86E9BF8879371A9E0A176587912D1CF344CDEA03DE86B587548FD05D775686D36B8A3B5AC77165B6226682EA37B935C9FE0E02A8FF9951E2467626865C6369A8DA0916AFBFC03DCFD599163BEE9F73F99E34A3F8356E5F193E76C4648053269A659E080A7014A3EA4D7D9766FDB36CC8919294E88D722D9996FA0EFAE5FC3DDA45C14636AE77342A5654D12731B64E40255DBB777CD68D73B7CBB3D8D1013CADE109F474DEE5565B1852F646002BDFCE39C736116E56EB8EC6F75A46F2A19ECE8F0CAD24152DFA63F89AE0C375E32AE637BFD43A1D3B027930461A8CAE0809D65E9B81DE9BA9D0D498262EF57887D6B892F149030F734B44BD9DE9A4C8E97772A50E7404020A9D64D6785059250DC03745A68353456A7229B21F0DF6AFF33894919136D210915581A525208E3FC16F1AC5BAD3908D4D7D7155929F32C5B790F625CF89B8AD92622A0B155ACC09CA4CDC24518B84CCF0C924388B77DDD51F3FEE646A774CE41367F983402ED44E85B679908928FF5F7522BF9199CA1A41A6B42C6CCE575A6343E512475A3CC90B7D0A456141E1C3ED6ACAA15C6241328BA1936A6F78E0D6BEE97827CE1E329F2CC6B58E311847B4195B396C8AEFCC5D9A8F08EE282B26B4CEE8B79043589828F854650D73A433E0B879E11C577ECCFC08AB67DD9FAC9C3E5128060C2F2695DCAE7520EF6C12DB22F74F2F261ABE6F9FC6244489B96ED9222803F635DAD7FBB43AF6C2913FF809E208C97D9379BF5BC7E4276CEE51C6509A6D13D4EEC779A04A07B3D80569AF1A325ACF378A219999B8F91DD48AFF90105FFF878F4 remain = 1048574 -max = 1048575 \ No newline at end of file +max = 1048575 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-2_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-2_256.rsp index 4a3ba78be4..a07767dc99 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-2_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-2_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHA2_20/2_256 - pk = 00000001049D5FE86EA348F4C6D28583AA3F9F86C36156FD23AAE68BD09B104163E2E2EB04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 00000001000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A049D5FE86EA348F4C6D28583AA3F9F86C36156FD23AAE68BD09B104163E2E2EB04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD0900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E7040000000000017D93C20AE191054626B3138F02E186A4607EDEF6E32DD3B2D788325E88FB01E90500000000000159008B71F97B67D9710ACBCAD0DCEB434823D0DDE4E8526701AF9ADE23FBCDC406000000000001410E6F39D12638391198E1827F643E6547AD7438BE85774B713D8FF3D8CB682507000000000001030C34B96241353C81CD7DDEA97ED6CBED8C9F9FB86DB60A6B78E39A253C001B08000000000001B07CBF5330F3B30963D6B0A4AC7AC4DD77585E4EB8A08B62B9AF1FBF42B76FE509000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014BCBE4FA64052B0853EDE00CD41BF95B66DA2A519216FA1A0A8BA5F10B4EAFD8BE62C40DA2A76DFD8A5EE8EF42A8B808C55A533FC488A2B33A935A635E24F3E0C717E2320FF575ADDB18C567B1333DECB0855E069D5759C48FE6D8C6A9D217BFCB7A9D40735A3151382E3456CC4BEDF6C7EC94F186FCB6BF9398FEC934714E8E231402FC7BD5153981C7C789B26208DDD77E4796F70D6A72B7B9C5EC75E4E3CD122F72621E92B1AC515A33B12B1801B2C3E461AF788661815E6BAD2E6472116B89B941A0E68A232089C6F831229BE2EB0CD244BE4FED78C8371D2DC614445C76907F4A3EDF18722BF0998FD03209C31C348CC79A2AD06ABB1B3CC549E73B206A05345EC801A1C5C42D794BA1A35747493D76CA8567B62F0C2151923D8D9CD2F37D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB385C19D6AC3BDECA5BE59F322A17FBAFF466E945FBB943BFE35854802837FEFEA3937069240712886742E890428C0C21BC057E82D5BB961095A5A18DE149CD19F79E9DC3CF0FEB5149F856C5A7BB82B6AFD4B5310993D9E4E1D33B4CC601265906186B98CAB4AF1570CFDC928C0A221A3BBFFE8E566D580A689AB51BB69826FA60135F60C1A1EA97CCCC9AE96CC93B66942370BCF910D916CBB7F87A0BF5EF46DFEBB050637754B0E40509441E19465B238EA45270D7BF5E0610A89B4A47AA821D9A3BA58127DDCEE4E7204C38E0EEDDFF72B07FA5AD8EB1FA89554D940C2C88EF588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE5966743689380FD336A081B8C7F753B889BD73F10345B8C4988A7A4C865250E3707A8424B606059E3ACEA75F2F732058477097D5BF8F5A2DF82E4AF0EE9C4BB251A5657C15808B7EF26806E2F3D61137B44C9DF4196A9208065ED1C70F9DCE3C75AFD719F14D79818812360E4709E521E78B983F99B31863039069D3F86FFAAF318853EB4A1AFFC5E598ACB6B15198E016C779BB7D77C54971E4566C2071EDFC0D19B41827913C5F7EE5D8A9411AB2706F3C9DD8E2CF4AF497765A647C1AA42E3645485AD6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291B3530D6094FDEDB782E1C927C11235EE632F6C3FA150DE1BC1125FEB330079EDB0733B58F1CDD3D20904F85DE31C06FE375E7D1E20F4C79484C5431A026EF8F5C8AC47E7FEA2A80E17256ED956484E9004BD99AD8ECD0D1EE5790A83CF9A14827C3B5D5C25AA18255F5D512917BC1FA868AF35ED3540BF0C10CABB267F612C26AE27DEDB5665A4DE3913AA2631C034C1BD22E5A721194BE6D1E4337D1CF488E9F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA498B7DA996B2692EB8C3D1D8BC9BECCFECC8EC67EE3A87DF5B0B9C7C887DCB0CBA7F5E1372399F3A4F4CC7DF247752994CE0D024D2C6E620EDD0B8CD30891FAF58D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB074AA6092A1F23DCD01D8B8C70674D55670C07A6D0655CF37D0516E6E1102865F0C53C5AF80A45B09B078337D61AFBD12DA2820AE45CC4B213C00576FF3D5FC21D0DB8D877757226F81078653EB4C90C0D2C7D304A6E0C4265DC3C1DB343202664008385964C6C56FA11532D7CF41E93F92EF28F3DE2CA1D5817AF2114A97BDA7F6504EBB2A6EE6BF4753274BE064D3CE467673717AD7350DE4E83A1BA27306F11DF36A2E30572E3FEF2EF6B2518419395DA9B7D4B191C88F3A863A477A2D226E5BCC04E39AAF1AA042A7B115CA26BE8DA52A162FDCEC6E511B1497FFB8B8AD23D3C429F71236DCAF9DE275D7B1D2DBE83822FF7D8C9BC7BA3AB5CB517228AFE2E30C53E64C44D02CF9CB51CE371827CDBDF798B1723B418EC7CDF66CF09F444A06DDB94355F529337D6A3178D754D68BE658934FEABD4F4874B11E739F0EE4E95D2D23B41F037B9668C9F74D2B3D31027861779FF8516A29246D766D2A61A02CD5B8E338B9630E8E0ED5BDACB017A6D3B89C8A1108E525BAD96E203E7A0C0B7F2148274FD20F9B53601F2B38DF303D7F8785D06260485D7507782E11855EA62F44C755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E695CCF3818C69AE16DC71782D99440EC9AF4A9C33FFBC728C9C62C47E0D37CEA661064246A8B2BBA14ABF5767F33E490AEAD721929515F091663B4437BDC34F5B15C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFFBD90B13035960ABEF4E3CFF91B9871E49B16A6F0FF86445C441921D2E698117109D810C864F024F62F8D25C263CADA33916763373D76EC8955ED113F71C40834E79A1BD5E21CC2373598C66168492FFCD083D2A8E7E480F76274C048719AFF98C5E2774BB1039646BD25A240875655A77023B7F884F5852DCD9C5DA173DACEF7F01F6527CB7F5375FEC1FD2D5C90A46D3D0501715B2D4CF51166226D8F35DB7A9ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272AC230107F230E29845C2E2283763A5832809AF2428C304C07CB21A96D7B7CDADF857F54C91A22B8AE6E4EDC0DEE01FA60697269BB1299F9FD7D3699D4D865A25BF0F31F93DAE1D51C42FE755219BC2A4B2505487483A1B81BFA86BF6A99642C51AC3DC78D5E42FEA4ADCC51C0501A8FD543217134694262E0FF5957CE719766EB0CB34CA2E541992CC2619C65822A763FE6572E3B33C4C8C216B4A62A13BE7FE6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156D49ED44C7713B7A50EEEBC575166A1B6CC3AEC2CA98398971F648242C35E8EAA21257BFAC587485D48AC54BC306344EDEBBF2A42B7E37B6086B1D9F54255742F @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 4963 sm = 000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA701095690ED3CAA8519B752CDFBACE3666EDC260EE5325F9EA849CF9DFE6CDAD655BFAEEE83253874CD01D7C5D07C53050812648A4891B86ED9B949459337CE4E48A389B5FA7E67C06E689894EBA9EF2B30A6E85FAE21DB5E8D5F6499CF1C5A59A6D7A8D490A5464AF68854E65606D09C887C8A95A511E76865A1B432139E0C164EEAEDB66976EB9610DA9403923B229A8A81AD64A8292003BCC9A8FBD97284FB83F255CA9569583D0B40DC8A5942B9284515CCD9497D7AC749BEFAB0032A08D412C0291B9F93EA852A8937854ABE02DA2E505DE98BE606DF1ECF315300F6145C26529510438E87AB06D786CF52C18D7F9C95D7B82F4F0E1AEB59E4221D40C67EB13EF80BB3601C44E35C901ABEE1EE25BFAAB80639021377FDA25672D97ED4126B888B571BCF4A34CE363BF227A5830ACB4844CB17A942625686FEB09DBDA47AF7568C4ED2AD3DC8191BE8F775AB35E37528F5B94BE4DDFF4E56600E488856881A622BB8619A78752AB810E1EF1E95A04A10597D7B674C38102590FA8BB21B909B3E05A4453E58D0D1EFC4EE285C0B3EB81F2DB7E57C22946C3ED1D4155D0A6041072FB2968834D281510FE4DCCE2D85ED825C3F2C646CB718C5C742C8E7694C288548F3B542B812369DE5C5B650683CCAA23D4B8BBEB833B694BE7EAB094F39BD8D4E6FC2CFF5A94DF26DA0C0170FD8713CFC44391EB96DA0957FD5066FD83C6A49E07417E807C087062711DCC7BBFA4B0D54077AD8DB142A191E6BA6BB2518374F77E9F7FB8C2790CBA9844A7FC11D1E6C38E1E9EA573E0A80CE46DB790375D915D3C1F311F819D63F288CAAC1F49DCEFCF8F9B30E025FB946B8A8520860ED5D425878CEED7D6CA693518B5A2F5418135EA9316EFFDECDB1DFFC9EE3A62EFF0E6647A2D39C98B01A8BA4A8B9FDFF89292303C02C3AEEC2EEDB69DB6CAB0F45463BA7A25D6C3E4B7D39A28A65A5628A93556FA9F54E273B583F9A197BFF4731E04237D992BAB4119585A36F7584D2B25A2263A428A218CF009BF9EB533839059E362FDFAC5E8EE98639254EB106410A8BEE8214C66A7BB81C99C989737A7EC3EDB303EDD88D20A7D32FE8E2735A21A0055B3473BA260666DC3A9CD83E3AE3B6FF7D7D8D5964AF6A4DDD928553D5D44D3A6ED501CED954E06F89F82D334C458125844219EE3DB69A83DDED1030CBEA57D3D2EFE8AE168D83856DA3FBADB0102D52C5EB3E72F1046CBFF94254043D879CA0B64F7BD7AEC79F5F87C11DE3DE80756E92F7BDF93266EA7D5A17B974C518C7024DE642D12B495063AC5363EF6C532E0D9C96AA96BFC9E1D6A851663336861DA97A10FFC00A4D5A8E4F1CA04A8C91FAB90CEA2895370C57B8BD4DAEBA7B426B8E8B3968A6ECA166D917889AEBDB335E3B8115DAFADB4F258D8BBED23B21C65486E46D8BCA833B6967A09FC7DA038DE146403C9AF2D41510FE1D89C15CE442C7FCE52DD7AEF5B65923DD8CE7C031E671882B33206242916D836656273E7BCF440A020F6BD2212AFED89DB1DF7C77FEDA1143CC52238532A9293D465022828337D62D54CD964879D20BD79F2F5C8042F16A9C2FB2E1A7013828FF9CFA9903E4C46D7F0A4409133EA2AF9207A68E5DF1EBB203398C519742B581D604C13E10DFEDBCAD3EB1F66133D21F83B2C15BA70E2084E20169B68E73B20457198BA678C4496B02F7124E0474EE3BB9B7107646385F85E396D5B6413A9FF0BC969B011DC3639F1798CE4EDACACC625459A25639F6F2C5C15DB24488CAC196FD09E1A5AA1ADF13D6A4316B27BABDF3ADD912C5D1A25114B322FAC7F9853AD29B44EAFA7AA9A4ED2471B0BC91B4E1FDB7E6A80056C0F264C07EA4901DD4FF16E8E94B742AB1BA0D9B7C12674D959DF58DA15C7E22363C8AE8B2D2003632CBB912A4F788E97B9BB1C7EED5532B3026F7B8574061C607F615F7BE429B3D9A386E40B99329DE24163911705BC3137F0C728AB5848532999315D2BFD2336DA5A304D0F3455927360BF5040E95D1454106F2A8A7CD27D5510E7B54E165DB2CBF8027EE9B5CF5EBCC9DD06A5C319E2B9611BE946B6020CE4D9DD7329B336BF3E1A68CE17D1FB3485EC4AE8A823AD73C293A8AD9C8A45B2313792CEC3A649FB0DB6EE6F511B9B48E3DA2B198695DF9ACDD096ED9BE58CB5A6DFE702D4F9CEF844F63D60F6E671DF4C58FA9737EF38E41D273D28CB5091AFD0A9857C87AD54963C2B8344F1B0B7D04CF60AF2F462FC9E118D52827FEA10BB9FFE8A0669C43C7F0FD2B44AFC59F5F1E04E13D3FAEC42EF2E5CE5C39BB7E9A671F6FC6AE6BF9D49BB099E99E115FB80548BDCA3276CA7DD2F3200DA1FC5724E17D63321E7518484F9CBC19EAA901C9B4359152FCD7C0E51C82C962FF3F9A68B4F8B30440B23AD28725612F5FB98FF740AFB457915740084644120ADD17B445078AAF541DDAAE3B630834D387AA4B42958AAFD178D333B9E1D92DDDDC028609DD1C65C57A704637AD2E628163EE49D33FFA1530ED03F0A3E771B74CCF546BEF58EF21DD186BD74BB36D42E7D9D5F94DD718412DD7417024BA0156A865CBF27A461847E450F0DD03D0B6940BF0A7A3D0DCF04FFA9F744E8EDE879679E9B2B30DF30EC5C8C9AB598E42C39CE458F83C500EFAE48C4B8B2B688A9AE8C84C68CCA9D73C640BF005BBEC6C139005A872F0D032278DDCFEE8E636303308F418F73E3FCB7B63464D0B798AF6C9717BBC5DEE4C9150E8B271E12B53D2DC24D62BB1B522696BA13C5F73022D8B7CF740D798573335CAA3B04CEE0BDCADCC2DFD20E920A0B83391E2CFA2E0441B6473EBD291791F09B4ADA70A5286EB05167BD59BFD8C46427413D6079846BE00FC21D586D7F2C2AF4FEF5A3F2E0AD8F4D487B9B6BF50ACE604177339912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70D676B893C9B7BEF24DF70145E4CE1DD2B660884C82FB0EE47D1473FDD0B8C4414011CBE8E48BFCBC428382A66B103B905C0CAB36A7511B1BD6E23F4C69073CBE6C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A14BCBE4FA64052B0853EDE00CD41BF95B66DA2A519216FA1A0A8BA5F10B4EAFD8BE62C40DA2A76DFD8A5EE8EF42A8B808C55A533FC488A2B33A935A635E24F3E0C717E2320FF575ADDB18C567B1333DECB0855E069D5759C48FE6D8C6A9D217BFCB7A9D40735A3151382E3456CC4BEDF6C7EC94F186FCB6BF9398FEC934714E8E231402FC7BD5153981C7C789B26208DDD77E4796F70D6A72B7B9C5EC75E4E3CD122F72621E92B1AC515A33B12B1801B2C3E461AF788661815E6BAD2E6472116B89B941A0E68A232089C6F831229BE2EB0CD244BE4FED78C8371D2DC614445C76907F4A3EDF18722BF0998FD03209C31C348CC79A2AD06ABB1B3CC549E73B206A05345EC801A1C5C42D794BA1A35747493D76CA8567B62F0C2151923D8D9CD2F37D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB385C19D6AC3BDECA5BE59F322A17FBAFF466E945FBB943BFE35854802837FEFEA3937069240712886742E890428C0C21BC057E82D5BB961095A5A18DE149CD19F79E9DC3CF0FEB5149F856C5A7BB82B6AFD4B5310993D9E4E1D33B4CC601265906186B98CAB4AF1570CFDC928C0A221A3BBFFE8E566D580A689AB51BB69826FA60135F60C1A1EA97CCCC9AE96CC93B66942370BCF910D916CBB7F87A0BF5EF46DFEBB050637754B0E40509441E19465B238EA45270D7BF5E0610A89B4A47AA821D9A3BA58127DDCEE4E7204C38E0EEDDFF72B07FA5AD8EB1FA89554D940C2C88EF588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE5966743689380FD336A081B8C7F753B889BD73F10345B8C4988A7A4C865250E3707A8424B606059E3ACEA75F2F732058477097D5BF8F5A2DF82E4AF0EE9C4BB251A5657C15808B7EF26806E2F3D61137B44C9DF4196A9208065ED1C70F9DCE3C75AFD719F14D79818812360E4709E521E78B983F99B31863039069D3F86FFAAF318853EB4A1AFFC5E598ACB6B15198E016C779BB7D77C54971E4566C2071EDFC0D19B41827913C5F7EE5D8A9411AB2706F3C9DD8E2CF4AF497765A647C1AA42E3645485AD6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291B3530D6094FDEDB782E1C927C11235EE632F6C3FA150DE1BC1125FEB330079EDB0733B58F1CDD3D20904F85DE31C06FE375E7D1E20F4C79484C5431A026EF8F5C8AC47E7FEA2A80E17256ED956484E9004BD99AD8ECD0D1EE5790A83CF9A14827C3B5D5C25AA18255F5D512917BC1FA868AF35ED3540BF0C10CABB267F612C26AE27DEDB5665A4DE3913AA2631C034C1BD22E5A721194BE6D1E4337D1CF488E9F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA498B7DA996B2692EB8C3D1D8BC9BECCFECC8EC67EE3A87DF5B0B9C7C887DCB0CBA7F5E1372399F3A4F4CC7DF247752994CE0D024D2C6E620EDD0B8CD30891FAF58D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB074AA6092A1F23DCD01D8B8C70674D55670C07A6D0655CF37D0516E6E1102865F0C53C5AF80A45B09B078337D61AFBD12DA2820AE45CC4B213C00576FF3D5FC21D0DB8D877757226F81078653EB4C90C0D2C7D304A6E0C4265DC3C1DB343202664008385964C6C56FA11532D7CF41E93F92EF28F3DE2CA1D5817AF2114A97BDA7F6504EBB2A6EE6BF4753274BE064D3CE467673717AD7350DE4E83A1BA27306F11DF36A2E30572E3FEF2EF6B2518419395DA9B7D4B191C88F3A863A477A2D226E5BCC04E39AAF1AA042A7B115CA26BE8DA52A162FDCEC6E511B1497FFB8B8AD23D3C429F71236DCAF9DE275D7B1D2DBE83822FF7D8C9BC7BA3AB5CB517228AFE2E30C53E64C44D02CF9CB51CE371827CDBDF798B1723B418EC7CDF66CF09F444A06DDB94355F529337D6A3178D754D68BE658934FEABD4F4874B11E739F0EE4E95D2D23B41F037B9668C9F74D2B3D31027861779FF8516A29246D766D2A61A02CD5B8E338B9630E8E0ED5BDACB017A6D3B89C8A1108E525BAD96E203E7A0C0B7F2148274FD20F9B53601F2B38DF303D7F8785D06260485D7507782E11855EA62F44C755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E695CCF3818C69AE16DC71782D99440EC9AF4A9C33FFBC728C9C62C47E0D37CEA661064246A8B2BBA14ABF5767F33E490AEAD721929515F091663B4437BDC34F5B15C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFFBD90B13035960ABEF4E3CFF91B9871E49B16A6F0FF86445C441921D2E698117109D810C864F024F62F8D25C263CADA33916763373D76EC8955ED113F71C40834E79A1BD5E21CC2373598C66168492FFCD083D2A8E7E480F76274C048719AFF98C5E2774BB1039646BD25A240875655A77023B7F884F5852DCD9C5DA173DACEF7F01F6527CB7F5375FEC1FD2D5C90A46D3D0501715B2D4CF51166226D8F35DB7A9ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272AC230107F230E29845C2E2283763A5832809AF2428C304C07CB21A96D7B7CDADF857F54C91A22B8AE6E4EDC0DEE01FA60697269BB1299F9FD7D3699D4D865A25BF0F31F93DAE1D51C42FE755219BC2A4B2505487483A1B81BFA86BF6A99642C51AC3DC78D5E42FEA4ADCC51C0501A8FD543217134694262E0FF5957CE719766EB0CB34CA2E541992CC2619C65822A763FE6572E3B33C4C8C216B4A62A13BE7FE6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156D49ED44C7713B7A50EEEBC575166A1B6CC3AEC2CA98398971F648242C35E8EAA21257BFAC587485D48AC54BC306344EDEBBF2A42B7E37B6086B1D9F54255742F000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F7 remain = 1048574 -max = 1048575 \ No newline at end of file +max = 1048575 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-4_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-4_256.rsp index a5a2cd2a31..4bbff39fe9 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-4_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_20-4_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHA2_20/4_256 - pk = 00000002CFA7F813F78C9797C0F6AD44C84059350BE2D1EE249919C6E1F305D3C0E7024404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 00000002000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94ACFA7F813F78C9797C0F6AD44C84059350BE2D1EE249919C6E1F305D3C0E7024404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E704000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF54961000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113CD47F2466A56323209409FD7FCF7485A71CD8CE96D61298A20473D9ACBF99C010000000000019AB3950B30D3E7877159B364A25B214B41B8AA32E293E2DDD44AEB7DFC560A82020000000000019C359D104347B69607EB28A02E6924C24BD2A26DE4CFFF3FF98E48688E291E58030000000000011EC9B78F3B1189A5482238BCF700922D642E45D07E7EA10833E31A4CBC3CA08F0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019C1A7BFD8300283215BA57DB5CDD95EDCBD04E1C41419317BC2069C2AAAE22130100000000000143ED646E32FC21554D8DAD350C5732270CC220F7E264ECB5B7A8E8A4586D0CD002000000000001762D040EECA13E137753604D099809D946063368BFE1C7CF0E6549FCA746F7C6030000000000015FB7406F1B25A2B4A6A1666269772EB08D6FE78D8A8395C56AD80FE6924DF082040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009D550F851D023315BE35A69C83D099341F6BA69B6A40E224DC554A3489D33729C9EC8196BD665514030C26AAEF80CD6E1BB9EC739BAA2B8E4A63EE691AD2BFBABDDEE2B13CFFEEAB7C25273CAD45409B5270678CB1535AB800679906CE77189DCFE05BBF92FB5E31F184CECF3C427437958F695917E343ACF46DA2B9D988CFE316313FA9FAAD49EDB72B007A7F3D6FC55A88E6BA784FEBE9737803AF05B4801CE0C723C0D15CD8E7CA8E237D4A1C0BB1413D369FC3F21F69205D428069EABE626B971A2B5698ED05BAE54218300BE8C4BC9A52EE5FB296BAF2A9AA42F3C865DCC1DDA69969F085C91D3CC5934567476EB70461B942059AC0F83BA10DFE783F5FB405F159563419B3F5699179D6F33AD05E840EC9227C592E361A49E31D99445437D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB3844833CA9CC7907865878A01BCAE7DB72BA4F7701F20523E0E98B27AF08AA747B57DB1DAAA1B616DE469C7FC83CAA1DA1D6BA6F0C2B0F7F2CB7A4F58FBF7FFEC292AAA7FC3B87E797DCA067ED7672BA9B4CBC27FE9AAEEA63C8569A567129990E1E12A8D23039A877F7FA3EA9B9359A842A19E33CDBF284AF95FAE2A2DDEB80030A8245A7E51131D27EAE94B6C38A8C4818CA7EAE0A1C0841E7AACDDF68A4C4491EF97D5F3F6AD8CC47D2489DF1FF96B7DD444D31DD2FFFDC69C9ED7F750526B3CD81EDEEE2CBBFC0BCEBE875DBB644B3828795D2B81DFE37E0E4E68F9A798E09588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE596674368D1D405B742EE812FB88947D9F5DE52083777E54C2F0A1F605027BCA5A12BDBF9CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318ECCE515F732608A96D4E557ACCA60F144A212276CD52FAC0F12C39F7F45565346B6EE409558FF37D5C50280099C9D75B688C7D873EA7D07EC6C9305AB367ABC2FEAFF9200CAD14D71DE9E1F1DFFC4F15FD0908C6687F585D9721AA773BDECA4C7DBDA2D8275C59A2E90EE07ED6734A09566174D695356166041C646F18180DFC5ACCBA61F1672213C3CA6933A5ED65898AEB4BAF534751900D2CF25A7A94C273533B8694EEFB366F4B3E6D4DBE7FF5FC70EF5341217906FCEC863502598936A4A0D7DD4267B1C0C6E8175CFB3B9B6BA86CF3094D4677BD57712235CA8395A6914063B4E2849AFA406B7EC6E3AE39B343EE39348D2D29A0C2319BB34655A53E1A816CD5FBAD3A3796FEF2C7B67BE4507438E5AEB603B1A0796293A274A3F3D63C7C1F14297987085EC271F06E8DC986CE41DDA37ADBB39613E6790644A669594AF10B5D7C2DCDA7190B03F77E69D79A143E9B7D8B42E18E56D1D191DE05D58DC29F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA4C86ADE353F4AA57DE2220D13EAC9BC8FE02D625EBE3BF2761493F180F968DE438B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE8D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB07425116F11D430A927D45FBAC134C59EA8E5907C35A59E0CF2FA548F9AA27A3530AEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBE6FFF1A2A91E8DD23131A7840BF7CDEA3E18E706A324AB688A5866B82EC18082D89DB83F78DB30D5CE6EF134BBCE7628AC017E6D6974B1D82E4227235AEC9862899B7A4E0E8B10A8AD0B19A54DE7ECA861D6AFA1D91C9CAC7B8D6AE536C458E176AE68697912D7EC853D514AD4EDE982FA89400CE895D3241E5610D0AFB17AEFE51FBB41E2DE044A00D84BE759242476BC0099DFE159F0CAF2187BB311DF2342A59C003778A56907F086C8DC9309D8E41703779C8E1141070708E02B9F987ACF3214A8E442B76121374DD243643D64283D01279A49154760E3567E46ACE89898BCD67842223D5B8CAB03DC13930BE7210FAB7FB2318BDCD92B642F6BF178BC30B4F959F5D8BE15F67C5AC4A4C81F1E3E707AADF0B4CD02982ED4E4E52A81EA2FCB60ACB5817849D53C2FFFBF7906E290BF76E505071913AE0361FDFCA4B279897C9DECF546FB0366D65C9F81A9B51402F3694F0B5DC600B7E4F084383B643AABC755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E6C007F614D3C0A2E45486C2E457C2E6636BC1AFB76B2A7FA351FD88399098C64E379F99B64A3340473DD46C11564937DB9A28C4DE3745308433153B2BC6D5E0D515C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFF0116375D404211C3D3302D17DDD0390712E06CA05FB4BB2AF749D3439A5B30D3E9FF4731822AE6607BD96108BD229A4BDA5ACF50F7185BD1C0F56CC56D69C008077082C0869F237A6F19D73ADCF9844686E3C5583E7D8FFDA636E70E989B1742ACA4DCE98101BBAEDA8E852555033A46F8DF4E3DCA1B9A09E9F938E0C1E468C52F7DC695389C21D0F425B4DB554FD5BE1FDC2765B997FAB1F94D864DE1B4C8FB1323A8D90DC0CD7FA7363AB70728FDBF33C2325FF97C59ADC84C104E730C85CFBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272D144DEFA2E32DCBE8CF7843CBDB9A67EAD7892ABCE9B25A6B91AF0B893846ADDDB6C26354D4D8B77B14FC2FA2D8D589237C4BAF80344C306439619E5A4DDD4630B558BC9B3581AB842BC8B630F232BD18D4BB10FFA1DD3805B18635F6A9A22CE0D470FAA2AB813662EF63C784628138499A1A3648CC877300401E61DA9A379FDB3FC6DD985CA26EE8093A24879BEF107C4D6A38017BE3AA5CCE124259C42519C6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156771072191C21BC3190193111CD3BD0604EC5427C6D70B1BF21DB6E59ED636342BC417CD9F69B804EDB6359C9F8E347AD253370E065D500CAC64BFABE3E420E39C27D20CB93DA243BB3270F1EF2DE68AFB80842E8BE7C1FD48BF0F5622530CE84C1D30BC69EE1164CC602F2522FA39158D4D0D30ABE4FDE43213ABD6E4D65E62FBEC9AA1D485599FB7ADF5C2C97B90C82A1DCCD2C44ED66CCE79EFCEDCAD0CA1366FA51DD03DAC9BFC60B79719033B32247DDA9195233329F5AA36627FCEC5E42F078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DF657C03A3914FD3BF1E82EF96AD7EA46373B0A4DD0F5655F22F754DCD35ADA89358DDAF6AFF78EEEF21010DBC6556C2C3A018E4DA1D612CC3EF237BC2B1E9E600D923E2CE04FA27CE8EE63B969F6079FF8551B8C06018E99D84669C059AE08081E3A1C7ABC19272D7FA3F2704CCF6E491AF93C7CBD4660410389D86BBA47BD5A0E996F788FB9CE600AD76485D265628019B57FC69631D5266E8E46913ED9142FEFAD87E26DE53ECDF43B352EAC14BF6DA899058228C9414E7323430F9357D6244E7165F5CA2FF2DC9899AA6D8C2B8DDE8E2C5FB7C6E02BF74F578823CFA2355F2FCA1F776C6A87943344A5E53BFA39559EF98C397423C75EB318EA9B5F375C17E7B46A8D592651E7D50E70233224592389C1EBD1EB66678AC42C2862A2C660BACD03BA4064EA38D34A7D44B32DB9E75ABC6B5025B504DEC60512A80F78876C54D36324C7143FEA85ECB9E66800E8F4004061EA7607EAB964DE3F9A273D2C7A4CECC1B4270ECFF87A254A139DEA1E0F0B0F6366C02A0A790D46EAC94866A82DD8349F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DEA67846512E96901F78E601EE427F8B1A7986FB8832D091D575C277CB202E87602D670CE131CC6023A9E83AF41486A04D62616C1E912D4EAECD5DC815BAC1C0DBDB347F6B5DF06B0F58441FAB98B9511AC0423ACFA43E0422A62AE32A48E935C6288BD0D2314C6A739A7779BFE24DD7E2D66E9C4A4111E22481688EA39F256224531ED241A9D35D395F340421F2D8F5C05B873052D2128CEDF4ABE49E609176674363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D02AB14858954A117C6B6F2CDF4823BEEF1904FFB4D841B30537D57C577968CDF18EC8631C536AF09B54D5887FC0EB11A70E86B72EF315FD722FB680EF03A3487434215A0EEA412C0D78DB2EFE20061576237453927710860F0A49DE0ED0C42FDE2A5903D635B19D4F2001EE353D7B5210E1C01F50251ED6E753635A972EC8C1914E36522B1B41BA51E9F3F1CE83BB5F526FBEC31C21983736E42EB7880B9B27EF6CAE0618E57F881193714D3E8B38C9E9056378DD79E78422BD7C4CD57D230EF44B38F6A107ABC77B8D5A953D3A3969FBB7DAB145C4F4615FAF8F2172AA2BDEB35C4A0494100CB9CE188DA4318EA5B617EBACE910A32F0A280C82AF82121720569232D71AD065E45268B36F92DDA13673529F24E6B83A865F3E266635D9655C8000C06478530294DE092640DFB324E09DB3B87497C94502BD46092D72DAEDFA93A0353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB51691B3F0ACA92B02FE916D2AEB98BD9E23313F49A0F44394883A432523EB5B34B690EF9C16B4D60572EF2D791F2BF403255A28D9BC3352B02687AD9200D34C05259FE0C93B75455218E031D59A65D4F571CD7F8B130A0CA1363BAF2D9895A8E8925ED20ADBE8FE96C34A6A13B9318AC8A23A7EA320B83B7175FB54868DAFA9E233B0F4B18CF6FC7D85F7A2B28CEEC561222C5051572B092F2FB269ABF1CC7826675F09949FC443EF723AB476E9E5D670C5F05E46DAE93837AA0F65A4E83AE2C71DD02CAB1038086531F93E163AD65BD962ACB9497C0F268876B5AD3CBBFC4C24EB2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADB0A78B6C1C4ACB8B4C97EA8C4CC3F3778CBF761AA653D9531216588A46701366E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC4050CBFA6FEF6B9FE785A59511CCCE21EC5AE3F429A07B4626A4F0C555A15B42C26A5F353E7A479A700595689D5734C39D61177AAB2943775ADAC879B4ED7B8ED826CB43881D2C1B5734F64A5490A4F77ED4DCB9775B258C18182B42C560E6CEE89A329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB041A19053D3003420EC262BF0F45F1C7CF6E55BA9001E4BE097329CA460D335BA899503CAE0D617BB7FFF0AD37076C91B1659BD448C05C49D9360462B4BC601536844FF2C635BB654EC5749FBCEF3288E41B8A7835B645E0BB501FF805EA4B39785C203BE03F0B105D17E513D50B7738E78EC18AFAB3FE134FD551E754CAA189DC4FA2308B6EED1B8CE87EBCE212E15E72C9516B778C1F62819131E2EFA7AF63BCF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0A2979199F43F2F59FB2C62E8AF2EABAFE9B89B71E75AF029BEC77A6A56F86EF6A4A7212A7458986D2DAC9E00CF68EDB81CA05A297B522D3CB2E0AC3146E4638995B683EC201C67C911C83E6BA3567D31565DF914783F41077E2C31B06640446A6D403F9D46BB9D00B3C436FE1FFDA80AD0AC466AF0417D18D5E7DFEDD7D68987BA55F545F3B89A38908BCCA1DACE0B89FFB49FBA3A67EE7384DEE68FD05721483030ED53913A6CFA059DDB451C780877E919BB86DDCA9E18814123CCC822A8F30D0AB4602815D2279398ADEDE00B23AF4EE605A771AC616CAFFCD3AB12991023A6BE6BCEAFB1672ADA631C6CC29827088627EF9380FFF46FC479E2B586432B58F95A824C0D5F08704C2B596A7BD0A36A52BFD8C14D999F92E676C83EA62DE54C3ED7ABF290BF17C48DD69F949668E11D957299DB6920D740252A9AFB65179FDD62B69D2A1A339CEF805FD258D83FD2F406841565AEF5E42ED7687D9D466E6A4E513E072A9EF6181016DAD988F7C2305A77740F196465CE30A35BF3D098781DBA7285753A9438517AA7159A9C806A19CE8B8BA5F9C99250358404671F36214E8A7B5A04767FF8C094A3CD74751835BD896FAEFD1747DDFBBE79F48148D56BF585CB0CBBF34300CBFAB9DB32469814F107EF7822151D158CAD68F01418F88B181B092970DACAE4D5DEA7AE39965D1929CBAB7685E758206D309CADC07687274657F6EEF56A657D3FED4D34C7FF6C9CC5F344F0EF4F0E752F83E06B8A23DA0D65A2C10C2D675CB3A214F5D363C35E6E10A1323579803E4268F7D868F4716BF849B3C3D8EDA94476BE7322891C36D6DF146075F11AD02434D2216351CC26600662BE0D38E1DFEF9A832B9F066718FCB2134115F33717B57936CCD2DFA3A95C1D4C4C98BD09D64EC04912C06C7C6A2FFDCA2801628D873EE6D0D43EB67FF0AC93A7666C9ACBB9400593C00316E05F0F5706ABD923D85DE72A0D1CA9F0774F5180B65AA578B95BD20C1FCC322A5B23995ACC9DC97CE3043B1A723AA2815314637B7667DE02ED0FA0924C0791CA09FA028633CCC594429D6E7429930C7F01EB6A134952E89B8CCEC743A23C63CDD9E161B5A2D1F1E0D005F16727A3B0E8B90C20656B850A4F8B5D400B65E91E45AA25A880B76BE09F226DDD4F0E0AEA00259E19634EBAD387CCAB556997A153D1C1B87AA62E5B613A5E02C65E7EE7DDE2E19D965D27B42AF8542066549A6FEFF3E10A93B349EACB843759F5E4EECA76CF82277BD55C57FAD09BE938ABB47720E49CED626AC860446B290C7FE9BC83DB0C7FDCBD5CA2B8FF6C52B2CF2556040B3792BA99DD43EDF1FD4CBE38970D235E8BEE40DDCD2708E432008992D3F9DCD73AD594171092909019E9BBE7A5D4A21EADF82C5C22D877F422EBC64734717C93A027E9EA7EDADFFBB8A04B465E2F1BDDA54BA30963A41978562C27EE91E8ADD7A95B97A1F9F5C0494C3E44AC5422759F971200B1927F5C37B003499B213C1CEF1823847ED4A308D7D98FD5E42115D49B1FD42C7405B55437E1C8C0226884DD801CD89163AEE8D74105F621EF2CE222B13ABBD14078943CE054E3D68F7E8D763948CA83876F0AB7CA5123ABA8C5F68679FCD116D03391F2A53F637D26EC486FF6363F0C297E1A672EB717107ED9540C2AAD46038F8D4C2B5D1D918AF6BFBA7DE46E6628B2C217672257EB98F585A4E4CDD87729BA5ED16719F869FA1495302E8BD043F92ECF8799DAB7B9C501DC956EE3E55FF30E6D565E228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023E10A68B5275694C30FA7BE9BE2392EE6B18651980A01348A97C4BF091DE3501B30B528092599313ADC93C8407FB07E740F784E80461A23A1DCCD78BE8A72EE2AD69CC6E63F385963275DF49AF300E5D468285CA4457F090504D42056F571A8D453903B85D7E63F893431A5A1C8A66A8E4C999F0592D75717940E296C8275952C4A8DC6E97B3D5602408DF3644E8A1338C856296C37B1BA8445883CAFB408EFB9A545AB53CD632C40659DC607F4937A4F364F7E3B47A907BD30D8558C76A8EA9EB357177B8B2639477433604EB74F9C2E3528215459533C1A989FEF107944FC8A402E29495F72F2C210135FD836028B9E21E76C6F13096DBD2BE9721DD2C35504D648C474907FFB896B014CB022942F308C3263CFF227D4444763A483658E728EE6B7954C48E3FCAB1246CED1B1E2EA9CC4D5475BD4FA43FFEF56AB2A2D779E9D206E3E657A2244108BCF55C7F4F97666457CF5F796105ABC773C541173B9E338B4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F9338191406A4C257E6B7C058565272FB78A54A46007F5550234FE9B7952A82581C08AA6A1EA68E497D663F82C5D20E9D1134816EEA319EEAC8E431A0D82B6D62F7B93D121D8382F0EB3DDBB9FCD43901C8AF1AA019A7160B76B72D4E8CA1228E5E9DFD49E24F3154F4A914987FD0264ADA4C8D6FF9EBB91C59C03CBD484E9EE72F1A98C3F97B9F2479FFB79DFAFBC33C8ED249286369F003C471C8B64A9B1546B1F31BFDD0ACA06AAB3EFB61E49CDF5506AF8A4693A7591498D9D7F8B28A72A10EC60F806A9955D7EB41D2654EE5B37C284F41CFF3F591C227E3FD0CD524379DCB384ACF486CE7B1E658CC743293DCF546BE85382FC40CFDFDFA407A9EA33AC46468E060524BF06C9CC109A726CEAF0811D0F857C08A3D4AEA67CCC0B17B2C38C53DA9F860C99E3AA769EE27CB7C9229207ACAEFE6C62D3ECFCA201DDFAAEEE1EC7BFD40086AA922961198B53C94BCFA97EEC1DC0FB8FF1D9448B6770DE4F5703CAE179FB51CEAF935F666F398B74BDE9FC87B01AFB6EE8B47490453198F9B38AA2259D2194E9EBC42E1C57994921413D6327018B91538CCB0B90E965564171D133CCD9E7F65E851971FB71F2C47B4592C2A52A4101D2EE7A69DCAB3852A56C4DBC9295D2EEC5BAD1B8A13B7EDE84768C0AF5FF0B0253B44038C236412ADCEC91508A76BD8D16E6D6BD5CBB3179B34DB8902863056CC65A4DD40B6A1929F28DFAE1CEC64A74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7E8104E8D9DB129F0AEFF48177BE4EB60236851F6D0DF3EAF508CA7F97E4D5814F71ACBCF00471EF263D3B5CD58ADEEF11E3465C704D90101A5FCC1C8CAC25387B7D6B83C7CBEF04E05BBA1766C5C5D804642609AF84AF3FA7E4572393761664021A632DA048F2A10C2A349E2E1C260C1C3CA6184BEF6045F43D9C767E2328B9AF5E48EFE8298DF69599C49CFE153BF59010741DEE011FFFBFB4EFC5AA4B5DE409B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F83369497B16CBA6B3104624902242C468F89E89322D299123ECDD8ECC98FD5C53D99FDFBBADB056D1034CA39CBBFF29300769BFF634A38678FE7BF929676A43CD0FC3161391877F0623D9B59DF30E28F5B47C0445F83B36F0AA67F6A2DB8C0C3D3F45738A4DE393D8675E286F4530AC810D244C621963923BEB20810EE32909D @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 9251 sm = 000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA7010591AF601BF50208B6C5968D4F692F07279A9C6AA2E66590F7D2E54DCFB47261CD2CB50DDA1EDFD708F002ABF07D0001C3357A70F6511884C4185790EECECCC57389B5FA7E67C06E689894EBA9EF2B30A6E85FAE21DB5E8D5F6499CF1C5A59A6DE8D17E2B400CB70FB0A864A239D1985E799F31F1ABDA096C57123F06B2260714AEDB66976EB9610DA9403923B229A8A81AD64A8292003BCC9A8FBD97284FB83F96A944CC1878D4FBA0A59E308F18BB3A90F9704B0342262BB5FC542743D246CDC9AB35B9AE477B083CA1810094CA5FB540A37E570282E48E4CEB5FC19A7FA82B29E510FD11DA67C0C0D3B6448B88B96E0834210FDDA112F57C7B4FA60EC32332EF80BB3601C44E35C901ABEE1EE25BFAAB80639021377FDA25672D97ED4126B8D5943C4AFC991D3AD0413BE1E84DA3156547C13C9BA17DFF08C34E5B226D7389E9E8D58659CAA4ED33A02C4FD0D3315C22ED07A04A4D89DD74EB188F9E0FF02F0B87F56AFDE4094CB079CD0DF2CB4106DEA80FDEA7967AC53FC349C83C144DCA2D75F2338FEDB00B906C9EC104C5E837EDA2180E53BCF4279D3487DA42B1605BC7329B6C264A9B24F73BD95BC8890AF4C36695EC8E2C29B32F4CEF4E02DBA54908D2003A825CBFF22E3F6A582C3944C6CE0F79099F574A57715E751395D7428173F09C28EFF19BBC4B99C5ED3075C013067DDA903F8D8067153887B056A1BEADCDC912C2D8FF1E15C4F4B6AA4FC3A25CD8150DCB968F8910F6D22AFA80331596967C92BD4979E062D2D38663ABC59D3CBFED0FC6D94A1F157100389EB4322BF05345F497F595F49DEC594407A3E14B55229FC1F72F4926A530EB5F018889C61F4E34D56CFBFE507E95A9E3D86591149D0E5DB6DD9A9A83A811D103580A40F3EAFAA8FD4A12AD43A403062FC7003ECC756E3E26F8B1BA47801DAA46173063E3788684AC3B47FBEA813CEFA4754D02086281392EADE94F003AD0EF78DA65C89BAA29BA00E66D42A900F85130532F5303C7BE837860BC82BC2CF7CDF0ECEA9429324A966984DC99442F4ABA490765F650C46FB2FF9CEA7A8549C511820CB2C81C1119E23CF21A5FADFDB79C0C60627E58576F274261515F1D9F4ADBBC5F6E4DB507F51EAD30CDFD170155A675ABB01E2C06C2E04365A619CC6294601207BA2CCCC2C1B049484D6D933B4EA4A53B85BA8826BB108E2C952F3242AF6AFADA16D637C5A2328C40E977558DBDECCB8D643E07A573A9CB5DB4518877320FBB4998BFDC592B0C80FEDEE27F500EE81F76D642DA862FB4DC7DDE2B33A88A1C5AC5EBD3E3E887B7E0BCDD9121C2855C87CCC9078FFD868D7F0BCAB9C6072DC52A6153A0DC12803AD91DBE0FE7081209F6371361D5124161843DA7EC990EB54FD15CB869367DD46439B14A2742EE6EBFF2C55CCA5FBB9C29C633E4C347BBE6E4C95A0F0F9BCE5B2498F110E32A3127A635B6DFE2413D522BD462E99E87FB994697278830F86200B9471B5BB0CBC8D62AA1AD1A74AC26884557924123193F3F7540906676F61AC572A5E6BBC3E395E57FAA869661A2E4E12409A5E93DC41D80304AA2C5460A3C233D422BE3274839110264F30E81818E6E3C7E9BE404E7FC7F65B63D626E1E2E34E94DA2CACCA212FB48BE3F9EAA310547E73C388D881F36AE21EFEDD23744F620169B68E73B20457198BA678C4496B02F7124E0474EE3BB9B7107646385F85E396D5B6413A9FF0BC969B011DC3639F1798CE4EDACACC625459A25639F6F2C5CC0C8F560E82F0063AA2E8E30BE04FA85AEF5C9611EF09217024036C5BAADA004AD711158BFAEEB39C98014D0C1A172699F3C6D33C5D9DC9BE93C7F3A5780F02A0D255B78E7882973749CE5859469B762FAA1148C77AADD965812EBEE90117C4CA841B2EF96801D464F6EA1053BF96F6E69F495D45535AC3FD4411C27FF7DEE1AEE1E3CC0C81F4B82E43B89CACC69C9B8ADCA1670F7D4E50DB7BCD94C2115E75F382819029917785C50C6293EF5A4461875F80FECE5C7F7BFD56D8B45D8D59D19FA3E07904DA1B884619C6E3FF0826E79AE517976FC153C3398CB2DC279B1E90BBFE9E700412A7D23BDCA95940640182B3D6373522124BEA741629250B1BEC7BB67CF87021CB7E256C70F86B56C1B9C8E222683513965F6CB1CAEB8A6E90054B7B720A94A981790243729EDAD9D6BE0866AFCAF7BA6E3B7ABF0CA31CFC74DD2C1E852D3991702738A85EC058C598740343B21D7817D3CB805E07860B3EFEBB2B2B70F2AF126A3DABA5C918B224DE444B8733E6FA601B3D349307E94583D0EC976AEDA2B90972324B3ACE8C7B79A67723AEA037E12DA9EFA9CA9668A4F5FDADFB92C273480A18885B0DC4B717D93BCDD352B3DE4A2A90F04B239520B8C1149BF0D4EC078D85E41744750FDA0D2767044797A4C3BDB3307C68D3782370C2FC6F67129BE58F68365C622E70B4DFF55E2C1B9F1759BBABCA9629C31DE06948FC51E605F1B5C01196329311414797CD5F67FFC54AAD04C803FF7E83C2E8BA224CE8369A9FBD8420530F63CD1638B988724A1E11888CB9A2B11411C221BA02F0ADCF54F6F0BFEB7D77B5227DB43AC1360C86DFEDA86872B28FA47CE1C78A4DA2508F21483C440334815B9506D25B8D970FD578FC5AAF4B225892F9EC8E55F185005E630CF90BFF0245E82E1D31C75E2D8542DB6E613BA52A0831D06796D3F4D752CA7F4D280B6021BE71887616028A0B0ECB4193524480B917CD352870C0C33591E887DF0B23E656D7E2729177C18213323818435F2951FAF7288F66F9B7B6ABBFC9617B0191CC9DA4EDE34F511E0849E7C27115FA6EB6C43172DC2FD4CB1AF4C27A4A6CFA68635EAFBE197FA2785E5C4BC21108FBB7FF7D8B47C356EE380B7A1DD9F2F9912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70DCA617FE06B50B30FDC6C79E168F5C8BD57CBA8E2CC34CCD54E6665ED65E0F64F8970AA0F4B350BBE7F49626406F6F1828F6C57A1CF9FFD94051500D66388DC4FC22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC9D550F851D023315BE35A69C83D099341F6BA69B6A40E224DC554A3489D33729C9EC8196BD665514030C26AAEF80CD6E1BB9EC739BAA2B8E4A63EE691AD2BFBABDDEE2B13CFFEEAB7C25273CAD45409B5270678CB1535AB800679906CE77189DCFE05BBF92FB5E31F184CECF3C427437958F695917E343ACF46DA2B9D988CFE316313FA9FAAD49EDB72B007A7F3D6FC55A88E6BA784FEBE9737803AF05B4801CE0C723C0D15CD8E7CA8E237D4A1C0BB1413D369FC3F21F69205D428069EABE626B971A2B5698ED05BAE54218300BE8C4BC9A52EE5FB296BAF2A9AA42F3C865DCC1DDA69969F085C91D3CC5934567476EB70461B942059AC0F83BA10DFE783F5FB405F159563419B3F5699179D6F33AD05E840EC9227C592E361A49E31D99445437D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB3844833CA9CC7907865878A01BCAE7DB72BA4F7701F20523E0E98B27AF08AA747B57DB1DAAA1B616DE469C7FC83CAA1DA1D6BA6F0C2B0F7F2CB7A4F58FBF7FFEC292AAA7FC3B87E797DCA067ED7672BA9B4CBC27FE9AAEEA63C8569A567129990E1E12A8D23039A877F7FA3EA9B9359A842A19E33CDBF284AF95FAE2A2DDEB80030A8245A7E51131D27EAE94B6C38A8C4818CA7EAE0A1C0841E7AACDDF68A4C4491EF97D5F3F6AD8CC47D2489DF1FF96B7DD444D31DD2FFFDC69C9ED7F750526B3CD81EDEEE2CBBFC0BCEBE875DBB644B3828795D2B81DFE37E0E4E68F9A798E09588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE596674368D1D405B742EE812FB88947D9F5DE52083777E54C2F0A1F605027BCA5A12BDBF9CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318ECCE515F732608A96D4E557ACCA60F144A212276CD52FAC0F12C39F7F45565346B6EE409558FF37D5C50280099C9D75B688C7D873EA7D07EC6C9305AB367ABC2FEAFF9200CAD14D71DE9E1F1DFFC4F15FD0908C6687F585D9721AA773BDECA4C7DBDA2D8275C59A2E90EE07ED6734A09566174D695356166041C646F18180DFC5ACCBA61F1672213C3CA6933A5ED65898AEB4BAF534751900D2CF25A7A94C273533B8694EEFB366F4B3E6D4DBE7FF5FC70EF5341217906FCEC863502598936A4A0D7DD4267B1C0C6E8175CFB3B9B6BA86CF3094D4677BD57712235CA8395A6914063B4E2849AFA406B7EC6E3AE39B343EE39348D2D29A0C2319BB34655A53E1A816CD5FBAD3A3796FEF2C7B67BE4507438E5AEB603B1A0796293A274A3F3D63C7C1F14297987085EC271F06E8DC986CE41DDA37ADBB39613E6790644A669594AF10B5D7C2DCDA7190B03F77E69D79A143E9B7D8B42E18E56D1D191DE05D58DC29F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA4C86ADE353F4AA57DE2220D13EAC9BC8FE02D625EBE3BF2761493F180F968DE438B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE8D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB07425116F11D430A927D45FBAC134C59EA8E5907C35A59E0CF2FA548F9AA27A3530AEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBE6FFF1A2A91E8DD23131A7840BF7CDEA3E18E706A324AB688A5866B82EC18082D89DB83F78DB30D5CE6EF134BBCE7628AC017E6D6974B1D82E4227235AEC9862899B7A4E0E8B10A8AD0B19A54DE7ECA861D6AFA1D91C9CAC7B8D6AE536C458E176AE68697912D7EC853D514AD4EDE982FA89400CE895D3241E5610D0AFB17AEFE51FBB41E2DE044A00D84BE759242476BC0099DFE159F0CAF2187BB311DF2342A59C003778A56907F086C8DC9309D8E41703779C8E1141070708E02B9F987ACF3214A8E442B76121374DD243643D64283D01279A49154760E3567E46ACE89898BCD67842223D5B8CAB03DC13930BE7210FAB7FB2318BDCD92B642F6BF178BC30B4F959F5D8BE15F67C5AC4A4C81F1E3E707AADF0B4CD02982ED4E4E52A81EA2FCB60ACB5817849D53C2FFFBF7906E290BF76E505071913AE0361FDFCA4B279897C9DECF546FB0366D65C9F81A9B51402F3694F0B5DC600B7E4F084383B643AABC755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E6C007F614D3C0A2E45486C2E457C2E6636BC1AFB76B2A7FA351FD88399098C64E379F99B64A3340473DD46C11564937DB9A28C4DE3745308433153B2BC6D5E0D515C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFF0116375D404211C3D3302D17DDD0390712E06CA05FB4BB2AF749D3439A5B30D3E9FF4731822AE6607BD96108BD229A4BDA5ACF50F7185BD1C0F56CC56D69C008077082C0869F237A6F19D73ADCF9844686E3C5583E7D8FFDA636E70E989B1742ACA4DCE98101BBAEDA8E852555033A46F8DF4E3DCA1B9A09E9F938E0C1E468C52F7DC695389C21D0F425B4DB554FD5BE1FDC2765B997FAB1F94D864DE1B4C8FB1323A8D90DC0CD7FA7363AB70728FDBF33C2325FF97C59ADC84C104E730C85CFBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272D144DEFA2E32DCBE8CF7843CBDB9A67EAD7892ABCE9B25A6B91AF0B893846ADDDB6C26354D4D8B77B14FC2FA2D8D589237C4BAF80344C306439619E5A4DDD4630B558BC9B3581AB842BC8B630F232BD18D4BB10FFA1DD3805B18635F6A9A22CE0D470FAA2AB813662EF63C784628138499A1A3648CC877300401E61DA9A379FDB3FC6DD985CA26EE8093A24879BEF107C4D6A38017BE3AA5CCE124259C42519C6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156771072191C21BC3190193111CD3BD0604EC5427C6D70B1BF21DB6E59ED636342BC417CD9F69B804EDB6359C9F8E347AD253370E065D500CAC64BFABE3E420E39000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D00C27D20CB93DA243BB3270F1EF2DE68AFB80842E8BE7C1FD48BF0F5622530CE84C1D30BC69EE1164CC602F2522FA39158D4D0D30ABE4FDE43213ABD6E4D65E62FBEC9AA1D485599FB7ADF5C2C97B90C82A1DCCD2C44ED66CCE79EFCEDCAD0CA1366FA51DD03DAC9BFC60B79719033B32247DDA9195233329F5AA36627FCEC5E42F078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DF657C03A3914FD3BF1E82EF96AD7EA46373B0A4DD0F5655F22F754DCD35ADA89358DDAF6AFF78EEEF21010DBC6556C2C3A018E4DA1D612CC3EF237BC2B1E9E600D923E2CE04FA27CE8EE63B969F6079FF8551B8C06018E99D84669C059AE08081E3A1C7ABC19272D7FA3F2704CCF6E491AF93C7CBD4660410389D86BBA47BD5A0E996F788FB9CE600AD76485D265628019B57FC69631D5266E8E46913ED9142FEFAD87E26DE53ECDF43B352EAC14BF6DA899058228C9414E7323430F9357D6244E7165F5CA2FF2DC9899AA6D8C2B8DDE8E2C5FB7C6E02BF74F578823CFA2355F2FCA1F776C6A87943344A5E53BFA39559EF98C397423C75EB318EA9B5F375C17E7B46A8D592651E7D50E70233224592389C1EBD1EB66678AC42C2862A2C660BACD03BA4064EA38D34A7D44B32DB9E75ABC6B5025B504DEC60512A80F78876C54D36324C7143FEA85ECB9E66800E8F4004061EA7607EAB964DE3F9A273D2C7A4CECC1B4270ECFF87A254A139DEA1E0F0B0F6366C02A0A790D46EAC94866A82DD8349F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DEA67846512E96901F78E601EE427F8B1A7986FB8832D091D575C277CB202E87602D670CE131CC6023A9E83AF41486A04D62616C1E912D4EAECD5DC815BAC1C0DBDB347F6B5DF06B0F58441FAB98B9511AC0423ACFA43E0422A62AE32A48E935C6288BD0D2314C6A739A7779BFE24DD7E2D66E9C4A4111E22481688EA39F256224531ED241A9D35D395F340421F2D8F5C05B873052D2128CEDF4ABE49E609176674363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D02AB14858954A117C6B6F2CDF4823BEEF1904FFB4D841B30537D57C577968CDF18EC8631C536AF09B54D5887FC0EB11A70E86B72EF315FD722FB680EF03A3487434215A0EEA412C0D78DB2EFE20061576237453927710860F0A49DE0ED0C42FDE2A5903D635B19D4F2001EE353D7B5210E1C01F50251ED6E753635A972EC8C1914E36522B1B41BA51E9F3F1CE83BB5F526FBEC31C21983736E42EB7880B9B27EF6CAE0618E57F881193714D3E8B38C9E9056378DD79E78422BD7C4CD57D230EF44B38F6A107ABC77B8D5A953D3A3969FBB7DAB145C4F4615FAF8F2172AA2BDEB35C4A0494100CB9CE188DA4318EA5B617EBACE910A32F0A280C82AF82121720569232D71AD065E45268B36F92DDA13673529F24E6B83A865F3E266635D9655C8000C06478530294DE092640DFB324E09DB3B87497C94502BD46092D72DAEDFA93A0353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB51691B3F0ACA92B02FE916D2AEB98BD9E23313F49A0F44394883A432523EB5B34B690EF9C16B4D60572EF2D791F2BF403255A28D9BC3352B02687AD9200D34C05259FE0C93B75455218E031D59A65D4F571CD7F8B130A0CA1363BAF2D9895A8E8925ED20ADBE8FE96C34A6A13B9318AC8A23A7EA320B83B7175FB54868DAFA9E233B0F4B18CF6FC7D85F7A2B28CEEC561222C5051572B092F2FB269ABF1CC7826675F09949FC443EF723AB476E9E5D670C5F05E46DAE93837AA0F65A4E83AE2C71DD02CAB1038086531F93E163AD65BD962ACB9497C0F268876B5AD3CBBFC4C24EB2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADB0A78B6C1C4ACB8B4C97EA8C4CC3F3778CBF761AA653D9531216588A46701366E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC4050CBFA6FEF6B9FE785A59511CCCE21EC5AE3F429A07B4626A4F0C555A15B42C26A5F353E7A479A700595689D5734C39D61177AAB2943775ADAC879B4ED7B8ED826CB43881D2C1B5734F64A5490A4F77ED4DCB9775B258C18182B42C560E6CEE89A329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB041A19053D3003420EC262BF0F45F1C7CF6E55BA9001E4BE097329CA460D335BA899503CAE0D617BB7FFF0AD37076C91B1659BD448C05C49D9360462B4BC601536844FF2C635BB654EC5749FBCEF3288E41B8A7835B645E0BB501FF805EA4B39785C203BE03F0B105D17E513D50B7738E78EC18AFAB3FE134FD551E754CAA189DC4FA2308B6EED1B8CE87EBCE212E15E72C9516B778C1F62819131E2EFA7AF63BCF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0A2979199F43F2F59FB2C62E8AF2EABAFE9B89B71E75AF029BEC77A6A56F86EF6A4A7212A7458986D2DAC9E00CF68EDB81CA05A297B522D3CB2E0AC3146E4638995B683EC201C67C911C83E6BA3567D31565DF914783F41077E2C31B06640446A6D403F9D46BB9D00B3C436FE1FFDA80AD0AC466AF0417D18D5E7DFEDD7D68987BA55F545F3B89A38908BCCA1DACE0B89FFB49FBA3A67EE7384DEE68FD05721483030ED53913A6CFA059DDB451C780877E919BB86DDCA9E18814123CCC822A8F30D0AB4602815D2279398ADEDE00B23AF4EE605A771AC616CAFFCD3AB12991023A6BE6BCEAFB1672ADA631C6CC29827088627EF9380FFF46FC479E2B586432B58F95A824C0D5F08704C2B596A7BD0A36A52BFD8C14D999F92E676C83EA62DE54C3ED7ABF290BF17C48DD69F949668E11D957299DB6920D740252A9AFB65179FDD62B69D2A1A339CEF805FD258D83FD2F406841565AEF5E42ED7687D9D466E6A4E513E072A9EF6181016DAD988F7C2305A77740F196465CE30A35BF3D098781DBA2F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549617285753A9438517AA7159A9C806A19CE8B8BA5F9C99250358404671F36214E8A7B5A04767FF8C094A3CD74751835BD896FAEFD1747DDFBBE79F48148D56BF585CB0CBBF34300CBFAB9DB32469814F107EF7822151D158CAD68F01418F88B181B092970DACAE4D5DEA7AE39965D1929CBAB7685E758206D309CADC07687274657F6EEF56A657D3FED4D34C7FF6C9CC5F344F0EF4F0E752F83E06B8A23DA0D65A2C10C2D675CB3A214F5D363C35E6E10A1323579803E4268F7D868F4716BF849B3C3D8EDA94476BE7322891C36D6DF146075F11AD02434D2216351CC26600662BE0D38E1DFEF9A832B9F066718FCB2134115F33717B57936CCD2DFA3A95C1D4C4C98BD09D64EC04912C06C7C6A2FFDCA2801628D873EE6D0D43EB67FF0AC93A7666C9ACBB9400593C00316E05F0F5706ABD923D85DE72A0D1CA9F0774F5180B65AA578B95BD20C1FCC322A5B23995ACC9DC97CE3043B1A723AA2815314637B7667DE02ED0FA0924C0791CA09FA028633CCC594429D6E7429930C7F01EB6A134952E89B8CCEC743A23C63CDD9E161B5A2D1F1E0D005F16727A3B0E8B90C20656B850A4F8B5D400B65E91E45AA25A880B76BE09F226DDD4F0E0AEA00259E19634EBAD387CCAB556997A153D1C1B87AA62E5B613A5E02C65E7EE7DDE2E19D965D27B42AF8542066549A6FEFF3E10A93B349EACB843759F5E4EECA76CF82277BD55C57FAD09BE938ABB47720E49CED626AC860446B290C7FE9BC83DB0C7FDCBD5CA2B8FF6C52B2CF2556040B3792BA99DD43EDF1FD4CBE38970D235E8BEE40DDCD2708E432008992D3F9DCD73AD594171092909019E9BBE7A5D4A21EADF82C5C22D877F422EBC64734717C93A027E9EA7EDADFFBB8A04B465E2F1BDDA54BA30963A41978562C27EE91E8ADD7A95B97A1F9F5C0494C3E44AC5422759F971200B1927F5C37B003499B213C1CEF1823847ED4A308D7D98FD5E42115D49B1FD42C7405B55437E1C8C0226884DD801CD89163AEE8D74105F621EF2CE222B13ABBD14078943CE054E3D68F7E8D763948CA83876F0AB7CA5123ABA8C5F68679FCD116D03391F2A53F637D26EC486FF6363F0C297E1A672EB717107ED9540C2AAD46038F8D4C2B5D1D918AF6BFBA7DE46E6628B2C217672257EB98F585A4E4CDD87729BA5ED16719F869FA1495302E8BD043F92ECF8799DAB7B9C501DC956EE3E55FF30E6D565E228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023E10A68B5275694C30FA7BE9BE2392EE6B18651980A01348A97C4BF091DE3501B30B528092599313ADC93C8407FB07E740F784E80461A23A1DCCD78BE8A72EE2AD69CC6E63F385963275DF49AF300E5D468285CA4457F090504D42056F571A8D453903B85D7E63F893431A5A1C8A66A8E4C999F0592D75717940E296C8275952C4A8DC6E97B3D5602408DF3644E8A1338C856296C37B1BA8445883CAFB408EFB9A545AB53CD632C40659DC607F4937A4F364F7E3B47A907BD30D8558C76A8EA9EB357177B8B2639477433604EB74F9C2E3528215459533C1A989FEF107944FC8A402E29495F72F2C210135FD836028B9E21E76C6F13096DBD2BE9721DD2C35504D648C474907FFB896B014CB022942F308C3263CFF227D4444763A483658E728EE6B7954C48E3FCAB1246CED1B1E2EA9CC4D5475BD4FA43FFEF56AB2A2D779E9D206E3E657A2244108BCF55C7F4F97666457CF5F796105ABC773C541173B9E338B4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F9338191406A4C257E6B7C058565272FB78A54A46007F5550234FE9B7952A82581C08AA6A1EA68E497D663F82C5D20E9D1134816EEA319EEAC8E431A0D82B6D62F7B93D121D8382F0EB3DDBB9FCD43901C8AF1AA019A7160B76B72D4E8CA1228E5E9DFD49E24F3154F4A914987FD0264ADA4C8D6FF9EBB91C59C03CBD484E9EE72F1A98C3F97B9F2479FFB79DFAFBC33C8ED249286369F003C471C8B64A9B1546B1F31BFDD0ACA06AAB3EFB61E49CDF5506AF8A4693A7591498D9D7F8B28A72A10EC60F806A9955D7EB41D2654EE5B37C284F41CFF3F591C227E3FD0CD524379DCB384ACF486CE7B1E658CC743293DCF546BE85382FC40CFDFDFA407A9EA33AC46468E060524BF06C9CC109A726CEAF0811D0F857C08A3D4AEA67CCC0B17B2C38C53DA9F860C99E3AA769EE27CB7C9229207ACAEFE6C62D3ECFCA201DDFAAEEE1EC7BFD40086AA922961198B53C94BCFA97EEC1DC0FB8FF1D9448B6770DE4F5703CAE179FB51CEAF935F666F398B74BDE9FC87B01AFB6EE8B47490453198F9B38AA2259D2194E9EBC42E1C57994921413D6327018B91538CCB0B90E965564171D133CCD9E7F65E851971FB71F2C47B4592C2A52A4101D2EE7A69DCAB3852A56C4DBC9295D2EEC5BAD1B8A13B7EDE84768C0AF5FF0B0253B44038C236412ADCEC91508A76BD8D16E6D6BD5CBB3179B34DB8902863056CC65A4DD40B6A1929F28DFAE1CEC64A74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7E8104E8D9DB129F0AEFF48177BE4EB60236851F6D0DF3EAF508CA7F97E4D5814F71ACBCF00471EF263D3B5CD58ADEEF11E3465C704D90101A5FCC1C8CAC25387B7D6B83C7CBEF04E05BBA1766C5C5D804642609AF84AF3FA7E4572393761664021A632DA048F2A10C2A349E2E1C260C1C3CA6184BEF6045F43D9C767E2328B9AF5E48EFE8298DF69599C49CFE153BF59010741DEE011FFFBFB4EFC5AA4B5DE409B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F83369497B16CBA6B3104624902242C468F89E89322D299123ECDD8ECC98FD5C53D99FDFBBADB056D1034CA39CBBFF29300769BFF634A38678FE7BF929676A43CD0FC3161391877F0623D9B59DF30E28F5B47C0445F83B36F0AA67F6A2DB8C0C3D3F45738A4DE393D8675E286F4530AC810D244C621963923BEB20810EE32909DC96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A3 remain = 1048574 -max = 1048575 \ No newline at end of file +max = 1048575 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-2_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-2_256.rsp index 8fba48c4f8..9b66f0f23c 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-2_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-2_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHA2_40/2_256 - pk = 000000030D4B3BE22EE30889C2EA6A12AD6FCC92452E1B92832A599FB4CE52C86E8C429504562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 000000030000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A0D4B3BE22EE30889C2EA6A12AD6FCC92452E1B92832A599FB4CE52C86E8C429504562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5832CE029A1A95FFCBD5C8B157282F7364E680C60B252C49483FCA03529693B074E0D2B1F6DFD6463B974DE6829A616F20C839B0D2B8BE5405623B5B722EF22F7A3BB78E91315F715D9DCDB0C8639CB8A90685BEE7969671789047083CACF24FBC4B601B1B23B2E79E42176B2438CB405BDF46369F4DE5F411B2ACD32BEE3065DF9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD09000000000001D5DA3370DA40FE4B2AA8D93A4C52E009ED16134083746A63365266ED868E33160A0000000000010EB7A75A56A1497F0FC1FE5B3F6B396014CC9357B7FE8A6D2BA1B553EE3518610B0000000000011B23B9B57C09E7B440346ACFAAB7028D8821AF52CA85D5CEEE66FA4E95B45CA40C0000000000016AC8FE7754C3CBB4F71F8514603EAE30A764437F404409A1283CFF4B7159C0F80D000000000001CC6FF52DE53BEBD4E1D3DD11D0BE5FFEB977CA63FF2ED1099705AD3D5BEB1AE90E0000000000019B6C3951BCA1748DC7B89630F962DEB3937A4F8D15BF5634741113C38D2699F10F000000000001F21F01A1F02A9D105C71E89A189791BDA7CFB7BC89003D2EEB2AC6E7DBC26814100000000000019CD3ED9E3D49C10FE36B3813045F452DD0B3CEB702EA9FD3DE2289FEA46C9E41110000000000010CD4EC639F5FA5159D505EFD1215E62E35B38AC9A8B36077EB263B10F5BB4B741200000000000111A178357024706621EF264E4A66422A6F5B9F4C24A35579CB17DC686277D0591300000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F7F8F9EAAA74A5C910DD60B2FA5179B3FC341BEDAB53B1E957F40AFFE59FD454EE839D34EE92ED029C1B5853A46CC8B48B58DC4F74EBE2164B7F867B17ACD180761BBD5017870DCC53B0ADDCBB8DD1A6F5D014B1A789493C53C3D7B304F6237F836AA9372B0CD7007588A7EE166C1F8BC1C7826CA9D6E2D73B1B217E238FFB65DA1671204B7137B3C91D19ED0DAA12A98AB71C239C6F0E6B29D3F61DE3F71688560646DCBB9846A8F28BD1E7606E2C93CC0CBAC8A85BB578671BB01347E7B2BA757AA92131B2693D7F9501E87FC7C1BBEE1B8BF15E28DAF9B74487ED12BE8A4075FDE22DA018C0531776136F0FAB5ABF372E160CF51685CD0B8FEC7D63D39F4A7EE635051E54EEBEC7E8C4A408EBE848B7255685201592E3730C4DCCC6E7DE956B4FF296E76D0052EC6C037ACACA6E6474CB17AB271FFCA98A688D224C3A25425F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E7040000000000017D93C20AE191054626B3138F02E186A4607EDEF6E32DD3B2D788325E88FB01E90500000000000159008B71F97B67D9710ACBCAD0DCEB434823D0DDE4E8526701AF9ADE23FBCDC406000000000001410E6F39D12638391198E1827F643E6547AD7438BE85774B713D8FF3D8CB682507000000000001030C34B96241353C81CD7DDEA97ED6CBED8C9F9FB86DB60A6B78E39A253C001B08000000000001B07CBF5330F3B30963D6B0A4AC7AC4DD77585E4EB8A08B62B9AF1FBF42B76FE509000000000001D62A2ECDA2D153580BB57CB3FC1EDFFE89B6C06DE234962509FDD49A5A2438EC0A0000000000013792F4A440FAC20AF31472E40F1E79BD1E1C5DADC93FCA0319589FC55A542CBF0B000000000001FC454756AAA4BF5A8163937BA2E80D39CEF46D765C11FD66664120A83A61838E0C0000000000015DD4A3768F248125F414048EBD3F6AA793AAE4CA471DEDF5A9890841DF6DD56B0D000000000001CF0D1BF19096E3DE0950E9EB4C435D0C6B3DB4604FEBB60342D5B7C30528D4730E0000000000016ADD9B858AD6562C3B812B026D9BCE050D5A40ED6D936B1034C036AA490CFF910F000000000001925FBBBD85D4CB4AA7F5D18D703449AEABB18A5D32CEF076C16B7131DCFC08D8100000000000018DBF8B67F11FF96E3229EF8CBDD85719101DC3D8E6F636CEC6D19E63ADF5679011000000000001AE3D1E12FA31B287D509FBE36C261650C199242799057289B96E8D67301B473312000000000001AB1B5ABFFCFA0D28692F1FE23A1C1C3C31133714D112C66E05A09912A1CE32C213000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087DFB8B692D4548E69E8F52A40B52D87261DAAEA3F734803A146D4622D4C8B17E1D98A7B04CF346B99E512072176F7A8811405EF38E007181DA3563CABBC577F41D6B8EEE36B0D67FF4AA525185A5821F2ACE2DD7F0607828ACF8AB08FE940D7FD268225449F5D20ABF61D2C7DB585A8513AEF60841E1BFD4AD3C47D3A00F68F71DCD9236D7E0FBC428C7095CA12D8D10B2E69C9FB6C976F4831246C9C0E2686091FB040E21C594960A1F6734A0B84BAAACE4EEC7FD1FABCA7F71373620EF656309B93B9D768970B0A03B9E07FA9C888A01D85B0B92F6550534E528BFF6289CC398003AC6A91CF86329B6BEB13854C20A8A75DCBE7A470B216C334CFE6AC120B8AA42EF5A9BC9FD224967218F17A334DB9364F966DA366BE08CA2D1C6DBAD769ED1537C3F5528CA849841BA495B78D07901481631E624DC0656F7F5D0B4820B6FC2269E404ABD245B49EB4FE7FB119E88663C8B8E75EC63C9C5A8EE478313B3B058DF1ACA81F65DB0F2E3E411A30158178585699BE52B6C11A2DC966753D7485AFBC75AB6EB6D0443DAD871D0BF43128A057593EBD325466AFCA3EA492311A31788F75372B5321217937AB4FF23D37D3A01E3578E758A2087941120E801C12F26FCC55D089C712C0A05E67122E28351745998168D1760B16D105D854BF2EFF369971D100CF448D3D00C2C34D5F6037A07522DE2EBE014E1E60D7A535B4CAC42EB69F7856E7A259627F4492A0CDA142D743D7BB90F78EDCC15B1EDF8DE7D0D4366367E581254AF959768265DAC9175E18F133DFFEF628CF769EE7E9BD0E07259AFD067AD441ABF81FA7726FEB1140C3146BB510185AF098DB53040DB97F1EF894CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318E413A87250637B5C4A4BF18A2D661BB2458CA7C7F9E320228FFFEE614E88838DE28767053DAF289E9BB8073D60114D20309CD17A6EBA5FF2FC47B49402DA3600DBC4323559761781818334D1C0CAF34FAB5A940C83D6A363433E390C3B589E1B6D09A2F4276547FB279D1F0E2D1ED91A3AFC953F9E7942BEFCF2AA66B19AE877A6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291D560067063A6EBCB1EABAF7FC12F66BD94F1BAD021254D0CE1F1F850B081262A446E84188C3A9A3CB89A80BC9E8F597EA247A39A6F59BE2D76CCDD6C96DDEB9EB0A272D02C5327DF20934FF8C0E26C71F6736FBD5B85A56F15E41F03DF2713DA70DEC489B962A1F7E119465FC8D72AD1DA559EE0F25FF661AD2F62C6BF172C4B7B0891FF05D0C985FBDCC4DEF2DFC3A73AEA39EAE9010A080DD47BC1268BBC1B5282DA83C62A9FE25CBC62E611951A411B03FA8832E227D761A35F4FB902E54083FD05142177B5D2987BE26FC4F9C5D13FFA21E7488F19245FD19D9FE2DA32608B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE5BCC31B508B8177B41775B459DB06F4AACB419F24EA979AA24C996554DEC91EBCB16E9E1B754DCD221E02231F10FBAABF79E362A514D54670DE7493B7CD7B66BAEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBB0A1E0563E934CB60493FD19327C71D824F361B1133A15E47857567979B5F8288D5FABC9D1D47402577CFAB60BF840EEF0D9173D47757BAF197EE10941704811690592F587BC7F532446BA10B875CB7994CA2613A25F65D16A6735E9CC0C4238036F68FFC1A893DDE19859CCE3F5ABA348F769D122DE567889C14924B243B1379AE65238446E7294F293F0DF1751C166CCF58B4F76A4A7A6178A136E3F72D120FCCFDD47311A340A0734C7DC77664B6D7BD87EA93215C69CA59F0DAD8E258637B49DF9864B84B76089E4F50B6C2BC496835D701C6F106B2B96CDA03A7F118AB5AC2F7073E7596BAE489C83FE68A8DB1E9A5427A31E8A6DC4E2962E5571FF061908EBBED929D64B2505C1C491CA277C2917E0A964218059309167716F47FF2699FEE7248ABFC6723085934D706ADBA0BE046CE3156EE682A5E0ED51534CFEBFE9B7118577F6D3157F31E8D849071E31A734BCC1DABDEF02B7D817FBFFF2CF120ACAF9BE403C35D92B960CDABB7242115FFBC4208977E19BFFBF250DE7C71814EC7206CB8F2E1D523E293E557D49801FA6D9E5AE279D396F91021690DF5EA153B3020CA3E08D8C53DC9DCD731315CB24C9394C6DEA84543806DF231011B086BE37A57CA2B888A74FBE7379EA346ADB56D932BA4B7B857A7918116B70987865FEAB8A42792F788F8CE13F75670B36029660F68A7E27FA23EBD2CC06C7CE9A51FC7B92220D44C4E9C7900E1FFD77D08D35B34B201EC5DCE6348FF7AA08F0DE5A4AE7C664F8E70D3531E181B4B5F7D74E8B6FCA7AE776AC73C4620B77C1C2397B987C241CC139C6407FEBF5B912A407695EE8AB6612C8C3D610D6E11E107E43AA6C638FF86104557546FD5CA0098C44C4EFEF0825DD5E8B33E5311238A32672242BD19ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDC05256E7B9EC23FA6F460956174696C9283AF19A615B7FD209C25EEA0587D15765808D7814EA792B7C31F469AA7004FB9A78EA5E59459C6E3F75E9E4DE961B5FABE5149967C9F97B1BC5DBF8E297DB4B25FC55241FDC189E9488FE06F71E9D1D4E19D50E7A3B81FCFA4799B127AA0D8C12FAF48811D52E4EA08D965813E20A7CB532F3EBEA5CB60601DDBFB1CD19FCE3F0A9CD1E452D1BCDDD215B91160F6EF5892280D847E32600F50E5DBB0DA83A650FD17E4A58EC02BC05DE23CD3B2C04172708C15A96A3D43A212FFD4401EEC87861C35351A0BE9D7D4D6AC5D60DA8AB5E1BBC7D943F4439AEBD7A6B022C8EFEB712BE5EAB7A1802CDD2FB9D93FA6E4383586E517A4D79D9FD2F6BBFEF8C65F1F3111067670E6A059A1308948697F5650C @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 5605 sm = 0000000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA7010591AF601BF50208B6C5968D4F692F07279A9C6AA2E66590F7D2E54DCFB47261C040A14FD137EE498C24B0DC750905F56FED22A393C31815CAF6ECFA1D3BC458E3DCC2B150E1DD088C95AED7DBA928946BCC8351DAF6136F7335FA45EE8F4651C6B0A4897AB5ED84C95BF9D9D78816FE9E92F843558029A08EF7015764C3D1AF1852C50D360F65F887479E9631A2CA30FE3AD92E7BF648643835F4F8CC081A6C9255CA9569583D0B40DC8A5942B9284515CCD9497D7AC749BEFAB0032A08D412C7E9C14ABF9DB094E3BC134A7340CCC65AF466D98443007DC0D228B92614C4AEA2949A5EB26C517909E0E663E36753491182975206009107509DFFC898D308B903E84A8B29718BF7125397AFF5467D53CF8F36EB945B6B98D48E81C0174A0E035CD71994D48CEDA477BF92043B7E7C743DFD9E32948D29632C6C47355A5701C0EA6EEF78B8184B2E355CC338055DD2A26DD02B1A0740CD15F6CBA4EF429254DBC42B4E4CAF8C6A654DC35E975B5D6F725102362943C6BE446FE298B8F60D4F7945F48FA30DE2E92AD9D0EAC1F4B2F6B8DBA9D1F8CCB77367706BBBF6A04658E8B5B20D28D1B9384DF1D710AC39FAF699989418B7856C2034C695A693ECC336EB44A408370993A75DB92E04D2AE87E9B68A9B3ED860AE3B2FE35CF590BBD5C8FDB578DDD5CC10FD6A277CB7F7E3FE7D4A0BE921B1618FEA9ACD67A0A6403A4CF19503DD53FB1B3AF7ACFE24C28A700632DD3934A56129B66BA60E6BE40B7EC27DAE98F99E31983B4C2DF95885EAFD770642683F7BE36EBD50B76020DA763EC0CDFED7CF9BAE790E7EC9573A0DE43636BBED92A210DFE814B95600B775240CF7337D124B757C9441C0D52C3585DD7B4EF2379A73DDA87B41CE87DDCD392A4B6FD9942A9A24E79B7D98A56EF751FD1AAB89A95F99301932337C4E7820B84B1DE9CA28684AC3B47FBEA813CEFA4754D02086281392EADE94F003AD0EF78DA65C89BAA18FB1BD12E0428923AEF51F55928C8DA0D632382E3325E4CC5C6A3EBC4776C9F6520EF2C6960F0129A707F90315AC1AB035A7BA0D293A6400C30D363DF000F536BC9BE5B558AF33A21292D74831447DC10BDCE1DDE460F168D09CE0EBC1866581CDAABB3A1CF1B2F23B1B131831F0AA6A9B9812A422573EC10548371DA356F10510E48DFB7E23CB49D6FCA39A1E0F471F16A8BB65AF02150D059036D00386DD2921D5E8459ACCA633C5B50F7C6A36062BE168AF6246317A8B052CD7F15A96EDC0BCA137C5F65137C2F61DC5E02708B286B4A416EB49929D86E713FB912E44B87F85D73CB40792FF03F8F20427D951444990CA3976A71368A7DC1455E880722F0300029FD0D41FB427D0515FF9AA3344F5F3E4811431191A1AC406B7A16DA1063115DAFADB4F258D8BBED23B21C65486E46D8BCA833B6967A09FC7DA038DE1464689E09376BF39F4C562ECB1A68E02D5D91318EC0C91D38E8E480B8A0E65F45252585CE1A0C20AF62AA5A28C4FBF5D15AA7B0A71F964FF58031123CD5A9986D9F89CC18F2B6664B4D83235357E327821B297F813F86DCCDB13E3B5903FAD26CFB2298461DDE724EDA70528C54B09AB368C492937993E3093A695AF1F950B14A1D348B12C3C63D8F8EADB9A26B8FFD6DFE7453EC8B6FAF4B9F5D6F74F6CDB81B5420169B68E73B20457198BA678C4496B02F7124E0474EE3BB9B7107646385F85EFBFDFA55C12A388836717BB2BDD97E89121C56C3B53E8198242315C9E438512ED74BEB3BDC53DC8CBD2A281340B78F7635419636A3C38E9D5515CF8A035A439DA3D8CAABF1F06E36E322294F3AE10918203801BE05F8E4EB9A2663EF7894829F1A380C43F95D362E0680D9EA2CA47E1DC8C49703E22650B765F847AD86BE25A31377FD516E97B6AF21BDAACCDC8D36619B7D89C62EAB646A95A90E0EB467A75C97C1014D748D6338397737A54B2CD2CF860C14CBE1AAC697CC39DDE00C3037102F1EAAC7944E4E7E754B78F741D7B3858E4BF33C370C36B8A7560D6445B6D2F64E165DB2CBF8027EE9B5CF5EBCC9DD06A5C319E2B9611BE946B6020CE4D9DD736E8EEAA2FEB1CC855F0A745AAC84A610DF0238112C6519F8E7346C45331A6036D84CE48A25C1D687C6AB85A7863A51EE463CD2CC2686DF144AEC6049484E3FC1A1646DDEF29122F153C5B5197A2AA78E9DEBDF712F92C42BEDB4BF1AF46B1A2F47D9A150ABAFCBBB6BD37E68B51E1E3B76A88186784096804E0CA23134BDB161FC9578D9E5B309675B6C05FC8264D3591B80770D4DDFAD2AC53E7A93D8A8469837FAFA9FE1D707144A2290523A7D25AC1BB6206AB824556519D2B909E4D04DE82C273480A18885B0DC4B717D93BCDD352B3DE4A2A90F04B239520B8C1149BF0D4EC078D85E41744750FDA0D2767044797A4C3BDB3307C68D3782370C2FC6F6712FC7EF1891A77E1A3F29D810C205EE212E75863F3B8B1ED216DF888ADD07AFF47738AE40641E2FEFB1097D7048C618D4A0B99C75276B6F41EAFB4FA57B0925FB775013C6C36C81EB0FB69F86B4514EA931FF7E4C4179DFDC31A92EE8F618321A2F4DC28CF39967D04766E592F7D01995F16BA6C9D1FBA22CE251F5F0FA554D59D75BD46109FC202692A3FE21B7739AA9C39BD1B24AB82C59373CC06D3F92D48BEFBA495E0499587494A9B6E4974C37F5C006A34FF102A23985FA9F660326DA393AC26CB1FAC5A29BA262D95C83C292FF3D75F4DA803F4C139AF1778793988AB25608A8216E5C8E91E1E89EFEA60DC1306CFBC26529D23619E354A7F1332E790C6730FBF34A79269B4FD988E4712D927E6487995B4A33B3DB9292AF35F278442B99E10440F06BC626856A2015DD832F087A72864D390131A760B46BFE305E3B4E9912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70DD4CD344ED3ADDBE4C748D918BF1846595ED36485972F668C65B6365638B4D41B7AA1071D740ABE2895647F286260874BBE8C609165131481CD81E4C6D98293F1C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5832CE029A1A95FFCBD5C8B157282F7364E680C60B252C49483FCA03529693B074E0D2B1F6DFD6463B974DE6829A616F20C839B0D2B8BE5405623B5B722EF22F7A3BB78E91315F715D9DCDB0C8639CB8A90685BEE7969671789047083CACF24FBC4B601B1B23B2E79E42176B2438CB405BDF46369F4DE5F411B2ACD32BEE3065DF987DFB8B692D4548E69E8F52A40B52D87261DAAEA3F734803A146D4622D4C8B17E1D98A7B04CF346B99E512072176F7A8811405EF38E007181DA3563CABBC577F41D6B8EEE36B0D67FF4AA525185A5821F2ACE2DD7F0607828ACF8AB08FE940D7FD268225449F5D20ABF61D2C7DB585A8513AEF60841E1BFD4AD3C47D3A00F68F71DCD9236D7E0FBC428C7095CA12D8D10B2E69C9FB6C976F4831246C9C0E2686091FB040E21C594960A1F6734A0B84BAAACE4EEC7FD1FABCA7F71373620EF656309B93B9D768970B0A03B9E07FA9C888A01D85B0B92F6550534E528BFF6289CC398003AC6A91CF86329B6BEB13854C20A8A75DCBE7A470B216C334CFE6AC120B8AA42EF5A9BC9FD224967218F17A334DB9364F966DA366BE08CA2D1C6DBAD769ED1537C3F5528CA849841BA495B78D07901481631E624DC0656F7F5D0B4820B6FC2269E404ABD245B49EB4FE7FB119E88663C8B8E75EC63C9C5A8EE478313B3B058DF1ACA81F65DB0F2E3E411A30158178585699BE52B6C11A2DC966753D7485AFBC75AB6EB6D0443DAD871D0BF43128A057593EBD325466AFCA3EA492311A31788F75372B5321217937AB4FF23D37D3A01E3578E758A2087941120E801C12F26FCC55D089C712C0A05E67122E28351745998168D1760B16D105D854BF2EFF369971D100CF448D3D00C2C34D5F6037A07522DE2EBE014E1E60D7A535B4CAC42EB69F7856E7A259627F4492A0CDA142D743D7BB90F78EDCC15B1EDF8DE7D0D4366367E581254AF959768265DAC9175E18F133DFFEF628CF769EE7E9BD0E07259AFD067AD441ABF81FA7726FEB1140C3146BB510185AF098DB53040DB97F1EF894CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318E413A87250637B5C4A4BF18A2D661BB2458CA7C7F9E320228FFFEE614E88838DE28767053DAF289E9BB8073D60114D20309CD17A6EBA5FF2FC47B49402DA3600DBC4323559761781818334D1C0CAF34FAB5A940C83D6A363433E390C3B589E1B6D09A2F4276547FB279D1F0E2D1ED91A3AFC953F9E7942BEFCF2AA66B19AE877A6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291D560067063A6EBCB1EABAF7FC12F66BD94F1BAD021254D0CE1F1F850B081262A446E84188C3A9A3CB89A80BC9E8F597EA247A39A6F59BE2D76CCDD6C96DDEB9EB0A272D02C5327DF20934FF8C0E26C71F6736FBD5B85A56F15E41F03DF2713DA70DEC489B962A1F7E119465FC8D72AD1DA559EE0F25FF661AD2F62C6BF172C4B7B0891FF05D0C985FBDCC4DEF2DFC3A73AEA39EAE9010A080DD47BC1268BBC1B5282DA83C62A9FE25CBC62E611951A411B03FA8832E227D761A35F4FB902E54083FD05142177B5D2987BE26FC4F9C5D13FFA21E7488F19245FD19D9FE2DA32608B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE5BCC31B508B8177B41775B459DB06F4AACB419F24EA979AA24C996554DEC91EBCB16E9E1B754DCD221E02231F10FBAABF79E362A514D54670DE7493B7CD7B66BAEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBB0A1E0563E934CB60493FD19327C71D824F361B1133A15E47857567979B5F8288D5FABC9D1D47402577CFAB60BF840EEF0D9173D47757BAF197EE10941704811690592F587BC7F532446BA10B875CB7994CA2613A25F65D16A6735E9CC0C4238036F68FFC1A893DDE19859CCE3F5ABA348F769D122DE567889C14924B243B1379AE65238446E7294F293F0DF1751C166CCF58B4F76A4A7A6178A136E3F72D120FCCFDD47311A340A0734C7DC77664B6D7BD87EA93215C69CA59F0DAD8E258637B49DF9864B84B76089E4F50B6C2BC496835D701C6F106B2B96CDA03A7F118AB5AC2F7073E7596BAE489C83FE68A8DB1E9A5427A31E8A6DC4E2962E5571FF061908EBBED929D64B2505C1C491CA277C2917E0A964218059309167716F47FF2699FEE7248ABFC6723085934D706ADBA0BE046CE3156EE682A5E0ED51534CFEBFE9B7118577F6D3157F31E8D849071E31A734BCC1DABDEF02B7D817FBFFF2CF120ACAF9BE403C35D92B960CDABB7242115FFBC4208977E19BFFBF250DE7C71814EC7206CB8F2E1D523E293E557D49801FA6D9E5AE279D396F91021690DF5EA153B3020CA3E08D8C53DC9DCD731315CB24C9394C6DEA84543806DF231011B086BE37A57CA2B888A74FBE7379EA346ADB56D932BA4B7B857A7918116B70987865FEAB8A42792F788F8CE13F75670B36029660F68A7E27FA23EBD2CC06C7CE9A51FC7B92220D44C4E9C7900E1FFD77D08D35B34B201EC5DCE6348FF7AA08F0DE5A4AE7C664F8E70D3531E181B4B5F7D74E8B6FCA7AE776AC73C4620B77C1C2397B987C241CC139C6407FEBF5B912A407695EE8AB6612C8C3D610D6E11E107E43AA6C638FF86104557546FD5CA0098C44C4EFEF0825DD5E8B33E5311238A32672242BD19ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDC05256E7B9EC23FA6F460956174696C9283AF19A615B7FD209C25EEA0587D15765808D7814EA792B7C31F469AA7004FB9A78EA5E59459C6E3F75E9E4DE961B5FABE5149967C9F97B1BC5DBF8E297DB4B25FC55241FDC189E9488FE06F71E9D1D4E19D50E7A3B81FCFA4799B127AA0D8C12FAF48811D52E4EA08D965813E20A7CB532F3EBEA5CB60601DDBFB1CD19FCE3F0A9CD1E452D1BCDDD215B91160F6EF5892280D847E32600F50E5DBB0DA83A650FD17E4A58EC02BC05DE23CD3B2C04172708C15A96A3D43A212FFD4401EEC87861C35351A0BE9D7D4D6AC5D60DA8AB5E1BBC7D943F4439AEBD7A6B022C8EFEB712BE5EAB7A1802CDD2FB9D93FA6E4383586E517A4D79D9FD2F6BBFEF8C65F1F3111067670E6A059A1308948697F5650C000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F7F8F9EAAA74A5C910DD60B2FA5179B3FC341BEDAB53B1E957F40AFFE59FD454EE839D34EE92ED029C1B5853A46CC8B48B58DC4F74EBE2164B7F867B17ACD180761BBD5017870DCC53B0ADDCBB8DD1A6F5D014B1A789493C53C3D7B304F6237F836AA9372B0CD7007588A7EE166C1F8BC1C7826CA9D6E2D73B1B217E238FFB65DA1671204B7137B3C91D19ED0DAA12A98AB71C239C6F0E6B29D3F61DE3F71688560646DCBB9846A8F28BD1E7606E2C93CC0CBAC8A85BB578671BB01347E7B2BA757AA92131B2693D7F9501E87FC7C1BBEE1B8BF15E28DAF9B74487ED12BE8A4075FDE22DA018C0531776136F0FAB5ABF372E160CF51685CD0B8FEC7D63D39F4A7EE635051E54EEBEC7E8C4A408EBE848B7255685201592E3730C4DCCC6E7DE956B4FF296E76D0052EC6C037ACACA6E6474CB17AB271FFCA98A688D224C3A25425F remain = 1099511627774 -max = 1099511627775 \ No newline at end of file +max = 1099511627775 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-4_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-4_256.rsp index ced74682a5..d17a127d5f 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-4_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-4_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHA2_40/4_256 - pk = 0000000463FD804E9E56657035D9C1FC5A291B8586E41D1E5E5560AA76B30C26198181A604562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 000000040000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A63FD804E9E56657035D9C1FC5A291B8586E41D1E5E5560AA76B30C26198181A604562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD0900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E7040000000000017D93C20AE191054626B3138F02E186A4607EDEF6E32DD3B2D788325E88FB01E90500000000000159008B71F97B67D9710ACBCAD0DCEB434823D0DDE4E8526701AF9ADE23FBCDC406000000000001410E6F39D12638391198E1827F643E6547AD7438BE85774B713D8FF3D8CB682507000000000001030C34B96241353C81CD7DDEA97ED6CBED8C9F9FB86DB60A6B78E39A253C001B08000000000001B07CBF5330F3B30963D6B0A4AC7AC4DD77585E4EB8A08B62B9AF1FBF42B76FE509000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549619B2CE208EEF551E81A9AE87029B4302D012853622BB3BCD47FBB055E048923FF9ACD043DD40211F720396E02E71DB06FCE4E8D757DC264B4F5AC3089FE49361710B3FEBAE56D82E67A6C29504D6B061DB48FFCD3AB91E7B6B870AF8042312735EA06532FA075BA5DCCF6C9E92AF59BAD50EF0A3797C335F50FC43DF22481EC203C13BEEEB42DC753BE45EC74C10D40CFB3D55B68602D288855C63FCE824A2F4A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113CD47F2466A56323209409FD7FCF7485A71CD8CE96D61298A20473D9ACBF99C010000000000019AB3950B30D3E7877159B364A25B214B41B8AA32E293E2DDD44AEB7DFC560A82020000000000019C359D104347B69607EB28A02E6924C24BD2A26DE4CFFF3FF98E48688E291E58030000000000011EC9B78F3B1189A5482238BCF700922D642E45D07E7EA10833E31A4CBC3CA08F04000000000001F37353B4AAC3DE6FA6FA583102CC2F35D6CC95325A07AB88D9B0304EF6F8103305000000000001E087F84EB8A6A13A9581B22CDEEF8942E186FE62896C636D0503675B28692B72060000000000015FDAFB6EEAA60CDFFD2E2D1C034AF7306D60B106F145206FADB857BA565C66FA07000000000001CA463E7885C94740495E419265530662D2D8B0CF6C9E7C290FA86E8E136261DD08000000000001761CA5CF20BB11D4515629D8BEC9D72E02E0D3392C20084723610CE22260DF920900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A3928351163E04D8BA817C168A0CE68CAA6FA744E7E30A2670B2BB88F27810C887E48E90EFAD40F9735B5767F60EC515C146D56EA534C970E04BDD10302D85A2317C478BD195FC93499C051F5AF61A6C5CECB89A1D67BF5BE2CA7EFBDCC20B884597EB2BB0799DB9B86E2EB8FD93389AB91A391F2D68A057FDE361AC97A87F4406F40A7EE2E7709E46DCD756617DCB0DBBF43E6BD4851F3D834BB53CB150D2FB7B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019C1A7BFD8300283215BA57DB5CDD95EDCBD04E1C41419317BC2069C2AAAE22130100000000000143ED646E32FC21554D8DAD350C5732270CC220F7E264ECB5B7A8E8A4586D0CD002000000000001762D040EECA13E137753604D099809D946063368BFE1C7CF0E6549FCA746F7C6030000000000015FB7406F1B25A2B4A6A1666269772EB08D6FE78D8A8395C56AD80FE6924DF08204000000000001207155BDC49069839D60C0C74C9F57C739D2F36E6AAD0F698CA840A48FB11EFE050000000000012B5052F4510570C5839D41287DA3BD24DE8CBD40BA9E159E783C5812A28606A7060000000000015C07001390BCC398A47CF40395338496D66003B5E0C1DD7187A5D605984F79ED07000000000001285C8B2D9B398B8A212B3CE0FA820CE44048C2105C067AB9FE6FA70B1E712C33080000000000016F81A741E38029A214AF0CDE4C75E79A618C7B4942F7819A53CBF8EAA263EE490900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014BCBE4FA64052B0853EDE00CD41BF95B66DA2A519216FA1A0A8BA5F10B4EAFD8BE62C40DA2A76DFD8A5EE8EF42A8B808C55A533FC488A2B33A935A635E24F3E0C717E2320FF575ADDB18C567B1333DECB0855E069D5759C48FE6D8C6A9D217BFCB7A9D40735A3151382E3456CC4BEDF6C7EC94F186FCB6BF9398FEC934714E8E231402FC7BD5153981C7C789B26208DDD77E4796F70D6A72B7B9C5EC75E4E3CD122F72621E92B1AC515A33B12B1801B2C3E461AF788661815E6BAD2E6472116B89B941A0E68A232089C6F831229BE2EB0CD244BE4FED78C8371D2DC614445C76907F4A3EDF18722BF0998FD03209C31C348CC79A2AD06ABB1B3CC549E73B206A05345EC801A1C5C42D794BA1A35747493D76CA8567B62F0C2151923D8D9CD2F37D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB385C19D6AC3BDECA5BE59F322A17FBAFF466E945FBB943BFE35854802837FEFEA3937069240712886742E890428C0C21BC057E82D5BB961095A5A18DE149CD19F79E9DC3CF0FEB5149F856C5A7BB82B6AFD4B5310993D9E4E1D33B4CC601265906186B98CAB4AF1570CFDC928C0A221A3BBFFE8E566D580A689AB51BB69826FA60135F60C1A1EA97CCCC9AE96CC93B66942370BCF910D916CBB7F87A0BF5EF46DFEBB050637754B0E40509441E19465B238EA45270D7BF5E0610A89B4A47AA821D9A3BA58127DDCEE4E7204C38E0EEDDFF72B07FA5AD8EB1FA89554D940C2C88EF588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE5966743689380FD336A081B8C7F753B889BD73F10345B8C4988A7A4C865250E3707A8424B606059E3ACEA75F2F732058477097D5BF8F5A2DF82E4AF0EE9C4BB251A5657C15808B7EF26806E2F3D61137B44C9DF4196A9208065ED1C70F9DCE3C75AFD719F14D79818812360E4709E521E78B983F99B31863039069D3F86FFAAF318853EB4A1AFFC5E598ACB6B15198E016C779BB7D77C54971E4566C2071EDFC0D19B41827913C5F7EE5D8A9411AB2706F3C9DD8E2CF4AF497765A647C1AA42E3645485AD6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291B3530D6094FDEDB782E1C927C11235EE632F6C3FA150DE1BC1125FEB330079EDB0733B58F1CDD3D20904F85DE31C06FE375E7D1E20F4C79484C5431A026EF8F5C8AC47E7FEA2A80E17256ED956484E9004BD99AD8ECD0D1EE5790A83CF9A14827C3B5D5C25AA18255F5D512917BC1FA868AF35ED3540BF0C10CABB267F612C26AE27DEDB5665A4DE3913AA2631C034C1BD22E5A721194BE6D1E4337D1CF488E9F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA498B7DA996B2692EB8C3D1D8BC9BECCFECC8EC67EE3A87DF5B0B9C7C887DCB0CBA7F5E1372399F3A4F4CC7DF247752994CE0D024D2C6E620EDD0B8CD30891FAF58D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB074AA6092A1F23DCD01D8B8C70674D55670C07A6D0655CF37D0516E6E1102865F0C53C5AF80A45B09B078337D61AFBD12DA2820AE45CC4B213C00576FF3D5FC21D0DB8D877757226F81078653EB4C90C0D2C7D304A6E0C4265DC3C1DB343202664008385964C6C56FA11532D7CF41E93F92EF28F3DE2CA1D5817AF2114A97BDA7F6504EBB2A6EE6BF4753274BE064D3CE467673717AD7350DE4E83A1BA27306F11DF36A2E30572E3FEF2EF6B2518419395DA9B7D4B191C88F3A863A477A2D226E5BCC04E39AAF1AA042A7B115CA26BE8DA52A162FDCEC6E511B1497FFB8B8AD23D3C429F71236DCAF9DE275D7B1D2DBE83822FF7D8C9BC7BA3AB5CB517228AFE2E30C53E64C44D02CF9CB51CE371827CDBDF798B1723B418EC7CDF66CF09F444A06DDB94355F529337D6A3178D754D68BE658934FEABD4F4874B11E739F0EE4E95D2D23B41F037B9668C9F74D2B3D31027861779FF8516A29246D766D2A61A02CD5B8E338B9630E8E0ED5BDACB017A6D3B89C8A1108E525BAD96E203E7A0C0B7F2148274FD20F9B53601F2B38DF303D7F8785D06260485D7507782E11855EA62F44C755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E695CCF3818C69AE16DC71782D99440EC9AF4A9C33FFBC728C9C62C47E0D37CEA661064246A8B2BBA14ABF5767F33E490AEAD721929515F091663B4437BDC34F5B15C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFFBD90B13035960ABEF4E3CFF91B9871E49B16A6F0FF86445C441921D2E698117109D810C864F024F62F8D25C263CADA33916763373D76EC8955ED113F71C40834E79A1BD5E21CC2373598C66168492FFCD083D2A8E7E480F76274C048719AFF98C5E2774BB1039646BD25A240875655A77023B7F884F5852DCD9C5DA173DACEF7F01F6527CB7F5375FEC1FD2D5C90A46D3D0501715B2D4CF51166226D8F35DB7A9ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272AC230107F230E29845C2E2283763A5832809AF2428C304C07CB21A96D7B7CDADF857F54C91A22B8AE6E4EDC0DEE01FA60697269BB1299F9FD7D3699D4D865A25BF0F31F93DAE1D51C42FE755219BC2A4B2505487483A1B81BFA86BF6A99642C51AC3DC78D5E42FEA4ADCC51C0501A8FD543217134694262E0FF5957CE719766EB0CB34CA2E541992CC2619C65822A763FE6572E3B33C4C8C216B4A62A13BE7FE6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156D49ED44C7713B7A50EEEBC575166A1B6CC3AEC2CA98398971F648242C35E8EAA21257BFAC587485D48AC54BC306344EDEBBF2A42B7E37B6086B1D9F54255742F1C9BBD708D6DB1AB7F44BC2473A4897D83DAEA510BADD3ECC8C9F2E4F889D5AB62334F4B56AA20F9BB57C09EBF41BADB20D36485AD613C790428C382B437866A681635BB509C97D4AA12387C320F6CEFD1838459F0DABA3DA54684B83E3ED10C07B8CE62549A876A13D86D8F3D001504D939500462E64C94B6EEAEDDB8856D13AB345659CB16C8B977B6670208B70920BA34E31E6A10EC724CC6FB3C299ABE890047E1F6B3D5A69BF731EFE803088FC8D3B9E69DF3102AABBEBE90C3EE20DD829BC1C46E6764AA8C8E2396E4FD1A65A171D9EEDB2B04843DD2845B5E5F5BB714212BBF4237C6D69B1D61531257FAFB41BCD74462C292880AA396FDB392A42C4AAD9B5492EE4F2A076CEA42927C22BF7CA54FCA135A0FF512CAFDA620DA75DF70C37EDADD455AB3C8EB0F334679EF94E6ED2E8BFACF20DECAC68B3AFF3979869B755D1BA8476CF0553AA3B5049EB57DF8F00AC5DAC2C1DEF316793E5DDAF9F352894CB9E2B7C860E4D2BD42D0053B2BC8C7F3C11FC0DAF6DECA58CA37526095779A89119240A8E28D1D44AE57D7D3252B69192353D745AE1C066DB60F6C6E82F35854FE73C1C961A0E178F047DE9EC62C589C2D7E30929DEA6CE37C4042F04615F48FC178E8CD389A2DEA13C83E2534271AE7DB54D7C89B8714666381C388D37BEC8102F8497D8A820C70C47254582C5C27D3D97A6ECE379315D5520BA346E8F5B5F7887F9E3E44FE4C156E7472EE8D9C327587A0704A8035E519B1C4A9D2E07949F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DB9D6E9AB3A0926402DD8095AAFB46217FC41A2E0D7C5960C1FC814E461B1F1F219CBD0A97D50180BB017229AC9F884896F357900724A3A7A8E4D479CF6A093FC30778F755C63CF618073C40F6042FB2143DECEE8DC32CE9D3E0064EE378F78B8F945A05629C118D60A6AB5DE2DA55A06B7325FCCEE42C01A5C408F0291E3610C44684BE1F66D3FB8F6BE43EDAD2EA87FAD50C993CC447DCAF79AB19DD406B20974363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D024DAFD78B7F2D3B3C54AE60062DDCEEC2BF3A579A53E27A72402BED5DA1678158142C023B3C238A93F3D1CB8E48EF84C168E27E6645DC6DC6689E89CA0A74D07087B760743BB526662636725B7FB700BBC0B3A73793C291EBBBCD4970B27370C2E85E7BAC610B75AE5CFA9DD39290DA4DADF4F61BEFE0F87959174D2BC28BD76B780BF58A5656928CC6684D80B728FA0C1570B8268DFD57EC9168CF7D39997BC8458A5D4126FEB278B26769C4F55EE77EBCD778D00F836BFA6EB13307BA2D7417B0812FDA4CEEDA359BF73865982622728D7EA8BAE1620A63483DAC957E4F8E082588E12FFC57A2871119AED0B43DE4ED1EDC4AD6434A485C64D9FAFBFC7F01A8793E5649BF33A7186BDBDBA5DFEEBCC16F2CCB67E355774B8C32B932119DA7158A4D131F560491BB42B47C9EF1594FF6F09BF29E972502A7D62A2240FBBBE55C3D82050B374EB42E433CDBABC163A95A6492A7F7DA6824B5A20527C9D0933B97C753932ED9ED277E40CCB8C4A042FD5B88E9C5D569A48F512ABA1DE68C821BD20C1A995235727654ED6E59B063EBA5F4046E7D047B886A22A7D7C5BE009F3E14629FFB78F8555B7376AA2B7B4B360F0D3C295ABC2590CE1AA36943A46379C1085D66FFE0DCF3C37C89BBF1C7D76B6D62D5D2D265EAC52164E4799C52D9A7E67836B66532608870BCF43815BA0633B82CF8E92FDD0A4DF829039370202BBD93541D4D398C42900F96D70AB85AEE46D4AE2CDB5BC61B0E57DE8AF9BC4A366730CC4A8443203C374F1F58A2203BACAA6A0C93783B0BFD8E85A869ECA37AE0FA0349E9A943B50EA190BF7E28B4406FC4B14E77203739F8DF7D168EC43FE06D0645ADBFBC26542CD0335EE21852C8CAE8DBE734028D2F6BF457CB086172F176456A64E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC40509461C2CEE814F7E26684AB01D51A1385EA51162E9CE43172A1564809B328A45AA68BC14BF38692467DE23B8908FB07BA05C90DD44A372477233DEEC84BF89287B1F8E1FED4F275FAD98265AA76F0D798266081567140ADAF2A9C64F41E053D1F329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB03F8A842A1FF048CFCF92A8D77409DE43CA455C5ED59F89358559BE214EE1B531915180697A948C945A9924FD6864D9CFF00E1D47F38B54092E4CFF1F92A65CCABF206A7D71F25A66969E37EA7D52EFD74B80E93CD7A048F71EDDE1EAF82A24F20145528EC96BF1857E0F1D8F19812EAB34E07D4262D195D1BB4D20FF3E226C2468B90E951C8212023248340ED5B7E4EDF3C6AF6A6FEE63F8DE613EC6F1526E3F6A9327A17C2279BEF50B6CCF1569A86FA56DC4B8866C365DC5D16B9BA888234D6860885B2A420401C0E3F8A971BE2CCF46FB27EB58D6C8EDE207B703FB7EBFEAC77465237E1EE73B675C37F656EBABF91BA91A79FC679C5566A637F6417B8981C93D4B2B08DD6DD375D4C84791CE66913FD4E3D6B01287F258E8EB01A223CD222F81B1412BAD3DF60D89E29F4FCED352A1DC0D52A296D6D8145BB66BCC936BAC362F309AE4520552C369E4BBE918F20C4AEDF8F037EC9AE0A3BE8BA1BA0CBD40949CEB55F41C8728AA639789BD51539F1AFA46F71106F428C9FC659F34F6BAA879DADCECAAFA80505AC2E0ECBBDBA3679A483BC7B92A54BDEAADFA7F386BA0AA79EB4AB02F6134488DF1220F8FA56D2C14630DA6F79094DFEE7180D218C621A32C153D6E5AA82C318BCBEC16FD901CB860793B8B3E9E357D0F008EA80BADACA56795A369F5E6F910F706986E7F66A84B100C265BB5339972BBDF6B770B694B8D2DD8323E86A90E83EE039AE031A331E6D7B99E75FDE0E8E42AF855F52C925F1DE1A2B10D241ECAD1523291D88D5D0EFE1D5CA4DE89F22AB2605BB5AF0CC6564C0FEBBCAAE5A19E133CA77B6C4AFE98FA12CFEB1A87D38463C35DE33D5B7D2E08C3DAED2A32A25502AA2B4E2F2A330F06294E202466F0701D4B361C71DB74253ECA3148CC5E1119591830C19DE38FEF1A5F9302B766F68E4E6616611EA940522EE92E6625C8783357799CB4B9F6A56A84976EDB84939B94A676D4657DBD04F7D754A901CEE47AFF04327CF6E0193DD3EF8CD61ECAB28CE8CDE2A56ED422C47BBD5E4B1C005EFD6C982E1601461DFE8EFF46797FCA8B79156473C7A964515B4A0B4373513F5DE44B5088663F1B9D235681C2A0F31675B7BD215F95D42216FC76E5C93A2C8929163064A58FCAB39F6A8700820BBC9EB62588C0377C15BD74E5B7E4F11559E54EAA502404D245774A51F17A9CA804C570941434AE4464CA23D8CB2D042633395BB951DF71EFCE0FEB7AA66CB0EBC83321C73AAB08C45F89D8DD625753795B7BDABB1CC042A4EA7BEEBA6AD585ABE6849B63C9630142B7191742C772BEDBDA162F8B4101824D6F16D189D65446852A08B37F359617ED6B0F2DC1A5648983AFC78D3D4009BFBB088F85D85B551DFCB0C99B46C65130CF3A25EEA02FAD2159409FEA41A7F3BF71F020CE618D82E4A2D5DD005E1E8839EF6B43D864647D89502AC44A7517F0D0E9E06BF9F55BE677F11F7A4689D51E5DC4892181C32AB56A831AD8E8691C9DC7C8D59FB0098C7581BF682298C353CAE2242C7BDE5F5933B48E88624CFC605A87E401D4B01FCE73BCC86D9FDDE138A185AB4B79B2394FC0718A30D5B8FAB24C2A67DF7C57690E380B21B9BD08674E49328286D6CD82FD782FF7BABEE169FCEF38BD5DC8ED8ACB324A374F426B0D835A5A947627DD5D026DACB3669212EAE997EFA073A3800694A8470BA89780C06F034BD1ACA26229A7C13345B4514B3C48A810C8A017062BA454688349B3244A3022F86EBD132636D566A899C38D183C149E8C9EE50F7F254409A4FA45ABB9B74750B0FFE552845BD460BDB3FFBF6259FA6D048B59198B4FD2B135A9DD870881D24109F95CB1B0857B395683A40C358ADFBED50D70A8FA540F6006D2493B59AE4BEECC8BE3E70396BF298B2F49B468B64DDAF12FD0C594DC243A782FB8862B2B73BF1F59FF1B812DCE96AD72D73D928EDD5D6D384CF214C7EBBE25676FE612556461D465BD1D1C8AE96BD8F349371553AD9E9B80623B49D5C8C38489415ACE7DB17DEA495DB1CE9B68AE228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023C8C898A4A7D16063A2F7FB6F6C00EBEBADE4B5A79A9814803CDA526D542E0C4C44DAFAE06659E810969F48EAB6EB002F7938B62157E85E1BF258D2B81ABD9195EB828938D84BCD92C9793BDA17DCD6ECB92068BEA49626C4595EE621E192309156F9B0127FA44454075F7C73A94992400B22CAB60A056EED2E04045E74494017E601F044245A2B64B83EA8BFEF2A02A32029224D3C9F5DAE64E4A3298688C1E4205FD9038743CEF33B08CD9366560AB57EEE937008332B6A4224476A759B07D04DEB016DDB8EDF3665BA71053A894F98DBEBA95EFEE3F46AFB944601CC71C39315012B024E672E7CEBA843F35C6F435983AAB0F14BDB63B2D130A91AF9F72CDFD73EA39DC02AD3074F0E4B3780E81732B550B298998169B1640D80FD56474FF655A233E3ED6C48E5D94A4C6D31ECBB5257DC07F29D5A4C98177DE0A4DE1BE24D2CA3CEF4DD2A3FFBD818E75023732E1F1D3F9051AF6E8047081FE588E2492E5EB4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F933819140A786527AEFC7A872908B98E8356286485E2ADA68D8733129C32FE7E0D0B7AB63E890DE8AEC5DB2D52F88D328E1DB56FF586DC2026817A277844C18228D01C4A792C6D27D72D4E36AC852098685807B31A411B62DF550CE9C5080F1BA5CEB1634B8EE7CBBDA91DA660CECF740A502064AF7781F544A2A9F6527CB431A33A905262210B977C09374F03C360642BB200F00F13EFCAB19685DBAAAD7EFBD4D42A8B428342F44A61D9D58808B9E7620ACE2D4FA47D16FA98950485E67EA182414D9C7B78C51CAA4960A79B1BEF4B6BB5CBA79515042433C7505B5038C4DD0CC8805CB9C1AA93B2BF96402909E229C46A5C2C7CB18F0B7747642714BF204D42A8AF263AA6C8F1DED9414FD0E6586D7B680D4BF1CB6CB6DD90D63511150A76C2C40384A4F156E827A22D0D207611E84477254E492397A85643BE2EFA36371F9DF6119813B2CA7F31D099B0715927919FFABE384400D3AA0869AF2E95B525D9A1453679B1624C4F2718AF080BE493D1DF583843CB08C5FAC4587627805AF278A009530F8545958E7C04ECD445240A70C6D0450DE5A3F3CBE710E610D8EEEA17F97381119B8A53A62EF7F4B0D8F84BDC86BCA2245664DA120E7E36945038F7973099B1ED88113E6594EC0CBE05B5CF5ECEFD58D48FFE4C16E0F941FCFFFDE6D3E584584EC8A03AEDB6126EF5F479E4FE8C97BA01A4980F78D12717DF17BC4E9040B105B2D74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7566DC65863A7E07D0D8774305019C67D504E7FC4DF77A8821AECBFB762EF377DFDE75F24A9DEF9CA7997E8F4AF3B4E60071F11DBA6303A964B7F9C3FD443C766346B4B1E50EA1D79357CA76ACE991F4760184016A12C2368F7D4E6BAF0C8EFCF4A869F3973B41564F52D762BECBC7FA49B40D6FCA22052287E1B10DD8FA257423F984FF4CA38BD49F322C84CA37874056055B3A0C51060360F05BE3E1DA6E1829B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F3171151E6F5442468D000FA46F17DC7437B058242696056ACAAC06AF22742452798DA226D91074DEFCAC6C3D770DC54CF7ECE9ADFEDB3B421ABCD9DF305D412A71FC77801FAEA989C03A0D633C4B06766491F4C0DC67FF8DEB16AFC8BC7E3D41601BF7B964B91A8638DDB7CC08B68691D5D501B5D3D72915442F0D1B9EA4DE4A @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 9893 sm = 0000000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA70104A82ECC99EF0F9172F36D2B461A6515DC13666B7F1D917746E7086F99C8F1A63D2CB50DDA1EDFD708F002ABF07D0001C3357A70F6511884C4185790EECECCC578715C21A26FC1E7A951C54A30ABCDB7EC71AAD92F2662BC900F9E9A93054CF398017E582746F531B4697925154A22E2D6A0F1B81913438000C295153D7ADCA8FB21C6552D41F5F3865791CF993DD00FE3A036175178B6407E88A3F76605B5EAA51B83B77608A08C021821DA61962CFCC8E97D75441921D39C5AD537543EFBAF05BA4B0955661EA3FC882D9D64954405502E2BEF7D3063D36F993460D2557C79729E510FD11DA67C0C0D3B6448B88B96E0834210FDDA112F57C7B4FA60EC323321A23B8EE4F3EC419BA999054325BEB9B8BFCA6A2BBDF11FF7F8A170E9C5481D78F113C56F2E3BB35FE284CE8EAEC342D0D110591B00EBA3DBCD0FB7B965F199AA6EEF78B8184B2E355CC338055DD2A26DD02B1A0740CD15F6CBA4EF429254DBCD060C040187ECA41B2E544463458CAEEF75CA6EF08474060A8A1A356F1BA92EA6CE2FDA531076DF2E6296DD460D39973BF771E938FC21B05C01C27ECAEEF1B29C7329B6C264A9B24F73BD95BC8890AF4C36695EC8E2C29B32F4CEF4E02DBA54963C09D5F56674AB6CBB75352E7D87BFE1D85372318F051B955CA3661F1797D3C46191DCEFF06EAE14F3762FA5C231D3D57770F230802C2188D108FE326778A109E07417E807C087062711DCC7BBFA4B0D54077AD8DB142A191E6BA6BB251837447D20C4427ECD55AF940037B6D3485F6D6C7B3CDF5A5C19C958655A51A34BA73B87452100271944681A77667368E04F077001DD9B1454DA4614F631A83335A8C8953DDF5F0562A9D378DF36D061DCBEAAC8613034756516EBF622F21096E20646F3D05BD9D5F8679B536BB6D39792B28DF2481A6EECB9BEE40B11A10D39A90EABA7A25D6C3E4B7D39A28A65A5628A93556FA9F54E273B583F9A197BFF4731E04E7725CD11443807BC4EECBC46D46EC3D79A9C0C755A65AB867B1BA4B07FC1C2F151BE85B8E8195CC2F070BFD482702182B8A4A43ED942F6BD3CBF9DE7E8AEB17BE6840E11EDD8EEB095E890AF71214311C2811E2E07C1EBBEA8EFB786EB321559FFEB8219555DB545D7DA6FB9A32B0A8F38A664FABAC2918C2C79A154F293CA8B7BC5ED49FD2BA5A1CA39BFFC9118DF8EBF732962924BC11BB190413E9BA0C7EA2328C40E977558DBDECCB8D643E07A573A9CB5DB4518877320FBB4998BFDC59FA3DFCF5C9CEC2D80AD509A65AEF0E3E663B7F31BCA437311BA799D4C2ACC1386FB466CD5FEBEE9FBC50D64DB78AB57238911EF50154835A6F32A63B7723BC668B79FD7241614D2FED6D1E2E5795827F146C2158BE0A39E9556BCE1B08B774530628FD7AD334BD17A52436209CB5E0CB08299AC5D618A73889380D9D4AF03D7E689E09376BF39F4C562ECB1A68E02D5D91318EC0C91D38E8E480B8A0E65F4525BB4B34F69DE75E4BBA54CE08465263BCD35B6C89003D738D145B03E200113735C572A5E6BBC3E395E57FAA869661A2E4E12409A5E93DC41D80304AA2C5460A3C55F9CA097AA6C3B65C5CD659AAE22F412427C2918AD8C309342C8369BB454C50B3A6F2E555E150F9C05581F09882E165B19FF0F393EBC3AC3C842D4DDD647F96B48E4353B554747AC62ADD7FE15D0C5CBE5A0CEA51D5E9339C72AE9F93FAD05EC782FFE265FEB6309F643277F09495ADB42B4C362E1EBD6790AEEB0C5329F797D0A9FC8BFE30C11D7093D7B9A82A4E2A7A62A65FA32300FD0750E3B6D38CE5763DDD3FD0A0CFEFE8577D87D69AA8E668F66279BE02DEC2D05BBA330A504C68A789B198A28F6AD355B74455297DDA5CBC8B88DEA9B7AB7D59E2C78363EC25A2601906247CBEFF8540483C95BA2BDD8E11CBE540D0B6958770D798891C01C696A3ADE5F5BA26D69ED191B3B47599B1CF4E28004F8C1DA229C20EE36147369CE8C9EB4272CF4BB9282993823EE7F187D67EB5B220C01EB64244F80B74F3A82B819BE69444398FBE437D944C74C4A366503580CC17367118F5FA8F818D7903BD4C0C9E8CEE39FB9496CCB77190F052B8DC58C76C5ECE6F0FB81A47088D8AA2085533BA507C80E3BEA5C0A43536117479EF4EFAF26DEBE8B536B932C8726E54D309445E44D90F65A4EC5BA93065A2A731CD107EBEFA54AADA64C3014C9A6A25066075A718AFA60C9411C80143C846F4E65173BFA7B8E0E02F10ECE9CBAD48DA9E0916B70F2AF126A3DABA5C918B224DE444B8733E6FA601B3D349307E94583D0EC976E6BF9D49BB099E99E115FB80548BDCA3276CA7DD2F3200DA1FC5724E17D6332169D5C20AA99EDA34414373F438014E66E104843EFEB4D8C735C73A32E68E00D0F22790BDF69AB447551B814FDB4BC3FEE56516113672C869715AB940097C9F18D612C657CB314841775DF71EC753FD66B70DF8C75C96468E20AE8126BF8BF62D20F53E003B1D12EB97F7B0B9A2A8B101C3C30C8FB78B8BE3267E1F3149A49AF062737735846EF0C8EF26765413ED32BA0C4D0359151681DB165A82B25B9C5D7F839CE80CEA428581B6CE720C459D6D2961C5A7FA8256FEC4951B69C04FD5383B74580BC603BF35A74329BF88F2621953FAFF5398064AE5E95A44336EC46CE73B986BB677DE38EDB99E61FCED7CFB2FFE50FC26E59109A2F3A365893F037E2C27DFFB2756E97349C738E49615B3CFC7A7AECFFAE45EE75E4B94D35E5F625EEEA50CAF3D4773504CDF16EBFED64F678FB18F012193B1DCC67B722A5D175DF541B89B2327AA33BB2F01AA3598D08D6246E5D4CBBB73C8008D6EC423B27CEC92CC88AB2ABA8C222B35CAB84737275612307A060F36E3012E9AEA3B69196711BF0BC48D2AE42D887D10EDBCABE6AAF951E0A070D881879332064C99F8527A5EFF25241013CC40576F20A6467A647F7E679E6C7D146BA3071C18496307D2DB4CE99FD37AA1071D740ABE2895647F286260874BBE8C609165131481CD81E4C6D98293F1C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A14BCBE4FA64052B0853EDE00CD41BF95B66DA2A519216FA1A0A8BA5F10B4EAFD8BE62C40DA2A76DFD8A5EE8EF42A8B808C55A533FC488A2B33A935A635E24F3E0C717E2320FF575ADDB18C567B1333DECB0855E069D5759C48FE6D8C6A9D217BFCB7A9D40735A3151382E3456CC4BEDF6C7EC94F186FCB6BF9398FEC934714E8E231402FC7BD5153981C7C789B26208DDD77E4796F70D6A72B7B9C5EC75E4E3CD122F72621E92B1AC515A33B12B1801B2C3E461AF788661815E6BAD2E6472116B89B941A0E68A232089C6F831229BE2EB0CD244BE4FED78C8371D2DC614445C76907F4A3EDF18722BF0998FD03209C31C348CC79A2AD06ABB1B3CC549E73B206A05345EC801A1C5C42D794BA1A35747493D76CA8567B62F0C2151923D8D9CD2F37D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB385C19D6AC3BDECA5BE59F322A17FBAFF466E945FBB943BFE35854802837FEFEA3937069240712886742E890428C0C21BC057E82D5BB961095A5A18DE149CD19F79E9DC3CF0FEB5149F856C5A7BB82B6AFD4B5310993D9E4E1D33B4CC601265906186B98CAB4AF1570CFDC928C0A221A3BBFFE8E566D580A689AB51BB69826FA60135F60C1A1EA97CCCC9AE96CC93B66942370BCF910D916CBB7F87A0BF5EF46DFEBB050637754B0E40509441E19465B238EA45270D7BF5E0610A89B4A47AA821D9A3BA58127DDCEE4E7204C38E0EEDDFF72B07FA5AD8EB1FA89554D940C2C88EF588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE5966743689380FD336A081B8C7F753B889BD73F10345B8C4988A7A4C865250E3707A8424B606059E3ACEA75F2F732058477097D5BF8F5A2DF82E4AF0EE9C4BB251A5657C15808B7EF26806E2F3D61137B44C9DF4196A9208065ED1C70F9DCE3C75AFD719F14D79818812360E4709E521E78B983F99B31863039069D3F86FFAAF318853EB4A1AFFC5E598ACB6B15198E016C779BB7D77C54971E4566C2071EDFC0D19B41827913C5F7EE5D8A9411AB2706F3C9DD8E2CF4AF497765A647C1AA42E3645485AD6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291B3530D6094FDEDB782E1C927C11235EE632F6C3FA150DE1BC1125FEB330079EDB0733B58F1CDD3D20904F85DE31C06FE375E7D1E20F4C79484C5431A026EF8F5C8AC47E7FEA2A80E17256ED956484E9004BD99AD8ECD0D1EE5790A83CF9A14827C3B5D5C25AA18255F5D512917BC1FA868AF35ED3540BF0C10CABB267F612C26AE27DEDB5665A4DE3913AA2631C034C1BD22E5A721194BE6D1E4337D1CF488E9F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA498B7DA996B2692EB8C3D1D8BC9BECCFECC8EC67EE3A87DF5B0B9C7C887DCB0CBA7F5E1372399F3A4F4CC7DF247752994CE0D024D2C6E620EDD0B8CD30891FAF58D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB074AA6092A1F23DCD01D8B8C70674D55670C07A6D0655CF37D0516E6E1102865F0C53C5AF80A45B09B078337D61AFBD12DA2820AE45CC4B213C00576FF3D5FC21D0DB8D877757226F81078653EB4C90C0D2C7D304A6E0C4265DC3C1DB343202664008385964C6C56FA11532D7CF41E93F92EF28F3DE2CA1D5817AF2114A97BDA7F6504EBB2A6EE6BF4753274BE064D3CE467673717AD7350DE4E83A1BA27306F11DF36A2E30572E3FEF2EF6B2518419395DA9B7D4B191C88F3A863A477A2D226E5BCC04E39AAF1AA042A7B115CA26BE8DA52A162FDCEC6E511B1497FFB8B8AD23D3C429F71236DCAF9DE275D7B1D2DBE83822FF7D8C9BC7BA3AB5CB517228AFE2E30C53E64C44D02CF9CB51CE371827CDBDF798B1723B418EC7CDF66CF09F444A06DDB94355F529337D6A3178D754D68BE658934FEABD4F4874B11E739F0EE4E95D2D23B41F037B9668C9F74D2B3D31027861779FF8516A29246D766D2A61A02CD5B8E338B9630E8E0ED5BDACB017A6D3B89C8A1108E525BAD96E203E7A0C0B7F2148274FD20F9B53601F2B38DF303D7F8785D06260485D7507782E11855EA62F44C755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E695CCF3818C69AE16DC71782D99440EC9AF4A9C33FFBC728C9C62C47E0D37CEA661064246A8B2BBA14ABF5767F33E490AEAD721929515F091663B4437BDC34F5B15C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFFBD90B13035960ABEF4E3CFF91B9871E49B16A6F0FF86445C441921D2E698117109D810C864F024F62F8D25C263CADA33916763373D76EC8955ED113F71C40834E79A1BD5E21CC2373598C66168492FFCD083D2A8E7E480F76274C048719AFF98C5E2774BB1039646BD25A240875655A77023B7F884F5852DCD9C5DA173DACEF7F01F6527CB7F5375FEC1FD2D5C90A46D3D0501715B2D4CF51166226D8F35DB7A9ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272AC230107F230E29845C2E2283763A5832809AF2428C304C07CB21A96D7B7CDADF857F54C91A22B8AE6E4EDC0DEE01FA60697269BB1299F9FD7D3699D4D865A25BF0F31F93DAE1D51C42FE755219BC2A4B2505487483A1B81BFA86BF6A99642C51AC3DC78D5E42FEA4ADCC51C0501A8FD543217134694262E0FF5957CE719766EB0CB34CA2E541992CC2619C65822A763FE6572E3B33C4C8C216B4A62A13BE7FE6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156D49ED44C7713B7A50EEEBC575166A1B6CC3AEC2CA98398971F648242C35E8EAA21257BFAC587485D48AC54BC306344EDEBBF2A42B7E37B6086B1D9F54255742F000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F71C9BBD708D6DB1AB7F44BC2473A4897D83DAEA510BADD3ECC8C9F2E4F889D5AB62334F4B56AA20F9BB57C09EBF41BADB20D36485AD613C790428C382B437866A681635BB509C97D4AA12387C320F6CEFD1838459F0DABA3DA54684B83E3ED10C07B8CE62549A876A13D86D8F3D001504D939500462E64C94B6EEAEDDB8856D13AB345659CB16C8B977B6670208B70920BA34E31E6A10EC724CC6FB3C299ABE890047E1F6B3D5A69BF731EFE803088FC8D3B9E69DF3102AABBEBE90C3EE20DD829BC1C46E6764AA8C8E2396E4FD1A65A171D9EEDB2B04843DD2845B5E5F5BB714212BBF4237C6D69B1D61531257FAFB41BCD74462C292880AA396FDB392A42C4AAD9B5492EE4F2A076CEA42927C22BF7CA54FCA135A0FF512CAFDA620DA75DF70C37EDADD455AB3C8EB0F334679EF94E6ED2E8BFACF20DECAC68B3AFF3979869B755D1BA8476CF0553AA3B5049EB57DF8F00AC5DAC2C1DEF316793E5DDAF9F352894CB9E2B7C860E4D2BD42D0053B2BC8C7F3C11FC0DAF6DECA58CA37526095779A89119240A8E28D1D44AE57D7D3252B69192353D745AE1C066DB60F6C6E82F35854FE73C1C961A0E178F047DE9EC62C589C2D7E30929DEA6CE37C4042F04615F48FC178E8CD389A2DEA13C83E2534271AE7DB54D7C89B8714666381C388D37BEC8102F8497D8A820C70C47254582C5C27D3D97A6ECE379315D5520BA346E8F5B5F7887F9E3E44FE4C156E7472EE8D9C327587A0704A8035E519B1C4A9D2E07949F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DB9D6E9AB3A0926402DD8095AAFB46217FC41A2E0D7C5960C1FC814E461B1F1F219CBD0A97D50180BB017229AC9F884896F357900724A3A7A8E4D479CF6A093FC30778F755C63CF618073C40F6042FB2143DECEE8DC32CE9D3E0064EE378F78B8F945A05629C118D60A6AB5DE2DA55A06B7325FCCEE42C01A5C408F0291E3610C44684BE1F66D3FB8F6BE43EDAD2EA87FAD50C993CC447DCAF79AB19DD406B20974363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D024DAFD78B7F2D3B3C54AE60062DDCEEC2BF3A579A53E27A72402BED5DA1678158142C023B3C238A93F3D1CB8E48EF84C168E27E6645DC6DC6689E89CA0A74D07087B760743BB526662636725B7FB700BBC0B3A73793C291EBBBCD4970B27370C2E85E7BAC610B75AE5CFA9DD39290DA4DADF4F61BEFE0F87959174D2BC28BD76B780BF58A5656928CC6684D80B728FA0C1570B8268DFD57EC9168CF7D39997BC8458A5D4126FEB278B26769C4F55EE77EBCD778D00F836BFA6EB13307BA2D7417B0812FDA4CEEDA359BF73865982622728D7EA8BAE1620A63483DAC957E4F8E082588E12FFC57A2871119AED0B43DE4ED1EDC4AD6434A485C64D9FAFBFC7F01A8793E5649BF33A7186BDBDBA5DFEEBCC16F2CCB67E355774B8C32B932119DA7158A4D131F560491BB42B47C9EF1594FF6F09BF29E972502A7D62A2240FBBBE55C3D82050B374EB42E433CDBABC163A95A6492A7F7DA6824B5A20527C9D0933B97C753932ED9ED277E40CCB8C4A042FD5B88E9C5D569A48F512ABA1DE68C821BD20C1A995235727654ED6E59B063EBA5F4046E7D047B886A22A7D7C5BE009F3E14629FFB78F8555B7376AA2B7B4B360F0D3C295ABC2590CE1AA36943A46379C1085D66FFE0DCF3C37C89BBF1C7D76B6D62D5D2D265EAC52164E4799C52D9A7E67836B66532608870BCF43815BA0633B82CF8E92FDD0A4DF829039370202BBD93541D4D398C42900F96D70AB85AEE46D4AE2CDB5BC61B0E57DE8AF9BC4A366730CC4A8443203C374F1F58A2203BACAA6A0C93783B0BFD8E85A869ECA37AE0FA0349E9A943B50EA190BF7E28B4406FC4B14E77203739F8DF7D168EC43FE06D0645ADBFBC26542CD0335EE21852C8CAE8DBE734028D2F6BF457CB086172F176456A64E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC40509461C2CEE814F7E26684AB01D51A1385EA51162E9CE43172A1564809B328A45AA68BC14BF38692467DE23B8908FB07BA05C90DD44A372477233DEEC84BF89287B1F8E1FED4F275FAD98265AA76F0D798266081567140ADAF2A9C64F41E053D1F329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB03F8A842A1FF048CFCF92A8D77409DE43CA455C5ED59F89358559BE214EE1B531915180697A948C945A9924FD6864D9CFF00E1D47F38B54092E4CFF1F92A65CCABF206A7D71F25A66969E37EA7D52EFD74B80E93CD7A048F71EDDE1EAF82A24F20145528EC96BF1857E0F1D8F19812EAB34E07D4262D195D1BB4D20FF3E226C2468B90E951C8212023248340ED5B7E4EDF3C6AF6A6FEE63F8DE613EC6F1526E3F6A9327A17C2279BEF50B6CCF1569A86FA56DC4B8866C365DC5D16B9BA888234D6860885B2A420401C0E3F8A971BE2CCF46FB27EB58D6C8EDE207B703FB7EBFEAC77465237E1EE73B675C37F656EBABF91BA91A79FC679C5566A637F6417B8981C93D4B2B08DD6DD375D4C84791CE66913FD4E3D6B01287F258E8EB01A223CD222F81B1412BAD3DF60D89E29F4FCED352A1DC0D52A296D6D8145BB66BCC936BAC362F309AE4520552C369E4BBE918F20C4AEDF8F037EC9AE0A3BE8BA1BA0CBD40949CEB55F41C8728AA639789BD51539F1AFA46F71106F428C9FC659F34F6BAA879DADCECAAFA80505AC2E0ECBBDBA3679A483BC7B92A54BDEAADFA7F386BA0AA79EB4AB02F6134488DF1220F8FA56D2C14630DA6F79094DFEE7180D218C621A32C153D6E5AA82C318BCBEC16FD901CB860793B8B3E9E357D0F008EA80BADACA56795A369F5E6F910F706986E7F66A84B100C265BB5339972BBDF6B770B694B8D2DD8323E86A90E83EE039AE031A331E6D7B99E75FDE0E8E42AF855F52C925F1DE1A2B10D241ECAD1523291D88D5D0EFE1D5CA4DE89F22AB2605BB5AF0CC6564C2F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549619B2CE208EEF551E81A9AE87029B4302D012853622BB3BCD47FBB055E048923FF9ACD043DD40211F720396E02E71DB06FCE4E8D757DC264B4F5AC3089FE49361710B3FEBAE56D82E67A6C29504D6B061DB48FFCD3AB91E7B6B870AF8042312735EA06532FA075BA5DCCF6C9E92AF59BAD50EF0A3797C335F50FC43DF22481EC203C13BEEEB42DC753BE45EC74C10D40CFB3D55B68602D288855C63FCE824A2F4A0FEBBCAAE5A19E133CA77B6C4AFE98FA12CFEB1A87D38463C35DE33D5B7D2E08C3DAED2A32A25502AA2B4E2F2A330F06294E202466F0701D4B361C71DB74253ECA3148CC5E1119591830C19DE38FEF1A5F9302B766F68E4E6616611EA940522EE92E6625C8783357799CB4B9F6A56A84976EDB84939B94A676D4657DBD04F7D754A901CEE47AFF04327CF6E0193DD3EF8CD61ECAB28CE8CDE2A56ED422C47BBD5E4B1C005EFD6C982E1601461DFE8EFF46797FCA8B79156473C7A964515B4A0B4373513F5DE44B5088663F1B9D235681C2A0F31675B7BD215F95D42216FC76E5C93A2C8929163064A58FCAB39F6A8700820BBC9EB62588C0377C15BD74E5B7E4F11559E54EAA502404D245774A51F17A9CA804C570941434AE4464CA23D8CB2D042633395BB951DF71EFCE0FEB7AA66CB0EBC83321C73AAB08C45F89D8DD625753795B7BDABB1CC042A4EA7BEEBA6AD585ABE6849B63C9630142B7191742C772BEDBDA162F8B4101824D6F16D189D65446852A08B37F359617ED6B0F2DC1A5648983AFC78D3D4009BFBB088F85D85B551DFCB0C99B46C65130CF3A25EEA02FAD2159409FEA41A7F3BF71F020CE618D82E4A2D5DD005E1E8839EF6B43D864647D89502AC44A7517F0D0E9E06BF9F55BE677F11F7A4689D51E5DC4892181C32AB56A831AD8E8691C9DC7C8D59FB0098C7581BF682298C353CAE2242C7BDE5F5933B48E88624CFC605A87E401D4B01FCE73BCC86D9FDDE138A185AB4B79B2394FC0718A30D5B8FAB24C2A67DF7C57690E380B21B9BD08674E49328286D6CD82FD782FF7BABEE169FCEF38BD5DC8ED8ACB324A374F426B0D835A5A947627DD5D026DACB3669212EAE997EFA073A3800694A8470BA89780C06F034BD1ACA26229A7C13345B4514B3C48A810C8A017062BA454688349B3244A3022F86EBD132636D566A899C38D183C149E8C9EE50F7F254409A4FA45ABB9B74750B0FFE552845BD460BDB3FFBF6259FA6D048B59198B4FD2B135A9DD870881D24109F95CB1B0857B395683A40C358ADFBED50D70A8FA540F6006D2493B59AE4BEECC8BE3E70396BF298B2F49B468B64DDAF12FD0C594DC243A782FB8862B2B73BF1F59FF1B812DCE96AD72D73D928EDD5D6D384CF214C7EBBE25676FE612556461D465BD1D1C8AE96BD8F349371553AD9E9B80623B49D5C8C38489415ACE7DB17DEA495DB1CE9B68AE228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023C8C898A4A7D16063A2F7FB6F6C00EBEBADE4B5A79A9814803CDA526D542E0C4C44DAFAE06659E810969F48EAB6EB002F7938B62157E85E1BF258D2B81ABD9195EB828938D84BCD92C9793BDA17DCD6ECB92068BEA49626C4595EE621E192309156F9B0127FA44454075F7C73A94992400B22CAB60A056EED2E04045E74494017E601F044245A2B64B83EA8BFEF2A02A32029224D3C9F5DAE64E4A3298688C1E4205FD9038743CEF33B08CD9366560AB57EEE937008332B6A4224476A759B07D04DEB016DDB8EDF3665BA71053A894F98DBEBA95EFEE3F46AFB944601CC71C39315012B024E672E7CEBA843F35C6F435983AAB0F14BDB63B2D130A91AF9F72CDFD73EA39DC02AD3074F0E4B3780E81732B550B298998169B1640D80FD56474FF655A233E3ED6C48E5D94A4C6D31ECBB5257DC07F29D5A4C98177DE0A4DE1BE24D2CA3CEF4DD2A3FFBD818E75023732E1F1D3F9051AF6E8047081FE588E2492E5EB4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F933819140A786527AEFC7A872908B98E8356286485E2ADA68D8733129C32FE7E0D0B7AB63E890DE8AEC5DB2D52F88D328E1DB56FF586DC2026817A277844C18228D01C4A792C6D27D72D4E36AC852098685807B31A411B62DF550CE9C5080F1BA5CEB1634B8EE7CBBDA91DA660CECF740A502064AF7781F544A2A9F6527CB431A33A905262210B977C09374F03C360642BB200F00F13EFCAB19685DBAAAD7EFBD4D42A8B428342F44A61D9D58808B9E7620ACE2D4FA47D16FA98950485E67EA182414D9C7B78C51CAA4960A79B1BEF4B6BB5CBA79515042433C7505B5038C4DD0CC8805CB9C1AA93B2BF96402909E229C46A5C2C7CB18F0B7747642714BF204D42A8AF263AA6C8F1DED9414FD0E6586D7B680D4BF1CB6CB6DD90D63511150A76C2C40384A4F156E827A22D0D207611E84477254E492397A85643BE2EFA36371F9DF6119813B2CA7F31D099B0715927919FFABE384400D3AA0869AF2E95B525D9A1453679B1624C4F2718AF080BE493D1DF583843CB08C5FAC4587627805AF278A009530F8545958E7C04ECD445240A70C6D0450DE5A3F3CBE710E610D8EEEA17F97381119B8A53A62EF7F4B0D8F84BDC86BCA2245664DA120E7E36945038F7973099B1ED88113E6594EC0CBE05B5CF5ECEFD58D48FFE4C16E0F941FCFFFDE6D3E584584EC8A03AEDB6126EF5F479E4FE8C97BA01A4980F78D12717DF17BC4E9040B105B2D74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7566DC65863A7E07D0D8774305019C67D504E7FC4DF77A8821AECBFB762EF377DFDE75F24A9DEF9CA7997E8F4AF3B4E60071F11DBA6303A964B7F9C3FD443C766346B4B1E50EA1D79357CA76ACE991F4760184016A12C2368F7D4E6BAF0C8EFCF4A869F3973B41564F52D762BECBC7FA49B40D6FCA22052287E1B10DD8FA257423F984FF4CA38BD49F322C84CA37874056055B3A0C51060360F05BE3E1DA6E1829B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F3171151E6F5442468D000FA46F17DC7437B058242696056ACAAC06AF22742452798DA226D91074DEFCAC6C3D770DC54CF7ECE9ADFEDB3B421ABCD9DF305D412A71FC77801FAEA989C03A0D633C4B06766491F4C0DC67FF8DEB16AFC8BC7E3D41601BF7B964B91A8638DDB7CC08B68691D5D501B5D3D72915442F0D1B9EA4DE4AC96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A3928351163E04D8BA817C168A0CE68CAA6FA744E7E30A2670B2BB88F27810C887E48E90EFAD40F9735B5767F60EC515C146D56EA534C970E04BDD10302D85A2317C478BD195FC93499C051F5AF61A6C5CECB89A1D67BF5BE2CA7EFBDCC20B884597EB2BB0799DB9B86E2EB8FD93389AB91A391F2D68A057FDE361AC97A87F4406F40A7EE2E7709E46DCD756617DCB0DBBF43E6BD4851F3D834BB53CB150D2FB7B remain = 1099511627774 -max = 1099511627775 \ No newline at end of file +max = 1099511627775 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-8_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-8_256.rsp index 395864aeff..fac5a0f156 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-8_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_40-8_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHA2_40/8_256 - pk = 00000005AF6E11950B411D09B02C47AA513FC66675E96AA47C3B284279F9543FA23A226804562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 000000050000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94AAF6E11950B411D09B02C47AA513FC66675E96AA47C3B284279F9543FA23A226804562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E704000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF54961000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113CD47F2466A56323209409FD7FCF7485A71CD8CE96D61298A20473D9ACBF99C010000000000019AB3950B30D3E7877159B364A25B214B41B8AA32E293E2DDD44AEB7DFC560A82020000000000019C359D104347B69607EB28A02E6924C24BD2A26DE4CFFF3FF98E48688E291E58030000000000011EC9B78F3B1189A5482238BCF700922D642E45D07E7EA10833E31A4CBC3CA08F0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019C1A7BFD8300283215BA57DB5CDD95EDCBD04E1C41419317BC2069C2AAAE22130100000000000143ED646E32FC21554D8DAD350C5732270CC220F7E264ECB5B7A8E8A4586D0CD002000000000001762D040EECA13E137753604D099809D946063368BFE1C7CF0E6549FCA746F7C6030000000000015FB7406F1B25A2B4A6A1666269772EB08D6FE78D8A8395C56AD80FE6924DF082040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044E3C9C3413B4497ABA623AFE3257572D979FD7234C04292B8EC507187752446AD11D10DE925035D368AF83D202AF6979123C7F3B7FCB8D83812728A890B5C09B482529FFC0737FB59C35B552AD7C5820E27332D2E44F2A31ED972E2E5C834FCC652204BB401557D6FEC656BD9F63B9226056E2D025988ED1312A2A767D418F1342BE489B463AA4BE823D471648D9893364758DACBAA63BED8B3D8D4DE1E4A7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017F7DF0085A4DAADCB03AB4E8241B0E6DC05E727E817C3B6FA27F05AE1FA2DE1601000000000001BCF2F650C31EFD6F2F09775A3B4F87BBB33AD0D51537DAF37E0D1C1AE8BE8DC00200000000000174F4FE7914F390776AF328164E738CA8EB0751EF9E535BB1B0E80B05762E683C03000000000001241535B940156367A4ABD922871FB10B37235B67CA38CD8B2B02AA8064C5CAC60400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D4FF586D6CC300F09F878FF5FDD7E7BFD0AC3AA2AEC0C223DE23D190C6F67AFF7C00001F7DE39C907235BF8D5EC16A34AD2D2E6DDC419F5B24EACE1A17BEF5CC52AAA05F04D5AA8BB018210354282E98DABB918100165E7D962A6F396F22753B1FB928AE3576A91CE62216E9E6214ABFF91FCA2E6E77611AD13F70CC87E67A1E6D886120CD2C2404E0312A57635D1C2524C97EC0BDD9DE011D158F8FCA7AD1A2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000186A69EB284CFC56C72C2C83351D5CCDBEC831992175BC2D2D91B3F9378E0DE9E010000000000010A318F954C197DF2DF39A85C4B322E7EB1B16B0B4EB8C8A492F4F3B904C47E7602000000000001A9204F8E84112663772797AF87ED34C559ED4D6D37E634EFACE6A18C700CD53A03000000000001D2E20083FA11E157A2E5B72C9A986D3F47348E54C1935F48A86F7A9D78B2BE600400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6442DC6DD49889C3DA3AAF0FB310C3AD990480EF12059DD23AE881D5A72603F50C7C61626AB2E0BF9C8C198CB0F637EF72954E04DF5956355147B5073EEF3848CE65EBA73E67955A1CFF187CCA758372FB67823E230B05EAA9982488E8D22F6DA1415A731BD0A2B036F858FE16FB4349149B507D9DF770B9F3D3B45ED752EE888F40FEE65C4F3EC6897906303A19863DD968C666AC1980F26D8B574D5A16C95000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100132C90901F97161C5614019A534B035942B26ADCEF40AB97BE258B03C87585010000000000012BB35E6F2C4AE0A3430CE207629C011B30E4C6F5D6BDFF2AB750EA0C69BE95C1020000000000019CAFA71D2E43D02FBB0C55294A6CD0AF3AF0816F6E6D1F4022AEFD413DBE8C1E03000000000001943191FF197E71722D961AF04F9570BBEC438A6D22058F1018F6C61F3CED67E50400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000290F4FE6675D4A1FBE8A93A91C6B09B1456828554CD0CDA039569E2C08430C3481E2970BA760DA29C31944AF18085694530E8A952B54516062CD9528A95D0772323B4B8E02C7DCBD71FFD2236E772268E25F6D4C622F07F5D437275B2FEBECE7605967771BFA2007FECA33154FB46A3B788E9E7702F38BCDF175EFE4611B61147D89195BE90840FB1E365A76840BD9B40C21949F2D41205A491C019B7F49139C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012A13FF51186CBFE9467BCAB51417E5129671EFD5D0D686D09E2C5BB683FD45450100000000000184D0629348E528473585F873A1929F01BB41F19090B770D155E497E4AFF30A990200000000000163EB4A114558605E9DDBDA75D10B78F28322197D1DF7FB4214438DA12328F8F203000000000001B86361D142F7F14ADAF4EC3E307CA82B6106FBDE3777E656781187D3558E3E1F04000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009D550F851D023315BE35A69C83D099341F6BA69B6A40E224DC554A3489D33729C9EC8196BD665514030C26AAEF80CD6E1BB9EC739BAA2B8E4A63EE691AD2BFBABDDEE2B13CFFEEAB7C25273CAD45409B5270678CB1535AB800679906CE77189DCFE05BBF92FB5E31F184CECF3C427437958F695917E343ACF46DA2B9D988CFE316313FA9FAAD49EDB72B007A7F3D6FC55A88E6BA784FEBE9737803AF05B4801CE0C723C0D15CD8E7CA8E237D4A1C0BB1413D369FC3F21F69205D428069EABE626B971A2B5698ED05BAE54218300BE8C4BC9A52EE5FB296BAF2A9AA42F3C865DCC1DDA69969F085C91D3CC5934567476EB70461B942059AC0F83BA10DFE783F5FB405F159563419B3F5699179D6F33AD05E840EC9227C592E361A49E31D99445437D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB3844833CA9CC7907865878A01BCAE7DB72BA4F7701F20523E0E98B27AF08AA747B57DB1DAAA1B616DE469C7FC83CAA1DA1D6BA6F0C2B0F7F2CB7A4F58FBF7FFEC292AAA7FC3B87E797DCA067ED7672BA9B4CBC27FE9AAEEA63C8569A567129990E1E12A8D23039A877F7FA3EA9B9359A842A19E33CDBF284AF95FAE2A2DDEB80030A8245A7E51131D27EAE94B6C38A8C4818CA7EAE0A1C0841E7AACDDF68A4C4491EF97D5F3F6AD8CC47D2489DF1FF96B7DD444D31DD2FFFDC69C9ED7F750526B3CD81EDEEE2CBBFC0BCEBE875DBB644B3828795D2B81DFE37E0E4E68F9A798E09588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE596674368D1D405B742EE812FB88947D9F5DE52083777E54C2F0A1F605027BCA5A12BDBF9CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318ECCE515F732608A96D4E557ACCA60F144A212276CD52FAC0F12C39F7F45565346B6EE409558FF37D5C50280099C9D75B688C7D873EA7D07EC6C9305AB367ABC2FEAFF9200CAD14D71DE9E1F1DFFC4F15FD0908C6687F585D9721AA773BDECA4C7DBDA2D8275C59A2E90EE07ED6734A09566174D695356166041C646F18180DFC5ACCBA61F1672213C3CA6933A5ED65898AEB4BAF534751900D2CF25A7A94C273533B8694EEFB366F4B3E6D4DBE7FF5FC70EF5341217906FCEC863502598936A4A0D7DD4267B1C0C6E8175CFB3B9B6BA86CF3094D4677BD57712235CA8395A6914063B4E2849AFA406B7EC6E3AE39B343EE39348D2D29A0C2319BB34655A53E1A816CD5FBAD3A3796FEF2C7B67BE4507438E5AEB603B1A0796293A274A3F3D63C7C1F14297987085EC271F06E8DC986CE41DDA37ADBB39613E6790644A669594AF10B5D7C2DCDA7190B03F77E69D79A143E9B7D8B42E18E56D1D191DE05D58DC29F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA4C86ADE353F4AA57DE2220D13EAC9BC8FE02D625EBE3BF2761493F180F968DE438B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE8D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB07425116F11D430A927D45FBAC134C59EA8E5907C35A59E0CF2FA548F9AA27A3530AEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBE6FFF1A2A91E8DD23131A7840BF7CDEA3E18E706A324AB688A5866B82EC18082D89DB83F78DB30D5CE6EF134BBCE7628AC017E6D6974B1D82E4227235AEC9862899B7A4E0E8B10A8AD0B19A54DE7ECA861D6AFA1D91C9CAC7B8D6AE536C458E176AE68697912D7EC853D514AD4EDE982FA89400CE895D3241E5610D0AFB17AEFE51FBB41E2DE044A00D84BE759242476BC0099DFE159F0CAF2187BB311DF2342A59C003778A56907F086C8DC9309D8E41703779C8E1141070708E02B9F987ACF3214A8E442B76121374DD243643D64283D01279A49154760E3567E46ACE89898BCD67842223D5B8CAB03DC13930BE7210FAB7FB2318BDCD92B642F6BF178BC30B4F959F5D8BE15F67C5AC4A4C81F1E3E707AADF0B4CD02982ED4E4E52A81EA2FCB60ACB5817849D53C2FFFBF7906E290BF76E505071913AE0361FDFCA4B279897C9DECF546FB0366D65C9F81A9B51402F3694F0B5DC600B7E4F084383B643AABC755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E6C007F614D3C0A2E45486C2E457C2E6636BC1AFB76B2A7FA351FD88399098C64E379F99B64A3340473DD46C11564937DB9A28C4DE3745308433153B2BC6D5E0D515C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFF0116375D404211C3D3302D17DDD0390712E06CA05FB4BB2AF749D3439A5B30D3E9FF4731822AE6607BD96108BD229A4BDA5ACF50F7185BD1C0F56CC56D69C008077082C0869F237A6F19D73ADCF9844686E3C5583E7D8FFDA636E70E989B1742ACA4DCE98101BBAEDA8E852555033A46F8DF4E3DCA1B9A09E9F938E0C1E468C52F7DC695389C21D0F425B4DB554FD5BE1FDC2765B997FAB1F94D864DE1B4C8FB1323A8D90DC0CD7FA7363AB70728FDBF33C2325FF97C59ADC84C104E730C85CFBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272D144DEFA2E32DCBE8CF7843CBDB9A67EAD7892ABCE9B25A6B91AF0B893846ADDDB6C26354D4D8B77B14FC2FA2D8D589237C4BAF80344C306439619E5A4DDD4630B558BC9B3581AB842BC8B630F232BD18D4BB10FFA1DD3805B18635F6A9A22CE0D470FAA2AB813662EF63C784628138499A1A3648CC877300401E61DA9A379FDB3FC6DD985CA26EE8093A24879BEF107C4D6A38017BE3AA5CCE124259C42519C6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156771072191C21BC3190193111CD3BD0604EC5427C6D70B1BF21DB6E59ED636342BC417CD9F69B804EDB6359C9F8E347AD253370E065D500CAC64BFABE3E420E39C27D20CB93DA243BB3270F1EF2DE68AFB80842E8BE7C1FD48BF0F5622530CE84C1D30BC69EE1164CC602F2522FA39158D4D0D30ABE4FDE43213ABD6E4D65E62FBEC9AA1D485599FB7ADF5C2C97B90C82A1DCCD2C44ED66CCE79EFCEDCAD0CA1366FA51DD03DAC9BFC60B79719033B32247DDA9195233329F5AA36627FCEC5E42F078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DF657C03A3914FD3BF1E82EF96AD7EA46373B0A4DD0F5655F22F754DCD35ADA89358DDAF6AFF78EEEF21010DBC6556C2C3A018E4DA1D612CC3EF237BC2B1E9E600D923E2CE04FA27CE8EE63B969F6079FF8551B8C06018E99D84669C059AE08081E3A1C7ABC19272D7FA3F2704CCF6E491AF93C7CBD4660410389D86BBA47BD5A0E996F788FB9CE600AD76485D265628019B57FC69631D5266E8E46913ED9142FEFAD87E26DE53ECDF43B352EAC14BF6DA899058228C9414E7323430F9357D6244E7165F5CA2FF2DC9899AA6D8C2B8DDE8E2C5FB7C6E02BF74F578823CFA2355F2FCA1F776C6A87943344A5E53BFA39559EF98C397423C75EB318EA9B5F375C17E7B46A8D592651E7D50E70233224592389C1EBD1EB66678AC42C2862A2C660BACD03BA4064EA38D34A7D44B32DB9E75ABC6B5025B504DEC60512A80F78876C54D36324C7143FEA85ECB9E66800E8F4004061EA7607EAB964DE3F9A273D2C7A4CECC1B4270ECFF87A254A139DEA1E0F0B0F6366C02A0A790D46EAC94866A82DD8349F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DEA67846512E96901F78E601EE427F8B1A7986FB8832D091D575C277CB202E87602D670CE131CC6023A9E83AF41486A04D62616C1E912D4EAECD5DC815BAC1C0DBDB347F6B5DF06B0F58441FAB98B9511AC0423ACFA43E0422A62AE32A48E935C6288BD0D2314C6A739A7779BFE24DD7E2D66E9C4A4111E22481688EA39F256224531ED241A9D35D395F340421F2D8F5C05B873052D2128CEDF4ABE49E609176674363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D02AB14858954A117C6B6F2CDF4823BEEF1904FFB4D841B30537D57C577968CDF18EC8631C536AF09B54D5887FC0EB11A70E86B72EF315FD722FB680EF03A3487434215A0EEA412C0D78DB2EFE20061576237453927710860F0A49DE0ED0C42FDE2A5903D635B19D4F2001EE353D7B5210E1C01F50251ED6E753635A972EC8C1914E36522B1B41BA51E9F3F1CE83BB5F526FBEC31C21983736E42EB7880B9B27EF6CAE0618E57F881193714D3E8B38C9E9056378DD79E78422BD7C4CD57D230EF44B38F6A107ABC77B8D5A953D3A3969FBB7DAB145C4F4615FAF8F2172AA2BDEB35C4A0494100CB9CE188DA4318EA5B617EBACE910A32F0A280C82AF82121720569232D71AD065E45268B36F92DDA13673529F24E6B83A865F3E266635D9655C8000C06478530294DE092640DFB324E09DB3B87497C94502BD46092D72DAEDFA93A0353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB51691B3F0ACA92B02FE916D2AEB98BD9E23313F49A0F44394883A432523EB5B34B690EF9C16B4D60572EF2D791F2BF403255A28D9BC3352B02687AD9200D34C05259FE0C93B75455218E031D59A65D4F571CD7F8B130A0CA1363BAF2D9895A8E8925ED20ADBE8FE96C34A6A13B9318AC8A23A7EA320B83B7175FB54868DAFA9E233B0F4B18CF6FC7D85F7A2B28CEEC561222C5051572B092F2FB269ABF1CC7826675F09949FC443EF723AB476E9E5D670C5F05E46DAE93837AA0F65A4E83AE2C71DD02CAB1038086531F93E163AD65BD962ACB9497C0F268876B5AD3CBBFC4C24EB2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADB0A78B6C1C4ACB8B4C97EA8C4CC3F3778CBF761AA653D9531216588A46701366E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC4050CBFA6FEF6B9FE785A59511CCCE21EC5AE3F429A07B4626A4F0C555A15B42C26A5F353E7A479A700595689D5734C39D61177AAB2943775ADAC879B4ED7B8ED826CB43881D2C1B5734F64A5490A4F77ED4DCB9775B258C18182B42C560E6CEE89A329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB041A19053D3003420EC262BF0F45F1C7CF6E55BA9001E4BE097329CA460D335BA899503CAE0D617BB7FFF0AD37076C91B1659BD448C05C49D9360462B4BC601536844FF2C635BB654EC5749FBCEF3288E41B8A7835B645E0BB501FF805EA4B39785C203BE03F0B105D17E513D50B7738E78EC18AFAB3FE134FD551E754CAA189DC4FA2308B6EED1B8CE87EBCE212E15E72C9516B778C1F62819131E2EFA7AF63BCF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0A2979199F43F2F59FB2C62E8AF2EABAFE9B89B71E75AF029BEC77A6A56F86EF6A4A7212A7458986D2DAC9E00CF68EDB81CA05A297B522D3CB2E0AC3146E4638995B683EC201C67C911C83E6BA3567D31565DF914783F41077E2C31B06640446A6D403F9D46BB9D00B3C436FE1FFDA80AD0AC466AF0417D18D5E7DFEDD7D68987BA55F545F3B89A38908BCCA1DACE0B89FFB49FBA3A67EE7384DEE68FD05721483030ED53913A6CFA059DDB451C780877E919BB86DDCA9E18814123CCC822A8F30D0AB4602815D2279398ADEDE00B23AF4EE605A771AC616CAFFCD3AB12991023A6BE6BCEAFB1672ADA631C6CC29827088627EF9380FFF46FC479E2B586432B58F95A824C0D5F08704C2B596A7BD0A36A52BFD8C14D999F92E676C83EA62DE54C3ED7ABF290BF17C48DD69F949668E11D957299DB6920D740252A9AFB65179FDD62B69D2A1A339CEF805FD258D83FD2F406841565AEF5E42ED7687D9D466E6A4E513E072A9EF6181016DAD988F7C2305A77740F196465CE30A35BF3D098781DBA7285753A9438517AA7159A9C806A19CE8B8BA5F9C99250358404671F36214E8A7B5A04767FF8C094A3CD74751835BD896FAEFD1747DDFBBE79F48148D56BF585CB0CBBF34300CBFAB9DB32469814F107EF7822151D158CAD68F01418F88B181B092970DACAE4D5DEA7AE39965D1929CBAB7685E758206D309CADC07687274657F6EEF56A657D3FED4D34C7FF6C9CC5F344F0EF4F0E752F83E06B8A23DA0D65A2C10C2D675CB3A214F5D363C35E6E10A1323579803E4268F7D868F4716BF849B3C3D8EDA94476BE7322891C36D6DF146075F11AD02434D2216351CC26600662BE0D38E1DFEF9A832B9F066718FCB2134115F33717B57936CCD2DFA3A95C1D4C4C98BD09D64EC04912C06C7C6A2FFDCA2801628D873EE6D0D43EB67FF0AC93A7666C9ACBB9400593C00316E05F0F5706ABD923D85DE72A0D1CA9F0774F5180B65AA578B95BD20C1FCC322A5B23995ACC9DC97CE3043B1A723AA2815314637B7667DE02ED0FA0924C0791CA09FA028633CCC594429D6E7429930C7F01EB6A134952E89B8CCEC743A23C63CDD9E161B5A2D1F1E0D005F16727A3B0E8B90C20656B850A4F8B5D400B65E91E45AA25A880B76BE09F226DDD4F0E0AEA00259E19634EBAD387CCAB556997A153D1C1B87AA62E5B613A5E02C65E7EE7DDE2E19D965D27B42AF8542066549A6FEFF3E10A93B349EACB843759F5E4EECA76CF82277BD55C57FAD09BE938ABB47720E49CED626AC860446B290C7FE9BC83DB0C7FDCBD5CA2B8FF6C52B2CF2556040B3792BA99DD43EDF1FD4CBE38970D235E8BEE40DDCD2708E432008992D3F9DCD73AD594171092909019E9BBE7A5D4A21EADF82C5C22D877F422EBC64734717C93A027E9EA7EDADFFBB8A04B465E2F1BDDA54BA30963A41978562C27EE91E8ADD7A95B97A1F9F5C0494C3E44AC5422759F971200B1927F5C37B003499B213C1CEF1823847ED4A308D7D98FD5E42115D49B1FD42C7405B55437E1C8C0226884DD801CD89163AEE8D74105F621EF2CE222B13ABBD14078943CE054E3D68F7E8D763948CA83876F0AB7CA5123ABA8C5F68679FCD116D03391F2A53F637D26EC486FF6363F0C297E1A672EB717107ED9540C2AAD46038F8D4C2B5D1D918AF6BFBA7DE46E6628B2C217672257EB98F585A4E4CDD87729BA5ED16719F869FA1495302E8BD043F92ECF8799DAB7B9C501DC956EE3E55FF30E6D565E228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023E10A68B5275694C30FA7BE9BE2392EE6B18651980A01348A97C4BF091DE3501B30B528092599313ADC93C8407FB07E740F784E80461A23A1DCCD78BE8A72EE2AD69CC6E63F385963275DF49AF300E5D468285CA4457F090504D42056F571A8D453903B85D7E63F893431A5A1C8A66A8E4C999F0592D75717940E296C8275952C4A8DC6E97B3D5602408DF3644E8A1338C856296C37B1BA8445883CAFB408EFB9A545AB53CD632C40659DC607F4937A4F364F7E3B47A907BD30D8558C76A8EA9EB357177B8B2639477433604EB74F9C2E3528215459533C1A989FEF107944FC8A402E29495F72F2C210135FD836028B9E21E76C6F13096DBD2BE9721DD2C35504D648C474907FFB896B014CB022942F308C3263CFF227D4444763A483658E728EE6B7954C48E3FCAB1246CED1B1E2EA9CC4D5475BD4FA43FFEF56AB2A2D779E9D206E3E657A2244108BCF55C7F4F97666457CF5F796105ABC773C541173B9E338B4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F9338191406A4C257E6B7C058565272FB78A54A46007F5550234FE9B7952A82581C08AA6A1EA68E497D663F82C5D20E9D1134816EEA319EEAC8E431A0D82B6D62F7B93D121D8382F0EB3DDBB9FCD43901C8AF1AA019A7160B76B72D4E8CA1228E5E9DFD49E24F3154F4A914987FD0264ADA4C8D6FF9EBB91C59C03CBD484E9EE72F1A98C3F97B9F2479FFB79DFAFBC33C8ED249286369F003C471C8B64A9B1546B1F31BFDD0ACA06AAB3EFB61E49CDF5506AF8A4693A7591498D9D7F8B28A72A10EC60F806A9955D7EB41D2654EE5B37C284F41CFF3F591C227E3FD0CD524379DCB384ACF486CE7B1E658CC743293DCF546BE85382FC40CFDFDFA407A9EA33AC46468E060524BF06C9CC109A726CEAF0811D0F857C08A3D4AEA67CCC0B17B2C38C53DA9F860C99E3AA769EE27CB7C9229207ACAEFE6C62D3ECFCA201DDFAAEEE1EC7BFD40086AA922961198B53C94BCFA97EEC1DC0FB8FF1D9448B6770DE4F5703CAE179FB51CEAF935F666F398B74BDE9FC87B01AFB6EE8B47490453198F9B38AA2259D2194E9EBC42E1C57994921413D6327018B91538CCB0B90E965564171D133CCD9E7F65E851971FB71F2C47B4592C2A52A4101D2EE7A69DCAB3852A56C4DBC9295D2EEC5BAD1B8A13B7EDE84768C0AF5FF0B0253B44038C236412ADCEC91508A76BD8D16E6D6BD5CBB3179B34DB8902863056CC65A4DD40B6A1929F28DFAE1CEC64A74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7E8104E8D9DB129F0AEFF48177BE4EB60236851F6D0DF3EAF508CA7F97E4D5814F71ACBCF00471EF263D3B5CD58ADEEF11E3465C704D90101A5FCC1C8CAC25387B7D6B83C7CBEF04E05BBA1766C5C5D804642609AF84AF3FA7E4572393761664021A632DA048F2A10C2A349E2E1C260C1C3CA6184BEF6045F43D9C767E2328B9AF5E48EFE8298DF69599C49CFE153BF59010741DEE011FFFBFB4EFC5AA4B5DE409B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F83369497B16CBA6B3104624902242C468F89E89322D299123ECDD8ECC98FD5C53D99FDFBBADB056D1034CA39CBBFF29300769BFF634A38678FE7BF929676A43CD0FC3161391877F0623D9B59DF30E28F5B47C0445F83B36F0AA67F6A2DB8C0C3D3F45738A4DE393D8675E286F4530AC810D244C621963923BEB20810EE32909D5F79B7F944D0041C0130B7F59B0ADCCAD97670C92355CCC8F0FE34612A088BFAAB33542EBE8F3283AD67A79EECC3E7B7C5D4CCC29B6083AEDF7AABBFAC8281B7D7711DED8D4CA70C383C5042272379356BB80EC0A9BB8E4F1C73F2D2DE1676BF5AF43AF87AA2B2C4A6826DCDE46E599B2F31E9EA87A816EC5D8163952A7384603C8FEC20F58E1AAC52188E42774382077A35700EA5EA2FBD04135593A7E40ABA137FE400EB63BAC7F417252EF6AF6EA8FA9CB3BABE7718FAC4A756702AD64BF1F912E6ED44DC6D424CD15D3E45BC9F86ABF7CB2924D7B4E8AAF67D69401F5609B17D251140842D7A94FE5D911BF2FD37418208B716D2DC66320743B79E64CDAC6F2257AD34D112E22F977AE6034068C0E0F089FECA11DE03396BFBD365B1A788B2C550ACBED3643C1E4F13618F904B40031CA9E73F9B13293DC92102B33FBC16C9CDA02E511D49394D5DEFB95770E5CC750801623042B7113D385E8BE8FEDA1D7F9105D545B18AE98870B1326494F9BC31B33EC24CCA7CB8E53F9AF1A7E099B0D9A40CCF40B085C0D406B5F1DD7DCA794345FF98F272F7D9A11C30CC5448D2D311502B7F0F81437B52EB11CC5FF11C1FD62B9A34E2E102C5C59D14A3326702F6B6862383B5BA1041A59B2F4E009161857FEAAE3F0C4006926444BE77169E9963DF262BBACFC643F032414200B26840295326BA1983CF450DDABD0DEAF05B3AEE35CC029B1E67729517B6555FDC996782FE0CB275645E739BA0BC75A08869998C082BF6680E2DED0D643F06EED3947CB24E4D240CDAB6B07EB71762DB159BD8E8FEBFF190763906FAEE1D307115E7D6697AF3DB2192D37468806FD49ABAFFD157647B652B339A8912CAA3730EDB23593BE64CE9A50A1622D43538926E5B05D878029C5AE57DB40072EBB7889423A948257F9E8684E5B4F10C09A22AC506B5105246ADE89409D3AA78C4A88181FD562EB714E9402F8C4AB2129E73FD77BB64F3F6752E5AEEBC4DACC209D01A274E39A84857736671BD0604C153703CEC940CB0D79CC433D157EC5004ABA2F359B80DA9FC04267584B2897B594C494883185E613283B939DEBE0F324B3CB9F45A6FBF11AB1CF2704C5F83BE3B8CE1C38663757828909CA4AC49ACC134F533F5DAF470EC30D2E8FBC66C9B6C58CBD2ACBFBFA2842E78DEA2DCB820CCCBFB17454EFDB2B1D706B93B0254B3209CFFECDA9F52CFDC1CF312EAE3035C1A3D75D8764F693350C2301864EE1A3797F6574AE38F66B40F82904FFE6CBB34655B99959759EDB652F6A3BDC1D0F24E8EBE1761B43E876A6A7AA29E8B1158F1D150E25A742B5FBC7161234A85B35803FABBC0AEA40821E9990D48BA7EF7E1A50178ABB3CDBEE228B40C8B02C98C5E8B70CFF650E570988E64E6F4FB69DD11814016F8AFC30F853DCF0B793E150C3B796CDE2B1B43B3E346E257302026A4B5934CC6A417A99706CF783722DC2663F469896FF8EB4CC741D531F3C32B41F0BC6DCD4A32786747BE120B33718A94639FB4D754E0508B0315990F31555D6C1DE281244E229377BB4FDB9CBB38AE483A3569F735AC438C492DFE94149EB3F4A4F9779A1AEFE60FA343AC04323795C9D33DE8AF95219B8711B1168A107EF83062F033203511E5663EFA0C45ACF54432C9D4EFB5678332B5E164092612E42C61560D9EEC768594F4E0E6AF10AC7B3DCD22D229AFA8C022EB00AFA626C63E8E96B72DF979586867B42B8FEDE446A0F6807F1F1C775595FB5DEAA3BE2A45570235BF1169F163501B400DB5A48D7FF08851543CA92A0E8448F98BE619F41FACBF13EE45A1F97C20748CDC3B4068D993D944D5A165FB858FDF4FBF88632FB826103B1276C7791C64195106635996700A71E299889131E533F7F060C7F96E7C54F02D2A32835106FEBE6D40CD4D56B57ED26A7431731B04A78CB5A4884F0CACDF007DA6E1C4195B2B59A53F31C48EF9FC33CC7F6BD147032A1B6313C7EEC43B1E46164BEBFEF16FADDB1A176FBFBE34DDA7C88AC9C1EEFD4F33B7960D847872B8B433AD5D1293EA480E6FA097BB9AE29A7C0270A062EF9BADDD796FD8EBB1502606E9262357EFCBCC9B7343ACBD03CFAE6907BE46BCD32C4C4C4722C8D3A9EBC76EE4CDCE71B049D688C42104B94A1F7FE6F945BDD02E3DCE0C345C047AB31E7E8051ADDD3DBCBD33699AD660C1CE3E25D203C4EA56368B19C77D498E67CFE083ECD3D36BDCDF29A148224623E0D70D060EC964B329186162C1567F7E7B5B6921CAC8894E88BD8BD6FBA1E8EC4081D35931ECA2BE1E72E32D7C986956EE9CFB07CE0B5091605780D9770A00252C92C4DEDD4D8B942E14C90DFC5BD612D85CE24C5CEFDB3EA964FFF256B20A4DC2C0EFD50DA4BAB56BC846B09DE27F341EE42E63C0C23B6C61D15F2C9FFEE5663E3CC74F7400D0645219751B70C916C03C0C67159F71BC0B3BFA0956F026B91F8C2419D671D3E00D7F633DBD2DBE88126DEEFC7733C2C926D1D8B0C8BFB1077A700BBF3892F0C4F3E30DF78BCE0A340A8F98EBA5BD384684D1E0081C1237440B3A6F117178C0DE4F19D05D4241240924D9EAF9CA45E3D4231AC903C8EE5298A3445F01961D6D3786E36D24875E6DF3EB1D6C1BE5EEA0E060D3E0EED1DB2D4E795D35A0DABE4A745764F05A858291993541AE149CECC5147FEF0F3A96B42F38963B9B29466FD66AD46CADA8F10E2D53BFC3B823CFED410147B5FD315FAA62ED06429D6D3FE6E5778A64B5C9BB06A8CF5561EB7A8B15838AA226DDFCFD4C31805D53A6EB7D2DB861451027CF84218C39078756B2911021C3EAFC2E82ABF792C5012CFCA3AAFB0A277A9C9E1E515CBC4439D95B2A54510318F5D6EBF97C8DE2AE0D4FF669493AA354C25460D3C15B1A57AC53D7E6C07CA407AB1EEC4A366A637AD4081F0343433C555DE72B71ABCD8ED3C043532A61125CC3CA06CAA634E5F75B750BF262756A57E3FD235FA9EF00CDD9553D37968DD680EBD5935FBDFE43A82E9DD39F96FD483AAB7F2D0517F23727E8F4DACBF1442D207EFD647078CA9CDF7800804012D4EC23BA14C99666610A22DA87523E4E5E41A6698E5235743A9B9E1C4795F38AE20CBE5C3A2111ABA307C3BA6E03F092E96AC6EF297548A3F144ECF7F643EF19024B2E98B51173450ED06ED68EFFA06EFD60721E73C9C6993F14C00E3E4BE441791C648110F699AB5089D7CD092AAD82AE007C0C3C8659506D5F2817E75EAE8B803734822A2526861036E35C3689EDCBA348A7A2E4BE2F1E291F63473988AFFE650C1BC49CDEA3875DF4E6B541727B5AA6F04C9C1E4D06BC5CC744D1B955958E2578C6176AFD7E3262CCBC0F6FA21596BDC36349BF9329BCBA08FFF934E31DC1FEDB7D7F6B459BB1A0165043B902D600C447792A618B77C1671E5793473DED54FB3322180F198873E306E1F8BD17BE04FCD3CF4D6A9201B9B804BBC772B742097663C42F0FEE3766B3B205F14A39D6ABA56963D03DCDF538ECFB8A7AE64DA3C116BFC09506BACF5E8B5754B220F7CF70C5AA4492AB72D20CF8F4966A114833B057662EC63B9570D9B2DCEAC86590569934F91A61A03E18835E31ADBC2EED3BE0BC148FF004675C9555C901B280BFB56FF8A1C079E1F290C67FD1B7E53A6C27A5C649ECA9EEF836621F9E708EB84B6F5C529ED2F07BF0A6160154F41F323DFF8A498177FD09D22DB15A273F787529852D898A6DF0FDBEBEFBA3F3B602B1E67352224860125216AD6D68CA891606E179FB415DE4B95484CA6907319438F69337316203F06AB1488A471924545C81A470D78E2EA29AAF89E94920AC4B0E7F2FE01092BC8CF3839480A02C0E8DAC1E864C9BFF5CBF46C0FC7B6A01FF0DBBCF96E3585496C392C6496D06C44765878B26B6DFF2C2FEC20F26A9A2706838A2048E579C65F3BDDEFC58C89D8830FB8C75FAF96788998DD200D48189C3B59B41501BD310420DB96F7CC5B61A2EAF88B498ACD890F7DF623A35479472694CDDA58C000D9BC04FD903E4AB88A2E757700FF3F460F075F9876DB3F76F17003E01DC96A92543DCDFCD7EFC86A5C0DF387A50ABB69953D6DC19A699CD225941F82438A8EB7889B212F65ECA7399F89CA0D9B9915E827D2E520B6D481C27D4CD833EE7D985B20FA5BF7A21E4DFCAD092628EC0A6E2DC876E4C5BF248F94C2ADB3D6C9F23C3E70D1F611A2041C7759317B8EC1696B2632CA10CEFA498D7571D016E102DAC10051DAD086BEC58AD5DDFD7988C5F433DE87C314E3930FFF937A6E0C81787F04B77F893287AB63125CAB8B7460F119D03BF3076A98FF029EA5022201DD54C854711B8BE718EE678544B51AB13B7ED0262C8180C2F36CBAB64D862D38AD7D8172AD8BA3380706D52048826CAC611B07468967CA4A4DB52628A2FD56DD3A323382E5DB171811EA861E2D46537D0A4E545C65F238380083A064421DC7CE13EC2F715580924D9B6EFBDBB0D45AD8952F602BDED6455C0BC2734CB135B79966464546A261D0A551DEB43E5AE111CD02D0F2F2E996454DE17B471C6103D851CCE2E1FEDBB828C7F4EE66053A57831C708C377FDC6FDF037F400A09E9A610350BE6C013239D7F1C42758CA84B428EB06C6A6A3E05F10FED769CEE2D8EDC3EEA29204605005468B0366B2E957A7A55FBCC7842598F55021E58DBEEF44C5313226E6E56A2D3837F2A098C94BEC791737F355E6CE5643C954C4719C6C1C939B7716A29191CF0530BC2E78CD028D526EC286FCF02B18A077C86BC54F078A19A529F6EAF69D5562D4B31E4CE3B953A24655429BDBAEB5378C13E5B404A138B2B5473A415EA236245B0541B6D92F384D4CE63680ED5A6C035FFFC663C893C8F51C5DEC6F90D33573A05CBAED63B69079EE77DBDD21AD7A778B37EA5E0543BBDCD47497F355B1B2D8AD93DF4BB96A5E85A2344192B782D54C4C8DF251BD5F72EC415621FCE91148DB266EE1BDA0885827E96E8A9AD9C50F43D947DFA8260661FC9326B9E76214D36B22172C026EC12E04ADE3C62D4E957AAAAE686D350793BC6E9C862D968C0E56B3160B5C70520E9AC7767AD2BD8D1D6DC951A23BE9FAF9DBFF407E7766C84CCC3F281C6383079DC3188FBE8F9675D0A26831EC44071AC6184AACBFA0A2326D7EF097650C1D4D1E58134408C11E839A0DBA17CAC9DE3B437E697663AC136380D0690DA4A52070A2DC552275BA09C01B601D55E97AD7DE83A32B962D0A9053C1533600FEFD1171C638A50922B9962C195551F81FE80BE28342A13ED0B25FF8986E0E9C39F3C2F29B9F40AADF8CF61E879A7FC863B32F02C5B5BE16F0E2CF00F30E312820E84D09BDF073E0B16B1F32C73F0E6031DCB3221DDC48670D0F2DF9A8065BD027C30DCF9F12782C812753F109615828997768C75660D469691278A111D50A72CEE9600124E3850507C0B963E9121C8B28262B6C82510AC69F4785752AE1F619E3D334170A4ADB4DAF3138AE90AAF8D82573E7AD25A16243E16650219C47F4CEBE6915B433B0ED0354EE62FABFD3E118AC777A63316637DA755A99AF97DFE9857B2F58A83ED70041EDBC49997EC93C03A7D55524CCFFF8018EE1A587AAB9FB5D3E33FE7BAF2642CF9421540C134F9BDE458A65E6B9BB209359F7FA47B95EBB79C83F329ECF88C7541446868CEF363218841F55D346A2B714DD48C711555BB25B1CCEFA6199A0E7646646B667634E486116C0AAD7E977C091A5EA356778C299EFFB7DBD3232C4B73B54C796BD1E33284CC8E4354C772DF1CCF762F615715FAA903D1551A67965FED6C7E1ED7BABB9325AC30F92305FC284724C59079B11D1A0E32F4665AD8390B34968D1885C9EB8BC5DDF63D7858E042CF7C66FF5E36365F1C7156C79CCDF596EFA551E203456E5BB22C2D9B742F490824B1D5EE482F335393E34E69C7820A639858C6EFFC2E8377876E461788FD2736A2D1BAAA432B008850BBB44FA193DC54757D8C75760638A12DFB614580A882EBD945716D7A3D3D29396D4A0D267B07B035EC001CF29C87E23D8446E21D604BCAB110869FFA98C32E35A9B6C878360FD7BF8D564B09384D5C52E0C9BE0F45E814C954FBA214F3D3089AC4D01ACBCDB25B9331558FE1D29E67628E13BFC928F7A9A88D13E0759B77674C3F2795CDFE0C6617022F9C6A87B60C4B5A69E8D1706749FB0B4E086C94B5BFC16CC3B34FF3B7EC227A5CC646E9A003E5D897871067191AD1F8A8C33A0E567F4DF2D91D00FEA00B152183D202BD72DC0694F16ADFDD6E44A248D80FC6609E601CB91EE691C4535CD80BECFF9F23F32BAB5F106234A8867CAC0B5269CA2BC588E48AF922B5917BB6813E9D1005F35CCBFDFD419404B59A84497BCAD743384461F24267C497A932411B690BF405A7ADCA63858F439B123201F41AAAAA4D0A478101EDC6AD214E025B5DB6D24021464C53FB376503B6CAF4E4D4974E072F8C88A7C61957239581B589ED8D1753844ED928642CF96E5ACCA32E69B52CFA3AF54B9FF793E7553CBE16C4F9DD6114D1357E539C238AAA4434C5E540AB31FA584B82AFBF419DC51D6B08FEBE34B7991EBF2A82FF8E94990BFD02764F7D1DC049A635A08B7BFDB46A521170B6B8BD940883CD4505224D9DF930E33C5827E303083CAC4F846D9CB9A6E3FF57E755C7CCA541DF51819C5A52BDFDF005217000967A2776F51217813B2FFC509EE35F8AED6481BBFF5D5E61732BA17C90FBBCE1FC29E8DE849C146642845F982A2F766DFC0A703B5BB612E4C2B8CC426BB56196D714FC6F1BCAA0F19F32CBC06C3DD1406B591D2B0CD0E834D003CE56313B66C224594354866598118C87C1A86F7D247593846100395EE6303E54D130F91FDF81D0DFD021C274AA9567B9F9A500F35507519BCC25535407E419B52FA4D9ECD3D53F467B6295505DE979CBF6C7BC909812265ED65B30269FA1500264347FBCF1CB34AC5A405F208E73DD503D0D0E15FA474802F273C76C3D3DF98070BF3151D5D338DB368DA0D2280BD821880265763EAB2076766540EB9A51EAE647B96CA4326C82626DBCFCA1B3FF6DBA63DD64AEEA6741FA49E358E97D8F60C7F1A56248E8CE18933CD6F850E667134F69176DFBE2A4FC259994ADE12676F63D483FE16F7658F1003C1561B8D46FEA0888D2C82A4254AEB9E4104B9FBC973CF836BCAB5E263240ED9D87E9C434DC66E8F4A7B73EAEB30BB745F4094A4B82EC96CF99219F557ADEFA605DDE957CAD9D5343558A9A0904575A7A954948DC927E71786394DF40E9328C9B4382CF4FD8423B97088BB07CB4B257E5AC7B817088C3A6912441992153D374D477EA4EFD21C9F706D3619634AF7DB364F5FE73D12FF9623B665980B98E83991215E188462A57C4B3F653E11B4B1E16522CD421105A1FE67AD0F58F3D4AD34A8BDDEC13454EFD5FAC6146012476391769D4AAD22B1A0BD1CE9599600EEDD95DD265C4640CB064F92C22B0C45C64FC411375852E596F268EB415B03DA88ABF9A089EDCC5F06ABBD96E1BA461D4DFB3772938CCBE093AF922F5CE290295EBA2289660868ED4B6AE38B28B1ABAA06B66BB97A5396218691B13D099ACB89D6754517372564CAB054763190677139C9E2F0BA2FB19D0471E49BF6A0DFF2F951A414ED5D0F17C729891F4EF658F19FEB6D31F0BD8EC15DC9F9CC1FD73BBD7A6CA326AB06F55078D4F2F90CF185849567E8C78F2773938A916FDA23279FC3A9D62CE3C3AAD309264EA076635487EDE98CE79ED297D1BA99D96C84EB712CCE028298C8BAF5B5CB3EFB2EB8996EFFF6F7682D6EAFE498B886FFDC157AE3995D8493BC6B51541BE6862B41B5A35AC420D4D120957AC00B6E488AFA394C5C3F99DEDB4BC4AD4127082E44F22194654D3FEF9CFF3AFA66A764864D8344939255F4BD77942D6B2063FA9C0F82DD3B8D9ABF5C633B6CACB152AC09B9DF3BD12770444F99843FD913E2C815368910DECDB46DC4E13EF2E89AC3FC7D13749B88197F633BB6044E1EA0FF4CE060C7F426D01D0CE94833304CDEE3C857FC7258DB654F49E7C949C4D4B2DDD689DEA7E0C526E694B5EF77F8DBCC199F73D833C54C6C389C9C63A9E203FDF4389D83A4DF4AD86D7B36D3847C8DA829E04E31BD81791E403D6098AE9DA476D75B357A74FBE2F0C42FADDA27AC72B653FD87A8D1D72E72E2BAF5D852D1FD6DE10D5A6A600C795F65A4A59A00E2C503DA0BAD2344CD62FFFAF6761831AB2CA4055C18294DB1CCAF2BC6A13DB522CA1BFBA9DFCB930E4D6C32EC24DB5A8D5C15398CF2202878D240BEE11756559F26355C059A81765FD0D993FA64887D5CB6EDE1B379B2B8B5D5430F3D7A6ECB8259220DA7C9106CACBA69CF6444192275A2C6EDC588234E8D24985A0770607FE1C4AE8CC7559B3687522EBF7D3CEF0E19B229509D2A247E8650C3676B3B272340EB71C69064FD3CE931406569E7AC1603E49A13BEA93B2892704378ACB4796CEA77687C98E8AAEC3501143271E504408CA5D7ED271C45A1A7637CFABEA8EDFCB11DFF3F8324C8C2C7D9C73A26B8B1C05B6F18013E03928FFFBBB5068FCF4B29FBC21A5819EF85B91B19A5098883EF40D91B7E287749A578E7743680786FCA565BC4D19AAC06BF70C283E7649992BD6BC0305A0A093B75DCFAECD7E049E16F274AA9B017CAF3F5068FECB55C6FA6ED97F64E17CF1CDDDAEDB45036C6B2227A0AD5181AD7389B72C8967B8176E18CAA3506BECFCDFFF15B598C47D10E11E65D9AE8AF9AFC8B189562D98BBB02EE55D0A5C41EEFFD3D6E8EE69878B3A003DE7A52A98978892E51219387C24BAA7A773944F530816FB27BCDCA933370CB340781A70DB5724C597F72F7A34DC05B732FEB79A18171281AB7A94DFCDFC2C96DD00784F2E67D7E56D0F146F1585EAA1448BE1CCAFC6F334CAB07A27E524BEB95E19D426689B900176A70B21E32278F27EA3BAEE623F92B14696CFB1EABA0D90EDC414FAAB03AC0572B4B8836F071A375849BCF46E83A05979A4111167CE5C43F6FF48F386E3E8F92FCA1655E3ADF4C2123DA2C5551E252E9BFD93276B5B2BDADBC8F23C0406875614ABDE72C520002AFE6F55BF1D19ADB7F26D4F71842FC66335FF670C60583CE65DF747AA6DB218471551478BF36140DCC5C6B9AECD22944CD2B781A240C914D2BC4B37877709794CA33ABA878615050637B0A0B3F04DE2FCF37A2442A242E6C97398CF483260BE8A092F998EEA5FB5519EB25BB10B9350AC7F6948CE13DC282ADFD3A251C07E32A25A8A93276A563755B3164C0A9510260425ACDC093CBDBC6C8C5D0FEC94A6DDB415C80D45BF9A6D8DCDA606E3204EEF6AA291AAC9AF7122810A77E0E1160A461AED63687B3C137EC40897B972493F33636B2CFF07747A394747C0887C0402CC4F50E78F70785E5DA4C6084BFD7AE379F0AADBA0CBADF8C70C34FA7A6B0C14F32D52FE8AC726F750DDDA95C741131C7F692CAF7A3A80173479690A3CC0A93D1823BA1AFD5634A9D14E17E7858221497CE6934D7630E73D615127209FA239A190EB60B4D49770A1122DE7ED76708CB660EC4E52900D130C9A4638448CBFB16B1943D7C007D521F945D00D42CD0AE51FA89D5BBB9DC68360C2551D3A0E08CB0025B061057FEA0855305C0F6496903EC94DDF067E722AE07D06AD5AC67A1B5A9D1D036F4D157220087AB098F2C6A911F710332AC3AF782A6747B8E079F12A768B9372BAA222EF43084F65A46EFBDC5D8BE794084FEDD23BB2BE82A7FD1C5FCCCA0E10FFF7CD47FE805A43F82E73773670C4F43571767DB9F9A59A16B1C6DFF3AEB739FDFDCEE27D8699BC080B9D5973F30BD546DAC6DE594F91E5C2F0DF432099D949C5FD0E9ED66BA4FD37F77CBBA8D511A0D712DD62859D6E3C0177A264EDC37393FA86D8BB241B13A2023CECC4A8A57242DA1C7BB796DB4B50197F8E7DE6FD645C6B9099D6F76701B0A36CF2DBC1C9E2F56AC8CB222D37682E19D33A1728916687BE117E14BC7D137CE28948A0997FD9B25545316DC91AF2780D34EB5D9A262B327FE0E57AF30D9299C1CDD7FF92E3CF8C70A9CBA640A71425B164DE8D2D0D78A19853125F684FB1E94D7D02473BF12C6537595311354BAB832C69593F4195132C6552176CD781A04D4293BB9E329B78AE8929A249AAC01C5C81DC46DF707C914E08A642BF4B0277302BBFE3950EAB036CEABBDDED57D2AB2DAC00B61474150F0F641A571573A79C7CEFE5B1E08C2A0D7C144D69764BBAAA9DA45E8C1CE02AD4BDA14E86E6F4509823913D553117C25BA7727244D0A5F4106962D2441C4D3813A780757E169AB7DA6FAE572D7CB919DF7BA028ADD524236473F8CEC4509FA954310D970F13B8F57505F248413F93CCEB0D2A8B81A3B6B812422E630863D5F37142EC8B03444B7509B92C2C46E8B7DB79679EE93FFC1DF1B807E29773C0B9A280334CD97CFFA2AEAACDA2A662F8767A323DA9D48CBCD419ACB2EF27A01A26F7F2968B572B679155717F7AE7CF17987EEBF9B088B153D06F88F683CD8A53B1D69CA429BC5D17DFF465377F6895611C319A8C8BC23438BED492817703D83BDBB93CD491EA8C39122ACD809BA158D5951E0B78FA5409E63E7CC69B5B6BC9BC56349CAFB05B71BD8C8ACC90F929F58037617118351CC1E0E0B3CC4040BCAB505CA4AA36C06277B4D550922DC424A005854FEA6EBE6C833980D3F7D49F38F595E3B156B89809B65E62B57E0C79947B2EC463027DE21FECA9FBEE0CD5B8EC64BB776FC95D93232C53A5A5D8F5954AD65E6BA6A3677C62497C3F4DD408AB08F2B05E00F865CAC6983159D2E4EB54EC0B89384F890E6033F71C5C888A9EF25C2E5563F4B79CF7F80E221C59FCC0CBA7A56ACA182D6A22A77AFBDD2209D5BBE8400605B918912E1F8268EEA13534E86FE8B6588ACF64A1322DFBA8990E280AD5A2E185DC29AE3AB7AEDEBDFF8932A21ECB57071D2C6207740AB48DA0286EBABE44AB1566D845A6B231073076634B6493FF5F4669CE06BB0BEB477C3BF2F9173ED7A36C22EB347036E7358BB62192E4E7BF5B9515C6A433D21E47F56C886AF92422741D1CA07EEB3A67A027283E78A27B64C89AC0EDF6D3CA5AAB03AB2437B7813BC5E349434386F00F0C0D592256BB28E68D0ADD1F23F001F2F0DC867BE42CFB316FCC3AB7F2ADE8F262E2F2A817435D72D2B9F181E285F7D58C2E9D0ADCA7E67933CEE6F908BBF182523A0367EC978CAC6373140022E3B851EBAE9D7086C4191C0BB856FBA1C5785F57A555985D0060A4BD79FC0FBD7798CE46C543B3D26C62BF07B7FFC0C5CB00729D2F9DC75A8A308AD312EFDB71DCF069034FB4F970969B749BD6F487F5E77627FFA00F64DBCF819A4F8EC0681AC3816282EC1717DA96444B3EC00B32B8C07E806988EEE0B8CEAF0CEED4F400F27F1D79267AA4BA333E61B84E6F10222FDEAF05D3561F5796CD819C879A07E780BAE63E780C05F024F2880EBCAEA6C1C8258D94B753BEED298829CF221BEEFF249643A4915D5C0E8AEAD2C85ED170790074EEC22327260470E99DD940227A671D56A9204224861E56624244241513ED4AC7117ABD09523C29C4F23E0C41900011215540597EC1BF8516CD28C228D03F8C7A65E4FFE575C6F5FB1F833B04F3DD1FE2DA3F983FC8A6BEE8CD7FDCFBB4436D8E8F09D466CA0129B4080F5C4D2A078B1CA2BAB5B306B26B4F75F49335E128D5E27B6FE1D96B9B863268E813A092C5176087562125530D23E8F6D61D99ABF133B032021530A5FBD7CAA65063B17304B76498D90B0F3E6541534667952F6B31A74394000AA731CD42D2CAB1EF3AD7AADBAEC7541D04E60B843FD337D7D08B9991452889376EB57FFC5D2D454B35DE0BE42E0B04E5C21D950E809C5D499AC04DE0E4FF912237DD83AF0FFC5CB8E520493400C91235F9D49BB30724098295713F70ACB57194F53B656D4B3E5879E2E28734370A052FE51C8139021ADD0DFC6D3D8491AE9C7C8E3AEF6A5C1E119D65923212BFDC35792BB5E3109BC36003C17100DF5302C7FE73ADA012B36AFA5452CFE356C38E63C59E80C1F3FAA1735150F1F3CE87E7008281D125FE7627B3D6C8DB3A2101DD6D650656EE5B8E0E8F0CA1DBEE12303499B6CECE8AC80111C504804F9ABF9C616D22DF34FBDAF27 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 18469 sm = 0000000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA701095690ED3CAA8519B752CDFBACE3666EDC260EE5325F9EA849CF9DFE6CDAD655B850B4D00B825B12E384E4CE8F666B543D8C8BECD261A578DDE551E6CF90A36003E412EE569DA19D006D0826FB3293AC847724330EA49515D4E5B4DC3E46EF7486B0A4897AB5ED84C95BF9D9D78816FE9E92F843558029A08EF7015764C3D1AF1852C50D360F65F887479E9631A2CA30FE3AD92E7BF648643835F4F8CC081A6C9C439720087F16209AD7D3DAD7FBDFDFED8B6E91E5FD0D118B85F3616E510B8229CA2443C7CB3E2CB8A4496225E251B20EF7BF07A1A37D00A59DBFCC0BCFF40DF1E71AE21A2F47E739C7AED529E7EED5825FDA6446E40F6C889E249C813F2656995B25FB9169A3460E4AC08509F6C41627AFB5261A8E5ED535C7D0FB4869E1FBB9F9B5545373C3A86DDFDB1D863609DA537E44270132411E8A373729B4D37C277197E5E72AEDA323C10FB7CB3E7F169199EB86F5018CBAAC09E9B322FF53B461C6197F55B8A2C849396C4B19633627442973CA4FE54442355306C2207D6A632117E6AA6D434BAB8FD8B67091BE465C3BFB21CA9D16D794635422DEF832911110F5B20D28D1B9384DF1D710AC39FAF699989418B7856C2034C695A693ECC336EB44751F234CE3EB9DA99AFEA939C270AB221C09C99C1538BBA65D88E13DEE3D82EDDB9994161F2F83D2829B47A2886BFC4FAC9CCBF78EBBA2A40C9F2F0946579887C7CD9EC770C111D9681D6F1B97D908CBBD436444853FEB47F234D31F5E92B9EF436C0E8C75BF71D78A7F90EF443748CAB197234EA10CF3209320CCF8ABA1BA0E3A789C1A3A7E2EF2DD79D3C48A562D4599D4C204E3A393724FC11749CD28AF44E34D56CFBFE507E95A9E3D86591149D0E5DB6DD9A9A83A811D103580A40F3EAAC60C3D0D40B8744BD2A8C97E20821F46750D130024AAE8D968515F6314D8F25B7E267BC7716B6F64367028A87D330880BF8CB7FC94AD8DF4CCCD6D6C5C24AB9E7725CD11443807BC4EECBC46D46EC3D79A9C0C755A65AB867B1BA4B07FC1C2F62FDFAC5E8EE98639254EB106410A8BEE8214C66A7BB81C99C989737A7EC3EDB49D00B96789B4DC9018224DD7B1CCF3FC893A10C06EEAA776CF0013263513CF0F51EAD30CDFD170155A675ABB01E2C06C2E04365A619CC6294601207BA2CCCC24D08B9D0A5A3F6009F660E9B15456060AC696B025F2A874623DBF0B61F73C56A921D5E8459ACCA633C5B50F7C6A36062BE168AF6246317A8B052CD7F15A96EDCFA580D8FB229B0797A6B4C45DCA773108A4A0893546B4F42192E0B146B33581687B7E0BCDD9121C2855C87CCC9078FFD868D7F0BCAB9C6072DC52A6153A0DC127C0D7AE9E6AC7062BF0E32260C11266C4AEB1815B9D80CC2C7F5898A39D5C1CD10002B3D710DC236EC8D68027C56FA74F71482643230330B6FDF0306DA1A39805F56FAA5EB1B2038CF5FDC70F204F0F1D4982B7DBE1BFAEBFA628CA56052B581C1DDCC1B058B92BEAD301E8F3B8F5EF71EEE7966302B44D2E26D2A02393713E50E97A5E1309649D4E93719A883E1C7EAB902CDDA5AFE46434431417A67D20C0555F9CA097AA6C3B65C5CD659AAE22F412427C2918AD8C309342C8369BB454C503398C519742B581D604C13E10DFEDBCAD3EB1F66133D21F83B2C15BA70E2084E0E96D865CC4D6A606FBF4DE92C66BBFB686C56D23150B560DF6C4A899A3CAAD123DCEE5A1D81F1E20ABD1DEA550546C1D13ACB5AAEA1E6F2304541F641343DDEE6E0A066BC266687463E93C5A235862776216A7294A9B18BEAFDFF95A17AB7CB4E7FAB3B1D2265743AA9CEDE4423AA9D5E65EE25DA90FBAE188B81FEB612D3597B7615487DE8858DB8A45448140CF4A9D2152E12279DC7A6AE1DE1239BF9B1AC54D212926B7F2F17985DB1943D5ED8EC711A88DC5AF85CE6CC47237014255691B2B5807FEB4B1F2FA5FD7108614F0111A2006FC13859790AC63FB3A98442D30D2F1EAAC7944E4E7E754B78F741D7B3858E4BF33C370C36B8A7560D6445B6D2F6186530FE32C466597E512DC0924A135CAE452048EED75B482355223F2A9DAF3FCF987E323EB63EB61FB83F76123FD8CBE6155DD251E20F090991CD6489A6F433B8C51B0C6412F36BA064FEA5ED935CD8FC498C92D651E2C9BB0A294D35E87BE85E44D90F65A4EC5BA93065A2A731CD107EBEFA54AADA64C3014C9A6A2506607547D9A150ABAFCBBB6BD37E68B51E1E3B76A88186784096804E0CA23134BDB1616C6C6171F79A60A5759406D13E1DE37665471E194598FBC67D2713E4C767B295AEDA2B90972324B3ACE8C7B79A67723AEA037E12DA9EFA9CA9668A4F5FDADFB9E4278B48367B4C50FD7C42161E491BC40C35FE359EEE17A1333375545BAD7576FEB7542B22B51702D73D0253907F7AC6D32AFD378410070FBAB10D31A4B2BC818AE5DE2ED5D631B575F59F445A94E79190E6640E42F2A3DCAAC94A1C6E3D522BA874184C8A8D15DDA84BB247C2A2E48B5FC81BB64A1CE95161CE2661F6CF8ED45BB7916AC42B1861F5CB527FDBCD82DBFA31C5ACF981D8414203837504263C96BA3C6B4565D4163160F135D27A95E1105E4327276D2BC3688C76EAEA804631DF081B3C44B0F10FB7300874B5011FF0F97C52F975A31355884C2F12B6FFEE20E8371D38183C9D04977BFA037C9BD4DD7F7CE203FD7FAD3852B3C2AE9D078ADEC7886E0D5DCB57ADD979B87904537D98A9179696CAEFD7FE3EF62AD44C8FCBE817976035CED8547228BBDEF5341D9C876901B08FAD036AC277A918FD8D8CFF38F7E9447636C3FD64C2AAB9F44C2FC2E4B27A6D4D7CDCB4295F43E2B4B04C931AB8987079555572152AB8ABF9DE2FC4ECC91A00B7E36D11F49EC02620148D3147EB8D2AE42D887D10EDBCABE6AAF951E0A070D881879332064C99F8527A5EFF25241E773D96CAB3EC602D83261F07793CCE2DBF7A28EF9B5792412414567DBA9372712689DF5DE30ED5313C773311EC605B8E44C297ED4AAC95D3B1DAA8631F7786C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC9D550F851D023315BE35A69C83D099341F6BA69B6A40E224DC554A3489D33729C9EC8196BD665514030C26AAEF80CD6E1BB9EC739BAA2B8E4A63EE691AD2BFBABDDEE2B13CFFEEAB7C25273CAD45409B5270678CB1535AB800679906CE77189DCFE05BBF92FB5E31F184CECF3C427437958F695917E343ACF46DA2B9D988CFE316313FA9FAAD49EDB72B007A7F3D6FC55A88E6BA784FEBE9737803AF05B4801CE0C723C0D15CD8E7CA8E237D4A1C0BB1413D369FC3F21F69205D428069EABE626B971A2B5698ED05BAE54218300BE8C4BC9A52EE5FB296BAF2A9AA42F3C865DCC1DDA69969F085C91D3CC5934567476EB70461B942059AC0F83BA10DFE783F5FB405F159563419B3F5699179D6F33AD05E840EC9227C592E361A49E31D99445437D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB3844833CA9CC7907865878A01BCAE7DB72BA4F7701F20523E0E98B27AF08AA747B57DB1DAAA1B616DE469C7FC83CAA1DA1D6BA6F0C2B0F7F2CB7A4F58FBF7FFEC292AAA7FC3B87E797DCA067ED7672BA9B4CBC27FE9AAEEA63C8569A567129990E1E12A8D23039A877F7FA3EA9B9359A842A19E33CDBF284AF95FAE2A2DDEB80030A8245A7E51131D27EAE94B6C38A8C4818CA7EAE0A1C0841E7AACDDF68A4C4491EF97D5F3F6AD8CC47D2489DF1FF96B7DD444D31DD2FFFDC69C9ED7F750526B3CD81EDEEE2CBBFC0BCEBE875DBB644B3828795D2B81DFE37E0E4E68F9A798E09588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE596674368D1D405B742EE812FB88947D9F5DE52083777E54C2F0A1F605027BCA5A12BDBF9CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318ECCE515F732608A96D4E557ACCA60F144A212276CD52FAC0F12C39F7F45565346B6EE409558FF37D5C50280099C9D75B688C7D873EA7D07EC6C9305AB367ABC2FEAFF9200CAD14D71DE9E1F1DFFC4F15FD0908C6687F585D9721AA773BDECA4C7DBDA2D8275C59A2E90EE07ED6734A09566174D695356166041C646F18180DFC5ACCBA61F1672213C3CA6933A5ED65898AEB4BAF534751900D2CF25A7A94C273533B8694EEFB366F4B3E6D4DBE7FF5FC70EF5341217906FCEC863502598936A4A0D7DD4267B1C0C6E8175CFB3B9B6BA86CF3094D4677BD57712235CA8395A6914063B4E2849AFA406B7EC6E3AE39B343EE39348D2D29A0C2319BB34655A53E1A816CD5FBAD3A3796FEF2C7B67BE4507438E5AEB603B1A0796293A274A3F3D63C7C1F14297987085EC271F06E8DC986CE41DDA37ADBB39613E6790644A669594AF10B5D7C2DCDA7190B03F77E69D79A143E9B7D8B42E18E56D1D191DE05D58DC29F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA4C86ADE353F4AA57DE2220D13EAC9BC8FE02D625EBE3BF2761493F180F968DE438B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE8D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB07425116F11D430A927D45FBAC134C59EA8E5907C35A59E0CF2FA548F9AA27A3530AEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBE6FFF1A2A91E8DD23131A7840BF7CDEA3E18E706A324AB688A5866B82EC18082D89DB83F78DB30D5CE6EF134BBCE7628AC017E6D6974B1D82E4227235AEC9862899B7A4E0E8B10A8AD0B19A54DE7ECA861D6AFA1D91C9CAC7B8D6AE536C458E176AE68697912D7EC853D514AD4EDE982FA89400CE895D3241E5610D0AFB17AEFE51FBB41E2DE044A00D84BE759242476BC0099DFE159F0CAF2187BB311DF2342A59C003778A56907F086C8DC9309D8E41703779C8E1141070708E02B9F987ACF3214A8E442B76121374DD243643D64283D01279A49154760E3567E46ACE89898BCD67842223D5B8CAB03DC13930BE7210FAB7FB2318BDCD92B642F6BF178BC30B4F959F5D8BE15F67C5AC4A4C81F1E3E707AADF0B4CD02982ED4E4E52A81EA2FCB60ACB5817849D53C2FFFBF7906E290BF76E505071913AE0361FDFCA4B279897C9DECF546FB0366D65C9F81A9B51402F3694F0B5DC600B7E4F084383B643AABC755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E6C007F614D3C0A2E45486C2E457C2E6636BC1AFB76B2A7FA351FD88399098C64E379F99B64A3340473DD46C11564937DB9A28C4DE3745308433153B2BC6D5E0D515C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFF0116375D404211C3D3302D17DDD0390712E06CA05FB4BB2AF749D3439A5B30D3E9FF4731822AE6607BD96108BD229A4BDA5ACF50F7185BD1C0F56CC56D69C008077082C0869F237A6F19D73ADCF9844686E3C5583E7D8FFDA636E70E989B1742ACA4DCE98101BBAEDA8E852555033A46F8DF4E3DCA1B9A09E9F938E0C1E468C52F7DC695389C21D0F425B4DB554FD5BE1FDC2765B997FAB1F94D864DE1B4C8FB1323A8D90DC0CD7FA7363AB70728FDBF33C2325FF97C59ADC84C104E730C85CFBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272D144DEFA2E32DCBE8CF7843CBDB9A67EAD7892ABCE9B25A6B91AF0B893846ADDDB6C26354D4D8B77B14FC2FA2D8D589237C4BAF80344C306439619E5A4DDD4630B558BC9B3581AB842BC8B630F232BD18D4BB10FFA1DD3805B18635F6A9A22CE0D470FAA2AB813662EF63C784628138499A1A3648CC877300401E61DA9A379FDB3FC6DD985CA26EE8093A24879BEF107C4D6A38017BE3AA5CCE124259C42519C6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156771072191C21BC3190193111CD3BD0604EC5427C6D70B1BF21DB6E59ED636342BC417CD9F69B804EDB6359C9F8E347AD253370E065D500CAC64BFABE3E420E39000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D00C27D20CB93DA243BB3270F1EF2DE68AFB80842E8BE7C1FD48BF0F5622530CE84C1D30BC69EE1164CC602F2522FA39158D4D0D30ABE4FDE43213ABD6E4D65E62FBEC9AA1D485599FB7ADF5C2C97B90C82A1DCCD2C44ED66CCE79EFCEDCAD0CA1366FA51DD03DAC9BFC60B79719033B32247DDA9195233329F5AA36627FCEC5E42F078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DF657C03A3914FD3BF1E82EF96AD7EA46373B0A4DD0F5655F22F754DCD35ADA89358DDAF6AFF78EEEF21010DBC6556C2C3A018E4DA1D612CC3EF237BC2B1E9E600D923E2CE04FA27CE8EE63B969F6079FF8551B8C06018E99D84669C059AE08081E3A1C7ABC19272D7FA3F2704CCF6E491AF93C7CBD4660410389D86BBA47BD5A0E996F788FB9CE600AD76485D265628019B57FC69631D5266E8E46913ED9142FEFAD87E26DE53ECDF43B352EAC14BF6DA899058228C9414E7323430F9357D6244E7165F5CA2FF2DC9899AA6D8C2B8DDE8E2C5FB7C6E02BF74F578823CFA2355F2FCA1F776C6A87943344A5E53BFA39559EF98C397423C75EB318EA9B5F375C17E7B46A8D592651E7D50E70233224592389C1EBD1EB66678AC42C2862A2C660BACD03BA4064EA38D34A7D44B32DB9E75ABC6B5025B504DEC60512A80F78876C54D36324C7143FEA85ECB9E66800E8F4004061EA7607EAB964DE3F9A273D2C7A4CECC1B4270ECFF87A254A139DEA1E0F0B0F6366C02A0A790D46EAC94866A82DD8349F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DEA67846512E96901F78E601EE427F8B1A7986FB8832D091D575C277CB202E87602D670CE131CC6023A9E83AF41486A04D62616C1E912D4EAECD5DC815BAC1C0DBDB347F6B5DF06B0F58441FAB98B9511AC0423ACFA43E0422A62AE32A48E935C6288BD0D2314C6A739A7779BFE24DD7E2D66E9C4A4111E22481688EA39F256224531ED241A9D35D395F340421F2D8F5C05B873052D2128CEDF4ABE49E609176674363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D02AB14858954A117C6B6F2CDF4823BEEF1904FFB4D841B30537D57C577968CDF18EC8631C536AF09B54D5887FC0EB11A70E86B72EF315FD722FB680EF03A3487434215A0EEA412C0D78DB2EFE20061576237453927710860F0A49DE0ED0C42FDE2A5903D635B19D4F2001EE353D7B5210E1C01F50251ED6E753635A972EC8C1914E36522B1B41BA51E9F3F1CE83BB5F526FBEC31C21983736E42EB7880B9B27EF6CAE0618E57F881193714D3E8B38C9E9056378DD79E78422BD7C4CD57D230EF44B38F6A107ABC77B8D5A953D3A3969FBB7DAB145C4F4615FAF8F2172AA2BDEB35C4A0494100CB9CE188DA4318EA5B617EBACE910A32F0A280C82AF82121720569232D71AD065E45268B36F92DDA13673529F24E6B83A865F3E266635D9655C8000C06478530294DE092640DFB324E09DB3B87497C94502BD46092D72DAEDFA93A0353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB51691B3F0ACA92B02FE916D2AEB98BD9E23313F49A0F44394883A432523EB5B34B690EF9C16B4D60572EF2D791F2BF403255A28D9BC3352B02687AD9200D34C05259FE0C93B75455218E031D59A65D4F571CD7F8B130A0CA1363BAF2D9895A8E8925ED20ADBE8FE96C34A6A13B9318AC8A23A7EA320B83B7175FB54868DAFA9E233B0F4B18CF6FC7D85F7A2B28CEEC561222C5051572B092F2FB269ABF1CC7826675F09949FC443EF723AB476E9E5D670C5F05E46DAE93837AA0F65A4E83AE2C71DD02CAB1038086531F93E163AD65BD962ACB9497C0F268876B5AD3CBBFC4C24EB2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADB0A78B6C1C4ACB8B4C97EA8C4CC3F3778CBF761AA653D9531216588A46701366E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC4050CBFA6FEF6B9FE785A59511CCCE21EC5AE3F429A07B4626A4F0C555A15B42C26A5F353E7A479A700595689D5734C39D61177AAB2943775ADAC879B4ED7B8ED826CB43881D2C1B5734F64A5490A4F77ED4DCB9775B258C18182B42C560E6CEE89A329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB041A19053D3003420EC262BF0F45F1C7CF6E55BA9001E4BE097329CA460D335BA899503CAE0D617BB7FFF0AD37076C91B1659BD448C05C49D9360462B4BC601536844FF2C635BB654EC5749FBCEF3288E41B8A7835B645E0BB501FF805EA4B39785C203BE03F0B105D17E513D50B7738E78EC18AFAB3FE134FD551E754CAA189DC4FA2308B6EED1B8CE87EBCE212E15E72C9516B778C1F62819131E2EFA7AF63BCF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0A2979199F43F2F59FB2C62E8AF2EABAFE9B89B71E75AF029BEC77A6A56F86EF6A4A7212A7458986D2DAC9E00CF68EDB81CA05A297B522D3CB2E0AC3146E4638995B683EC201C67C911C83E6BA3567D31565DF914783F41077E2C31B06640446A6D403F9D46BB9D00B3C436FE1FFDA80AD0AC466AF0417D18D5E7DFEDD7D68987BA55F545F3B89A38908BCCA1DACE0B89FFB49FBA3A67EE7384DEE68FD05721483030ED53913A6CFA059DDB451C780877E919BB86DDCA9E18814123CCC822A8F30D0AB4602815D2279398ADEDE00B23AF4EE605A771AC616CAFFCD3AB12991023A6BE6BCEAFB1672ADA631C6CC29827088627EF9380FFF46FC479E2B586432B58F95A824C0D5F08704C2B596A7BD0A36A52BFD8C14D999F92E676C83EA62DE54C3ED7ABF290BF17C48DD69F949668E11D957299DB6920D740252A9AFB65179FDD62B69D2A1A339CEF805FD258D83FD2F406841565AEF5E42ED7687D9D466E6A4E513E072A9EF6181016DAD988F7C2305A77740F196465CE30A35BF3D098781DBA2F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549617285753A9438517AA7159A9C806A19CE8B8BA5F9C99250358404671F36214E8A7B5A04767FF8C094A3CD74751835BD896FAEFD1747DDFBBE79F48148D56BF585CB0CBBF34300CBFAB9DB32469814F107EF7822151D158CAD68F01418F88B181B092970DACAE4D5DEA7AE39965D1929CBAB7685E758206D309CADC07687274657F6EEF56A657D3FED4D34C7FF6C9CC5F344F0EF4F0E752F83E06B8A23DA0D65A2C10C2D675CB3A214F5D363C35E6E10A1323579803E4268F7D868F4716BF849B3C3D8EDA94476BE7322891C36D6DF146075F11AD02434D2216351CC26600662BE0D38E1DFEF9A832B9F066718FCB2134115F33717B57936CCD2DFA3A95C1D4C4C98BD09D64EC04912C06C7C6A2FFDCA2801628D873EE6D0D43EB67FF0AC93A7666C9ACBB9400593C00316E05F0F5706ABD923D85DE72A0D1CA9F0774F5180B65AA578B95BD20C1FCC322A5B23995ACC9DC97CE3043B1A723AA2815314637B7667DE02ED0FA0924C0791CA09FA028633CCC594429D6E7429930C7F01EB6A134952E89B8CCEC743A23C63CDD9E161B5A2D1F1E0D005F16727A3B0E8B90C20656B850A4F8B5D400B65E91E45AA25A880B76BE09F226DDD4F0E0AEA00259E19634EBAD387CCAB556997A153D1C1B87AA62E5B613A5E02C65E7EE7DDE2E19D965D27B42AF8542066549A6FEFF3E10A93B349EACB843759F5E4EECA76CF82277BD55C57FAD09BE938ABB47720E49CED626AC860446B290C7FE9BC83DB0C7FDCBD5CA2B8FF6C52B2CF2556040B3792BA99DD43EDF1FD4CBE38970D235E8BEE40DDCD2708E432008992D3F9DCD73AD594171092909019E9BBE7A5D4A21EADF82C5C22D877F422EBC64734717C93A027E9EA7EDADFFBB8A04B465E2F1BDDA54BA30963A41978562C27EE91E8ADD7A95B97A1F9F5C0494C3E44AC5422759F971200B1927F5C37B003499B213C1CEF1823847ED4A308D7D98FD5E42115D49B1FD42C7405B55437E1C8C0226884DD801CD89163AEE8D74105F621EF2CE222B13ABBD14078943CE054E3D68F7E8D763948CA83876F0AB7CA5123ABA8C5F68679FCD116D03391F2A53F637D26EC486FF6363F0C297E1A672EB717107ED9540C2AAD46038F8D4C2B5D1D918AF6BFBA7DE46E6628B2C217672257EB98F585A4E4CDD87729BA5ED16719F869FA1495302E8BD043F92ECF8799DAB7B9C501DC956EE3E55FF30E6D565E228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023E10A68B5275694C30FA7BE9BE2392EE6B18651980A01348A97C4BF091DE3501B30B528092599313ADC93C8407FB07E740F784E80461A23A1DCCD78BE8A72EE2AD69CC6E63F385963275DF49AF300E5D468285CA4457F090504D42056F571A8D453903B85D7E63F893431A5A1C8A66A8E4C999F0592D75717940E296C8275952C4A8DC6E97B3D5602408DF3644E8A1338C856296C37B1BA8445883CAFB408EFB9A545AB53CD632C40659DC607F4937A4F364F7E3B47A907BD30D8558C76A8EA9EB357177B8B2639477433604EB74F9C2E3528215459533C1A989FEF107944FC8A402E29495F72F2C210135FD836028B9E21E76C6F13096DBD2BE9721DD2C35504D648C474907FFB896B014CB022942F308C3263CFF227D4444763A483658E728EE6B7954C48E3FCAB1246CED1B1E2EA9CC4D5475BD4FA43FFEF56AB2A2D779E9D206E3E657A2244108BCF55C7F4F97666457CF5F796105ABC773C541173B9E338B4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F9338191406A4C257E6B7C058565272FB78A54A46007F5550234FE9B7952A82581C08AA6A1EA68E497D663F82C5D20E9D1134816EEA319EEAC8E431A0D82B6D62F7B93D121D8382F0EB3DDBB9FCD43901C8AF1AA019A7160B76B72D4E8CA1228E5E9DFD49E24F3154F4A914987FD0264ADA4C8D6FF9EBB91C59C03CBD484E9EE72F1A98C3F97B9F2479FFB79DFAFBC33C8ED249286369F003C471C8B64A9B1546B1F31BFDD0ACA06AAB3EFB61E49CDF5506AF8A4693A7591498D9D7F8B28A72A10EC60F806A9955D7EB41D2654EE5B37C284F41CFF3F591C227E3FD0CD524379DCB384ACF486CE7B1E658CC743293DCF546BE85382FC40CFDFDFA407A9EA33AC46468E060524BF06C9CC109A726CEAF0811D0F857C08A3D4AEA67CCC0B17B2C38C53DA9F860C99E3AA769EE27CB7C9229207ACAEFE6C62D3ECFCA201DDFAAEEE1EC7BFD40086AA922961198B53C94BCFA97EEC1DC0FB8FF1D9448B6770DE4F5703CAE179FB51CEAF935F666F398B74BDE9FC87B01AFB6EE8B47490453198F9B38AA2259D2194E9EBC42E1C57994921413D6327018B91538CCB0B90E965564171D133CCD9E7F65E851971FB71F2C47B4592C2A52A4101D2EE7A69DCAB3852A56C4DBC9295D2EEC5BAD1B8A13B7EDE84768C0AF5FF0B0253B44038C236412ADCEC91508A76BD8D16E6D6BD5CBB3179B34DB8902863056CC65A4DD40B6A1929F28DFAE1CEC64A74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7E8104E8D9DB129F0AEFF48177BE4EB60236851F6D0DF3EAF508CA7F97E4D5814F71ACBCF00471EF263D3B5CD58ADEEF11E3465C704D90101A5FCC1C8CAC25387B7D6B83C7CBEF04E05BBA1766C5C5D804642609AF84AF3FA7E4572393761664021A632DA048F2A10C2A349E2E1C260C1C3CA6184BEF6045F43D9C767E2328B9AF5E48EFE8298DF69599C49CFE153BF59010741DEE011FFFBFB4EFC5AA4B5DE409B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F83369497B16CBA6B3104624902242C468F89E89322D299123ECDD8ECC98FD5C53D99FDFBBADB056D1034CA39CBBFF29300769BFF634A38678FE7BF929676A43CD0FC3161391877F0623D9B59DF30E28F5B47C0445F83B36F0AA67F6A2DB8C0C3D3F45738A4DE393D8675E286F4530AC810D244C621963923BEB20810EE32909DC96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A35F79B7F944D0041C0130B7F59B0ADCCAD97670C92355CCC8F0FE34612A088BFAAB33542EBE8F3283AD67A79EECC3E7B7C5D4CCC29B6083AEDF7AABBFAC8281B7D7711DED8D4CA70C383C5042272379356BB80EC0A9BB8E4F1C73F2D2DE1676BF5AF43AF87AA2B2C4A6826DCDE46E599B2F31E9EA87A816EC5D8163952A7384603C8FEC20F58E1AAC52188E42774382077A35700EA5EA2FBD04135593A7E40ABA137FE400EB63BAC7F417252EF6AF6EA8FA9CB3BABE7718FAC4A756702AD64BF1F912E6ED44DC6D424CD15D3E45BC9F86ABF7CB2924D7B4E8AAF67D69401F5609B17D251140842D7A94FE5D911BF2FD37418208B716D2DC66320743B79E64CDAC6F2257AD34D112E22F977AE6034068C0E0F089FECA11DE03396BFBD365B1A788B2C550ACBED3643C1E4F13618F904B40031CA9E73F9B13293DC92102B33FBC16C9CDA02E511D49394D5DEFB95770E5CC750801623042B7113D385E8BE8FEDA1D7F9105D545B18AE98870B1326494F9BC31B33EC24CCA7CB8E53F9AF1A7E099B0D9A40CCF40B085C0D406B5F1DD7DCA794345FF98F272F7D9A11C30CC5448D2D311502B7F0F81437B52EB11CC5FF11C1FD62B9A34E2E102C5C59D14A3326702F6B6862383B5BA1041A59B2F4E009161857FEAAE3F0C4006926444BE77169E9963DF262BBACFC643F032414200B26840295326BA1983CF450DDABD0DEAF05B3AEE35CC029B1E67729517B6555FDC996782FE0CB275645E739BA0BC75A08869998C082BF6680E2DED0D643F06EED3947CB24E4D240CDAB6B07EB71762DB159BD8E8FEBFF190763906FAEE1D307115E7D6697AF3DB2192D37468806FD49ABAFFD157647B652B339A8912CAA3730EDB23593BE64CE9A50A1622D43538926E5B05D878029C5AE57DB40072EBB7889423A948257F9E8684E5B4F10C09A22AC506B5105246ADE89409D3AA78C4A88181FD562EB714E9402F8C4AB2129E73FD77BB64F3F6752E5AEEBC4DACC209D01A274E39A84857736671BD0604C153703CEC940CB0D79CC433D157EC5004ABA2F359B80DA9FC04267584B2897B594C494883185E613283B939DEBE0F324B3CB9F45A6FBF11AB1CF2704C5F83BE3B8CE1C38663757828909CA4AC49ACC134F533F5DAF470EC30D2E8FBC66C9B6C58CBD2ACBFBFA2842E78DEA2DCB820CCCBFB17454EFDB2B1D706B93B0254B3209CFFECDA9F52CFDC1CF312EAE3035C1A3D75D8764F693350C2301864EE1A3797F6574AE38F66B40F82904FFE6CBB34655B99959759EDB652F6A3BDC1D0F24E8EBE1761B43E876A6A7AA29E8B1158F1D150E25A742B5FBC7161234A85B35803FABBC0AEA40821E9990D48BA7EF7E1A50178ABB3CDBEE228B40C8B02C98C5E8B70CFF650E570988E64E6F4FB69DD11814016F8AFC30F853DCF0B793E150C3B796CDE2B1B43B3E346E257302026A4B5934CC6A417A99706CF783722DC2663F469896FF8EB4CC741D531F3C32B41F0BC6DCD4A32786747BE120B33718A94639FB4D754E0508B0315990F31555D6C1DE281244E229377BB4FDB9CBB38AE483A3569F735AC438C492DFE94149EB3F4A4F9779A1AEFE60FA343AC04323795C9D33DE8AF95219B8711B1168A107EF83062F033203511E5663EFA0C45ACF54432C9D4EFB5678332B5E164092612E42C61560D9EEC768594F4E0E6AF10AC7B3DCD22D229AFA8C022EB00AFA626C63E8E96B72DF979586867B42B8FEDE446A0F6807F1F1C775595FB5DEAA3BE2A45570235BF1169F163501B400DB5A48D7FF08851543CA92A0E8448F98BE619F41FACBF13EE45A1F97C20748CDC3B4068D993D944D5A165FB858FDF4FBF88632FB826103B1276C7791C64195106635996700A71E299889131E533F7F060C7F96E7C54F02D2A32835106FEBE6D40CD4D56B57ED26A7431731B04A78CB5A4884F0CACDF007DA6E1C4195B2B59A53F31C48EF9FC33CC7F6BD147032A1B6313C7EEC43B1E46164BEBFEF16FADDB1A176FBFBE34DDA7C88AC9C1EEFD4F33B7960D847872B8B433AD5D1293EA480E6FA097BB9AE29A7C0270A062EF9BADDD796FD8EBB1502606E9262357EFCBCC9B7343ACBD03CFAE6907BE46BCD32C4C4C4722C8D3A9EBC76EE4CDCE71B049D688C42104B94A1F7FE6F945BDD02E3DCE0C345C047AB31E7E8051ADDD3DBCBD33699AD660C1CE3E25D203C4EA56368B19C77D498E67CFE083ECD3D36BDCDF29A148224623E0D70D060EC964B329186162C1567F7E7B5B6921CAC8894E88BD8BD6FBA1E8EC4081D35931ECA2BE1E72E32D7C986956EE9CFB07CE0B5091605780D9770A00252C92C4DEDD4D8B942E14C90DFC5BD612D85CE24C5CEFDB3EA964FFF256B20A4DC2C0EFD50DA4BAB56BC846B09DE27F341EE42E63C0C23B6C61D15F2C9FFEE5663E3CC74F7400D0645219751B70C916C03C0C67159F71BC0B3BFA0956F026B91F8C2419D671D3E00D7F633DBD2DBE88126DEEFC7733C2C926D1D8B0C8BFB1077A700BBF3892F0C4F3E30DF78BCE0A340A8F98EBA5BD384684D1E0081C1237440B3A6F117178C0DE4F19D05D4241240924D9EAF9CA45E3D4231AC903C8EE5298A3445F01961D6D3786E36D24875E6DF3EB1D6C1BE5EEA0E060D3E0EED1DB2D4E795D35A0DABE4A745764F05A858291993541AE149CECC5147FEF0F3A96B42F38963B9B29466FD66AD46CADA8F10E2D53BFC3B823CFED410147B5FD315FAA62ED06429D6D3FE6E5778A64B5C9BB06A8CF5561EB7A8B15838AA226DDFCFD4C31805D53A6EB7D2DB861451027CF84218C39078756B2911021C3EAFC2E82ABF792C5012CFCA3AAFB0A277A9C9E1E515CBC4439D95B2A54510318F5D6EBF97C8DE2AE0D4FF669493AA354C25460D3C15B1A57AC53D7E6C07CA407AB1EEC4A366A637AD4081F0343433C555DE72B71ABCD8ED3C043532A61125CC3CA06CAA634E5F75B750BF262756A57E3FD235FA9EF00CDD9553D37968DD680EBD5935FBDFE43A82E9DD39F96FD483AAB7F2D0517F23727E8F4DACBF144E3C9C3413B4497ABA623AFE3257572D979FD7234C04292B8EC507187752446AD11D10DE925035D368AF83D202AF6979123C7F3B7FCB8D83812728A890B5C09B482529FFC0737FB59C35B552AD7C5820E27332D2E44F2A31ED972E2E5C834FCC652204BB401557D6FEC656BD9F63B9226056E2D025988ED1312A2A767D418F1342BE489B463AA4BE823D471648D9893364758DACBAA63BED8B3D8D4DE1E4A76442D207EFD647078CA9CDF7800804012D4EC23BA14C99666610A22DA87523E4E5E41A6698E5235743A9B9E1C4795F38AE20CBE5C3A2111ABA307C3BA6E03F092E96AC6EF297548A3F144ECF7F643EF19024B2E98B51173450ED06ED68EFFA06EFD60721E73C9C6993F14C00E3E4BE441791C648110F699AB5089D7CD092AAD82AE007C0C3C8659506D5F2817E75EAE8B803734822A2526861036E35C3689EDCBA348A7A2E4BE2F1E291F63473988AFFE650C1BC49CDEA3875DF4E6B541727B5AA6F04C9C1E4D06BC5CC744D1B955958E2578C6176AFD7E3262CCBC0F6FA21596BDC36349BF9329BCBA08FFF934E31DC1FEDB7D7F6B459BB1A0165043B902D600C447792A618B77C1671E5793473DED54FB3322180F198873E306E1F8BD17BE04FCD3CF4D6A9201B9B804BBC772B742097663C42F0FEE3766B3B205F14A39D6ABA56963D03DCDF538ECFB8A7AE64DA3C116BFC09506BACF5E8B5754B220F7CF70C5AA4492AB72D20CF8F4966A114833B057662EC63B9570D9B2DCEAC86590569934F91A61A03E18835E31ADBC2EED3BE0BC148FF004675C9555C901B280BFB56FF8A1C079E1F290C67FD1B7E53A6C27A5C649ECA9EEF836621F9E708EB84B6F5C529ED2F07BF0A6160154F41F323DFF8A498177FD09D22DB15A273F787529852D898A6DF0FDBEBEFBA3F3B602B1E67352224860125216AD6D68CA891606E179FB415DE4B95484CA6907319438F69337316203F06AB1488A471924545C81A470D78E2EA29AAF89E94920AC4B0E7F2FE01092BC8CF3839480A02C0E8DAC1E864C9BFF5CBF46C0FC7B6A01FF0DBBCF96E3585496C392C6496D06C44765878B26B6DFF2C2FEC20F26A9A2706838A2048E579C65F3BDDEFC58C89D8830FB8C75FAF96788998DD200D48189C3B59B41501BD310420DB96F7CC5B61A2EAF88B498ACD890F7DF623A35479472694CDDA58C000D9BC04FD903E4AB88A2E757700FF3F460F075F9876DB3F76F17003E01DC96A92543DCDFCD7EFC86A5C0DF387A50ABB69953D6DC19A699CD225941F82438A8EB7889B212F65ECA7399F89CA0D9B9915E827D2E520B6D481C27D4CD833EE7D985B20FA5BF7A21E4DFCAD092628EC0A6E2DC876E4C5BF248F94C2ADB3D6C9F23C3E70D1F611A2041C7759317B8EC1696B2632CA10CEFA498D7571D016E102DAC10051DAD086BEC58AD5DDFD7988C5F433DE87C314E3930FFF937A6E0C81787F04B77F893287AB63125CAB8B7460F119D03BF3076A98FF029EA5022201DD54C854711B8BE718EE678544B51AB13B7ED0262C8180C2F36CBAB64D862D38AD7D8172AD8BA3380706D52048826CAC611B07468967CA4A4DB52628A2FD56DD3A323382E5DB171811EA861E2D46537D0A4E545C65F238380083A064421DC7CE13EC2F715580924D9B6EFBDBB0D45AD8952F602BDED6455C0BC2734CB135B79966464546A261D0A551DEB43E5AE111CD02D0F2F2E996454DE17B471C6103D851CCE2E1FEDBB828C7F4EE66053A57831C708C377FDC6FDF037F400A09E9A610350BE6C013239D7F1C42758CA84B428EB06C6A6A3E05F10FED769CEE2D8EDC3EEA29204605005468B0366B2E957A7A55FBCC7842598F55021E58DBEEF44C5313226E6E56A2D3837F2A098C94BEC791737F355E6CE5643C954C4719C6C1C939B7716A29191CF0530BC2E78CD028D526EC286FCF02B18A077C86BC54F078A19A529F6EAF69D5562D4B31E4CE3B953A24655429BDBAEB5378C13E5B404A138B2B5473A415EA236245B0541B6D92F384D4CE63680ED5A6C035FFFC663C893C8F51C5DEC6F90D33573A05CBAED63B69079EE77DBDD21AD7A778B37EA5E0543BBDCD47497F355B1B2D8AD93DF4BB96A5E85A2344192B782D54C4C8DF251BD5F72EC415621FCE91148DB266EE1BDA0885827E96E8A9AD9C50F43D947DFA8260661FC9326B9E76214D36B22172C026EC12E04ADE3C62D4E957AAAAE686D350793BC6E9C862D968C0E56B3160B5C70520E9AC7767AD2BD8D1D6DC951A23BE9FAF9DBFF407E7766C84CCC3F281C6383079DC3188FBE8F9675D0A26831EC44071AC6184AACBFA0A2326D7EF097650C1D4D1E58134408C11E839A0DBA17CAC9DE3B437E697663AC136380D0690DA4A52070A2DC552275BA09C01B601D55E97AD7DE83A32B962D0A9053C1533600FEFD1171C638A50922B9962C195551F81FE80BE28342A13ED0B25FF8986E0E9C39F3C2F29B9F40AADF8CF61E879A7FC863B32F02C5B5BE16F0E2CF00F30E312820E84D09BDF073E0B16B1F32C73F0E6031DCB3221DDC48670D0F2DF9A8065BD027C30DCF9F12782C812753F109615828997768C75660D469691278A111D50A72CEE9600124E3850507C0B963E9121C8B28262B6C82510AC69F4785752AE1F619E3D334170A4ADB4DAF3138AE90AAF8D82573E7AD25A16243E16650219C47F4CEBE6915B433B0ED0354EE62FABFD3E118AC777A63316637DA755A99AF97DFE9857B2F58A83ED70041EDBC49997EC93C03A7D55524CCFFF8018EE1A587AAB9FB5D3E33FE7BAF2642CF9421540C134F9BDE458A65E6B9BB209359F7FA47B95EBB79C83F329ECF88C7541446868CEF363218841F55D346A2B714DD48C711555BB25B1CCEFA6199A0E7646646B667634E486116C0AAD7E977C091A5EA356778C299EFFB7DBD3232C4B73B54C796BD1E33284CC8E4354C772DF1CCF762F615715FAA903D1551A67965FED6C7E1ED7BABB9325AC30F92305FC284724C59079B11D1A0E32F4665AD8390B34968D1885C9EB8BC5DDF63D7858E042CF7C66FF5E36365F1C7156C79CCDF596EFA551E203456E5BB22C2D9B742F490824B1D5EE482F335393E34E69C7820A639858C6EFFC2E8377876E461788FD2736A2D1BAAA432B008850BBB44FA193DC54757D8C75760638A12DFB614580A882EBD945716D7A3D3D29396D4A0D267B07B035EC001CF29C87E23D8446E21D604BCAB110869FFA98C32E35A9B6C878360FD7BF8D564B09384D5C52ED4FF586D6CC300F09F878FF5FDD7E7BFD0AC3AA2AEC0C223DE23D190C6F67AFF7C00001F7DE39C907235BF8D5EC16A34AD2D2E6DDC419F5B24EACE1A17BEF5CC52AAA05F04D5AA8BB018210354282E98DABB918100165E7D962A6F396F22753B1FB928AE3576A91CE62216E9E6214ABFF91FCA2E6E77611AD13F70CC87E67A1E6D886120CD2C2404E0312A57635D1C2524C97EC0BDD9DE011D158F8FCA7AD1A20C9BE0F45E814C954FBA214F3D3089AC4D01ACBCDB25B9331558FE1D29E67628E13BFC928F7A9A88D13E0759B77674C3F2795CDFE0C6617022F9C6A87B60C4B5A69E8D1706749FB0B4E086C94B5BFC16CC3B34FF3B7EC227A5CC646E9A003E5D897871067191AD1F8A8C33A0E567F4DF2D91D00FEA00B152183D202BD72DC0694F16ADFDD6E44A248D80FC6609E601CB91EE691C4535CD80BECFF9F23F32BAB5F106234A8867CAC0B5269CA2BC588E48AF922B5917BB6813E9D1005F35CCBFDFD419404B59A84497BCAD743384461F24267C497A932411B690BF405A7ADCA63858F439B123201F41AAAAA4D0A478101EDC6AD214E025B5DB6D24021464C53FB376503B6CAF4E4D4974E072F8C88A7C61957239581B589ED8D1753844ED928642CF96E5ACCA32E69B52CFA3AF54B9FF793E7553CBE16C4F9DD6114D1357E539C238AAA4434C5E540AB31FA584B82AFBF419DC51D6B08FEBE34B7991EBF2A82FF8E94990BFD02764F7D1DC049A635A08B7BFDB46A521170B6B8BD940883CD4505224D9DF930E33C5827E303083CAC4F846D9CB9A6E3FF57E755C7CCA541DF51819C5A52BDFDF005217000967A2776F51217813B2FFC509EE35F8AED6481BBFF5D5E61732BA17C90FBBCE1FC29E8DE849C146642845F982A2F766DFC0A703B5BB612E4C2B8CC426BB56196D714FC6F1BCAA0F19F32CBC06C3DD1406B591D2B0CD0E834D003CE56313B66C224594354866598118C87C1A86F7D247593846100395EE6303E54D130F91FDF81D0DFD021C274AA9567B9F9A500F35507519BCC25535407E419B52FA4D9ECD3D53F467B6295505DE979CBF6C7BC909812265ED65B30269FA1500264347FBCF1CB34AC5A405F208E73DD503D0D0E15FA474802F273C76C3D3DF98070BF3151D5D338DB368DA0D2280BD821880265763EAB2076766540EB9A51EAE647B96CA4326C82626DBCFCA1B3FF6DBA63DD64AEEA6741FA49E358E97D8F60C7F1A56248E8CE18933CD6F850E667134F69176DFBE2A4FC259994ADE12676F63D483FE16F7658F1003C1561B8D46FEA0888D2C82A4254AEB9E4104B9FBC973CF836BCAB5E263240ED9D87E9C434DC66E8F4A7B73EAEB30BB745F4094A4B82EC96CF99219F557ADEFA605DDE957CAD9D5343558A9A0904575A7A954948DC927E71786394DF40E9328C9B4382CF4FD8423B97088BB07CB4B257E5AC7B817088C3A6912441992153D374D477EA4EFD21C9F706D3619634AF7DB364F5FE73D12FF9623B665980B98E83991215E188462A57C4B3F653E11B4B1E16522CD421105A1FE67AD0F58F3D4AD34A8BDDEC13454EFD5FAC6146012476391769D4AAD22B1A0BD1CE9599600EEDD95DD265C4640CB064F92C22B0C45C64FC411375852E596F268EB415B03DA88ABF9A089EDCC5F06ABBD96E1BA461D4DFB3772938CCBE093AF922F5CE290295EBA2289660868ED4B6AE38B28B1ABAA06B66BB97A5396218691B13D099ACB89D6754517372564CAB054763190677139C9E2F0BA2FB19D0471E49BF6A0DFF2F951A414ED5D0F17C729891F4EF658F19FEB6D31F0BD8EC15DC9F9CC1FD73BBD7A6CA326AB06F55078D4F2F90CF185849567E8C78F2773938A916FDA23279FC3A9D62CE3C3AAD309264EA076635487EDE98CE79ED297D1BA99D96C84EB712CCE028298C8BAF5B5CB3EFB2EB8996EFFF6F7682D6EAFE498B886FFDC157AE3995D8493BC6B51541BE6862B41B5A35AC420D4D120957AC00B6E488AFA394C5C3F99DEDB4BC4AD4127082E44F22194654D3FEF9CFF3AFA66A764864D8344939255F4BD77942D6B2063FA9C0F82DD3B8D9ABF5C633B6CACB152AC09B9DF3BD12770444F99843FD913E2C815368910DECDB46DC4E13EF2E89AC3FC7D13749B88197F633BB6044E1EA0FF4CE060C7F426D01D0CE94833304CDEE3C857FC7258DB654F49E7C949C4D4B2DDD689DEA7E0C526E694B5EF77F8DBCC199F73D833C54C6C389C9C63A9E203FDF4389D83A4DF4AD86D7B36D3847C8DA829E04E31BD81791E403D6098AE9DA476D75B357A74FBE2F0C42FADDA27AC72B653FD87A8D1D72E72E2BAF5D852D1FD6DE10D5A6A600C795F65A4A59A00E2C503DA0BAD2344CD62FFFAF6761831AB2CA4055C18294DB1CCAF2BC6A13DB522CA1BFBA9DFCB930E4D6C32EC24DB5A8D5C15398CF2202878D240BEE11756559F26355C059A81765FD0D993FA64887D5CB6EDE1B379B2B8B5D5430F3D7A6ECB8259220DA7C9106CACBA69CF6444192275A2C6EDC588234E8D24985A0770607FE1C4AE8CC7559B3687522EBF7D3CEF0E19B229509D2A247E8650C3676B3B272340EB71C69064FD3CE931406569E7AC1603E49A13BEA93B2892704378ACB4796CEA77687C98E8AAEC3501143271E504408CA5D7ED271C45A1A7637CFABEA8EDFCB11DFF3F8324C8C2C7D9C73A26B8B1C05B6F18013E03928FFFBBB5068FCF4B29FBC21A5819EF85B91B19A5098883EF40D91B7E287749A578E7743680786FCA565BC4D19AAC06BF70C283E7649992BD6BC0305A0A093B75DCFAECD7E049E16F274AA9B017CAF3F5068FECB55C6FA6ED97F64E17CF1CDDDAEDB45036C6B2227A0AD5181AD7389B72C8967B8176E18CAA3506BECFCDFFF15B598C47D10E11E65D9AE8AF9AFC8B189562D98BBB02EE55D0A5C41EEFFD3D6E8EE69878B3A003DE7A52A98978892E51219387C24BAA7A773944F530816FB27BCDCA933370CB340781A70DB5724C597F72F7A34DC05B732FEB79A18171281AB7A94DFCDFC2C96DD00784F2E67D7E56D0F146F1585EAA1448BE1CCAFC6F334CAB07A27E524BEB95E19D426689B900176A70B21E32278F27EA3BAEE623F92B14696CFB1EABA0D90EDC414FAAB03AC0572B4B8836F071A375849BCF46E83A05979A4111167CE5C43F6FF48F386E3E8F92FCA1655E3ADF4C2123DA2C5551E252E9BFD93276B5B2BDADBC8F23C0406875614ABDE72C520002AFE6F55BF1D19ADB7F26D4F71842FC66335FF670C60583CE65DFA6442DC6DD49889C3DA3AAF0FB310C3AD990480EF12059DD23AE881D5A72603F50C7C61626AB2E0BF9C8C198CB0F637EF72954E04DF5956355147B5073EEF3848CE65EBA73E67955A1CFF187CCA758372FB67823E230B05EAA9982488E8D22F6DA1415A731BD0A2B036F858FE16FB4349149B507D9DF770B9F3D3B45ED752EE888F40FEE65C4F3EC6897906303A19863DD968C666AC1980F26D8B574D5A16C95747AA6DB218471551478BF36140DCC5C6B9AECD22944CD2B781A240C914D2BC4B37877709794CA33ABA878615050637B0A0B3F04DE2FCF37A2442A242E6C97398CF483260BE8A092F998EEA5FB5519EB25BB10B9350AC7F6948CE13DC282ADFD3A251C07E32A25A8A93276A563755B3164C0A9510260425ACDC093CBDBC6C8C5D0FEC94A6DDB415C80D45BF9A6D8DCDA606E3204EEF6AA291AAC9AF7122810A77E0E1160A461AED63687B3C137EC40897B972493F33636B2CFF07747A394747C0887C0402CC4F50E78F70785E5DA4C6084BFD7AE379F0AADBA0CBADF8C70C34FA7A6B0C14F32D52FE8AC726F750DDDA95C741131C7F692CAF7A3A80173479690A3CC0A93D1823BA1AFD5634A9D14E17E7858221497CE6934D7630E73D615127209FA239A190EB60B4D49770A1122DE7ED76708CB660EC4E52900D130C9A4638448CBFB16B1943D7C007D521F945D00D42CD0AE51FA89D5BBB9DC68360C2551D3A0E08CB0025B061057FEA0855305C0F6496903EC94DDF067E722AE07D06AD5AC67A1B5A9D1D036F4D157220087AB098F2C6A911F710332AC3AF782A6747B8E079F12A768B9372BAA222EF43084F65A46EFBDC5D8BE794084FEDD23BB2BE82A7FD1C5FCCCA0E10FFF7CD47FE805A43F82E73773670C4F43571767DB9F9A59A16B1C6DFF3AEB739FDFDCEE27D8699BC080B9D5973F30BD546DAC6DE594F91E5C2F0DF432099D949C5FD0E9ED66BA4FD37F77CBBA8D511A0D712DD62859D6E3C0177A264EDC37393FA86D8BB241B13A2023CECC4A8A57242DA1C7BB796DB4B50197F8E7DE6FD645C6B9099D6F76701B0A36CF2DBC1C9E2F56AC8CB222D37682E19D33A1728916687BE117E14BC7D137CE28948A0997FD9B25545316DC91AF2780D34EB5D9A262B327FE0E57AF30D9299C1CDD7FF92E3CF8C70A9CBA640A71425B164DE8D2D0D78A19853125F684FB1E94D7D02473BF12C6537595311354BAB832C69593F4195132C6552176CD781A04D4293BB9E329B78AE8929A249AAC01C5C81DC46DF707C914E08A642BF4B0277302BBFE3950EAB036CEABBDDED57D2AB2DAC00B61474150F0F641A571573A79C7CEFE5B1E08C2A0D7C144D69764BBAAA9DA45E8C1CE02AD4BDA14E86E6F4509823913D553117C25BA7727244D0A5F4106962D2441C4D3813A780757E169AB7DA6FAE572D7CB919DF7BA028ADD524236473F8CEC4509FA954310D970F13B8F57505F248413F93CCEB0D2A8B81A3B6B812422E630863D5F37142EC8B03444B7509B92C2C46E8B7DB79679EE93FFC1DF1B807E29773C0B9A280334CD97CFFA2AEAACDA2A662F8767A323DA9D48CBCD419ACB2EF27A01A26F7F2968B572B679155717F7AE7CF17987EEBF9B088B153D06F88F683CD8A53B1D69CA429BC5D17DFF465377F6895611C319A8C8BC23438BED492817703D83BDBB93CD491EA8C39122ACD809BA158D5951E0B78FA5409E63E7CC69B5B6BC9BC56349CAFB05B71BD8C8ACC90F929F58037617118351CC1E0E0B3CC4040BCAB505CA4AA36C06277B4D550922DC424A005854FEA6EBE6C833980D3F7D49F38F595E3B156B89809B65E62B57E0C79947B2EC463027DE21FECA9FBEE0CD5B8EC64BB776FC95D93232C53A5A5D8F5954AD65E6BA6A3677C62497C3F4DD408AB08F2B05E00F865CAC6983159D2E4EB54EC0B89384F890E6033F71C5C888A9EF25C2E5563F4B79CF7F80E221C59FCC0CBA7A56ACA182D6A22A77AFBDD2209D5BBE8400605B918912E1F8268EEA13534E86FE8B6588ACF64A1322DFBA8990E280AD5A2E185DC29AE3AB7AEDEBDFF8932A21ECB57071D2C6207740AB48DA0286EBABE44AB1566D845A6B231073076634B6493FF5F4669CE06BB0BEB477C3BF2F9173ED7A36C22EB347036E7358BB62192E4E7BF5B9515C6A433D21E47F56C886AF92422741D1CA07EEB3A67A027283E78A27B64C89AC0EDF6D3CA5AAB03AB2437B7813BC5E349434386F00F0C0D592256BB28E68D0ADD1F23F001F2F0DC867BE42CFB316FCC3AB7F2ADE8F262E2F2A817435D72D2B9F181E285F7D58C2E9D0ADCA7E67933CEE6F908BBF182523A0367EC978CAC6373140022E3B851EBAE9D7086C4191C0BB856FBA1C5785F57A555985D0060A4BD79FC0FBD7798CE46C543B3D26C62BF07B7FFC0C5CB00729D2F9DC75A8A308AD312EFDB71DCF069034FB4F970969B749BD6F487F5E77627FFA00F64DBCF819A4F8EC0681AC3816282EC1717DA96444B3EC00B32B8C07E806988EEE0B8CEAF0CEED4F400F27F1D79267AA4BA333E61B84E6F10222FDEAF05D3561F5796CD819C879A07E780BAE63E780C05F024F2880EBCAEA6C1C8258D94B753BEED298829CF221BEEFF249643A4915D5C0E8AEAD2C85ED170790074EEC22327260470E99DD940227A671D56A9204224861E56624244241513ED4AC7117ABD09523C29C4F23E0C41900011215540597EC1BF8516CD28C228D03F8C7A65E4FFE575C6F5FB1F833B04F3DD1FE2DA3F983FC8A6BEE8CD7FDCFBB4436D8E8F09D466CA0129B4080F5C4D2A078B1CA2BAB5B306B26B4F75F49335E128D5E27B6FE1D96B9B863268E813A092C5176087562125530D23E8F6D61D99ABF133B032021530A5FBD7CAA65063B17304B76498D90B0F3E6541534667952F6B31A74394000AA731CD42D2CAB1EF3AD7AADBAEC7541D04E60B843FD337D7D08B9991452889376EB57FFC5D2D454B35DE0BE42E0B04E5C21D950E809C5D499AC04DE0E4FF912237DD83AF0FFC5CB8E520493400C91235F9D49BB30724098295713F70ACB57194F53B656D4B3E5879E2E28734370A052FE51C8139021ADD0DFC6D3D8491AE9C7C8E3AEF6A5C1E119D65923212BFDC35792BB5E3109BC36003C17100DF5302C7FE73ADA012B36AFA5452CFE356C38E63C59E80C1F3FAA1735150F1F3CE87E7008281D125FE7627B3D6C8DB3A2101DD6D650656EE5B8E0E8F0CA1DBEE12303499B6CECE8AC80111C504804F9ABF9C616D22DF34FBDAF27290F4FE6675D4A1FBE8A93A91C6B09B1456828554CD0CDA039569E2C08430C3481E2970BA760DA29C31944AF18085694530E8A952B54516062CD9528A95D0772323B4B8E02C7DCBD71FFD2236E772268E25F6D4C622F07F5D437275B2FEBECE7605967771BFA2007FECA33154FB46A3B788E9E7702F38BCDF175EFE4611B61147D89195BE90840FB1E365A76840BD9B40C21949F2D41205A491C019B7F49139C remain = 1099511627774 -max = 1099511627775 \ No newline at end of file +max = 1099511627775 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-12_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-12_256.rsp index b5b876c43b..a99617b857 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-12_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-12_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHA2_60/12_256 - pk = 000000089C3469640CD3578A98E9F9471F596649E45D969754FFE37395B79731156A1E2204562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 000000080000000000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A9C3469640CD3578A98E9F9471F596649E45D969754FFE37395B79731156A1E2204562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E704000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF54961000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113CD47F2466A56323209409FD7FCF7485A71CD8CE96D61298A20473D9ACBF99C010000000000019AB3950B30D3E7877159B364A25B214B41B8AA32E293E2DDD44AEB7DFC560A82020000000000019C359D104347B69607EB28A02E6924C24BD2A26DE4CFFF3FF98E48688E291E58030000000000011EC9B78F3B1189A5482238BCF700922D642E45D07E7EA10833E31A4CBC3CA08F0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019C1A7BFD8300283215BA57DB5CDD95EDCBD04E1C41419317BC2069C2AAAE22130100000000000143ED646E32FC21554D8DAD350C5732270CC220F7E264ECB5B7A8E8A4586D0CD002000000000001762D040EECA13E137753604D099809D946063368BFE1C7CF0E6549FCA746F7C6030000000000015FB7406F1B25A2B4A6A1666269772EB08D6FE78D8A8395C56AD80FE6924DF082040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044E3C9C3413B4497ABA623AFE3257572D979FD7234C04292B8EC507187752446AD11D10DE925035D368AF83D202AF6979123C7F3B7FCB8D83812728A890B5C09B482529FFC0737FB59C35B552AD7C5820E27332D2E44F2A31ED972E2E5C834FCC652204BB401557D6FEC656BD9F63B9226056E2D025988ED1312A2A767D418F1342BE489B463AA4BE823D471648D9893364758DACBAA63BED8B3D8D4DE1E4A7600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017F7DF0085A4DAADCB03AB4E8241B0E6DC05E727E817C3B6FA27F05AE1FA2DE1601000000000001BCF2F650C31EFD6F2F09775A3B4F87BBB33AD0D51537DAF37E0D1C1AE8BE8DC00200000000000174F4FE7914F390776AF328164E738CA8EB0751EF9E535BB1B0E80B05762E683C03000000000001241535B940156367A4ABD922871FB10B37235B67CA38CD8B2B02AA8064C5CAC60400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D4FF586D6CC300F09F878FF5FDD7E7BFD0AC3AA2AEC0C223DE23D190C6F67AFF7C00001F7DE39C907235BF8D5EC16A34AD2D2E6DDC419F5B24EACE1A17BEF5CC52AAA05F04D5AA8BB018210354282E98DABB918100165E7D962A6F396F22753B1FB928AE3576A91CE62216E9E6214ABFF91FCA2E6E77611AD13F70CC87E67A1E6D886120CD2C2404E0312A57635D1C2524C97EC0BDD9DE011D158F8FCA7AD1A2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000186A69EB284CFC56C72C2C83351D5CCDBEC831992175BC2D2D91B3F9378E0DE9E010000000000010A318F954C197DF2DF39A85C4B322E7EB1B16B0B4EB8C8A492F4F3B904C47E7602000000000001A9204F8E84112663772797AF87ED34C559ED4D6D37E634EFACE6A18C700CD53A03000000000001D2E20083FA11E157A2E5B72C9A986D3F47348E54C1935F48A86F7A9D78B2BE600400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A6442DC6DD49889C3DA3AAF0FB310C3AD990480EF12059DD23AE881D5A72603F50C7C61626AB2E0BF9C8C198CB0F637EF72954E04DF5956355147B5073EEF3848CE65EBA73E67955A1CFF187CCA758372FB67823E230B05EAA9982488E8D22F6DA1415A731BD0A2B036F858FE16FB4349149B507D9DF770B9F3D3B45ED752EE888F40FEE65C4F3EC6897906303A19863DD968C666AC1980F26D8B574D5A16C95000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100132C90901F97161C5614019A534B035942B26ADCEF40AB97BE258B03C87585010000000000012BB35E6F2C4AE0A3430CE207629C011B30E4C6F5D6BDFF2AB750EA0C69BE95C1020000000000019CAFA71D2E43D02FBB0C55294A6CD0AF3AF0816F6E6D1F4022AEFD413DBE8C1E03000000000001943191FF197E71722D961AF04F9570BBEC438A6D22058F1018F6C61F3CED67E50400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000290F4FE6675D4A1FBE8A93A91C6B09B1456828554CD0CDA039569E2C08430C3481E2970BA760DA29C31944AF18085694530E8A952B54516062CD9528A95D0772323B4B8E02C7DCBD71FFD2236E772268E25F6D4C622F07F5D437275B2FEBECE7605967771BFA2007FECA33154FB46A3B788E9E7702F38BCDF175EFE4611B61147D89195BE90840FB1E365A76840BD9B40C21949F2D41205A491C019B7F49139C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012A13FF51186CBFE9467BCAB51417E5129671EFD5D0D686D09E2C5BB683FD45450100000000000184D0629348E528473585F873A1929F01BB41F19090B770D155E497E4AFF30A990200000000000163EB4A114558605E9DDBDA75D10B78F28322197D1DF7FB4214438DA12328F8F203000000000001B86361D142F7F14ADAF4EC3E307CA82B6106FBDE3777E656781187D3558E3E1F04000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008AAD20F59A5E2539D3EA32A9A717691D72C2FF90173D53FDF598E4BC0790180A6CD182CDC6CA0B5FE69AD663506A6A43EF780D1F2B7E05E904271A587E0619EAB04598E3574C7F271892C3F482D2817BF74FABF9B63E43E74348386C624CD0A73AFF1C917D1DBB8D08BF504299C0DE3E5736BC9E3FAC872BFEBC1E5DDF68D69EB0572AF7243E531157C9EA81ED640B87BC14A959FBCC7658CB5BDF6E87F4E6770000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E203D0691CEA545CC43DCFBE161452022A98B0EE265DD051C66D4D40CB142EC70100000000000198AD7048E8F4A1AC6FE162435B004552EAD82ED6463EC081779E26B35577C7A202000000000001BEB756F3DA637E592811BCF2D4051971434CDDBA76FAD2E9BA59F8BDD7AD523903000000000001F5264362A5684064AAD87ED555D342E88F3DD3AD0D4CD54CDABCB2A33B347A5C0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000CB4A42F0E5A9ACBBA9A6E6568753C7B8E4AEAB9B1DCE5052A2971003750085CB05B68E6E9E126AD5BE084FECDF62C8AEDC63A920DA15D1A3B4C5CAD650A2DB43D93EDAD2E498B0ABA4071B75F8DDE617299C990E6979D860461342EF7D52E632ED2C78AE41EB9ED9ECBDB9CEC925EF47CF57E413BD7A4B9A71E6236CAA1AAFFF8A8066E50E19D3CEA70F910537B76B350CC194B2804C1458A428BDEF11FD82470000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C59C0BECDDC4FC283AEFB2854FC4736C46F380627C810301EA77C23239780A100100000000000157A6050CCF22BE4B46B275064B9A7EA36848C9FACF2ADFC708F950326444E35C0200000000000179C1F7FF0B18868E800C6EBCB4BD4C88CF17A157A22A079435B5D8AF520D290203000000000001DD30F4FDD599D12004F8B06EB85EBE61659BD7CE19E28309A1F5D103154FE4260400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DA74B87E0ADF3119B9A2AD38D7679D60DF92CB86566B14AA71186C40C338B3A396579902434ED860428BBEF6BBA18121004411641C50A92EC832174AD38A679F5A49946EF241A8FA1D26974F9E465B1DB8C6F88D84B62A1507CAD3AF350DBAC43276A87D94FA1C7A9E8488B5E3A2EB66605C69AE4C2D7A551163F85877A81D5B0F988F48A6B2D06C9CB879DA0068CC2B3DBC36C5BD714E30A5021AB48AA57F830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DF4DA42AF634CA5BD15D0E372A2AC3B003D11DD9BFAE0B70E6E492E9661278CE0100000000000123BA7FBE99564830BF93790201B8BD29A47D288046D9E19DD1011CB8CD8470E502000000000001427455E428922B66D2C1F37EEA0B540B002E8989FE01F762D0523B5E22BC74D403000000000001CE06EA2927B35D814BA88A8222E3070EDA3149DA0FBB30A0B7EB1206B74E4487040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020468B089D5CAB0CD8F29FD284ED47E7546D39B4D6124B431B7190FE5D5489DF4C39914BFC951CCE080444FDB4D4BFDDDEBF80A22412911D5CB7DF5CCF5434E2E9C7094FF22B5924EB967324E73090832FB75FAB896104DABED028C4D096234B96BEFDEC7E669F850CD731ED2782B60512E2F83B3E063719F2A0F984C9EAB52C8BB7672F4A7E75231855BE3B541BE8BDF4638136802A83225ECB0020B956B6900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001E7143B6E483C8094DFD75A5579E15E27298991073099C5103C6F44E17604725001000000000001C261BA3B2D08ABFCAB9362CCD93DC25527163262B29AD7AA14725737393423E902000000000001E990075F7BD30339EBF3E3034821B5794A5D5031F2842DDCEBBEAB049F3B5F41030000000000019415C6FC5645D2BCB5D37DE763D8A3038A00E8A5547CE9A4719C5DE467C12CBE0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009D550F851D023315BE35A69C83D099341F6BA69B6A40E224DC554A3489D33729C9EC8196BD665514030C26AAEF80CD6E1BB9EC739BAA2B8E4A63EE691AD2BFBABDDEE2B13CFFEEAB7C25273CAD45409B5270678CB1535AB800679906CE77189DCFE05BBF92FB5E31F184CECF3C427437958F695917E343ACF46DA2B9D988CFE316313FA9FAAD49EDB72B007A7F3D6FC55A88E6BA784FEBE9737803AF05B4801CE0C723C0D15CD8E7CA8E237D4A1C0BB1413D369FC3F21F69205D428069EABE626B971A2B5698ED05BAE54218300BE8C4BC9A52EE5FB296BAF2A9AA42F3C865DCC1DDA69969F085C91D3CC5934567476EB70461B942059AC0F83BA10DFE783F5FB405F159563419B3F5699179D6F33AD05E840EC9227C592E361A49E31D99445437D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB3844833CA9CC7907865878A01BCAE7DB72BA4F7701F20523E0E98B27AF08AA747B57DB1DAAA1B616DE469C7FC83CAA1DA1D6BA6F0C2B0F7F2CB7A4F58FBF7FFEC292AAA7FC3B87E797DCA067ED7672BA9B4CBC27FE9AAEEA63C8569A567129990E1E12A8D23039A877F7FA3EA9B9359A842A19E33CDBF284AF95FAE2A2DDEB80030A8245A7E51131D27EAE94B6C38A8C4818CA7EAE0A1C0841E7AACDDF68A4C4491EF97D5F3F6AD8CC47D2489DF1FF96B7DD444D31DD2FFFDC69C9ED7F750526B3CD81EDEEE2CBBFC0BCEBE875DBB644B3828795D2B81DFE37E0E4E68F9A798E09588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE596674368D1D405B742EE812FB88947D9F5DE52083777E54C2F0A1F605027BCA5A12BDBF9CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318ECCE515F732608A96D4E557ACCA60F144A212276CD52FAC0F12C39F7F45565346B6EE409558FF37D5C50280099C9D75B688C7D873EA7D07EC6C9305AB367ABC2FEAFF9200CAD14D71DE9E1F1DFFC4F15FD0908C6687F585D9721AA773BDECA4C7DBDA2D8275C59A2E90EE07ED6734A09566174D695356166041C646F18180DFC5ACCBA61F1672213C3CA6933A5ED65898AEB4BAF534751900D2CF25A7A94C273533B8694EEFB366F4B3E6D4DBE7FF5FC70EF5341217906FCEC863502598936A4A0D7DD4267B1C0C6E8175CFB3B9B6BA86CF3094D4677BD57712235CA8395A6914063B4E2849AFA406B7EC6E3AE39B343EE39348D2D29A0C2319BB34655A53E1A816CD5FBAD3A3796FEF2C7B67BE4507438E5AEB603B1A0796293A274A3F3D63C7C1F14297987085EC271F06E8DC986CE41DDA37ADBB39613E6790644A669594AF10B5D7C2DCDA7190B03F77E69D79A143E9B7D8B42E18E56D1D191DE05D58DC29F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA4C86ADE353F4AA57DE2220D13EAC9BC8FE02D625EBE3BF2761493F180F968DE438B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE8D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB07425116F11D430A927D45FBAC134C59EA8E5907C35A59E0CF2FA548F9AA27A3530AEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBE6FFF1A2A91E8DD23131A7840BF7CDEA3E18E706A324AB688A5866B82EC18082D89DB83F78DB30D5CE6EF134BBCE7628AC017E6D6974B1D82E4227235AEC9862899B7A4E0E8B10A8AD0B19A54DE7ECA861D6AFA1D91C9CAC7B8D6AE536C458E176AE68697912D7EC853D514AD4EDE982FA89400CE895D3241E5610D0AFB17AEFE51FBB41E2DE044A00D84BE759242476BC0099DFE159F0CAF2187BB311DF2342A59C003778A56907F086C8DC9309D8E41703779C8E1141070708E02B9F987ACF3214A8E442B76121374DD243643D64283D01279A49154760E3567E46ACE89898BCD67842223D5B8CAB03DC13930BE7210FAB7FB2318BDCD92B642F6BF178BC30B4F959F5D8BE15F67C5AC4A4C81F1E3E707AADF0B4CD02982ED4E4E52A81EA2FCB60ACB5817849D53C2FFFBF7906E290BF76E505071913AE0361FDFCA4B279897C9DECF546FB0366D65C9F81A9B51402F3694F0B5DC600B7E4F084383B643AABC755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E6C007F614D3C0A2E45486C2E457C2E6636BC1AFB76B2A7FA351FD88399098C64E379F99B64A3340473DD46C11564937DB9A28C4DE3745308433153B2BC6D5E0D515C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFF0116375D404211C3D3302D17DDD0390712E06CA05FB4BB2AF749D3439A5B30D3E9FF4731822AE6607BD96108BD229A4BDA5ACF50F7185BD1C0F56CC56D69C008077082C0869F237A6F19D73ADCF9844686E3C5583E7D8FFDA636E70E989B1742ACA4DCE98101BBAEDA8E852555033A46F8DF4E3DCA1B9A09E9F938E0C1E468C52F7DC695389C21D0F425B4DB554FD5BE1FDC2765B997FAB1F94D864DE1B4C8FB1323A8D90DC0CD7FA7363AB70728FDBF33C2325FF97C59ADC84C104E730C85CFBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272D144DEFA2E32DCBE8CF7843CBDB9A67EAD7892ABCE9B25A6B91AF0B893846ADDDB6C26354D4D8B77B14FC2FA2D8D589237C4BAF80344C306439619E5A4DDD4630B558BC9B3581AB842BC8B630F232BD18D4BB10FFA1DD3805B18635F6A9A22CE0D470FAA2AB813662EF63C784628138499A1A3648CC877300401E61DA9A379FDB3FC6DD985CA26EE8093A24879BEF107C4D6A38017BE3AA5CCE124259C42519C6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156771072191C21BC3190193111CD3BD0604EC5427C6D70B1BF21DB6E59ED636342BC417CD9F69B804EDB6359C9F8E347AD253370E065D500CAC64BFABE3E420E39C27D20CB93DA243BB3270F1EF2DE68AFB80842E8BE7C1FD48BF0F5622530CE84C1D30BC69EE1164CC602F2522FA39158D4D0D30ABE4FDE43213ABD6E4D65E62FBEC9AA1D485599FB7ADF5C2C97B90C82A1DCCD2C44ED66CCE79EFCEDCAD0CA1366FA51DD03DAC9BFC60B79719033B32247DDA9195233329F5AA36627FCEC5E42F078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DF657C03A3914FD3BF1E82EF96AD7EA46373B0A4DD0F5655F22F754DCD35ADA89358DDAF6AFF78EEEF21010DBC6556C2C3A018E4DA1D612CC3EF237BC2B1E9E600D923E2CE04FA27CE8EE63B969F6079FF8551B8C06018E99D84669C059AE08081E3A1C7ABC19272D7FA3F2704CCF6E491AF93C7CBD4660410389D86BBA47BD5A0E996F788FB9CE600AD76485D265628019B57FC69631D5266E8E46913ED9142FEFAD87E26DE53ECDF43B352EAC14BF6DA899058228C9414E7323430F9357D6244E7165F5CA2FF2DC9899AA6D8C2B8DDE8E2C5FB7C6E02BF74F578823CFA2355F2FCA1F776C6A87943344A5E53BFA39559EF98C397423C75EB318EA9B5F375C17E7B46A8D592651E7D50E70233224592389C1EBD1EB66678AC42C2862A2C660BACD03BA4064EA38D34A7D44B32DB9E75ABC6B5025B504DEC60512A80F78876C54D36324C7143FEA85ECB9E66800E8F4004061EA7607EAB964DE3F9A273D2C7A4CECC1B4270ECFF87A254A139DEA1E0F0B0F6366C02A0A790D46EAC94866A82DD8349F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DEA67846512E96901F78E601EE427F8B1A7986FB8832D091D575C277CB202E87602D670CE131CC6023A9E83AF41486A04D62616C1E912D4EAECD5DC815BAC1C0DBDB347F6B5DF06B0F58441FAB98B9511AC0423ACFA43E0422A62AE32A48E935C6288BD0D2314C6A739A7779BFE24DD7E2D66E9C4A4111E22481688EA39F256224531ED241A9D35D395F340421F2D8F5C05B873052D2128CEDF4ABE49E609176674363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D02AB14858954A117C6B6F2CDF4823BEEF1904FFB4D841B30537D57C577968CDF18EC8631C536AF09B54D5887FC0EB11A70E86B72EF315FD722FB680EF03A3487434215A0EEA412C0D78DB2EFE20061576237453927710860F0A49DE0ED0C42FDE2A5903D635B19D4F2001EE353D7B5210E1C01F50251ED6E753635A972EC8C1914E36522B1B41BA51E9F3F1CE83BB5F526FBEC31C21983736E42EB7880B9B27EF6CAE0618E57F881193714D3E8B38C9E9056378DD79E78422BD7C4CD57D230EF44B38F6A107ABC77B8D5A953D3A3969FBB7DAB145C4F4615FAF8F2172AA2BDEB35C4A0494100CB9CE188DA4318EA5B617EBACE910A32F0A280C82AF82121720569232D71AD065E45268B36F92DDA13673529F24E6B83A865F3E266635D9655C8000C06478530294DE092640DFB324E09DB3B87497C94502BD46092D72DAEDFA93A0353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB51691B3F0ACA92B02FE916D2AEB98BD9E23313F49A0F44394883A432523EB5B34B690EF9C16B4D60572EF2D791F2BF403255A28D9BC3352B02687AD9200D34C05259FE0C93B75455218E031D59A65D4F571CD7F8B130A0CA1363BAF2D9895A8E8925ED20ADBE8FE96C34A6A13B9318AC8A23A7EA320B83B7175FB54868DAFA9E233B0F4B18CF6FC7D85F7A2B28CEEC561222C5051572B092F2FB269ABF1CC7826675F09949FC443EF723AB476E9E5D670C5F05E46DAE93837AA0F65A4E83AE2C71DD02CAB1038086531F93E163AD65BD962ACB9497C0F268876B5AD3CBBFC4C24EB2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADB0A78B6C1C4ACB8B4C97EA8C4CC3F3778CBF761AA653D9531216588A46701366E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC4050CBFA6FEF6B9FE785A59511CCCE21EC5AE3F429A07B4626A4F0C555A15B42C26A5F353E7A479A700595689D5734C39D61177AAB2943775ADAC879B4ED7B8ED826CB43881D2C1B5734F64A5490A4F77ED4DCB9775B258C18182B42C560E6CEE89A329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB041A19053D3003420EC262BF0F45F1C7CF6E55BA9001E4BE097329CA460D335BA899503CAE0D617BB7FFF0AD37076C91B1659BD448C05C49D9360462B4BC601536844FF2C635BB654EC5749FBCEF3288E41B8A7835B645E0BB501FF805EA4B39785C203BE03F0B105D17E513D50B7738E78EC18AFAB3FE134FD551E754CAA189DC4FA2308B6EED1B8CE87EBCE212E15E72C9516B778C1F62819131E2EFA7AF63BCF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0A2979199F43F2F59FB2C62E8AF2EABAFE9B89B71E75AF029BEC77A6A56F86EF6A4A7212A7458986D2DAC9E00CF68EDB81CA05A297B522D3CB2E0AC3146E4638995B683EC201C67C911C83E6BA3567D31565DF914783F41077E2C31B06640446A6D403F9D46BB9D00B3C436FE1FFDA80AD0AC466AF0417D18D5E7DFEDD7D68987BA55F545F3B89A38908BCCA1DACE0B89FFB49FBA3A67EE7384DEE68FD05721483030ED53913A6CFA059DDB451C780877E919BB86DDCA9E18814123CCC822A8F30D0AB4602815D2279398ADEDE00B23AF4EE605A771AC616CAFFCD3AB12991023A6BE6BCEAFB1672ADA631C6CC29827088627EF9380FFF46FC479E2B586432B58F95A824C0D5F08704C2B596A7BD0A36A52BFD8C14D999F92E676C83EA62DE54C3ED7ABF290BF17C48DD69F949668E11D957299DB6920D740252A9AFB65179FDD62B69D2A1A339CEF805FD258D83FD2F406841565AEF5E42ED7687D9D466E6A4E513E072A9EF6181016DAD988F7C2305A77740F196465CE30A35BF3D098781DBA7285753A9438517AA7159A9C806A19CE8B8BA5F9C99250358404671F36214E8A7B5A04767FF8C094A3CD74751835BD896FAEFD1747DDFBBE79F48148D56BF585CB0CBBF34300CBFAB9DB32469814F107EF7822151D158CAD68F01418F88B181B092970DACAE4D5DEA7AE39965D1929CBAB7685E758206D309CADC07687274657F6EEF56A657D3FED4D34C7FF6C9CC5F344F0EF4F0E752F83E06B8A23DA0D65A2C10C2D675CB3A214F5D363C35E6E10A1323579803E4268F7D868F4716BF849B3C3D8EDA94476BE7322891C36D6DF146075F11AD02434D2216351CC26600662BE0D38E1DFEF9A832B9F066718FCB2134115F33717B57936CCD2DFA3A95C1D4C4C98BD09D64EC04912C06C7C6A2FFDCA2801628D873EE6D0D43EB67FF0AC93A7666C9ACBB9400593C00316E05F0F5706ABD923D85DE72A0D1CA9F0774F5180B65AA578B95BD20C1FCC322A5B23995ACC9DC97CE3043B1A723AA2815314637B7667DE02ED0FA0924C0791CA09FA028633CCC594429D6E7429930C7F01EB6A134952E89B8CCEC743A23C63CDD9E161B5A2D1F1E0D005F16727A3B0E8B90C20656B850A4F8B5D400B65E91E45AA25A880B76BE09F226DDD4F0E0AEA00259E19634EBAD387CCAB556997A153D1C1B87AA62E5B613A5E02C65E7EE7DDE2E19D965D27B42AF8542066549A6FEFF3E10A93B349EACB843759F5E4EECA76CF82277BD55C57FAD09BE938ABB47720E49CED626AC860446B290C7FE9BC83DB0C7FDCBD5CA2B8FF6C52B2CF2556040B3792BA99DD43EDF1FD4CBE38970D235E8BEE40DDCD2708E432008992D3F9DCD73AD594171092909019E9BBE7A5D4A21EADF82C5C22D877F422EBC64734717C93A027E9EA7EDADFFBB8A04B465E2F1BDDA54BA30963A41978562C27EE91E8ADD7A95B97A1F9F5C0494C3E44AC5422759F971200B1927F5C37B003499B213C1CEF1823847ED4A308D7D98FD5E42115D49B1FD42C7405B55437E1C8C0226884DD801CD89163AEE8D74105F621EF2CE222B13ABBD14078943CE054E3D68F7E8D763948CA83876F0AB7CA5123ABA8C5F68679FCD116D03391F2A53F637D26EC486FF6363F0C297E1A672EB717107ED9540C2AAD46038F8D4C2B5D1D918AF6BFBA7DE46E6628B2C217672257EB98F585A4E4CDD87729BA5ED16719F869FA1495302E8BD043F92ECF8799DAB7B9C501DC956EE3E55FF30E6D565E228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023E10A68B5275694C30FA7BE9BE2392EE6B18651980A01348A97C4BF091DE3501B30B528092599313ADC93C8407FB07E740F784E80461A23A1DCCD78BE8A72EE2AD69CC6E63F385963275DF49AF300E5D468285CA4457F090504D42056F571A8D453903B85D7E63F893431A5A1C8A66A8E4C999F0592D75717940E296C8275952C4A8DC6E97B3D5602408DF3644E8A1338C856296C37B1BA8445883CAFB408EFB9A545AB53CD632C40659DC607F4937A4F364F7E3B47A907BD30D8558C76A8EA9EB357177B8B2639477433604EB74F9C2E3528215459533C1A989FEF107944FC8A402E29495F72F2C210135FD836028B9E21E76C6F13096DBD2BE9721DD2C35504D648C474907FFB896B014CB022942F308C3263CFF227D4444763A483658E728EE6B7954C48E3FCAB1246CED1B1E2EA9CC4D5475BD4FA43FFEF56AB2A2D779E9D206E3E657A2244108BCF55C7F4F97666457CF5F796105ABC773C541173B9E338B4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F9338191406A4C257E6B7C058565272FB78A54A46007F5550234FE9B7952A82581C08AA6A1EA68E497D663F82C5D20E9D1134816EEA319EEAC8E431A0D82B6D62F7B93D121D8382F0EB3DDBB9FCD43901C8AF1AA019A7160B76B72D4E8CA1228E5E9DFD49E24F3154F4A914987FD0264ADA4C8D6FF9EBB91C59C03CBD484E9EE72F1A98C3F97B9F2479FFB79DFAFBC33C8ED249286369F003C471C8B64A9B1546B1F31BFDD0ACA06AAB3EFB61E49CDF5506AF8A4693A7591498D9D7F8B28A72A10EC60F806A9955D7EB41D2654EE5B37C284F41CFF3F591C227E3FD0CD524379DCB384ACF486CE7B1E658CC743293DCF546BE85382FC40CFDFDFA407A9EA33AC46468E060524BF06C9CC109A726CEAF0811D0F857C08A3D4AEA67CCC0B17B2C38C53DA9F860C99E3AA769EE27CB7C9229207ACAEFE6C62D3ECFCA201DDFAAEEE1EC7BFD40086AA922961198B53C94BCFA97EEC1DC0FB8FF1D9448B6770DE4F5703CAE179FB51CEAF935F666F398B74BDE9FC87B01AFB6EE8B47490453198F9B38AA2259D2194E9EBC42E1C57994921413D6327018B91538CCB0B90E965564171D133CCD9E7F65E851971FB71F2C47B4592C2A52A4101D2EE7A69DCAB3852A56C4DBC9295D2EEC5BAD1B8A13B7EDE84768C0AF5FF0B0253B44038C236412ADCEC91508A76BD8D16E6D6BD5CBB3179B34DB8902863056CC65A4DD40B6A1929F28DFAE1CEC64A74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7E8104E8D9DB129F0AEFF48177BE4EB60236851F6D0DF3EAF508CA7F97E4D5814F71ACBCF00471EF263D3B5CD58ADEEF11E3465C704D90101A5FCC1C8CAC25387B7D6B83C7CBEF04E05BBA1766C5C5D804642609AF84AF3FA7E4572393761664021A632DA048F2A10C2A349E2E1C260C1C3CA6184BEF6045F43D9C767E2328B9AF5E48EFE8298DF69599C49CFE153BF59010741DEE011FFFBFB4EFC5AA4B5DE409B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F83369497B16CBA6B3104624902242C468F89E89322D299123ECDD8ECC98FD5C53D99FDFBBADB056D1034CA39CBBFF29300769BFF634A38678FE7BF929676A43CD0FC3161391877F0623D9B59DF30E28F5B47C0445F83B36F0AA67F6A2DB8C0C3D3F45738A4DE393D8675E286F4530AC810D244C621963923BEB20810EE32909D5F79B7F944D0041C0130B7F59B0ADCCAD97670C92355CCC8F0FE34612A088BFAAB33542EBE8F3283AD67A79EECC3E7B7C5D4CCC29B6083AEDF7AABBFAC8281B7D7711DED8D4CA70C383C5042272379356BB80EC0A9BB8E4F1C73F2D2DE1676BF5AF43AF87AA2B2C4A6826DCDE46E599B2F31E9EA87A816EC5D8163952A7384603C8FEC20F58E1AAC52188E42774382077A35700EA5EA2FBD04135593A7E40ABA137FE400EB63BAC7F417252EF6AF6EA8FA9CB3BABE7718FAC4A756702AD64BF1F912E6ED44DC6D424CD15D3E45BC9F86ABF7CB2924D7B4E8AAF67D69401F5609B17D251140842D7A94FE5D911BF2FD37418208B716D2DC66320743B79E64CDAC6F2257AD34D112E22F977AE6034068C0E0F089FECA11DE03396BFBD365B1A788B2C550ACBED3643C1E4F13618F904B40031CA9E73F9B13293DC92102B33FBC16C9CDA02E511D49394D5DEFB95770E5CC750801623042B7113D385E8BE8FEDA1D7F9105D545B18AE98870B1326494F9BC31B33EC24CCA7CB8E53F9AF1A7E099B0D9A40CCF40B085C0D406B5F1DD7DCA794345FF98F272F7D9A11C30CC5448D2D311502B7F0F81437B52EB11CC5FF11C1FD62B9A34E2E102C5C59D14A3326702F6B6862383B5BA1041A59B2F4E009161857FEAAE3F0C4006926444BE77169E9963DF262BBACFC643F032414200B26840295326BA1983CF450DDABD0DEAF05B3AEE35CC029B1E67729517B6555FDC996782FE0CB275645E739BA0BC75A08869998C082BF6680E2DED0D643F06EED3947CB24E4D240CDAB6B07EB71762DB159BD8E8FEBFF190763906FAEE1D307115E7D6697AF3DB2192D37468806FD49ABAFFD157647B652B339A8912CAA3730EDB23593BE64CE9A50A1622D43538926E5B05D878029C5AE57DB40072EBB7889423A948257F9E8684E5B4F10C09A22AC506B5105246ADE89409D3AA78C4A88181FD562EB714E9402F8C4AB2129E73FD77BB64F3F6752E5AEEBC4DACC209D01A274E39A84857736671BD0604C153703CEC940CB0D79CC433D157EC5004ABA2F359B80DA9FC04267584B2897B594C494883185E613283B939DEBE0F324B3CB9F45A6FBF11AB1CF2704C5F83BE3B8CE1C38663757828909CA4AC49ACC134F533F5DAF470EC30D2E8FBC66C9B6C58CBD2ACBFBFA2842E78DEA2DCB820CCCBFB17454EFDB2B1D706B93B0254B3209CFFECDA9F52CFDC1CF312EAE3035C1A3D75D8764F693350C2301864EE1A3797F6574AE38F66B40F82904FFE6CBB34655B99959759EDB652F6A3BDC1D0F24E8EBE1761B43E876A6A7AA29E8B1158F1D150E25A742B5FBC7161234A85B35803FABBC0AEA40821E9990D48BA7EF7E1A50178ABB3CDBEE228B40C8B02C98C5E8B70CFF650E570988E64E6F4FB69DD11814016F8AFC30F853DCF0B793E150C3B796CDE2B1B43B3E346E257302026A4B5934CC6A417A99706CF783722DC2663F469896FF8EB4CC741D531F3C32B41F0BC6DCD4A32786747BE120B33718A94639FB4D754E0508B0315990F31555D6C1DE281244E229377BB4FDB9CBB38AE483A3569F735AC438C492DFE94149EB3F4A4F9779A1AEFE60FA343AC04323795C9D33DE8AF95219B8711B1168A107EF83062F033203511E5663EFA0C45ACF54432C9D4EFB5678332B5E164092612E42C61560D9EEC768594F4E0E6AF10AC7B3DCD22D229AFA8C022EB00AFA626C63E8E96B72DF979586867B42B8FEDE446A0F6807F1F1C775595FB5DEAA3BE2A45570235BF1169F163501B400DB5A48D7FF08851543CA92A0E8448F98BE619F41FACBF13EE45A1F97C20748CDC3B4068D993D944D5A165FB858FDF4FBF88632FB826103B1276C7791C64195106635996700A71E299889131E533F7F060C7F96E7C54F02D2A32835106FEBE6D40CD4D56B57ED26A7431731B04A78CB5A4884F0CACDF007DA6E1C4195B2B59A53F31C48EF9FC33CC7F6BD147032A1B6313C7EEC43B1E46164BEBFEF16FADDB1A176FBFBE34DDA7C88AC9C1EEFD4F33B7960D847872B8B433AD5D1293EA480E6FA097BB9AE29A7C0270A062EF9BADDD796FD8EBB1502606E9262357EFCBCC9B7343ACBD03CFAE6907BE46BCD32C4C4C4722C8D3A9EBC76EE4CDCE71B049D688C42104B94A1F7FE6F945BDD02E3DCE0C345C047AB31E7E8051ADDD3DBCBD33699AD660C1CE3E25D203C4EA56368B19C77D498E67CFE083ECD3D36BDCDF29A148224623E0D70D060EC964B329186162C1567F7E7B5B6921CAC8894E88BD8BD6FBA1E8EC4081D35931ECA2BE1E72E32D7C986956EE9CFB07CE0B5091605780D9770A00252C92C4DEDD4D8B942E14C90DFC5BD612D85CE24C5CEFDB3EA964FFF256B20A4DC2C0EFD50DA4BAB56BC846B09DE27F341EE42E63C0C23B6C61D15F2C9FFEE5663E3CC74F7400D0645219751B70C916C03C0C67159F71BC0B3BFA0956F026B91F8C2419D671D3E00D7F633DBD2DBE88126DEEFC7733C2C926D1D8B0C8BFB1077A700BBF3892F0C4F3E30DF78BCE0A340A8F98EBA5BD384684D1E0081C1237440B3A6F117178C0DE4F19D05D4241240924D9EAF9CA45E3D4231AC903C8EE5298A3445F01961D6D3786E36D24875E6DF3EB1D6C1BE5EEA0E060D3E0EED1DB2D4E795D35A0DABE4A745764F05A858291993541AE149CECC5147FEF0F3A96B42F38963B9B29466FD66AD46CADA8F10E2D53BFC3B823CFED410147B5FD315FAA62ED06429D6D3FE6E5778A64B5C9BB06A8CF5561EB7A8B15838AA226DDFCFD4C31805D53A6EB7D2DB861451027CF84218C39078756B2911021C3EAFC2E82ABF792C5012CFCA3AAFB0A277A9C9E1E515CBC4439D95B2A54510318F5D6EBF97C8DE2AE0D4FF669493AA354C25460D3C15B1A57AC53D7E6C07CA407AB1EEC4A366A637AD4081F0343433C555DE72B71ABCD8ED3C043532A61125CC3CA06CAA634E5F75B750BF262756A57E3FD235FA9EF00CDD9553D37968DD680EBD5935FBDFE43A82E9DD39F96FD483AAB7F2D0517F23727E8F4DACBF1442D207EFD647078CA9CDF7800804012D4EC23BA14C99666610A22DA87523E4E5E41A6698E5235743A9B9E1C4795F38AE20CBE5C3A2111ABA307C3BA6E03F092E96AC6EF297548A3F144ECF7F643EF19024B2E98B51173450ED06ED68EFFA06EFD60721E73C9C6993F14C00E3E4BE441791C648110F699AB5089D7CD092AAD82AE007C0C3C8659506D5F2817E75EAE8B803734822A2526861036E35C3689EDCBA348A7A2E4BE2F1E291F63473988AFFE650C1BC49CDEA3875DF4E6B541727B5AA6F04C9C1E4D06BC5CC744D1B955958E2578C6176AFD7E3262CCBC0F6FA21596BDC36349BF9329BCBA08FFF934E31DC1FEDB7D7F6B459BB1A0165043B902D600C447792A618B77C1671E5793473DED54FB3322180F198873E306E1F8BD17BE04FCD3CF4D6A9201B9B804BBC772B742097663C42F0FEE3766B3B205F14A39D6ABA56963D03DCDF538ECFB8A7AE64DA3C116BFC09506BACF5E8B5754B220F7CF70C5AA4492AB72D20CF8F4966A114833B057662EC63B9570D9B2DCEAC86590569934F91A61A03E18835E31ADBC2EED3BE0BC148FF004675C9555C901B280BFB56FF8A1C079E1F290C67FD1B7E53A6C27A5C649ECA9EEF836621F9E708EB84B6F5C529ED2F07BF0A6160154F41F323DFF8A498177FD09D22DB15A273F787529852D898A6DF0FDBEBEFBA3F3B602B1E67352224860125216AD6D68CA891606E179FB415DE4B95484CA6907319438F69337316203F06AB1488A471924545C81A470D78E2EA29AAF89E94920AC4B0E7F2FE01092BC8CF3839480A02C0E8DAC1E864C9BFF5CBF46C0FC7B6A01FF0DBBCF96E3585496C392C6496D06C44765878B26B6DFF2C2FEC20F26A9A2706838A2048E579C65F3BDDEFC58C89D8830FB8C75FAF96788998DD200D48189C3B59B41501BD310420DB96F7CC5B61A2EAF88B498ACD890F7DF623A35479472694CDDA58C000D9BC04FD903E4AB88A2E757700FF3F460F075F9876DB3F76F17003E01DC96A92543DCDFCD7EFC86A5C0DF387A50ABB69953D6DC19A699CD225941F82438A8EB7889B212F65ECA7399F89CA0D9B9915E827D2E520B6D481C27D4CD833EE7D985B20FA5BF7A21E4DFCAD092628EC0A6E2DC876E4C5BF248F94C2ADB3D6C9F23C3E70D1F611A2041C7759317B8EC1696B2632CA10CEFA498D7571D016E102DAC10051DAD086BEC58AD5DDFD7988C5F433DE87C314E3930FFF937A6E0C81787F04B77F893287AB63125CAB8B7460F119D03BF3076A98FF029EA5022201DD54C854711B8BE718EE678544B51AB13B7ED0262C8180C2F36CBAB64D862D38AD7D8172AD8BA3380706D52048826CAC611B07468967CA4A4DB52628A2FD56DD3A323382E5DB171811EA861E2D46537D0A4E545C65F238380083A064421DC7CE13EC2F715580924D9B6EFBDBB0D45AD8952F602BDED6455C0BC2734CB135B79966464546A261D0A551DEB43E5AE111CD02D0F2F2E996454DE17B471C6103D851CCE2E1FEDBB828C7F4EE66053A57831C708C377FDC6FDF037F400A09E9A610350BE6C013239D7F1C42758CA84B428EB06C6A6A3E05F10FED769CEE2D8EDC3EEA29204605005468B0366B2E957A7A55FBCC7842598F55021E58DBEEF44C5313226E6E56A2D3837F2A098C94BEC791737F355E6CE5643C954C4719C6C1C939B7716A29191CF0530BC2E78CD028D526EC286FCF02B18A077C86BC54F078A19A529F6EAF69D5562D4B31E4CE3B953A24655429BDBAEB5378C13E5B404A138B2B5473A415EA236245B0541B6D92F384D4CE63680ED5A6C035FFFC663C893C8F51C5DEC6F90D33573A05CBAED63B69079EE77DBDD21AD7A778B37EA5E0543BBDCD47497F355B1B2D8AD93DF4BB96A5E85A2344192B782D54C4C8DF251BD5F72EC415621FCE91148DB266EE1BDA0885827E96E8A9AD9C50F43D947DFA8260661FC9326B9E76214D36B22172C026EC12E04ADE3C62D4E957AAAAE686D350793BC6E9C862D968C0E56B3160B5C70520E9AC7767AD2BD8D1D6DC951A23BE9FAF9DBFF407E7766C84CCC3F281C6383079DC3188FBE8F9675D0A26831EC44071AC6184AACBFA0A2326D7EF097650C1D4D1E58134408C11E839A0DBA17CAC9DE3B437E697663AC136380D0690DA4A52070A2DC552275BA09C01B601D55E97AD7DE83A32B962D0A9053C1533600FEFD1171C638A50922B9962C195551F81FE80BE28342A13ED0B25FF8986E0E9C39F3C2F29B9F40AADF8CF61E879A7FC863B32F02C5B5BE16F0E2CF00F30E312820E84D09BDF073E0B16B1F32C73F0E6031DCB3221DDC48670D0F2DF9A8065BD027C30DCF9F12782C812753F109615828997768C75660D469691278A111D50A72CEE9600124E3850507C0B963E9121C8B28262B6C82510AC69F4785752AE1F619E3D334170A4ADB4DAF3138AE90AAF8D82573E7AD25A16243E16650219C47F4CEBE6915B433B0ED0354EE62FABFD3E118AC777A63316637DA755A99AF97DFE9857B2F58A83ED70041EDBC49997EC93C03A7D55524CCFFF8018EE1A587AAB9FB5D3E33FE7BAF2642CF9421540C134F9BDE458A65E6B9BB209359F7FA47B95EBB79C83F329ECF88C7541446868CEF363218841F55D346A2B714DD48C711555BB25B1CCEFA6199A0E7646646B667634E486116C0AAD7E977C091A5EA356778C299EFFB7DBD3232C4B73B54C796BD1E33284CC8E4354C772DF1CCF762F615715FAA903D1551A67965FED6C7E1ED7BABB9325AC30F92305FC284724C59079B11D1A0E32F4665AD8390B34968D1885C9EB8BC5DDF63D7858E042CF7C66FF5E36365F1C7156C79CCDF596EFA551E203456E5BB22C2D9B742F490824B1D5EE482F335393E34E69C7820A639858C6EFFC2E8377876E461788FD2736A2D1BAAA432B008850BBB44FA193DC54757D8C75760638A12DFB614580A882EBD945716D7A3D3D29396D4A0D267B07B035EC001CF29C87E23D8446E21D604BCAB110869FFA98C32E35A9B6C878360FD7BF8D564B09384D5C52E0C9BE0F45E814C954FBA214F3D3089AC4D01ACBCDB25B9331558FE1D29E67628E13BFC928F7A9A88D13E0759B77674C3F2795CDFE0C6617022F9C6A87B60C4B5A69E8D1706749FB0B4E086C94B5BFC16CC3B34FF3B7EC227A5CC646E9A003E5D897871067191AD1F8A8C33A0E567F4DF2D91D00FEA00B152183D202BD72DC0694F16ADFDD6E44A248D80FC6609E601CB91EE691C4535CD80BECFF9F23F32BAB5F106234A8867CAC0B5269CA2BC588E48AF922B5917BB6813E9D1005F35CCBFDFD419404B59A84497BCAD743384461F24267C497A932411B690BF405A7ADCA63858F439B123201F41AAAAA4D0A478101EDC6AD214E025B5DB6D24021464C53FB376503B6CAF4E4D4974E072F8C88A7C61957239581B589ED8D1753844ED928642CF96E5ACCA32E69B52CFA3AF54B9FF793E7553CBE16C4F9DD6114D1357E539C238AAA4434C5E540AB31FA584B82AFBF419DC51D6B08FEBE34B7991EBF2A82FF8E94990BFD02764F7D1DC049A635A08B7BFDB46A521170B6B8BD940883CD4505224D9DF930E33C5827E303083CAC4F846D9CB9A6E3FF57E755C7CCA541DF51819C5A52BDFDF005217000967A2776F51217813B2FFC509EE35F8AED6481BBFF5D5E61732BA17C90FBBCE1FC29E8DE849C146642845F982A2F766DFC0A703B5BB612E4C2B8CC426BB56196D714FC6F1BCAA0F19F32CBC06C3DD1406B591D2B0CD0E834D003CE56313B66C224594354866598118C87C1A86F7D247593846100395EE6303E54D130F91FDF81D0DFD021C274AA9567B9F9A500F35507519BCC25535407E419B52FA4D9ECD3D53F467B6295505DE979CBF6C7BC909812265ED65B30269FA1500264347FBCF1CB34AC5A405F208E73DD503D0D0E15FA474802F273C76C3D3DF98070BF3151D5D338DB368DA0D2280BD821880265763EAB2076766540EB9A51EAE647B96CA4326C82626DBCFCA1B3FF6DBA63DD64AEEA6741FA49E358E97D8F60C7F1A56248E8CE18933CD6F850E667134F69176DFBE2A4FC259994ADE12676F63D483FE16F7658F1003C1561B8D46FEA0888D2C82A4254AEB9E4104B9FBC973CF836BCAB5E263240ED9D87E9C434DC66E8F4A7B73EAEB30BB745F4094A4B82EC96CF99219F557ADEFA605DDE957CAD9D5343558A9A0904575A7A954948DC927E71786394DF40E9328C9B4382CF4FD8423B97088BB07CB4B257E5AC7B817088C3A6912441992153D374D477EA4EFD21C9F706D3619634AF7DB364F5FE73D12FF9623B665980B98E83991215E188462A57C4B3F653E11B4B1E16522CD421105A1FE67AD0F58F3D4AD34A8BDDEC13454EFD5FAC6146012476391769D4AAD22B1A0BD1CE9599600EEDD95DD265C4640CB064F92C22B0C45C64FC411375852E596F268EB415B03DA88ABF9A089EDCC5F06ABBD96E1BA461D4DFB3772938CCBE093AF922F5CE290295EBA2289660868ED4B6AE38B28B1ABAA06B66BB97A5396218691B13D099ACB89D6754517372564CAB054763190677139C9E2F0BA2FB19D0471E49BF6A0DFF2F951A414ED5D0F17C729891F4EF658F19FEB6D31F0BD8EC15DC9F9CC1FD73BBD7A6CA326AB06F55078D4F2F90CF185849567E8C78F2773938A916FDA23279FC3A9D62CE3C3AAD309264EA076635487EDE98CE79ED297D1BA99D96C84EB712CCE028298C8BAF5B5CB3EFB2EB8996EFFF6F7682D6EAFE498B886FFDC157AE3995D8493BC6B51541BE6862B41B5A35AC420D4D120957AC00B6E488AFA394C5C3F99DEDB4BC4AD4127082E44F22194654D3FEF9CFF3AFA66A764864D8344939255F4BD77942D6B2063FA9C0F82DD3B8D9ABF5C633B6CACB152AC09B9DF3BD12770444F99843FD913E2C815368910DECDB46DC4E13EF2E89AC3FC7D13749B88197F633BB6044E1EA0FF4CE060C7F426D01D0CE94833304CDEE3C857FC7258DB654F49E7C949C4D4B2DDD689DEA7E0C526E694B5EF77F8DBCC199F73D833C54C6C389C9C63A9E203FDF4389D83A4DF4AD86D7B36D3847C8DA829E04E31BD81791E403D6098AE9DA476D75B357A74FBE2F0C42FADDA27AC72B653FD87A8D1D72E72E2BAF5D852D1FD6DE10D5A6A600C795F65A4A59A00E2C503DA0BAD2344CD62FFFAF6761831AB2CA4055C18294DB1CCAF2BC6A13DB522CA1BFBA9DFCB930E4D6C32EC24DB5A8D5C15398CF2202878D240BEE11756559F26355C059A81765FD0D993FA64887D5CB6EDE1B379B2B8B5D5430F3D7A6ECB8259220DA7C9106CACBA69CF6444192275A2C6EDC588234E8D24985A0770607FE1C4AE8CC7559B3687522EBF7D3CEF0E19B229509D2A247E8650C3676B3B272340EB71C69064FD3CE931406569E7AC1603E49A13BEA93B2892704378ACB4796CEA77687C98E8AAEC3501143271E504408CA5D7ED271C45A1A7637CFABEA8EDFCB11DFF3F8324C8C2C7D9C73A26B8B1C05B6F18013E03928FFFBBB5068FCF4B29FBC21A5819EF85B91B19A5098883EF40D91B7E287749A578E7743680786FCA565BC4D19AAC06BF70C283E7649992BD6BC0305A0A093B75DCFAECD7E049E16F274AA9B017CAF3F5068FECB55C6FA6ED97F64E17CF1CDDDAEDB45036C6B2227A0AD5181AD7389B72C8967B8176E18CAA3506BECFCDFFF15B598C47D10E11E65D9AE8AF9AFC8B189562D98BBB02EE55D0A5C41EEFFD3D6E8EE69878B3A003DE7A52A98978892E51219387C24BAA7A773944F530816FB27BCDCA933370CB340781A70DB5724C597F72F7A34DC05B732FEB79A18171281AB7A94DFCDFC2C96DD00784F2E67D7E56D0F146F1585EAA1448BE1CCAFC6F334CAB07A27E524BEB95E19D426689B900176A70B21E32278F27EA3BAEE623F92B14696CFB1EABA0D90EDC414FAAB03AC0572B4B8836F071A375849BCF46E83A05979A4111167CE5C43F6FF48F386E3E8F92FCA1655E3ADF4C2123DA2C5551E252E9BFD93276B5B2BDADBC8F23C0406875614ABDE72C520002AFE6F55BF1D19ADB7F26D4F71842FC66335FF670C60583CE65DF747AA6DB218471551478BF36140DCC5C6B9AECD22944CD2B781A240C914D2BC4B37877709794CA33ABA878615050637B0A0B3F04DE2FCF37A2442A242E6C97398CF483260BE8A092F998EEA5FB5519EB25BB10B9350AC7F6948CE13DC282ADFD3A251C07E32A25A8A93276A563755B3164C0A9510260425ACDC093CBDBC6C8C5D0FEC94A6DDB415C80D45BF9A6D8DCDA606E3204EEF6AA291AAC9AF7122810A77E0E1160A461AED63687B3C137EC40897B972493F33636B2CFF07747A394747C0887C0402CC4F50E78F70785E5DA4C6084BFD7AE379F0AADBA0CBADF8C70C34FA7A6B0C14F32D52FE8AC726F750DDDA95C741131C7F692CAF7A3A80173479690A3CC0A93D1823BA1AFD5634A9D14E17E7858221497CE6934D7630E73D615127209FA239A190EB60B4D49770A1122DE7ED76708CB660EC4E52900D130C9A4638448CBFB16B1943D7C007D521F945D00D42CD0AE51FA89D5BBB9DC68360C2551D3A0E08CB0025B061057FEA0855305C0F6496903EC94DDF067E722AE07D06AD5AC67A1B5A9D1D036F4D157220087AB098F2C6A911F710332AC3AF782A6747B8E079F12A768B9372BAA222EF43084F65A46EFBDC5D8BE794084FEDD23BB2BE82A7FD1C5FCCCA0E10FFF7CD47FE805A43F82E73773670C4F43571767DB9F9A59A16B1C6DFF3AEB739FDFDCEE27D8699BC080B9D5973F30BD546DAC6DE594F91E5C2F0DF432099D949C5FD0E9ED66BA4FD37F77CBBA8D511A0D712DD62859D6E3C0177A264EDC37393FA86D8BB241B13A2023CECC4A8A57242DA1C7BB796DB4B50197F8E7DE6FD645C6B9099D6F76701B0A36CF2DBC1C9E2F56AC8CB222D37682E19D33A1728916687BE117E14BC7D137CE28948A0997FD9B25545316DC91AF2780D34EB5D9A262B327FE0E57AF30D9299C1CDD7FF92E3CF8C70A9CBA640A71425B164DE8D2D0D78A19853125F684FB1E94D7D02473BF12C6537595311354BAB832C69593F4195132C6552176CD781A04D4293BB9E329B78AE8929A249AAC01C5C81DC46DF707C914E08A642BF4B0277302BBFE3950EAB036CEABBDDED57D2AB2DAC00B61474150F0F641A571573A79C7CEFE5B1E08C2A0D7C144D69764BBAAA9DA45E8C1CE02AD4BDA14E86E6F4509823913D553117C25BA7727244D0A5F4106962D2441C4D3813A780757E169AB7DA6FAE572D7CB919DF7BA028ADD524236473F8CEC4509FA954310D970F13B8F57505F248413F93CCEB0D2A8B81A3B6B812422E630863D5F37142EC8B03444B7509B92C2C46E8B7DB79679EE93FFC1DF1B807E29773C0B9A280334CD97CFFA2AEAACDA2A662F8767A323DA9D48CBCD419ACB2EF27A01A26F7F2968B572B679155717F7AE7CF17987EEBF9B088B153D06F88F683CD8A53B1D69CA429BC5D17DFF465377F6895611C319A8C8BC23438BED492817703D83BDBB93CD491EA8C39122ACD809BA158D5951E0B78FA5409E63E7CC69B5B6BC9BC56349CAFB05B71BD8C8ACC90F929F58037617118351CC1E0E0B3CC4040BCAB505CA4AA36C06277B4D550922DC424A005854FEA6EBE6C833980D3F7D49F38F595E3B156B89809B65E62B57E0C79947B2EC463027DE21FECA9FBEE0CD5B8EC64BB776FC95D93232C53A5A5D8F5954AD65E6BA6A3677C62497C3F4DD408AB08F2B05E00F865CAC6983159D2E4EB54EC0B89384F890E6033F71C5C888A9EF25C2E5563F4B79CF7F80E221C59FCC0CBA7A56ACA182D6A22A77AFBDD2209D5BBE8400605B918912E1F8268EEA13534E86FE8B6588ACF64A1322DFBA8990E280AD5A2E185DC29AE3AB7AEDEBDFF8932A21ECB57071D2C6207740AB48DA0286EBABE44AB1566D845A6B231073076634B6493FF5F4669CE06BB0BEB477C3BF2F9173ED7A36C22EB347036E7358BB62192E4E7BF5B9515C6A433D21E47F56C886AF92422741D1CA07EEB3A67A027283E78A27B64C89AC0EDF6D3CA5AAB03AB2437B7813BC5E349434386F00F0C0D592256BB28E68D0ADD1F23F001F2F0DC867BE42CFB316FCC3AB7F2ADE8F262E2F2A817435D72D2B9F181E285F7D58C2E9D0ADCA7E67933CEE6F908BBF182523A0367EC978CAC6373140022E3B851EBAE9D7086C4191C0BB856FBA1C5785F57A555985D0060A4BD79FC0FBD7798CE46C543B3D26C62BF07B7FFC0C5CB00729D2F9DC75A8A308AD312EFDB71DCF069034FB4F970969B749BD6F487F5E77627FFA00F64DBCF819A4F8EC0681AC3816282EC1717DA96444B3EC00B32B8C07E806988EEE0B8CEAF0CEED4F400F27F1D79267AA4BA333E61B84E6F10222FDEAF05D3561F5796CD819C879A07E780BAE63E780C05F024F2880EBCAEA6C1C8258D94B753BEED298829CF221BEEFF249643A4915D5C0E8AEAD2C85ED170790074EEC22327260470E99DD940227A671D56A9204224861E56624244241513ED4AC7117ABD09523C29C4F23E0C41900011215540597EC1BF8516CD28C228D03F8C7A65E4FFE575C6F5FB1F833B04F3DD1FE2DA3F983FC8A6BEE8CD7FDCFBB4436D8E8F09D466CA0129B4080F5C4D2A078B1CA2BAB5B306B26B4F75F49335E128D5E27B6FE1D96B9B863268E813A092C5176087562125530D23E8F6D61D99ABF133B032021530A5FBD7CAA65063B17304B76498D90B0F3E6541534667952F6B31A74394000AA731CD42D2CAB1EF3AD7AADBAEC7541D04E60B843FD337D7D08B9991452889376EB57FFC5D2D454B35DE0BE42E0B04E5C21D950E809C5D499AC04DE0E4FF912237DD83AF0FFC5CB8E520493400C91235F9D49BB30724098295713F70ACB57194F53B656D4B3E5879E2E28734370A052FE51C8139021ADD0DFC6D3D8491AE9C7C8E3AEF6A5C1E119D65923212BFDC35792BB5E3109BC36003C17100DF5302C7FE73ADA012B36AFA5452CFE356C38E63C59E80C1F3FAA1735150F1F3CE87E7008281D125FE7627B3D6C8DB3A2101DD6D650656EE5B8E0E8F0CA1DBEE12303499B6CECE8AC80111C504804F9ABF9C616D22DF34FBDAF27C46002B5B7260F47253C1A5AC8745639F0E1833808F7CA27BD437569D38D2C4AFCC5293E6C221D9872EEA5B33A43C5217438DFADAAD8F243DDD779FBCF4E95C6E4CA4E11125F9FFA93A4F04D385175435E391A7DD4C026ACF110F0B0CCDEECB8DC1ED8C24AAC7B3499C0DFE478F292B8B46DBD70451F459D0C5487C973DB0D19E196A66DC3D611D3BE4DDE59128AA6229BA0CDD9077B20F9E03145EEA04CD0B2FBB5EF90D327C1030B15DC8B5CD259EBFBF04A5EC67C741F6D38180F9B0F1FFB97CA1D0C0C5C6C791CC92908B44374BE315D4545F5F7C10DEB4E94B676D47D08C4A0C7466803F767C8A42BB0B74B6E85E11C6BB5C7EC3A8D543C703095F2077FE89A6CD8F450DDAD4007C1EFF0E0CCE2ED78F8CBA8FA0724D395C8B7714EB2CD2BB4CCFF497F09661F28A04B7AE27C8324FB4840336EB48BDFAA240A39BE662A93F5B12682E80964A14E32F9513051FCACDFB4AF64D835A1BDC643D421C9C667F7EFF4E56A7988FB757281563991D1C6B5B0C97E1C38B9185D049B4A95124E6248DCE7073EE9544DBD370AEFD8291D1016D0995320B2675D300A28C061555D9F29925CB9BD253D214E1D4FF9141467FA3449674A71A800985A0656EA2EE415366F474DA24B9C899F26B072E7244E7CB2E76890A89D42E6B9B0AECBB5180D6EB2D34954D4098D10A36511465340E3245A716C3D37A619D0E36E129A92C205579A7AB47A6284C06E7984C714DA51CD825033C241C11CAA0F2A930DBA13A28BBEADE973C6E8A838A62E04B1A5AEC0C72A4A2B73EE9925DCFDEC7C65CCD3D4EB65621EB7C90BAC3D36D8BC3427E0DEB8F253E221605ACCD5F6DD73A50FE09215DAE82AAB23DF4B86910EC72E3EE515A746FFE7CF903077F4D13B59226DF6D94A528F57E13D741DF28C45A072A41C01CBE1EF6587D9664CDF4B8A3E2215F667E2970A841EE78F7E14CB1839199163AA591EE9A2B5AC639623254BA87A216FAA462C5F9F8A74E97C24FCBB3D53152ACDCAC8A32D5A18C890004471F9A43AFEB325C767807C66EEECA54A594567AD7D4E9135DFD212A01536B32D590B9F662C17AB9784D8603C618375383BE8FA258651259EFEC97CFC616C218E4BF54A8D84E4DB080BF25650D8F522CBC33DA5BAD3144C134547AE090930BADD38EE0EA02733B057F0CEC2AE05FAF9E494813DDC49DFBE8557E80650120EB1C9003A5F57D330888C56802199C89EBA3DC085ED5DE5C0E469686850AAA7C9DBFDB47C563AA9660B079A7E23187A2E8C57AEF291FA99B0EFFE67A6D43233D7F84A9E385403DC49997BCCC69F0CB3C6F707ADD2FE0CFCBA5410DF3735306F9D2029872992C772EC24635DA6C73628A1F5789ED2E5D91CB41F2C8DCDFE641A1361AB283A0BE8446A5CA187983E34434191C64DA727D6088F90430F1482FBD5B7493E15D3FFEE375680BDBCC812B93CE10FD51BA3A712C3130DE63A77A79DFAE2C946AB370F8700999B0EE37A1B06484CC4D3859A4308DF702D40590C5C14BF8CE6D6D2872A060190B14FA78592DE2D8B0766DDD09276BDBFE487FA6621A5E1108D01787969EB8043B236F8189D2FE9E60E95EC52E69D156E20B435C5DF5A98F25E829EF3C15464D1883277A5EA42AEDC83FEAC327FDD2EE1D9A0331F06DA74BADD8A9F80432CAB5CA1A81FFC79A1F23E604112DEF22E9854468592BD2291664517CB91C80035F1A8DC97A5C8A0501CBBA6F47213D8FE0C556842324BCA2ED74EEFE8F6CC896DD4794478C07BADDD3AF65E580664BF0609BBC243280C3641C9A5803E856525410755770BDA536F0C722612AEE5CB643DE530DDD0F7E68A8EA1FF9D1F08751BF99CB8ADE48089343C253794EF22037AC8EA20A28A22242EDB9F9A682F23D5E51E05CF68DEDC4E4BBF593DAEB24E2CC69A08F35106558D22DEFA9A696B6014DDD99FF8BC35E8DF6C2FE76F162F81682294A1D9444B9632F63144C0909890A934450E27DEB72E943076414576575834941A21152A535BF404B71F18CB4851C70FF3E167E65071236844BE4785D1AA773D641207323BEDAA64571D2EFEE19A59933F3EF8E7AF86C5C9C795E88322185CA8CEAD78CE097951B57CFFC98D9B4BC920AA3E67F502CA5C4A9DA541608647C8D7C6B8CF46C573F1C1EB086D416B2E20CE3B9F1F2C3193F9D3EED04E9AAE230EDADAF0ED5A297640AC642AB70494A6006DBE0F242DC002CEA1CA8C9578ABAFD7709B58C579E2A7C2DAEE05242D8F1A26F0B96442D65227084668FE64EBC1F31DC6D7EC5C0ED61307B70452A8B5B846B5CF3AA859F0B0ECABD6082429EC6C5C9F757BAA27F52693004B19D35A675CA00FD42ACEAE5AE07C6286F48AC02AE2E43BCA4DDB0982A40B411A23990864378836BEE832ACAF1A4BABFA6C3483A9CAA663ACE89844197AF9496D43FEB39053C4A03F04FD4E1DDCF130DC450C3AA99F85B34E54E4B7F372F8C6AFF5A17385B637169C396C230CBDC45B7452354F797446F75956ECE0CE4620EF515A6EDB2CBA3C01573E293A17A22A5C33EB367A8A9E331927DFC1697BEA0E9F6EC1303D6E63179A7ECF68B5865C5B12D79AB95B5E419C45EA2A117F233E6AB777BF3041268F9AF8F0337A989C1A24686B127A0AB21486A023E85C511351C7C5982B01484868342098EE2FEFFCF1339CA74F569E89F32EFDB11DCFD33EA1245ADC75BFBEA4D1CC707F7D52229A286A1BD4D4E69BCA878C62A8FFFCD096A741F8BE4B17E069899EC20C66C23DBB9571116C105814BF5CDBD71AFF209F55EA526D91858332457A486DCE7F4A5C46EB3FC8673D6CB46E2DE3098F22AE17745AB0BFD6A4E57CFE6D7317875912BE641651D98E70C940F7FE1BF9882AE12A52B76BA21255AA0CCF272F8215FDB211A506AFE5AAC69D951DD8449A5527DD2617DDA35CB1FCFDFAF6322DE113D48678405CA1E68B6DB9F005DD80FD447E045D6A5D3DC719EDB0223F14F92370E5DE7B22FD0189F6C7CA5FDAC1DFAC8C3525DA00707665040820A763DDB5406DF41C23BEBBE6011FACFEF3932CF353D6721124F8E8F2998DC06D262729071FD56F1FA76524815E4552548FD48EB6695B81C07A716E2D4BEB22348B4FD554A0A2ED702E6E2A51C1B621C6D6DF7C675D0169DE88A85F0E45BFC398D5FB2BEA9958DB9F05A82B5CC3CAD980B25415409DB4C0EA1B15F249A4ECE2CC71449C9219411CC81AF35468A8D4320B36328298CBEA852800113F9DC6A6E727B340FD8516277E3540A9950E5A8E64F0050AF7F9707389874BE4A616DDBD017CC0216DAF1D270EEF9605B26A588A285736B3574E6AA3B6F197DFD451FCC03F2B4F1788C1F4EC59BAC79BCEBA3253E8DB04357AACBB468E9C8A714366CA216EA44A764DE67989D504A8F721098CD0AB285456D21AD99BD11DA30A83054BA40BE695EF6C298E22F8D7269E995C5397DB95B5A56AF5D9BAAFEF08166AEFDE6612FB700BD797B26F6DAA7DA1A3ED773ADDFF19C592AE7C3FB87268406DB5B9BFD98D4C8CA02A18ECBAAF3FF88F7DB93E06A445BEA851E75CA4B8011F3A2E3F57286D691667E3C2DC11419B7DA22B5AED705CAF0B8EDC70F438D57D4D549D41F07955EC3E339042D11F17792EB71D8C3B9C464B54B35BE2D45A3E07EDCA62F86CCC96C6968C567730E3845D4C8B8D6675606C6994DFE5569260BD2943AA189AF3A3EFC8F63FEA89B71F2191A7BAB25BDDB5A02FABF7224243FE5C6CAAD0F7CC66A6C6FD9754F700E4DA2548843949C7F02CAD107FDCAB04204637D6714789155D2C61AD3930D6F8586EF5DB5515F673A8AEEEC8C9590598B16CBF84032545AD5C1BDFD11A92093B0B0B48DD98EA963E208A43E5857A0722C3A641E60C7C398D15084D8C4B35F4A3146E77AB439985209AD99296A12BAEE3C3F3E994E76387D15C2FAEBFF7B44BBCA08A9937E74F9CC01613A5A2745C3F3E0473373EB1E6B4E29188477CA96845A7B24C232F8FB9E405C715E3E8DB593B14FDBAB225165BF0B0612BE50214598D943BE032FE5D5D9A33C23BF8EA48A5FF6BFB80316B5314A9D73C07D8022D3431CDED66AE8326EF049B2DCA5E63C6354666D1656A46BD5C8B430A157A43FAB904BE87F7773F5683949A416510B361ED60D700387A5E1AF0DDBBE08017270673ECEA9FE1F59A4859E7C097B806B79019C7056E6B1B8C2B43D41F78389A1422EDD4FF13239F36C54673118333E1DCDEC960A524F3D9E3E4BA1DD9B62917E8820249A397DA3DFC9417652F02EC8995851FBBB668330EC8EF6F89F77928F54628F6E3AAF55940E6F73720533FC39AC2CAB0C8495FE09563D4A0B22C628DAA66D06855CC24E85F9BA30046A79BE4EFD1B9DCC6E098DF8EA4055B19871F55F71A07138F7ECE919D3F6EC059DE0A7A363C0E63A16FD8A9944150D65F56D4A0D1CE83CF4DFA3B79A87A3CA9D003CB578B0A862E8A8309A9F8617CD5D7D1634766ABA5CF5181B2DEFD4CAD9A1F8F2148FB137CE27EC8E62771F46E7A8AD1B370474B1BFF0A634408D56E33EBA8C4F4BA282D716E03FE0799D012C1B9D3F1EE3D223E3D30F3020C0E026604FF5BA9CA8F25CB0C6D1C7835F66BD1FECCB77B911C259394E8D6582ED0B83A44776DCCFD677E7CA0352569B227DAE57777BF15464A8C91A01547BF754178888EEE0274A0EAB6503A50905C3D04CBF80E39F5EDA193CBB574D9141AA553186CBF7934E9AD2A2FA730599D2910DC1CFC2AA8DAD926C58385BEE6F37203F94E5DF5688B9FE0DE1F67956CF2D7872A9A256382165A8572BDF85F083A94A94E4C08ED85FB17F2BFDDFCD4DCFC86CF4E608A6CE1E6615DD4EE79BEA7BEAB94B696F8EC236133067FA6417895B911914FC39971AABD1C5ADF8A1B46B34647599252EDB50610E4403CF05AEA437D1B23FC22BA4AFDC836FA167791D3703FE28BF015C7BA755FEE0FD33211AEA356FFCC38720D04F325DCBF5415037A0EACF799165D590D36F036E0778963F1B9B059A479E0E6A8BBF826B0D55399B8CFFFCAD4CCF859B7C226AAF04BBCF49260F242FE7665B72AE5B1AEBE3AD1C4FDE360C56F2A9F719E8B5A4679D3700F8483C54FC2CF99AF9814FBCCDF46A85A5359359040473A71AED3199AC0283983D8595ED6169FBEBCC92BF9CCC7A687B173193BBB636DC889ED448C942FD52BB8EE81BA817C800285CDBF370502BEE6273611ADC1EEB4EBF9A625AE0EFFA97DE9D0E5DE3BC4CE8B8CB1E07E79578BBB65984464F724E34FDD3E2B37D65886782874AEE3C700754D7EA76555F6A37BE99C25D3F7924B9F5C15D6D36E6F709AE41775902710A12E5568115101E6ECB68CEFC6C1E3EAFAD850677F925293937A7CBF1B545E56E20AF68ECB04595F8104D942BB3961B39997A8401107E938F74D6DA03821E8FC12D25B83958E720E544BC10D4DAF73F34BD23E19E52E2A3D675558BA09A6B9BF36EC3EB3EDA9E0F4CCA329BD2FE20482B7C424CD1A765DB6CDC7A5C3A0635A7F48F9FCAFF2245B13B6A91BB666DC0B131E4754C2D2C1E623122E73ED103B87DC55CB62A152DE41ECA29FF4DE07A3E3F85398A14FDF1FDB85C1A6202C0C5564C3F66796B7FB9D9481861271901B8281991A9F6F66DB8DD2ACA5B9E5FDF4197D61815E423A4C1DD61233E06C3499034CBD2490FB22660A966D4D7882FDE18CC041294B9758A5544F3A697CA7BCDAC81EF742221F56EEF86CC2999CE0C55503533CF7AC81EAE88AE83A835103E91F3AE125F46B3C7ED05B40737AE62DD89B82D90C22BBF36BD4C169A9D9D8FFE33E2E80D503FF0DC214D37EA4B81D9ED2704515C6E5B7CB57AEBB3A912109B8897E271B756C77D8B7C975E3F4697FCF8C1DD1CBBFD52C9F1BBD22E7DB82335E5A6FB849F5531AA9841B92FF1CBE5A34F4E9D5C41565145E2C69AB65196FEAB627BED94F77407F7A180F1AFC4E9D03988507831848F23AFD2CBAAA6422389D64C1667CCF290724D58E28B2B74D70771682F70492AFDB247A3C118572BA5DBAB9BB2E4ADA05E0D78C79F0A2F97AD053E87B43C8755A7B2C217340C81D5BAC243B9DC51236BB7977C2F84D6E765C579058C996960C0A548BD6BFF0959720C43E6AF1A94BEDBEB922A8B4A02E451E88D4FC8A29B92D66AC1F6BE6802B5CD979480264C1AACA5D6578F44BBE06230CE75105859584EA29D16C20ED4128A0EA85F4CA9A3EBDAD29D0B661D56784E0EC2F04EC2DA448FE96A3B9EAC31A9E53A2925701C52CDF1B19447F23C4BCD507909F3035D1F6BB9BB2074239D339492C6863337869B2855EE7CCDBCC6D4FD9131576DBD7B0B475C51970D3740D8F232724BF53C09325303CCC41645694D6A9F7A43A93464507BCA194F2E1C8159821D1DC950A3CB5E9D1FD829222E52ECB1AA5BE3FFB693766886FE328B33CF44ED3FECFA0D2EE91EC515A59B419D903524112CF788ECEBB117241C61FFB84E266905B4EADF0606D1F070C1FB0BAD9EE87EDABBAC32AFDEB276E3C63E1CF73C55FC76ECD8A275FC17BE731FD1983956B1454E5611192EE16996A744DBBDC88BB1E309425A23FD480477997C6A27B780396D4CE034063BD1684CDF49B42ED5D23FE2C36A8CFB0BCC4F8F3D029C5F233C9D28ECCB8EAD8ABBDDAC297371916B0F0025151DE512FBE03163D09E73776F09C5EB535A2C81CE454EFD21E27A51E8E746E018FD19B89B74923CB2C6136061B6F94ECF88BE57540FB784ED209BDF98BEFA822205B6EB9BA7C43DBF10E82A000DCEFB30E1B46ED4753F45F568368AF289D9B257609B81392354313ED12A0782ED0DA12049D4C3633639CE970D733B213C8D40A29BE5BF69EAE20F568BFC3E6755A423E22D68963FC2C85979FAA14F895FAE3A46ED30FF96D3ACE7B8A16B8527607915A8DFD7BC9ACB0B27E06A8F22E2FF223DF6826348E96F2D1F74995F0CE064B45B4944053E3FBAB1AB2336AB869C53B3CF65E3FED0C5B41B9B7860EF3427219FB2F47AECFEBBE00DA51FC22CD074FDD84990C1B70ABA87FE2FD5EEAA5A7E6D1B88CCF9AF31D6363DB8BF9728077B7D07B254CD768EB3E107C729BE3D2AD1146237B9FB53B4F9BFC4296099E94D35CD1B358123B1D28D78D010098ED1CADA99F82F5A0747DBF6D342922274658FBE819DB904D59977046F5636318DDE0CC440AC3C0474712B8FA488CA585DD81A7DE27EFE65EAB1BFA52A8CD16FBE2F56A131C86C7DD1F713BE0F5A6D0938891049CB452DCDD744665682C0E1F68EF9ACD4DE6776618492E822E5030D018443802B916A25A62DF68B95F847AD787C0848D2609487993893EA08733CFF496BE0FB34B21DD51F10A071C44837B9676A6F7343D5A2445F4B75314FAEF07E3E40EFEF20A32F8CDF8F82A1BDDBC7F96DCB3640F298C34D5DC72F7F262C8C8559066A4F0BBEC31B2AEC81F2BF690D4ABBDC56B7839666A5BE71743B38812645904BD1D1A9388FC18BD9EE7DD0C4DF20AF8AD4B50886867F0EE7B6C9ACAE5EE58ED2190D2C2637765F4D2784BC8DB292A12F297D2E905D1432DF48FA6F0EC3DB1612AF65B6BDC2B58EBADBF411C323CA09AE4B56ABBDA4452A2018FA5687720FF761AF1295968023628AED87B51716FF33AA80E4E931FBEABF76227337499829A6D79C7C6DACDAEF490CF021210DFFD0C27FAAA7F09BD37C5BC07B55A2E621C9AA9BE12598EA98AACBBAE1981C51F76C5D4E48693EAFC22BE0891F74BE3A115CD68FFBE55188A043D013B741044E59B3165C5A62BCEE94543B637E8E0808D64C228123E402CC047C45D9F63CB3E6F5CDE58F0199666F39280641623F48CB1EE9E76DBE6DE0986C71A3C91C8A82D51252D473A42CF4223B6045A73D9AA9F061BAA949660B1BA38BA3F4B9A2FAC838D2A386601DCFCD6F361DCFFF555FC9348735C1844E957DCFE0C7DDEA5EE03822A3A5E17D07419AACCA1E59E4E3B726D68E2EFE10394160B897C2CAA9A6AE2D7F9ABF852E7042B3B276941D5453909C2E9D80E0858769266731B99A4599B172A6CC20D7DC1F8478BBC5EC2EC8E387F88A63144DA10E09F17765C15694945C8496386AD0B83F7589DA9BA60888572B16ADF404D223FDE1B4D55E5D8B5D3CE2F5A492BF3B17748DA28B43216700BDB1352907E1AB5438AB1EE224749862D36524ED24C724940B38866C531CACDFFE38755A65375579021316511987CA6EF0B03F6E2D82A6B7D4CD8E310EF5FEA12B7D84A0CEADBAE39FAA04460E04FB2C4B1E759243B11A138063BA9C96242FAFA15FCE06ED9580E29B00F44F3E74A437C9D7541C5E4BDADD92D0179E86F84FA3DBAA8F1CEA1B4A329E56B0595C90B8670F63E942D42A47B30805D770D86F6412CC87AE063DCFCA9C353FDC3E8068E3E5A8E4C3D3B8E48E245B7728D6997FEBBE412C01406D869715AB2FE5432AB89577EFFA2C6FFA435FBA59958FCE9DCB9A3E9A748555AF0CB64D7F0D85ED5FB0AEFB361A411406AF6A34610CA9D280C5AD4ABC8F1B5CC4221FB6323930D8F0F2C7F1E79220144627D49B5D442FAE09A2033E1AEB858CE38A54D7FED0328A06F7075E206FE3434E00F09992C81F902742A2A0688AFFFBE257FDA551C2F0089C72F8B75FAD8787A4DEF71F6B39C2EF08E88A8BB0EDED81B001B29F8BFE1ECC36489135B3672C016052FBB824F4B3077E024794C3D1C1C11EB1C31D78A5F314A8CD10A228280C72E9D697598335D2EB05E256997FEB9977BE8A5F1472E5A7F361FF6520F58ACCB812C16FED197F4A967CDFAEE8DE32C65D6A8E176E776D80EB8069ACAB5DFDB3822EF8057E4222E2AA0A5E90D196DBB334EDAEF375D80D6220B069F0625CDF43727085BB9DD60DF31DBF16FDD02A1D3FD0932C4BC23586592F20C7A411225D44385E8CE6B17C43BB4FA6BC914218D88DD7815963120F630D178B34032FE24EE8C2D5F256D7005FD2FA005DF391923FFDD6B1A02DDE26D301AA91DF609967EFE772EEEA6D271F41F2623DD1096E8656DD44EF4AD4565CC8A6DB0FF5168C9552F9A08F84E91B335F3D18248B6F54F84121E17EF6BD48663A2EC9EAB0D20EF4BD6E27907F5D568F33659B2DCD64A10C82C82BCBDFF5296972DFD8369027198108E537D4F0F151D9E52D24360D38172FF8C77C03BFD97F904B50105E63FFAB45BCF5BD6D576C86115E90669BBA2CA946CBF8052D08C3C8F77333196822D3DD10B9955C4D1449F7E4EFC0AF27696929637533689D59BF3B03AE55C835A2AB28022A6738CC5F3FE43BB12DFB8BF1E0137A3CA5ACD5B0493ED71E9B575AFB0D25F8049731C85F50BE87DEBB3CD180077184EEFCC3233072E0A27A9918C0BB6B24E656559D2119391FDF74FA03BF6D982D156E54BCAB37A3F8C7367BA95DE2CB392E6B085E4AB974BADD8A55A4765F42C878E987782A59B9EC7419729869687DA4035147846B227E285AF50DDED91E9333B9EA118AF549280ADFCA75AD6C23B456CF7B222EDA5899E834BDBE2240C534B2ADFEF524AF4906BC66132EBEBCA911CFF0210B634767C0C163B94B169C178F0C7B40C641894A105F375758ED7BA6A1A2B6478F9E97A5D3ABE5F0097F6440F325793571FF212C4C53A38301C3E4D076878270DBFC080448E4BA5F048CCE407F963D2ED434A2AD17385557AEA88525E30E0C3A9D6228B72ED2761315A2EF649E8B483E231B9A21BFBF2F8F07BA5BF89C00E11C239F0C409C769419C748C506D878DF7D0E4F44DBF4900076FE304017BD3D6C87B4C20D92AE90729FC985BE4D9ED63C7FFA978957167E2197452392BD82CF4709A8DCF816C49C6588CECA3D0C1360BCA17F1F152DC439CCC3F153D2DE9771802841FC90943528B2D6FBDD00E88D091B11AF84CC4ED4F1E032180371037A94886F301ED534D63E1B92722954585CD167CAB7145AAC3FA46A692B8A3229D83FF6C34B64C92507F7433140480018374D78FF90BDBAA09354EC34B5AA399C5F2934EFF7131D6668371001A96168A0A8EBF49E6306D7AE4C624372677031109549F426108CA25085C2A40C808B405899C0CE905DAAF47B17617A99849605A619A03A104275AB9DEE9FF17AB747527B28539DDA5BBDD4341BE7B8613562A13CD37C3AE160B616D61C4E9D16ED85AACF2354D61A1506143BBAC9BD6958EF542C3641CEE7DB6A54A4D7251E653EB25E05B4C345FE6D06478E6FD39F73AEE17CDE073BCC7C19D4F239B84E5FD50CF04D928B7486ACF519C68904B838F1268F12C05FB40698585979C59C70AB2124BF99FB97E3CDA3441FDA18AF55DB4E5C39D3D75DE1F6E44950021288572D2F040253FABC31224798CE55E2BCB3BD976A8DCDD7C77A9797265187CD35777453C81286DB5FF66C6B9878619B45EE5BC62FB267615EB970B812A2B19A85B77F12B18D322DBFFE7FF462702C6ACBA478C0596972918F3054C7654A888879412FCE7232F084BC2818AEEC294E52980F854389367943F8C9D77B3050A71A475978C841CB373D37A3960B25BC7A257760C51133CDE7E50B78CF561F1EAB9E9A84B322DCB040FC246239F54DA7D7ADA41FB6026246E81D82E5E7C00487354C4525A8C2FA070963AA0FCE163AF71F5B522C64740D9DE5FD465E328C3F992BD53C2A66F44CD89AB53C19ED320CD6B1C3060A9DB6C3812818ECCDC7B02B9A854D07799F980566B8054045F656EF1989D6120A50395EB1EFDBEA3ED45ABDE671F2ADD8542A87B3727D3391E6125D1D950E0B15A595E23707F2FB9E7C597EBB3C571DD1A5E062A12BF9918DD7CFB06B80B71EE05283EBDA7A6CFE119079C10C55EF683F27CC9D06E85D26900F33188D39D2128B200E648ED30843460DFAEE006423B4D18F37D7AA70CD4209073C6EA812A67DA603A863BAD29A79C993C442BE5968A0DF0B7D26D56ACBD0AFB3ACAE7D42FD1400304AEF11E4D6B5AECD5CB77CC2C6E9FFF03CEBAC5DC54724FDCD47BD4A1D6EC45C6B5A0EFDBD97DCA8BAA7B6CE0F6323FFB6C0099A6414B5CE20A2F0109FC35EB142565EDDEF76754BA999672BCAD22B9849EAED945A7F112F46D9BDDBDE882A4E78DA96D38057DECA09C4BF232C0B89EC9743C6244CA2BFBF52A3285D758250EC4633063E0716962CDE9CD88E346E3579ED9D1F085909BA632EEFBD86536B205359A933F9FD148058D265FFF73902C85455339C92D178C6D26AEECA94375B0A4B7F293E101FF375E263B2561F971D7419983CF733C3BF50D77C4D33CAB9116E8F189A48C00C04AB7CAA471C360C696EEE43DFF6E33DC931ADB4E69806670F365FB97814E9367BE22919DBDE5016CE0F44E0465FBA667E751FCAF2DCDA33E5FC488BF1DD7748897D8C520E4A46FFA8F2A539453328E8C2BA6EAC0ADC1F1188F8D57EF7A28F44F7699CBE83D0E8F2E6AD098B921D1B770C1056BAD3B2B2B7D383E56C935400D84A50431FA94C88A53545656B62BDB67EB7B3E76E0E3BE35B99C529809F59C9FE65F0B19789F758B01C6BAB1A30A8A3FBB28B4EA3E14EC104B9046B70C228503D8E29291818F873DF242A3225C9DC7E1F2C27FFAD83C89C70D03ED21AA0C616137A2C2750A24B30EBBA9875A3074D922076F7D24ECA129549B33016182DE68A235C18AA78A9D27E6732684DAC97320984E441B9F65A5F5230C957B398454E2BA1ADE900CE36CD1A320F81E21FDD36A449A036BFE7410876E0880015BDD895D29AF0F0A9AEF2596BB022CEB44B5DDA25F5BF3EC0EE3AF476E28D5F60F1C8D104003BE1109792D3966DCE207109EF665552ECC29E3C0A887D0811BA980CA96EFDA9B823E1EB1F0E760F0BBB0DC9C8D2919402ACBE08F0E1522838ADAAC6B45CB71611ED85238D2E17907588715D328015A225B713F01300FA5AEF960DA36D4120722ECCBD6886DC08E57A0F68466769636712A361724FB2FBB4AC9775287BFAD7134D577C31170A8A9C39FD5F1557AFCC167B11DA412436F79946BE332F148A72351279E2E1E32522AA8C0731F2F312B893D4F24A35BF2C42279DB8872E70E987CA680DECFB29425A5C51709216A5F69C00166B9C971E9E02B52731AC8DA8988A8A7878CD368085244678777C7C1DC7B0C6340C71FAD6BE4EDB0ADD161D5F701B56E98CEC853AF23B3695AF8CA7493BCB3B405B2A3A5F247FED50EF3F0E5679C2AFA4C2F613AB73CCACDB655A97E00AD5F7F13 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 27688 sm = 0000000000000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA70108E5D31084F6F9D247281E725410F388DC94BF47D8D65423953F7BD8B175D8050E7A09B0DC1E96F31870177ABDD7AB42345B9BF49CA7689F703557EECD4C9FF327EA11B8824D0E94B4E1403A982CD894D9A0E85436647AA74A97735EF614234C47A8D490A5464AF68854E65606D09C887C8A95A511E76865A1B432139E0C164EE80E6C6D99D6EA3C828A660B7FF33E894955E19F46E5831EB21C675466E458406E786CDC1C6D52560A46A26FCF335479AB9678525B94DCCAFDB7A9B6959E00CBDA47DBBDEF5D6D974CCCC04C88FCDC86B9C3DED226919419949E1EC94EF5B162F13C44767ECF866B44F6B8947CFB4608F5F72F394BFB430C1D9513D81B13B05B495B25FB9169A3460E4AC08509F6C41627AFB5261A8E5ED535C7D0FB4869E1FBBECA5F998274C2E153FFF3CEB473D81B551AB5F85CA351B4BC225D7942733BC8DC1F0B2FFBFB477F46826ED037A6E7378BFCDD20578442F9E92BD6B03C8077EA3E89B174D5C4892BFC0417F1640D61FE20E88DB05BB1ABFD542EE6C14ABF5D244746A457DB0CB019795E480CCE9C457DE66257271565E72D03BAD5A02D8311B494290DEE03A74DB1B3A62D2EC10EA3C3EF2DB3375893598133F36B5B8F2AD592972DE5049C743089529695B028F2F72BE0893E59169E9A2376C64BC5CCAC5482E13DECC3723604111446FA56B31CB301051AEDB4E1533567612ABB95A8099FF158ED0D5C695A662B0EA2B85270674FCD635917F4F10D577CCEBEB8877FED67DCDEAC83360CF8C638B6D57B943C63DA7BAF63F99ABBAD2C9B47977BB7A57BEB9410160A61FAFBD48649A3D2032C1679A67F348E3E25275FCD9AF650937FEB0A30F8953DDF5F0562A9D378DF36D061DCBEAAC8613034756516EBF622F21096E206442A9A24E79B7D98A56EF751FD1AAB89A95F99301932337C4E7820B84B1DE9CA2BA7A25D6C3E4B7D39A28A65A5628A93556FA9F54E273B583F9A197BFF4731E0429BA00E66D42A900F85130532F5303C7BE837860BC82BC2CF7CDF0ECEA942932151BE85B8E8195CC2F070BFD482702182B8A4A43ED942F6BD3CBF9DE7E8AEB17EC786BFE2AFD21BCB353A1F77030A18BAE47C0D2B9F396BD8E5FF560328AEDB20C718E8427DC76AEED4A3F38D853470B7271A968B537E0F60E1979BC257B0A6AD433C67673DF7EAC9BE29415E55FFB6629F621AA5970B4F58A93F52564E58BCC84F2453E034B68E21C492FAAD68E2E6795244F4D34028C14B65C23E9F23D5C2BA27F67484ADFCD6EFF8E13E7C1BFE7EE5879654357E6A6B98DB099093D34E793C96AA96BFC9E1D6A851663336861DA97A10FFC00A4D5A8E4F1CA04A8C91FAB90346DA60FC80299F79BA6F8FEDB4E1F705DE37AB2A10761A89127B9757D0F10001923A14E18828A59272060C3C7F7B4F17BB4D470B214ED52B31626F1ED62F1D003C9AF2D41510FE1D89C15CE442C7FCE52DD7AEF5B65923DD8CE7C031E6718825D1BDD7C324F7587D4412000A3EAF78333B65C00A8540790414E83288FF8D9C9F2E5B8879D61077A83925E92D1C3106A85A7815F9CC0A00D536475C5C63263C26CF37929B5F2D4827B72B8B27B64DC91EBAB724047EF3EE1D4304B98D74984EC5E78F5662510C632A8A493910BD6DCE3B1EF3FFBE4583513F2B8D6667ECB86448E01139D394D40C1C23243D2CE8EB2D6334EFA975B68A57940B01E7AE65A38E77903B47056A97A9DF915AB3C3887E2C77DA350F5F8C4EED477B97F822CE86F520C8354A3E599CB7217AE688647A72985606BBD0720F6FA5C5B6F70E88234EE54AD711158BFAEEB39C98014D0C1A172699F3C6D33C5D9DC9BE93C7F3A5780F02AE964D131157AA78711B1A1FE5FAC4D087B5ED235135112034CEE15D792A362D046199906ACBD18807371EE76F04E4DEA69A68B75074CFCEEE3B13ED977BFDF0DADE5F5BA26D69ED191B3B47599B1CF4E28004F8C1DA229C20EE36147369CE8C9949F7E5CE56323077490807321869B9D7DC329B0144EE11C2608142C9A29446242BA70019E737774335AC1C50A0CD6E13B06E3499CDE6E9DEA640B89DBC09B7D867FD5AB1546E60AAA06344D4610348BA58D8269AE23C87A3B0A08D3B8DEBF66198403A17E0C98C14AC4A5FD5DD6D543BD9888A96C54644ECAD9B108AA9F04474BE804FFC6B0D772DD5757BEDF361C340C9CA3D9449895E9AFAD2BF923436FC420E668D3FD58E175278BC30BB57C0880833CAB3C77F12E98C3550A8ABD94869EB5B3BFF85B945AAE0B740C2A1AB94861181379BAA1ABB3B04E3716F43BE1FCCF919998375C849D7658B8FB77DEA0A72A17F5CA24C878412709283F7FFF77EAB385CAD8DD6D937172EC79F4AA07698FF6A6E4C559893DC05EA367C2A717CE120A7E2CB455011B3E98F8CB3799F0B0600E74AC1214454C9F6D1DBAD9EABF89C0608AE5DE2ED5D631B575F59F445A94E79190E6640E42F2A3DCAAC94A1C6E3D522B9682AF0F8FFE84461F7BACEF360D279EDD9537AD2838851E97C564BD2AEA949AA9FBD8420530F63CD1638B988724A1E11888CB9A2B11411C221BA02F0ADCF54F6F0BFEB7D77B5227DB43AC1360C86DFEDA86872B28FA47CE1C78A4DA2508F214D75BD46109FC202692A3FE21B7739AA9C39BD1B24AB82C59373CC06D3F92D48B005BBEC6C139005A872F0D032278DDCFEE8E636303308F418F73E3FCB7B63464E41C65227E6F51D5EC56D93D19E1D3279F668A13A2B3599139B265111473D5F8F73022D8B7CF740D798573335CAA3B04CEE0BDCADCC2DFD20E920A0B83391E2CFA2E0441B6473EBD291791F09B4ADA70A5286EB05167BD59BFD8C46427413D609827DE664819C8CF4522000CFEDEA88B1CD2818254337A24515536513833D8DB9912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70DBB81517936455A05C964F54489323E7A18431AC4CDA3E320A38C51634DAE5EEE35A116A3A2C931019499E44907A8AAC00D621FE3639FE1C31F4316EE530D4009C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC9D550F851D023315BE35A69C83D099341F6BA69B6A40E224DC554A3489D33729C9EC8196BD665514030C26AAEF80CD6E1BB9EC739BAA2B8E4A63EE691AD2BFBABDDEE2B13CFFEEAB7C25273CAD45409B5270678CB1535AB800679906CE77189DCFE05BBF92FB5E31F184CECF3C427437958F695917E343ACF46DA2B9D988CFE316313FA9FAAD49EDB72B007A7F3D6FC55A88E6BA784FEBE9737803AF05B4801CE0C723C0D15CD8E7CA8E237D4A1C0BB1413D369FC3F21F69205D428069EABE626B971A2B5698ED05BAE54218300BE8C4BC9A52EE5FB296BAF2A9AA42F3C865DCC1DDA69969F085C91D3CC5934567476EB70461B942059AC0F83BA10DFE783F5FB405F159563419B3F5699179D6F33AD05E840EC9227C592E361A49E31D99445437D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB3844833CA9CC7907865878A01BCAE7DB72BA4F7701F20523E0E98B27AF08AA747B57DB1DAAA1B616DE469C7FC83CAA1DA1D6BA6F0C2B0F7F2CB7A4F58FBF7FFEC292AAA7FC3B87E797DCA067ED7672BA9B4CBC27FE9AAEEA63C8569A567129990E1E12A8D23039A877F7FA3EA9B9359A842A19E33CDBF284AF95FAE2A2DDEB80030A8245A7E51131D27EAE94B6C38A8C4818CA7EAE0A1C0841E7AACDDF68A4C4491EF97D5F3F6AD8CC47D2489DF1FF96B7DD444D31DD2FFFDC69C9ED7F750526B3CD81EDEEE2CBBFC0BCEBE875DBB644B3828795D2B81DFE37E0E4E68F9A798E09588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE596674368D1D405B742EE812FB88947D9F5DE52083777E54C2F0A1F605027BCA5A12BDBF9CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318ECCE515F732608A96D4E557ACCA60F144A212276CD52FAC0F12C39F7F45565346B6EE409558FF37D5C50280099C9D75B688C7D873EA7D07EC6C9305AB367ABC2FEAFF9200CAD14D71DE9E1F1DFFC4F15FD0908C6687F585D9721AA773BDECA4C7DBDA2D8275C59A2E90EE07ED6734A09566174D695356166041C646F18180DFC5ACCBA61F1672213C3CA6933A5ED65898AEB4BAF534751900D2CF25A7A94C273533B8694EEFB366F4B3E6D4DBE7FF5FC70EF5341217906FCEC863502598936A4A0D7DD4267B1C0C6E8175CFB3B9B6BA86CF3094D4677BD57712235CA8395A6914063B4E2849AFA406B7EC6E3AE39B343EE39348D2D29A0C2319BB34655A53E1A816CD5FBAD3A3796FEF2C7B67BE4507438E5AEB603B1A0796293A274A3F3D63C7C1F14297987085EC271F06E8DC986CE41DDA37ADBB39613E6790644A669594AF10B5D7C2DCDA7190B03F77E69D79A143E9B7D8B42E18E56D1D191DE05D58DC29F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA4C86ADE353F4AA57DE2220D13EAC9BC8FE02D625EBE3BF2761493F180F968DE438B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE8D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB07425116F11D430A927D45FBAC134C59EA8E5907C35A59E0CF2FA548F9AA27A3530AEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBE6FFF1A2A91E8DD23131A7840BF7CDEA3E18E706A324AB688A5866B82EC18082D89DB83F78DB30D5CE6EF134BBCE7628AC017E6D6974B1D82E4227235AEC9862899B7A4E0E8B10A8AD0B19A54DE7ECA861D6AFA1D91C9CAC7B8D6AE536C458E176AE68697912D7EC853D514AD4EDE982FA89400CE895D3241E5610D0AFB17AEFE51FBB41E2DE044A00D84BE759242476BC0099DFE159F0CAF2187BB311DF2342A59C003778A56907F086C8DC9309D8E41703779C8E1141070708E02B9F987ACF3214A8E442B76121374DD243643D64283D01279A49154760E3567E46ACE89898BCD67842223D5B8CAB03DC13930BE7210FAB7FB2318BDCD92B642F6BF178BC30B4F959F5D8BE15F67C5AC4A4C81F1E3E707AADF0B4CD02982ED4E4E52A81EA2FCB60ACB5817849D53C2FFFBF7906E290BF76E505071913AE0361FDFCA4B279897C9DECF546FB0366D65C9F81A9B51402F3694F0B5DC600B7E4F084383B643AABC755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E6C007F614D3C0A2E45486C2E457C2E6636BC1AFB76B2A7FA351FD88399098C64E379F99B64A3340473DD46C11564937DB9A28C4DE3745308433153B2BC6D5E0D515C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFF0116375D404211C3D3302D17DDD0390712E06CA05FB4BB2AF749D3439A5B30D3E9FF4731822AE6607BD96108BD229A4BDA5ACF50F7185BD1C0F56CC56D69C008077082C0869F237A6F19D73ADCF9844686E3C5583E7D8FFDA636E70E989B1742ACA4DCE98101BBAEDA8E852555033A46F8DF4E3DCA1B9A09E9F938E0C1E468C52F7DC695389C21D0F425B4DB554FD5BE1FDC2765B997FAB1F94D864DE1B4C8FB1323A8D90DC0CD7FA7363AB70728FDBF33C2325FF97C59ADC84C104E730C85CFBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272D144DEFA2E32DCBE8CF7843CBDB9A67EAD7892ABCE9B25A6B91AF0B893846ADDDB6C26354D4D8B77B14FC2FA2D8D589237C4BAF80344C306439619E5A4DDD4630B558BC9B3581AB842BC8B630F232BD18D4BB10FFA1DD3805B18635F6A9A22CE0D470FAA2AB813662EF63C784628138499A1A3648CC877300401E61DA9A379FDB3FC6DD985CA26EE8093A24879BEF107C4D6A38017BE3AA5CCE124259C42519C6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156771072191C21BC3190193111CD3BD0604EC5427C6D70B1BF21DB6E59ED636342BC417CD9F69B804EDB6359C9F8E347AD253370E065D500CAC64BFABE3E420E39000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D00C27D20CB93DA243BB3270F1EF2DE68AFB80842E8BE7C1FD48BF0F5622530CE84C1D30BC69EE1164CC602F2522FA39158D4D0D30ABE4FDE43213ABD6E4D65E62FBEC9AA1D485599FB7ADF5C2C97B90C82A1DCCD2C44ED66CCE79EFCEDCAD0CA1366FA51DD03DAC9BFC60B79719033B32247DDA9195233329F5AA36627FCEC5E42F078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DF657C03A3914FD3BF1E82EF96AD7EA46373B0A4DD0F5655F22F754DCD35ADA89358DDAF6AFF78EEEF21010DBC6556C2C3A018E4DA1D612CC3EF237BC2B1E9E600D923E2CE04FA27CE8EE63B969F6079FF8551B8C06018E99D84669C059AE08081E3A1C7ABC19272D7FA3F2704CCF6E491AF93C7CBD4660410389D86BBA47BD5A0E996F788FB9CE600AD76485D265628019B57FC69631D5266E8E46913ED9142FEFAD87E26DE53ECDF43B352EAC14BF6DA899058228C9414E7323430F9357D6244E7165F5CA2FF2DC9899AA6D8C2B8DDE8E2C5FB7C6E02BF74F578823CFA2355F2FCA1F776C6A87943344A5E53BFA39559EF98C397423C75EB318EA9B5F375C17E7B46A8D592651E7D50E70233224592389C1EBD1EB66678AC42C2862A2C660BACD03BA4064EA38D34A7D44B32DB9E75ABC6B5025B504DEC60512A80F78876C54D36324C7143FEA85ECB9E66800E8F4004061EA7607EAB964DE3F9A273D2C7A4CECC1B4270ECFF87A254A139DEA1E0F0B0F6366C02A0A790D46EAC94866A82DD8349F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DEA67846512E96901F78E601EE427F8B1A7986FB8832D091D575C277CB202E87602D670CE131CC6023A9E83AF41486A04D62616C1E912D4EAECD5DC815BAC1C0DBDB347F6B5DF06B0F58441FAB98B9511AC0423ACFA43E0422A62AE32A48E935C6288BD0D2314C6A739A7779BFE24DD7E2D66E9C4A4111E22481688EA39F256224531ED241A9D35D395F340421F2D8F5C05B873052D2128CEDF4ABE49E609176674363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D02AB14858954A117C6B6F2CDF4823BEEF1904FFB4D841B30537D57C577968CDF18EC8631C536AF09B54D5887FC0EB11A70E86B72EF315FD722FB680EF03A3487434215A0EEA412C0D78DB2EFE20061576237453927710860F0A49DE0ED0C42FDE2A5903D635B19D4F2001EE353D7B5210E1C01F50251ED6E753635A972EC8C1914E36522B1B41BA51E9F3F1CE83BB5F526FBEC31C21983736E42EB7880B9B27EF6CAE0618E57F881193714D3E8B38C9E9056378DD79E78422BD7C4CD57D230EF44B38F6A107ABC77B8D5A953D3A3969FBB7DAB145C4F4615FAF8F2172AA2BDEB35C4A0494100CB9CE188DA4318EA5B617EBACE910A32F0A280C82AF82121720569232D71AD065E45268B36F92DDA13673529F24E6B83A865F3E266635D9655C8000C06478530294DE092640DFB324E09DB3B87497C94502BD46092D72DAEDFA93A0353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB51691B3F0ACA92B02FE916D2AEB98BD9E23313F49A0F44394883A432523EB5B34B690EF9C16B4D60572EF2D791F2BF403255A28D9BC3352B02687AD9200D34C05259FE0C93B75455218E031D59A65D4F571CD7F8B130A0CA1363BAF2D9895A8E8925ED20ADBE8FE96C34A6A13B9318AC8A23A7EA320B83B7175FB54868DAFA9E233B0F4B18CF6FC7D85F7A2B28CEEC561222C5051572B092F2FB269ABF1CC7826675F09949FC443EF723AB476E9E5D670C5F05E46DAE93837AA0F65A4E83AE2C71DD02CAB1038086531F93E163AD65BD962ACB9497C0F268876B5AD3CBBFC4C24EB2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADB0A78B6C1C4ACB8B4C97EA8C4CC3F3778CBF761AA653D9531216588A46701366E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC4050CBFA6FEF6B9FE785A59511CCCE21EC5AE3F429A07B4626A4F0C555A15B42C26A5F353E7A479A700595689D5734C39D61177AAB2943775ADAC879B4ED7B8ED826CB43881D2C1B5734F64A5490A4F77ED4DCB9775B258C18182B42C560E6CEE89A329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB041A19053D3003420EC262BF0F45F1C7CF6E55BA9001E4BE097329CA460D335BA899503CAE0D617BB7FFF0AD37076C91B1659BD448C05C49D9360462B4BC601536844FF2C635BB654EC5749FBCEF3288E41B8A7835B645E0BB501FF805EA4B39785C203BE03F0B105D17E513D50B7738E78EC18AFAB3FE134FD551E754CAA189DC4FA2308B6EED1B8CE87EBCE212E15E72C9516B778C1F62819131E2EFA7AF63BCF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0A2979199F43F2F59FB2C62E8AF2EABAFE9B89B71E75AF029BEC77A6A56F86EF6A4A7212A7458986D2DAC9E00CF68EDB81CA05A297B522D3CB2E0AC3146E4638995B683EC201C67C911C83E6BA3567D31565DF914783F41077E2C31B06640446A6D403F9D46BB9D00B3C436FE1FFDA80AD0AC466AF0417D18D5E7DFEDD7D68987BA55F545F3B89A38908BCCA1DACE0B89FFB49FBA3A67EE7384DEE68FD05721483030ED53913A6CFA059DDB451C780877E919BB86DDCA9E18814123CCC822A8F30D0AB4602815D2279398ADEDE00B23AF4EE605A771AC616CAFFCD3AB12991023A6BE6BCEAFB1672ADA631C6CC29827088627EF9380FFF46FC479E2B586432B58F95A824C0D5F08704C2B596A7BD0A36A52BFD8C14D999F92E676C83EA62DE54C3ED7ABF290BF17C48DD69F949668E11D957299DB6920D740252A9AFB65179FDD62B69D2A1A339CEF805FD258D83FD2F406841565AEF5E42ED7687D9D466E6A4E513E072A9EF6181016DAD988F7C2305A77740F196465CE30A35BF3D098781DBA2F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549617285753A9438517AA7159A9C806A19CE8B8BA5F9C99250358404671F36214E8A7B5A04767FF8C094A3CD74751835BD896FAEFD1747DDFBBE79F48148D56BF585CB0CBBF34300CBFAB9DB32469814F107EF7822151D158CAD68F01418F88B181B092970DACAE4D5DEA7AE39965D1929CBAB7685E758206D309CADC07687274657F6EEF56A657D3FED4D34C7FF6C9CC5F344F0EF4F0E752F83E06B8A23DA0D65A2C10C2D675CB3A214F5D363C35E6E10A1323579803E4268F7D868F4716BF849B3C3D8EDA94476BE7322891C36D6DF146075F11AD02434D2216351CC26600662BE0D38E1DFEF9A832B9F066718FCB2134115F33717B57936CCD2DFA3A95C1D4C4C98BD09D64EC04912C06C7C6A2FFDCA2801628D873EE6D0D43EB67FF0AC93A7666C9ACBB9400593C00316E05F0F5706ABD923D85DE72A0D1CA9F0774F5180B65AA578B95BD20C1FCC322A5B23995ACC9DC97CE3043B1A723AA2815314637B7667DE02ED0FA0924C0791CA09FA028633CCC594429D6E7429930C7F01EB6A134952E89B8CCEC743A23C63CDD9E161B5A2D1F1E0D005F16727A3B0E8B90C20656B850A4F8B5D400B65E91E45AA25A880B76BE09F226DDD4F0E0AEA00259E19634EBAD387CCAB556997A153D1C1B87AA62E5B613A5E02C65E7EE7DDE2E19D965D27B42AF8542066549A6FEFF3E10A93B349EACB843759F5E4EECA76CF82277BD55C57FAD09BE938ABB47720E49CED626AC860446B290C7FE9BC83DB0C7FDCBD5CA2B8FF6C52B2CF2556040B3792BA99DD43EDF1FD4CBE38970D235E8BEE40DDCD2708E432008992D3F9DCD73AD594171092909019E9BBE7A5D4A21EADF82C5C22D877F422EBC64734717C93A027E9EA7EDADFFBB8A04B465E2F1BDDA54BA30963A41978562C27EE91E8ADD7A95B97A1F9F5C0494C3E44AC5422759F971200B1927F5C37B003499B213C1CEF1823847ED4A308D7D98FD5E42115D49B1FD42C7405B55437E1C8C0226884DD801CD89163AEE8D74105F621EF2CE222B13ABBD14078943CE054E3D68F7E8D763948CA83876F0AB7CA5123ABA8C5F68679FCD116D03391F2A53F637D26EC486FF6363F0C297E1A672EB717107ED9540C2AAD46038F8D4C2B5D1D918AF6BFBA7DE46E6628B2C217672257EB98F585A4E4CDD87729BA5ED16719F869FA1495302E8BD043F92ECF8799DAB7B9C501DC956EE3E55FF30E6D565E228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023E10A68B5275694C30FA7BE9BE2392EE6B18651980A01348A97C4BF091DE3501B30B528092599313ADC93C8407FB07E740F784E80461A23A1DCCD78BE8A72EE2AD69CC6E63F385963275DF49AF300E5D468285CA4457F090504D42056F571A8D453903B85D7E63F893431A5A1C8A66A8E4C999F0592D75717940E296C8275952C4A8DC6E97B3D5602408DF3644E8A1338C856296C37B1BA8445883CAFB408EFB9A545AB53CD632C40659DC607F4937A4F364F7E3B47A907BD30D8558C76A8EA9EB357177B8B2639477433604EB74F9C2E3528215459533C1A989FEF107944FC8A402E29495F72F2C210135FD836028B9E21E76C6F13096DBD2BE9721DD2C35504D648C474907FFB896B014CB022942F308C3263CFF227D4444763A483658E728EE6B7954C48E3FCAB1246CED1B1E2EA9CC4D5475BD4FA43FFEF56AB2A2D779E9D206E3E657A2244108BCF55C7F4F97666457CF5F796105ABC773C541173B9E338B4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F9338191406A4C257E6B7C058565272FB78A54A46007F5550234FE9B7952A82581C08AA6A1EA68E497D663F82C5D20E9D1134816EEA319EEAC8E431A0D82B6D62F7B93D121D8382F0EB3DDBB9FCD43901C8AF1AA019A7160B76B72D4E8CA1228E5E9DFD49E24F3154F4A914987FD0264ADA4C8D6FF9EBB91C59C03CBD484E9EE72F1A98C3F97B9F2479FFB79DFAFBC33C8ED249286369F003C471C8B64A9B1546B1F31BFDD0ACA06AAB3EFB61E49CDF5506AF8A4693A7591498D9D7F8B28A72A10EC60F806A9955D7EB41D2654EE5B37C284F41CFF3F591C227E3FD0CD524379DCB384ACF486CE7B1E658CC743293DCF546BE85382FC40CFDFDFA407A9EA33AC46468E060524BF06C9CC109A726CEAF0811D0F857C08A3D4AEA67CCC0B17B2C38C53DA9F860C99E3AA769EE27CB7C9229207ACAEFE6C62D3ECFCA201DDFAAEEE1EC7BFD40086AA922961198B53C94BCFA97EEC1DC0FB8FF1D9448B6770DE4F5703CAE179FB51CEAF935F666F398B74BDE9FC87B01AFB6EE8B47490453198F9B38AA2259D2194E9EBC42E1C57994921413D6327018B91538CCB0B90E965564171D133CCD9E7F65E851971FB71F2C47B4592C2A52A4101D2EE7A69DCAB3852A56C4DBC9295D2EEC5BAD1B8A13B7EDE84768C0AF5FF0B0253B44038C236412ADCEC91508A76BD8D16E6D6BD5CBB3179B34DB8902863056CC65A4DD40B6A1929F28DFAE1CEC64A74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7E8104E8D9DB129F0AEFF48177BE4EB60236851F6D0DF3EAF508CA7F97E4D5814F71ACBCF00471EF263D3B5CD58ADEEF11E3465C704D90101A5FCC1C8CAC25387B7D6B83C7CBEF04E05BBA1766C5C5D804642609AF84AF3FA7E4572393761664021A632DA048F2A10C2A349E2E1C260C1C3CA6184BEF6045F43D9C767E2328B9AF5E48EFE8298DF69599C49CFE153BF59010741DEE011FFFBFB4EFC5AA4B5DE409B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F83369497B16CBA6B3104624902242C468F89E89322D299123ECDD8ECC98FD5C53D99FDFBBADB056D1034CA39CBBFF29300769BFF634A38678FE7BF929676A43CD0FC3161391877F0623D9B59DF30E28F5B47C0445F83B36F0AA67F6A2DB8C0C3D3F45738A4DE393D8675E286F4530AC810D244C621963923BEB20810EE32909DC96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A35F79B7F944D0041C0130B7F59B0ADCCAD97670C92355CCC8F0FE34612A088BFAAB33542EBE8F3283AD67A79EECC3E7B7C5D4CCC29B6083AEDF7AABBFAC8281B7D7711DED8D4CA70C383C5042272379356BB80EC0A9BB8E4F1C73F2D2DE1676BF5AF43AF87AA2B2C4A6826DCDE46E599B2F31E9EA87A816EC5D8163952A7384603C8FEC20F58E1AAC52188E42774382077A35700EA5EA2FBD04135593A7E40ABA137FE400EB63BAC7F417252EF6AF6EA8FA9CB3BABE7718FAC4A756702AD64BF1F912E6ED44DC6D424CD15D3E45BC9F86ABF7CB2924D7B4E8AAF67D69401F5609B17D251140842D7A94FE5D911BF2FD37418208B716D2DC66320743B79E64CDAC6F2257AD34D112E22F977AE6034068C0E0F089FECA11DE03396BFBD365B1A788B2C550ACBED3643C1E4F13618F904B40031CA9E73F9B13293DC92102B33FBC16C9CDA02E511D49394D5DEFB95770E5CC750801623042B7113D385E8BE8FEDA1D7F9105D545B18AE98870B1326494F9BC31B33EC24CCA7CB8E53F9AF1A7E099B0D9A40CCF40B085C0D406B5F1DD7DCA794345FF98F272F7D9A11C30CC5448D2D311502B7F0F81437B52EB11CC5FF11C1FD62B9A34E2E102C5C59D14A3326702F6B6862383B5BA1041A59B2F4E009161857FEAAE3F0C4006926444BE77169E9963DF262BBACFC643F032414200B26840295326BA1983CF450DDABD0DEAF05B3AEE35CC029B1E67729517B6555FDC996782FE0CB275645E739BA0BC75A08869998C082BF6680E2DED0D643F06EED3947CB24E4D240CDAB6B07EB71762DB159BD8E8FEBFF190763906FAEE1D307115E7D6697AF3DB2192D37468806FD49ABAFFD157647B652B339A8912CAA3730EDB23593BE64CE9A50A1622D43538926E5B05D878029C5AE57DB40072EBB7889423A948257F9E8684E5B4F10C09A22AC506B5105246ADE89409D3AA78C4A88181FD562EB714E9402F8C4AB2129E73FD77BB64F3F6752E5AEEBC4DACC209D01A274E39A84857736671BD0604C153703CEC940CB0D79CC433D157EC5004ABA2F359B80DA9FC04267584B2897B594C494883185E613283B939DEBE0F324B3CB9F45A6FBF11AB1CF2704C5F83BE3B8CE1C38663757828909CA4AC49ACC134F533F5DAF470EC30D2E8FBC66C9B6C58CBD2ACBFBFA2842E78DEA2DCB820CCCBFB17454EFDB2B1D706B93B0254B3209CFFECDA9F52CFDC1CF312EAE3035C1A3D75D8764F693350C2301864EE1A3797F6574AE38F66B40F82904FFE6CBB34655B99959759EDB652F6A3BDC1D0F24E8EBE1761B43E876A6A7AA29E8B1158F1D150E25A742B5FBC7161234A85B35803FABBC0AEA40821E9990D48BA7EF7E1A50178ABB3CDBEE228B40C8B02C98C5E8B70CFF650E570988E64E6F4FB69DD11814016F8AFC30F853DCF0B793E150C3B796CDE2B1B43B3E346E257302026A4B5934CC6A417A99706CF783722DC2663F469896FF8EB4CC741D531F3C32B41F0BC6DCD4A32786747BE120B33718A94639FB4D754E0508B0315990F31555D6C1DE281244E229377BB4FDB9CBB38AE483A3569F735AC438C492DFE94149EB3F4A4F9779A1AEFE60FA343AC04323795C9D33DE8AF95219B8711B1168A107EF83062F033203511E5663EFA0C45ACF54432C9D4EFB5678332B5E164092612E42C61560D9EEC768594F4E0E6AF10AC7B3DCD22D229AFA8C022EB00AFA626C63E8E96B72DF979586867B42B8FEDE446A0F6807F1F1C775595FB5DEAA3BE2A45570235BF1169F163501B400DB5A48D7FF08851543CA92A0E8448F98BE619F41FACBF13EE45A1F97C20748CDC3B4068D993D944D5A165FB858FDF4FBF88632FB826103B1276C7791C64195106635996700A71E299889131E533F7F060C7F96E7C54F02D2A32835106FEBE6D40CD4D56B57ED26A7431731B04A78CB5A4884F0CACDF007DA6E1C4195B2B59A53F31C48EF9FC33CC7F6BD147032A1B6313C7EEC43B1E46164BEBFEF16FADDB1A176FBFBE34DDA7C88AC9C1EEFD4F33B7960D847872B8B433AD5D1293EA480E6FA097BB9AE29A7C0270A062EF9BADDD796FD8EBB1502606E9262357EFCBCC9B7343ACBD03CFAE6907BE46BCD32C4C4C4722C8D3A9EBC76EE4CDCE71B049D688C42104B94A1F7FE6F945BDD02E3DCE0C345C047AB31E7E8051ADDD3DBCBD33699AD660C1CE3E25D203C4EA56368B19C77D498E67CFE083ECD3D36BDCDF29A148224623E0D70D060EC964B329186162C1567F7E7B5B6921CAC8894E88BD8BD6FBA1E8EC4081D35931ECA2BE1E72E32D7C986956EE9CFB07CE0B5091605780D9770A00252C92C4DEDD4D8B942E14C90DFC5BD612D85CE24C5CEFDB3EA964FFF256B20A4DC2C0EFD50DA4BAB56BC846B09DE27F341EE42E63C0C23B6C61D15F2C9FFEE5663E3CC74F7400D0645219751B70C916C03C0C67159F71BC0B3BFA0956F026B91F8C2419D671D3E00D7F633DBD2DBE88126DEEFC7733C2C926D1D8B0C8BFB1077A700BBF3892F0C4F3E30DF78BCE0A340A8F98EBA5BD384684D1E0081C1237440B3A6F117178C0DE4F19D05D4241240924D9EAF9CA45E3D4231AC903C8EE5298A3445F01961D6D3786E36D24875E6DF3EB1D6C1BE5EEA0E060D3E0EED1DB2D4E795D35A0DABE4A745764F05A858291993541AE149CECC5147FEF0F3A96B42F38963B9B29466FD66AD46CADA8F10E2D53BFC3B823CFED410147B5FD315FAA62ED06429D6D3FE6E5778A64B5C9BB06A8CF5561EB7A8B15838AA226DDFCFD4C31805D53A6EB7D2DB861451027CF84218C39078756B2911021C3EAFC2E82ABF792C5012CFCA3AAFB0A277A9C9E1E515CBC4439D95B2A54510318F5D6EBF97C8DE2AE0D4FF669493AA354C25460D3C15B1A57AC53D7E6C07CA407AB1EEC4A366A637AD4081F0343433C555DE72B71ABCD8ED3C043532A61125CC3CA06CAA634E5F75B750BF262756A57E3FD235FA9EF00CDD9553D37968DD680EBD5935FBDFE43A82E9DD39F96FD483AAB7F2D0517F23727E8F4DACBF144E3C9C3413B4497ABA623AFE3257572D979FD7234C04292B8EC507187752446AD11D10DE925035D368AF83D202AF6979123C7F3B7FCB8D83812728A890B5C09B482529FFC0737FB59C35B552AD7C5820E27332D2E44F2A31ED972E2E5C834FCC652204BB401557D6FEC656BD9F63B9226056E2D025988ED1312A2A767D418F1342BE489B463AA4BE823D471648D9893364758DACBAA63BED8B3D8D4DE1E4A76442D207EFD647078CA9CDF7800804012D4EC23BA14C99666610A22DA87523E4E5E41A6698E5235743A9B9E1C4795F38AE20CBE5C3A2111ABA307C3BA6E03F092E96AC6EF297548A3F144ECF7F643EF19024B2E98B51173450ED06ED68EFFA06EFD60721E73C9C6993F14C00E3E4BE441791C648110F699AB5089D7CD092AAD82AE007C0C3C8659506D5F2817E75EAE8B803734822A2526861036E35C3689EDCBA348A7A2E4BE2F1E291F63473988AFFE650C1BC49CDEA3875DF4E6B541727B5AA6F04C9C1E4D06BC5CC744D1B955958E2578C6176AFD7E3262CCBC0F6FA21596BDC36349BF9329BCBA08FFF934E31DC1FEDB7D7F6B459BB1A0165043B902D600C447792A618B77C1671E5793473DED54FB3322180F198873E306E1F8BD17BE04FCD3CF4D6A9201B9B804BBC772B742097663C42F0FEE3766B3B205F14A39D6ABA56963D03DCDF538ECFB8A7AE64DA3C116BFC09506BACF5E8B5754B220F7CF70C5AA4492AB72D20CF8F4966A114833B057662EC63B9570D9B2DCEAC86590569934F91A61A03E18835E31ADBC2EED3BE0BC148FF004675C9555C901B280BFB56FF8A1C079E1F290C67FD1B7E53A6C27A5C649ECA9EEF836621F9E708EB84B6F5C529ED2F07BF0A6160154F41F323DFF8A498177FD09D22DB15A273F787529852D898A6DF0FDBEBEFBA3F3B602B1E67352224860125216AD6D68CA891606E179FB415DE4B95484CA6907319438F69337316203F06AB1488A471924545C81A470D78E2EA29AAF89E94920AC4B0E7F2FE01092BC8CF3839480A02C0E8DAC1E864C9BFF5CBF46C0FC7B6A01FF0DBBCF96E3585496C392C6496D06C44765878B26B6DFF2C2FEC20F26A9A2706838A2048E579C65F3BDDEFC58C89D8830FB8C75FAF96788998DD200D48189C3B59B41501BD310420DB96F7CC5B61A2EAF88B498ACD890F7DF623A35479472694CDDA58C000D9BC04FD903E4AB88A2E757700FF3F460F075F9876DB3F76F17003E01DC96A92543DCDFCD7EFC86A5C0DF387A50ABB69953D6DC19A699CD225941F82438A8EB7889B212F65ECA7399F89CA0D9B9915E827D2E520B6D481C27D4CD833EE7D985B20FA5BF7A21E4DFCAD092628EC0A6E2DC876E4C5BF248F94C2ADB3D6C9F23C3E70D1F611A2041C7759317B8EC1696B2632CA10CEFA498D7571D016E102DAC10051DAD086BEC58AD5DDFD7988C5F433DE87C314E3930FFF937A6E0C81787F04B77F893287AB63125CAB8B7460F119D03BF3076A98FF029EA5022201DD54C854711B8BE718EE678544B51AB13B7ED0262C8180C2F36CBAB64D862D38AD7D8172AD8BA3380706D52048826CAC611B07468967CA4A4DB52628A2FD56DD3A323382E5DB171811EA861E2D46537D0A4E545C65F238380083A064421DC7CE13EC2F715580924D9B6EFBDBB0D45AD8952F602BDED6455C0BC2734CB135B79966464546A261D0A551DEB43E5AE111CD02D0F2F2E996454DE17B471C6103D851CCE2E1FEDBB828C7F4EE66053A57831C708C377FDC6FDF037F400A09E9A610350BE6C013239D7F1C42758CA84B428EB06C6A6A3E05F10FED769CEE2D8EDC3EEA29204605005468B0366B2E957A7A55FBCC7842598F55021E58DBEEF44C5313226E6E56A2D3837F2A098C94BEC791737F355E6CE5643C954C4719C6C1C939B7716A29191CF0530BC2E78CD028D526EC286FCF02B18A077C86BC54F078A19A529F6EAF69D5562D4B31E4CE3B953A24655429BDBAEB5378C13E5B404A138B2B5473A415EA236245B0541B6D92F384D4CE63680ED5A6C035FFFC663C893C8F51C5DEC6F90D33573A05CBAED63B69079EE77DBDD21AD7A778B37EA5E0543BBDCD47497F355B1B2D8AD93DF4BB96A5E85A2344192B782D54C4C8DF251BD5F72EC415621FCE91148DB266EE1BDA0885827E96E8A9AD9C50F43D947DFA8260661FC9326B9E76214D36B22172C026EC12E04ADE3C62D4E957AAAAE686D350793BC6E9C862D968C0E56B3160B5C70520E9AC7767AD2BD8D1D6DC951A23BE9FAF9DBFF407E7766C84CCC3F281C6383079DC3188FBE8F9675D0A26831EC44071AC6184AACBFA0A2326D7EF097650C1D4D1E58134408C11E839A0DBA17CAC9DE3B437E697663AC136380D0690DA4A52070A2DC552275BA09C01B601D55E97AD7DE83A32B962D0A9053C1533600FEFD1171C638A50922B9962C195551F81FE80BE28342A13ED0B25FF8986E0E9C39F3C2F29B9F40AADF8CF61E879A7FC863B32F02C5B5BE16F0E2CF00F30E312820E84D09BDF073E0B16B1F32C73F0E6031DCB3221DDC48670D0F2DF9A8065BD027C30DCF9F12782C812753F109615828997768C75660D469691278A111D50A72CEE9600124E3850507C0B963E9121C8B28262B6C82510AC69F4785752AE1F619E3D334170A4ADB4DAF3138AE90AAF8D82573E7AD25A16243E16650219C47F4CEBE6915B433B0ED0354EE62FABFD3E118AC777A63316637DA755A99AF97DFE9857B2F58A83ED70041EDBC49997EC93C03A7D55524CCFFF8018EE1A587AAB9FB5D3E33FE7BAF2642CF9421540C134F9BDE458A65E6B9BB209359F7FA47B95EBB79C83F329ECF88C7541446868CEF363218841F55D346A2B714DD48C711555BB25B1CCEFA6199A0E7646646B667634E486116C0AAD7E977C091A5EA356778C299EFFB7DBD3232C4B73B54C796BD1E33284CC8E4354C772DF1CCF762F615715FAA903D1551A67965FED6C7E1ED7BABB9325AC30F92305FC284724C59079B11D1A0E32F4665AD8390B34968D1885C9EB8BC5DDF63D7858E042CF7C66FF5E36365F1C7156C79CCDF596EFA551E203456E5BB22C2D9B742F490824B1D5EE482F335393E34E69C7820A639858C6EFFC2E8377876E461788FD2736A2D1BAAA432B008850BBB44FA193DC54757D8C75760638A12DFB614580A882EBD945716D7A3D3D29396D4A0D267B07B035EC001CF29C87E23D8446E21D604BCAB110869FFA98C32E35A9B6C878360FD7BF8D564B09384D5C52ED4FF586D6CC300F09F878FF5FDD7E7BFD0AC3AA2AEC0C223DE23D190C6F67AFF7C00001F7DE39C907235BF8D5EC16A34AD2D2E6DDC419F5B24EACE1A17BEF5CC52AAA05F04D5AA8BB018210354282E98DABB918100165E7D962A6F396F22753B1FB928AE3576A91CE62216E9E6214ABFF91FCA2E6E77611AD13F70CC87E67A1E6D886120CD2C2404E0312A57635D1C2524C97EC0BDD9DE011D158F8FCA7AD1A20C9BE0F45E814C954FBA214F3D3089AC4D01ACBCDB25B9331558FE1D29E67628E13BFC928F7A9A88D13E0759B77674C3F2795CDFE0C6617022F9C6A87B60C4B5A69E8D1706749FB0B4E086C94B5BFC16CC3B34FF3B7EC227A5CC646E9A003E5D897871067191AD1F8A8C33A0E567F4DF2D91D00FEA00B152183D202BD72DC0694F16ADFDD6E44A248D80FC6609E601CB91EE691C4535CD80BECFF9F23F32BAB5F106234A8867CAC0B5269CA2BC588E48AF922B5917BB6813E9D1005F35CCBFDFD419404B59A84497BCAD743384461F24267C497A932411B690BF405A7ADCA63858F439B123201F41AAAAA4D0A478101EDC6AD214E025B5DB6D24021464C53FB376503B6CAF4E4D4974E072F8C88A7C61957239581B589ED8D1753844ED928642CF96E5ACCA32E69B52CFA3AF54B9FF793E7553CBE16C4F9DD6114D1357E539C238AAA4434C5E540AB31FA584B82AFBF419DC51D6B08FEBE34B7991EBF2A82FF8E94990BFD02764F7D1DC049A635A08B7BFDB46A521170B6B8BD940883CD4505224D9DF930E33C5827E303083CAC4F846D9CB9A6E3FF57E755C7CCA541DF51819C5A52BDFDF005217000967A2776F51217813B2FFC509EE35F8AED6481BBFF5D5E61732BA17C90FBBCE1FC29E8DE849C146642845F982A2F766DFC0A703B5BB612E4C2B8CC426BB56196D714FC6F1BCAA0F19F32CBC06C3DD1406B591D2B0CD0E834D003CE56313B66C224594354866598118C87C1A86F7D247593846100395EE6303E54D130F91FDF81D0DFD021C274AA9567B9F9A500F35507519BCC25535407E419B52FA4D9ECD3D53F467B6295505DE979CBF6C7BC909812265ED65B30269FA1500264347FBCF1CB34AC5A405F208E73DD503D0D0E15FA474802F273C76C3D3DF98070BF3151D5D338DB368DA0D2280BD821880265763EAB2076766540EB9A51EAE647B96CA4326C82626DBCFCA1B3FF6DBA63DD64AEEA6741FA49E358E97D8F60C7F1A56248E8CE18933CD6F850E667134F69176DFBE2A4FC259994ADE12676F63D483FE16F7658F1003C1561B8D46FEA0888D2C82A4254AEB9E4104B9FBC973CF836BCAB5E263240ED9D87E9C434DC66E8F4A7B73EAEB30BB745F4094A4B82EC96CF99219F557ADEFA605DDE957CAD9D5343558A9A0904575A7A954948DC927E71786394DF40E9328C9B4382CF4FD8423B97088BB07CB4B257E5AC7B817088C3A6912441992153D374D477EA4EFD21C9F706D3619634AF7DB364F5FE73D12FF9623B665980B98E83991215E188462A57C4B3F653E11B4B1E16522CD421105A1FE67AD0F58F3D4AD34A8BDDEC13454EFD5FAC6146012476391769D4AAD22B1A0BD1CE9599600EEDD95DD265C4640CB064F92C22B0C45C64FC411375852E596F268EB415B03DA88ABF9A089EDCC5F06ABBD96E1BA461D4DFB3772938CCBE093AF922F5CE290295EBA2289660868ED4B6AE38B28B1ABAA06B66BB97A5396218691B13D099ACB89D6754517372564CAB054763190677139C9E2F0BA2FB19D0471E49BF6A0DFF2F951A414ED5D0F17C729891F4EF658F19FEB6D31F0BD8EC15DC9F9CC1FD73BBD7A6CA326AB06F55078D4F2F90CF185849567E8C78F2773938A916FDA23279FC3A9D62CE3C3AAD309264EA076635487EDE98CE79ED297D1BA99D96C84EB712CCE028298C8BAF5B5CB3EFB2EB8996EFFF6F7682D6EAFE498B886FFDC157AE3995D8493BC6B51541BE6862B41B5A35AC420D4D120957AC00B6E488AFA394C5C3F99DEDB4BC4AD4127082E44F22194654D3FEF9CFF3AFA66A764864D8344939255F4BD77942D6B2063FA9C0F82DD3B8D9ABF5C633B6CACB152AC09B9DF3BD12770444F99843FD913E2C815368910DECDB46DC4E13EF2E89AC3FC7D13749B88197F633BB6044E1EA0FF4CE060C7F426D01D0CE94833304CDEE3C857FC7258DB654F49E7C949C4D4B2DDD689DEA7E0C526E694B5EF77F8DBCC199F73D833C54C6C389C9C63A9E203FDF4389D83A4DF4AD86D7B36D3847C8DA829E04E31BD81791E403D6098AE9DA476D75B357A74FBE2F0C42FADDA27AC72B653FD87A8D1D72E72E2BAF5D852D1FD6DE10D5A6A600C795F65A4A59A00E2C503DA0BAD2344CD62FFFAF6761831AB2CA4055C18294DB1CCAF2BC6A13DB522CA1BFBA9DFCB930E4D6C32EC24DB5A8D5C15398CF2202878D240BEE11756559F26355C059A81765FD0D993FA64887D5CB6EDE1B379B2B8B5D5430F3D7A6ECB8259220DA7C9106CACBA69CF6444192275A2C6EDC588234E8D24985A0770607FE1C4AE8CC7559B3687522EBF7D3CEF0E19B229509D2A247E8650C3676B3B272340EB71C69064FD3CE931406569E7AC1603E49A13BEA93B2892704378ACB4796CEA77687C98E8AAEC3501143271E504408CA5D7ED271C45A1A7637CFABEA8EDFCB11DFF3F8324C8C2C7D9C73A26B8B1C05B6F18013E03928FFFBBB5068FCF4B29FBC21A5819EF85B91B19A5098883EF40D91B7E287749A578E7743680786FCA565BC4D19AAC06BF70C283E7649992BD6BC0305A0A093B75DCFAECD7E049E16F274AA9B017CAF3F5068FECB55C6FA6ED97F64E17CF1CDDDAEDB45036C6B2227A0AD5181AD7389B72C8967B8176E18CAA3506BECFCDFFF15B598C47D10E11E65D9AE8AF9AFC8B189562D98BBB02EE55D0A5C41EEFFD3D6E8EE69878B3A003DE7A52A98978892E51219387C24BAA7A773944F530816FB27BCDCA933370CB340781A70DB5724C597F72F7A34DC05B732FEB79A18171281AB7A94DFCDFC2C96DD00784F2E67D7E56D0F146F1585EAA1448BE1CCAFC6F334CAB07A27E524BEB95E19D426689B900176A70B21E32278F27EA3BAEE623F92B14696CFB1EABA0D90EDC414FAAB03AC0572B4B8836F071A375849BCF46E83A05979A4111167CE5C43F6FF48F386E3E8F92FCA1655E3ADF4C2123DA2C5551E252E9BFD93276B5B2BDADBC8F23C0406875614ABDE72C520002AFE6F55BF1D19ADB7F26D4F71842FC66335FF670C60583CE65DFA6442DC6DD49889C3DA3AAF0FB310C3AD990480EF12059DD23AE881D5A72603F50C7C61626AB2E0BF9C8C198CB0F637EF72954E04DF5956355147B5073EEF3848CE65EBA73E67955A1CFF187CCA758372FB67823E230B05EAA9982488E8D22F6DA1415A731BD0A2B036F858FE16FB4349149B507D9DF770B9F3D3B45ED752EE888F40FEE65C4F3EC6897906303A19863DD968C666AC1980F26D8B574D5A16C95747AA6DB218471551478BF36140DCC5C6B9AECD22944CD2B781A240C914D2BC4B37877709794CA33ABA878615050637B0A0B3F04DE2FCF37A2442A242E6C97398CF483260BE8A092F998EEA5FB5519EB25BB10B9350AC7F6948CE13DC282ADFD3A251C07E32A25A8A93276A563755B3164C0A9510260425ACDC093CBDBC6C8C5D0FEC94A6DDB415C80D45BF9A6D8DCDA606E3204EEF6AA291AAC9AF7122810A77E0E1160A461AED63687B3C137EC40897B972493F33636B2CFF07747A394747C0887C0402CC4F50E78F70785E5DA4C6084BFD7AE379F0AADBA0CBADF8C70C34FA7A6B0C14F32D52FE8AC726F750DDDA95C741131C7F692CAF7A3A80173479690A3CC0A93D1823BA1AFD5634A9D14E17E7858221497CE6934D7630E73D615127209FA239A190EB60B4D49770A1122DE7ED76708CB660EC4E52900D130C9A4638448CBFB16B1943D7C007D521F945D00D42CD0AE51FA89D5BBB9DC68360C2551D3A0E08CB0025B061057FEA0855305C0F6496903EC94DDF067E722AE07D06AD5AC67A1B5A9D1D036F4D157220087AB098F2C6A911F710332AC3AF782A6747B8E079F12A768B9372BAA222EF43084F65A46EFBDC5D8BE794084FEDD23BB2BE82A7FD1C5FCCCA0E10FFF7CD47FE805A43F82E73773670C4F43571767DB9F9A59A16B1C6DFF3AEB739FDFDCEE27D8699BC080B9D5973F30BD546DAC6DE594F91E5C2F0DF432099D949C5FD0E9ED66BA4FD37F77CBBA8D511A0D712DD62859D6E3C0177A264EDC37393FA86D8BB241B13A2023CECC4A8A57242DA1C7BB796DB4B50197F8E7DE6FD645C6B9099D6F76701B0A36CF2DBC1C9E2F56AC8CB222D37682E19D33A1728916687BE117E14BC7D137CE28948A0997FD9B25545316DC91AF2780D34EB5D9A262B327FE0E57AF30D9299C1CDD7FF92E3CF8C70A9CBA640A71425B164DE8D2D0D78A19853125F684FB1E94D7D02473BF12C6537595311354BAB832C69593F4195132C6552176CD781A04D4293BB9E329B78AE8929A249AAC01C5C81DC46DF707C914E08A642BF4B0277302BBFE3950EAB036CEABBDDED57D2AB2DAC00B61474150F0F641A571573A79C7CEFE5B1E08C2A0D7C144D69764BBAAA9DA45E8C1CE02AD4BDA14E86E6F4509823913D553117C25BA7727244D0A5F4106962D2441C4D3813A780757E169AB7DA6FAE572D7CB919DF7BA028ADD524236473F8CEC4509FA954310D970F13B8F57505F248413F93CCEB0D2A8B81A3B6B812422E630863D5F37142EC8B03444B7509B92C2C46E8B7DB79679EE93FFC1DF1B807E29773C0B9A280334CD97CFFA2AEAACDA2A662F8767A323DA9D48CBCD419ACB2EF27A01A26F7F2968B572B679155717F7AE7CF17987EEBF9B088B153D06F88F683CD8A53B1D69CA429BC5D17DFF465377F6895611C319A8C8BC23438BED492817703D83BDBB93CD491EA8C39122ACD809BA158D5951E0B78FA5409E63E7CC69B5B6BC9BC56349CAFB05B71BD8C8ACC90F929F58037617118351CC1E0E0B3CC4040BCAB505CA4AA36C06277B4D550922DC424A005854FEA6EBE6C833980D3F7D49F38F595E3B156B89809B65E62B57E0C79947B2EC463027DE21FECA9FBEE0CD5B8EC64BB776FC95D93232C53A5A5D8F5954AD65E6BA6A3677C62497C3F4DD408AB08F2B05E00F865CAC6983159D2E4EB54EC0B89384F890E6033F71C5C888A9EF25C2E5563F4B79CF7F80E221C59FCC0CBA7A56ACA182D6A22A77AFBDD2209D5BBE8400605B918912E1F8268EEA13534E86FE8B6588ACF64A1322DFBA8990E280AD5A2E185DC29AE3AB7AEDEBDFF8932A21ECB57071D2C6207740AB48DA0286EBABE44AB1566D845A6B231073076634B6493FF5F4669CE06BB0BEB477C3BF2F9173ED7A36C22EB347036E7358BB62192E4E7BF5B9515C6A433D21E47F56C886AF92422741D1CA07EEB3A67A027283E78A27B64C89AC0EDF6D3CA5AAB03AB2437B7813BC5E349434386F00F0C0D592256BB28E68D0ADD1F23F001F2F0DC867BE42CFB316FCC3AB7F2ADE8F262E2F2A817435D72D2B9F181E285F7D58C2E9D0ADCA7E67933CEE6F908BBF182523A0367EC978CAC6373140022E3B851EBAE9D7086C4191C0BB856FBA1C5785F57A555985D0060A4BD79FC0FBD7798CE46C543B3D26C62BF07B7FFC0C5CB00729D2F9DC75A8A308AD312EFDB71DCF069034FB4F970969B749BD6F487F5E77627FFA00F64DBCF819A4F8EC0681AC3816282EC1717DA96444B3EC00B32B8C07E806988EEE0B8CEAF0CEED4F400F27F1D79267AA4BA333E61B84E6F10222FDEAF05D3561F5796CD819C879A07E780BAE63E780C05F024F2880EBCAEA6C1C8258D94B753BEED298829CF221BEEFF249643A4915D5C0E8AEAD2C85ED170790074EEC22327260470E99DD940227A671D56A9204224861E56624244241513ED4AC7117ABD09523C29C4F23E0C41900011215540597EC1BF8516CD28C228D03F8C7A65E4FFE575C6F5FB1F833B04F3DD1FE2DA3F983FC8A6BEE8CD7FDCFBB4436D8E8F09D466CA0129B4080F5C4D2A078B1CA2BAB5B306B26B4F75F49335E128D5E27B6FE1D96B9B863268E813A092C5176087562125530D23E8F6D61D99ABF133B032021530A5FBD7CAA65063B17304B76498D90B0F3E6541534667952F6B31A74394000AA731CD42D2CAB1EF3AD7AADBAEC7541D04E60B843FD337D7D08B9991452889376EB57FFC5D2D454B35DE0BE42E0B04E5C21D950E809C5D499AC04DE0E4FF912237DD83AF0FFC5CB8E520493400C91235F9D49BB30724098295713F70ACB57194F53B656D4B3E5879E2E28734370A052FE51C8139021ADD0DFC6D3D8491AE9C7C8E3AEF6A5C1E119D65923212BFDC35792BB5E3109BC36003C17100DF5302C7FE73ADA012B36AFA5452CFE356C38E63C59E80C1F3FAA1735150F1F3CE87E7008281D125FE7627B3D6C8DB3A2101DD6D650656EE5B8E0E8F0CA1DBEE12303499B6CECE8AC80111C504804F9ABF9C616D22DF34FBDAF27290F4FE6675D4A1FBE8A93A91C6B09B1456828554CD0CDA039569E2C08430C3481E2970BA760DA29C31944AF18085694530E8A952B54516062CD9528A95D0772323B4B8E02C7DCBD71FFD2236E772268E25F6D4C622F07F5D437275B2FEBECE7605967771BFA2007FECA33154FB46A3B788E9E7702F38BCDF175EFE4611B61147D89195BE90840FB1E365A76840BD9B40C21949F2D41205A491C019B7F49139CC46002B5B7260F47253C1A5AC8745639F0E1833808F7CA27BD437569D38D2C4AFCC5293E6C221D9872EEA5B33A43C5217438DFADAAD8F243DDD779FBCF4E95C6E4CA4E11125F9FFA93A4F04D385175435E391A7DD4C026ACF110F0B0CCDEECB8DC1ED8C24AAC7B3499C0DFE478F292B8B46DBD70451F459D0C5487C973DB0D19E196A66DC3D611D3BE4DDE59128AA6229BA0CDD9077B20F9E03145EEA04CD0B2FBB5EF90D327C1030B15DC8B5CD259EBFBF04A5EC67C741F6D38180F9B0F1FFB97CA1D0C0C5C6C791CC92908B44374BE315D4545F5F7C10DEB4E94B676D47D08C4A0C7466803F767C8A42BB0B74B6E85E11C6BB5C7EC3A8D543C703095F2077FE89A6CD8F450DDAD4007C1EFF0E0CCE2ED78F8CBA8FA0724D395C8B7714EB2CD2BB4CCFF497F09661F28A04B7AE27C8324FB4840336EB48BDFAA240A39BE662A93F5B12682E80964A14E32F9513051FCACDFB4AF64D835A1BDC643D421C9C667F7EFF4E56A7988FB757281563991D1C6B5B0C97E1C38B9185D049B4A95124E6248DCE7073EE9544DBD370AEFD8291D1016D0995320B2675D300A28C061555D9F29925CB9BD253D214E1D4FF9141467FA3449674A71A800985A0656EA2EE415366F474DA24B9C899F26B072E7244E7CB2E76890A89D42E6B9B0AECBB5180D6EB2D34954D4098D10A36511465340E3245A716C3D37A619D0E36E129A92C205579A7AB47A6284C06E7984C714DA51CD825033C241C11CAA0F2A930DBA13A28BBEADE973C6E8A838A62E04B1A5AEC0C72A4A2B73EE9925DCFDEC7C65CCD3D4EB65621EB7C90BAC3D36D8BC3427E0DEB8F253E221605ACCD5F6DD73A50FE09215DAE82AAB23DF4B86910EC72E3EE515A746FFE7CF903077F4D13B59226DF6D94A528F57E13D741DF28C45A072A41C01CBE1EF6587D9664CDF4B8A3E2215F667E2970A841EE78F7E14CB1839199163AA591EE9A2B5AC639623254BA87A216FAA462C5F9F8A74E97C24FCBB3D53152ACDCAC8A32D5A18C890004471F9A43AFEB325C767807C66EEECA54A594567AD7D4E9135DFD212A01536B32D590B9F662C17AB9784D8603C618375383BE8FA258651259EFEC97CFC616C218E4BF54A8D84E4DB080BF25650D8F522CBC33DA5BAD3144C134547AE090930BADD38EE0EA02733B057F0CEC2AE05FAF9E494813DDC49DFBE8557E80650120EB1C9003A5F57D330888C56802199C89EBA3DC085ED5DE5C0E469686850AAA7C9DBFDB47C563AA9660B079A7E23187A2E8C57AEF291FA99B0EFFE67A6D43233D7F84A9E385403DC49997BCCC69F0CB3C6F707ADD2FE0CFCBA5410DF3735306F9D2029872992C772EC24635DA6C73628A1F5789ED2E5D91CB41F2C8DCDFE641A1361AB283A0BE8446A5CA187983E34434191C64DA727D6088F90430F1482FBD5B7493E15D3FFEE375680BDBCC812B93CE10FD51BA3A712C3130DE63A77A79DFAE2C946AB370F8700999B0EE37A1B06484CC4D3859A4308DF702D40590C5C14BF8CE6D6D2872A060190B14FA78592DE2D8B0766DDD09276BDBFE487FA6621A5E1108D01787969EB8043B236F8189D2FE9E60E95EC52E69D156E20B435C5DF5A98F25E829EF3C15464D1883277A5EA42AEDC83FEAC327FDD2EE1D9A0331F06DA74BADD8A9F80432CAB5CA1A81FFC79A1F23E604112DEF22E9854468592BD2291664517CB91C80035F1A8DC97A5C8A0501CBBA6F47213D8FE0C556842324BCA2ED74EEFE8F6CC896DD4794478C07BADDD3AF65E580664BF0609BBC243280C3641C9A5803E856525410755770BDA536F0C722612AEE5CB643DE530DDD0F7E68A8EA1FF9D1F08751BF99CB8ADE48089343C253794EF22037AC8EA20A28A22242EDB9F9A682F23D5E51E05CF68DEDC4E4BBF593DAEB24E2CC69A08F35106558D22DEFA9A696B6014DDD99FF8BC35E8DF6C2FE76F162F81682294A1D9444B9632F63144C0909890A934450E27DEB72E943076414576575834941A21152A535BF404B71F18CB4851C70FF3E167E65071236844BE4785D1AA773D641207323BEDAA64571D2EFEE19A59933F3EF8E7AF86C5C9C795E88322185CA8CEAD78CE097951B57CFFC98D9B4BC920AA3E67F502CA5C4A9DA541608647C8D7C6B8CF46C573F1C1EB086D416B2E20CE3B9F1F2C3193F9D3EED04E9AAE230EDADAF0ED5A297640AC642AB70494A6006DBE0F242DC002CEA1CA8C9578ABAFD7709B58C579E2A7C2DAEE05242D8F1A26F0B96442D65227084668FE64EBC1F31DC6D7EC5C0ED61307B70452A8B5B846B5CF3AA859F0B0ECABD6082429EC6C5C9F757BAA27F52693004B19D35A675CA00FD42ACEAE5AE07C6286F48AC02AE2E43BCA4DDB0982A40B411A23990864378836BEE832ACAF1A4BABFA6C3483A9CAA663ACE89844197AF9496D43FEB39053C4A03F04FD4E1DDCF130DC450C3AA99F85B34E54E4B7F372F8C6AFF5A17385B637169C396C230CBDC45B7452354F797446F75956ECE0CE4620EF515A6EDB2CBA3C01573E293A17A22A5C33EB367A8A9E331927DFC1697BEA0E9F6EC1303D6E63179A7ECF68B5865C5B12D79AB95B5E419C45EA2A117F233E6AB777BF3041268F9AF8F0337A989C1A24686B127A0AB21486A023E85C511351C7C5982B01484868342098EE2FEFFCF1339CA74F569E89F32EFDB11DCFD33EA1245ADC75BFBEA4D1CC707F7D52229A286A1BD4D4E69BCA878C62A8FFFCD096A741F8BE4B17E069899EC20C66C23DBB9571116C105814BF5CDBD71AFF209F55EA526D91858332457A486DCE7F4A5C46EB3FC8673D6CB46E2DE3098F22AE17745AB0BFD6A4E57CFE6D7317875912BE641651D98E70C940F7FE1BF9882AE12A52B76BA21255AA0CCF272F8215FDB211A506AFE5AAC69D951DD8449A5527DD2617DDA35CB1FCFDFAF6322DE113D48678405CA1E68B6DB9F005DD80FD447E045D6A5D3DC719EDB0223F14F92370E5DE7B22FD0189F6C7CA5FDAC1DFAC8C3525DA00707665040820A763DDB5406DF41C23BEBBE68AAD20F59A5E2539D3EA32A9A717691D72C2FF90173D53FDF598E4BC0790180A6CD182CDC6CA0B5FE69AD663506A6A43EF780D1F2B7E05E904271A587E0619EAB04598E3574C7F271892C3F482D2817BF74FABF9B63E43E74348386C624CD0A73AFF1C917D1DBB8D08BF504299C0DE3E5736BC9E3FAC872BFEBC1E5DDF68D69EB0572AF7243E531157C9EA81ED640B87BC14A959FBCC7658CB5BDF6E87F4E677011FACFEF3932CF353D6721124F8E8F2998DC06D262729071FD56F1FA76524815E4552548FD48EB6695B81C07A716E2D4BEB22348B4FD554A0A2ED702E6E2A51C1B621C6D6DF7C675D0169DE88A85F0E45BFC398D5FB2BEA9958DB9F05A82B5CC3CAD980B25415409DB4C0EA1B15F249A4ECE2CC71449C9219411CC81AF35468A8D4320B36328298CBEA852800113F9DC6A6E727B340FD8516277E3540A9950E5A8E64F0050AF7F9707389874BE4A616DDBD017CC0216DAF1D270EEF9605B26A588A285736B3574E6AA3B6F197DFD451FCC03F2B4F1788C1F4EC59BAC79BCEBA3253E8DB04357AACBB468E9C8A714366CA216EA44A764DE67989D504A8F721098CD0AB285456D21AD99BD11DA30A83054BA40BE695EF6C298E22F8D7269E995C5397DB95B5A56AF5D9BAAFEF08166AEFDE6612FB700BD797B26F6DAA7DA1A3ED773ADDFF19C592AE7C3FB87268406DB5B9BFD98D4C8CA02A18ECBAAF3FF88F7DB93E06A445BEA851E75CA4B8011F3A2E3F57286D691667E3C2DC11419B7DA22B5AED705CAF0B8EDC70F438D57D4D549D41F07955EC3E339042D11F17792EB71D8C3B9C464B54B35BE2D45A3E07EDCA62F86CCC96C6968C567730E3845D4C8B8D6675606C6994DFE5569260BD2943AA189AF3A3EFC8F63FEA89B71F2191A7BAB25BDDB5A02FABF7224243FE5C6CAAD0F7CC66A6C6FD9754F700E4DA2548843949C7F02CAD107FDCAB04204637D6714789155D2C61AD3930D6F8586EF5DB5515F673A8AEEEC8C9590598B16CBF84032545AD5C1BDFD11A92093B0B0B48DD98EA963E208A43E5857A0722C3A641E60C7C398D15084D8C4B35F4A3146E77AB439985209AD99296A12BAEE3C3F3E994E76387D15C2FAEBFF7B44BBCA08A9937E74F9CC01613A5A2745C3F3E0473373EB1E6B4E29188477CA96845A7B24C232F8FB9E405C715E3E8DB593B14FDBAB225165BF0B0612BE50214598D943BE032FE5D5D9A33C23BF8EA48A5FF6BFB80316B5314A9D73C07D8022D3431CDED66AE8326EF049B2DCA5E63C6354666D1656A46BD5C8B430A157A43FAB904BE87F7773F5683949A416510B361ED60D700387A5E1AF0DDBBE08017270673ECEA9FE1F59A4859E7C097B806B79019C7056E6B1B8C2B43D41F78389A1422EDD4FF13239F36C54673118333E1DCDEC960A524F3D9E3E4BA1DD9B62917E8820249A397DA3DFC9417652F02EC8995851FBBB668330EC8EF6F89F77928F54628F6E3AAF55940E6F73720533FC39AC2CAB0C8495FE09563D4A0B22C628DAA66D06855CC24E85F9BA30046A79BE4EFD1B9DCC6E098DF8EA4055B19871F55F71A07138F7ECE919D3F6EC059DE0A7A363C0E63A16FD8A9944150D65F56D4A0D1CE83CF4DFA3B79A87A3CA9D003CB578B0A862E8A8309A9F8617CD5D7D1634766ABA5CF5181B2DEFD4CAD9A1F8F2148FB137CE27EC8E62771F46E7A8AD1B370474B1BFF0A634408D56E33EBA8C4F4BA282D716E03FE0799D012C1B9D3F1EE3D223E3D30F3020C0E026604FF5BA9CA8F25CB0C6D1C7835F66BD1FECCB77B911C259394E8D6582ED0B83A44776DCCFD677E7CA0352569B227DAE57777BF15464A8C91A01547BF754178888EEE0274A0EAB6503A50905C3D04CBF80E39F5EDA193CBB574D9141AA553186CBF7934E9AD2A2FA730599D2910DC1CFC2AA8DAD926C58385BEE6F37203F94E5DF5688B9FE0DE1F67956CF2D7872A9A256382165A8572BDF85F083A94A94E4C08ED85FB17F2BFDDFCD4DCFC86CF4E608A6CE1E6615DD4EE79BEA7BEAB94B696F8EC236133067FA6417895B911914FC39971AABD1C5ADF8A1B46B34647599252EDB50610E4403CF05AEA437D1B23FC22BA4AFDC836FA167791D3703FE28BF015C7BA755FEE0FD33211AEA356FFCC38720D04F325DCBF5415037A0EACF799165D590D36F036E0778963F1B9B059A479E0E6A8BBF826B0D55399B8CFFFCAD4CCF859B7C226AAF04BBCF49260F242FE7665B72AE5B1AEBE3AD1C4FDE360C56F2A9F719E8B5A4679D3700F8483C54FC2CF99AF9814FBCCDF46A85A5359359040473A71AED3199AC0283983D8595ED6169FBEBCC92BF9CCC7A687B173193BBB636DC889ED448C942FD52BB8EE81BA817C800285CDBF370502BEE6273611ADC1EEB4EBF9A625AE0EFFA97DE9D0E5DE3BC4CE8B8CB1E07E79578BBB65984464F724E34FDD3E2B37D65886782874AEE3C700754D7EA76555F6A37BE99C25D3F7924B9F5C15D6D36E6F709AE41775902710A12E5568115101E6ECB68CEFC6C1E3EAFAD850677F925293937A7CBF1B545E56E20AF68ECB04595F8104D942BB3961B39997A8401107E938F74D6DA03821E8FC12D25B83958E720E544BC10D4DAF73F34BD23E19E52E2A3D675558BA09A6B9BF36EC3EB3EDA9E0F4CCA329BD2FE20482B7C424CD1A765DB6CDC7A5C3A0635A7F48F9FCAFF2245B13B6A91BB666DC0B131E4754C2D2C1E623122E73ED103B87DC55CB62A152DE41ECA29FF4DE07A3E3F85398A14FDF1FDB85C1A6202C0C5564C3F66796B7FB9D9481861271901B8281991A9F6F66DB8DD2ACA5B9E5FDF4197D61815E423A4C1DD61233E06C3499034CBD2490FB22660A966D4D7882FDE18CC041294B9758A5544F3A697CA7BCDAC81EF742221F56EEF86CC2999CE0C55503533CF7AC81EAE88AE83A835103E91F3AE125F46B3C7ED05B40737AE62DD89B82D90C22BBF36BD4C169A9D9D8FFE33E2E80D503FF0DC214D37EA4B81D9ED2704515C6E5B7CB57AEBB3A912109B8897E271B756C77D8B7C975E3F4697FCF8C1DD1CBBFD52C9F1BBD22E7DB82335E5A6FB849F5531AA9841B92FF1CBE5A34F4E9D5C41565145E2C69AB65196FEAB627BED94F77407F7A180F1AFC4E9D03988507831848F23AFD2CBAAA6422389D64C1667CCF290724D58E28B2B74D70771682F70492AFDB247A3C118572BA5DBAB9BB2E4ADA05E0D78C79F0A2F97AD053E87B43C8755A7B2C217340C81D5BAC243B9DC51236BB7977C2F84D6E76CB4A42F0E5A9ACBBA9A6E6568753C7B8E4AEAB9B1DCE5052A2971003750085CB05B68E6E9E126AD5BE084FECDF62C8AEDC63A920DA15D1A3B4C5CAD650A2DB43D93EDAD2E498B0ABA4071B75F8DDE617299C990E6979D860461342EF7D52E632ED2C78AE41EB9ED9ECBDB9CEC925EF47CF57E413BD7A4B9A71E6236CAA1AAFFF8A8066E50E19D3CEA70F910537B76B350CC194B2804C1458A428BDEF11FD82475C579058C996960C0A548BD6BFF0959720C43E6AF1A94BEDBEB922A8B4A02E451E88D4FC8A29B92D66AC1F6BE6802B5CD979480264C1AACA5D6578F44BBE06230CE75105859584EA29D16C20ED4128A0EA85F4CA9A3EBDAD29D0B661D56784E0EC2F04EC2DA448FE96A3B9EAC31A9E53A2925701C52CDF1B19447F23C4BCD507909F3035D1F6BB9BB2074239D339492C6863337869B2855EE7CCDBCC6D4FD9131576DBD7B0B475C51970D3740D8F232724BF53C09325303CCC41645694D6A9F7A43A93464507BCA194F2E1C8159821D1DC950A3CB5E9D1FD829222E52ECB1AA5BE3FFB693766886FE328B33CF44ED3FECFA0D2EE91EC515A59B419D903524112CF788ECEBB117241C61FFB84E266905B4EADF0606D1F070C1FB0BAD9EE87EDABBAC32AFDEB276E3C63E1CF73C55FC76ECD8A275FC17BE731FD1983956B1454E5611192EE16996A744DBBDC88BB1E309425A23FD480477997C6A27B780396D4CE034063BD1684CDF49B42ED5D23FE2C36A8CFB0BCC4F8F3D029C5F233C9D28ECCB8EAD8ABBDDAC297371916B0F0025151DE512FBE03163D09E73776F09C5EB535A2C81CE454EFD21E27A51E8E746E018FD19B89B74923CB2C6136061B6F94ECF88BE57540FB784ED209BDF98BEFA822205B6EB9BA7C43DBF10E82A000DCEFB30E1B46ED4753F45F568368AF289D9B257609B81392354313ED12A0782ED0DA12049D4C3633639CE970D733B213C8D40A29BE5BF69EAE20F568BFC3E6755A423E22D68963FC2C85979FAA14F895FAE3A46ED30FF96D3ACE7B8A16B8527607915A8DFD7BC9ACB0B27E06A8F22E2FF223DF6826348E96F2D1F74995F0CE064B45B4944053E3FBAB1AB2336AB869C53B3CF65E3FED0C5B41B9B7860EF3427219FB2F47AECFEBBE00DA51FC22CD074FDD84990C1B70ABA87FE2FD5EEAA5A7E6D1B88CCF9AF31D6363DB8BF9728077B7D07B254CD768EB3E107C729BE3D2AD1146237B9FB53B4F9BFC4296099E94D35CD1B358123B1D28D78D010098ED1CADA99F82F5A0747DBF6D342922274658FBE819DB904D59977046F5636318DDE0CC440AC3C0474712B8FA488CA585DD81A7DE27EFE65EAB1BFA52A8CD16FBE2F56A131C86C7DD1F713BE0F5A6D0938891049CB452DCDD744665682C0E1F68EF9ACD4DE6776618492E822E5030D018443802B916A25A62DF68B95F847AD787C0848D2609487993893EA08733CFF496BE0FB34B21DD51F10A071C44837B9676A6F7343D5A2445F4B75314FAEF07E3E40EFEF20A32F8CDF8F82A1BDDBC7F96DCB3640F298C34D5DC72F7F262C8C8559066A4F0BBEC31B2AEC81F2BF690D4ABBDC56B7839666A5BE71743B38812645904BD1D1A9388FC18BD9EE7DD0C4DF20AF8AD4B50886867F0EE7B6C9ACAE5EE58ED2190D2C2637765F4D2784BC8DB292A12F297D2E905D1432DF48FA6F0EC3DB1612AF65B6BDC2B58EBADBF411C323CA09AE4B56ABBDA4452A2018FA5687720FF761AF1295968023628AED87B51716FF33AA80E4E931FBEABF76227337499829A6D79C7C6DACDAEF490CF021210DFFD0C27FAAA7F09BD37C5BC07B55A2E621C9AA9BE12598EA98AACBBAE1981C51F76C5D4E48693EAFC22BE0891F74BE3A115CD68FFBE55188A043D013B741044E59B3165C5A62BCEE94543B637E8E0808D64C228123E402CC047C45D9F63CB3E6F5CDE58F0199666F39280641623F48CB1EE9E76DBE6DE0986C71A3C91C8A82D51252D473A42CF4223B6045A73D9AA9F061BAA949660B1BA38BA3F4B9A2FAC838D2A386601DCFCD6F361DCFFF555FC9348735C1844E957DCFE0C7DDEA5EE03822A3A5E17D07419AACCA1E59E4E3B726D68E2EFE10394160B897C2CAA9A6AE2D7F9ABF852E7042B3B276941D5453909C2E9D80E0858769266731B99A4599B172A6CC20D7DC1F8478BBC5EC2EC8E387F88A63144DA10E09F17765C15694945C8496386AD0B83F7589DA9BA60888572B16ADF404D223FDE1B4D55E5D8B5D3CE2F5A492BF3B17748DA28B43216700BDB1352907E1AB5438AB1EE224749862D36524ED24C724940B38866C531CACDFFE38755A65375579021316511987CA6EF0B03F6E2D82A6B7D4CD8E310EF5FEA12B7D84A0CEADBAE39FAA04460E04FB2C4B1E759243B11A138063BA9C96242FAFA15FCE06ED9580E29B00F44F3E74A437C9D7541C5E4BDADD92D0179E86F84FA3DBAA8F1CEA1B4A329E56B0595C90B8670F63E942D42A47B30805D770D86F6412CC87AE063DCFCA9C353FDC3E8068E3E5A8E4C3D3B8E48E245B7728D6997FEBBE412C01406D869715AB2FE5432AB89577EFFA2C6FFA435FBA59958FCE9DCB9A3E9A748555AF0CB64D7F0D85ED5FB0AEFB361A411406AF6A34610CA9D280C5AD4ABC8F1B5CC4221FB6323930D8F0F2C7F1E79220144627D49B5D442FAE09A2033E1AEB858CE38A54D7FED0328A06F7075E206FE3434E00F09992C81F902742A2A0688AFFFBE257FDA551C2F0089C72F8B75FAD8787A4DEF71F6B39C2EF08E88A8BB0EDED81B001B29F8BFE1ECC36489135B3672C016052FBB824F4B3077E024794C3D1C1C11EB1C31D78A5F314A8CD10A228280C72E9D697598335D2EB05E256997FEB9977BE8A5F1472E5A7F361FF6520F58ACCB812C16FED197F4A967CDFAEE8DE32C65D6A8E176E776D80EB8069ACAB5DFDB3822EF8057E4222E2AA0A5E90D196DBB334EDAEF375D80D6220B069F0625CDF43727085BB9DD60DF31DBF16FDD02A1D3FD0932C4BC23586592F20C7A411225D44385E8CE6B17C43BB4FA6BC914218D88DD7815963120F630D178B34032FE24EE8C2D5F256D7005FD2FA005DF391923FFDD6B1A02DDE26D301AA91DF609967EFE772EEEA6D271F41F2623DD1096E8656DD44EF4AD4565CC8A6DB0FF5168C9552F9A08F84E91B335F3D18248B6F54F84121E17EF6BD48663A2EC9EAB0D20EF4BD6E27907F5D568F33659B2DCD64A10C82C82BCBDFF5296972DFD8369027198108E537D4F0F151D9E52D24360D381DA74B87E0ADF3119B9A2AD38D7679D60DF92CB86566B14AA71186C40C338B3A396579902434ED860428BBEF6BBA18121004411641C50A92EC832174AD38A679F5A49946EF241A8FA1D26974F9E465B1DB8C6F88D84B62A1507CAD3AF350DBAC43276A87D94FA1C7A9E8488B5E3A2EB66605C69AE4C2D7A551163F85877A81D5B0F988F48A6B2D06C9CB879DA0068CC2B3DBC36C5BD714E30A5021AB48AA57F8372FF8C77C03BFD97F904B50105E63FFAB45BCF5BD6D576C86115E90669BBA2CA946CBF8052D08C3C8F77333196822D3DD10B9955C4D1449F7E4EFC0AF27696929637533689D59BF3B03AE55C835A2AB28022A6738CC5F3FE43BB12DFB8BF1E0137A3CA5ACD5B0493ED71E9B575AFB0D25F8049731C85F50BE87DEBB3CD180077184EEFCC3233072E0A27A9918C0BB6B24E656559D2119391FDF74FA03BF6D982D156E54BCAB37A3F8C7367BA95DE2CB392E6B085E4AB974BADD8A55A4765F42C878E987782A59B9EC7419729869687DA4035147846B227E285AF50DDED91E9333B9EA118AF549280ADFCA75AD6C23B456CF7B222EDA5899E834BDBE2240C534B2ADFEF524AF4906BC66132EBEBCA911CFF0210B634767C0C163B94B169C178F0C7B40C641894A105F375758ED7BA6A1A2B6478F9E97A5D3ABE5F0097F6440F325793571FF212C4C53A38301C3E4D076878270DBFC080448E4BA5F048CCE407F963D2ED434A2AD17385557AEA88525E30E0C3A9D6228B72ED2761315A2EF649E8B483E231B9A21BFBF2F8F07BA5BF89C00E11C239F0C409C769419C748C506D878DF7D0E4F44DBF4900076FE304017BD3D6C87B4C20D92AE90729FC985BE4D9ED63C7FFA978957167E2197452392BD82CF4709A8DCF816C49C6588CECA3D0C1360BCA17F1F152DC439CCC3F153D2DE9771802841FC90943528B2D6FBDD00E88D091B11AF84CC4ED4F1E032180371037A94886F301ED534D63E1B92722954585CD167CAB7145AAC3FA46A692B8A3229D83FF6C34B64C92507F7433140480018374D78FF90BDBAA09354EC34B5AA399C5F2934EFF7131D6668371001A96168A0A8EBF49E6306D7AE4C624372677031109549F426108CA25085C2A40C808B405899C0CE905DAAF47B17617A99849605A619A03A104275AB9DEE9FF17AB747527B28539DDA5BBDD4341BE7B8613562A13CD37C3AE160B616D61C4E9D16ED85AACF2354D61A1506143BBAC9BD6958EF542C3641CEE7DB6A54A4D7251E653EB25E05B4C345FE6D06478E6FD39F73AEE17CDE073BCC7C19D4F239B84E5FD50CF04D928B7486ACF519C68904B838F1268F12C05FB40698585979C59C70AB2124BF99FB97E3CDA3441FDA18AF55DB4E5C39D3D75DE1F6E44950021288572D2F040253FABC31224798CE55E2BCB3BD976A8DCDD7C77A9797265187CD35777453C81286DB5FF66C6B9878619B45EE5BC62FB267615EB970B812A2B19A85B77F12B18D322DBFFE7FF462702C6ACBA478C0596972918F3054C7654A888879412FCE7232F084BC2818AEEC294E52980F854389367943F8C9D77B3050A71A475978C841CB373D37A3960B25BC7A257760C51133CDE7E50B78CF561F1EAB9E9A84B322DCB040FC246239F54DA7D7ADA41FB6026246E81D82E5E7C00487354C4525A8C2FA070963AA0FCE163AF71F5B522C64740D9DE5FD465E328C3F992BD53C2A66F44CD89AB53C19ED320CD6B1C3060A9DB6C3812818ECCDC7B02B9A854D07799F980566B8054045F656EF1989D6120A50395EB1EFDBEA3ED45ABDE671F2ADD8542A87B3727D3391E6125D1D950E0B15A595E23707F2FB9E7C597EBB3C571DD1A5E062A12BF9918DD7CFB06B80B71EE05283EBDA7A6CFE119079C10C55EF683F27CC9D06E85D26900F33188D39D2128B200E648ED30843460DFAEE006423B4D18F37D7AA70CD4209073C6EA812A67DA603A863BAD29A79C993C442BE5968A0DF0B7D26D56ACBD0AFB3ACAE7D42FD1400304AEF11E4D6B5AECD5CB77CC2C6E9FFF03CEBAC5DC54724FDCD47BD4A1D6EC45C6B5A0EFDBD97DCA8BAA7B6CE0F6323FFB6C0099A6414B5CE20A2F0109FC35EB142565EDDEF76754BA999672BCAD22B9849EAED945A7F112F46D9BDDBDE882A4E78DA96D38057DECA09C4BF232C0B89EC9743C6244CA2BFBF52A3285D758250EC4633063E0716962CDE9CD88E346E3579ED9D1F085909BA632EEFBD86536B205359A933F9FD148058D265FFF73902C85455339C92D178C6D26AEECA94375B0A4B7F293E101FF375E263B2561F971D7419983CF733C3BF50D77C4D33CAB9116E8F189A48C00C04AB7CAA471C360C696EEE43DFF6E33DC931ADB4E69806670F365FB97814E9367BE22919DBDE5016CE0F44E0465FBA667E751FCAF2DCDA33E5FC488BF1DD7748897D8C520E4A46FFA8F2A539453328E8C2BA6EAC0ADC1F1188F8D57EF7A28F44F7699CBE83D0E8F2E6AD098B921D1B770C1056BAD3B2B2B7D383E56C935400D84A50431FA94C88A53545656B62BDB67EB7B3E76E0E3BE35B99C529809F59C9FE65F0B19789F758B01C6BAB1A30A8A3FBB28B4EA3E14EC104B9046B70C228503D8E29291818F873DF242A3225C9DC7E1F2C27FFAD83C89C70D03ED21AA0C616137A2C2750A24B30EBBA9875A3074D922076F7D24ECA129549B33016182DE68A235C18AA78A9D27E6732684DAC97320984E441B9F65A5F5230C957B398454E2BA1ADE900CE36CD1A320F81E21FDD36A449A036BFE7410876E0880015BDD895D29AF0F0A9AEF2596BB022CEB44B5DDA25F5BF3EC0EE3AF476E28D5F60F1C8D104003BE1109792D3966DCE207109EF665552ECC29E3C0A887D0811BA980CA96EFDA9B823E1EB1F0E760F0BBB0DC9C8D2919402ACBE08F0E1522838ADAAC6B45CB71611ED85238D2E17907588715D328015A225B713F01300FA5AEF960DA36D4120722ECCBD6886DC08E57A0F68466769636712A361724FB2FBB4AC9775287BFAD7134D577C31170A8A9C39FD5F1557AFCC167B11DA412436F79946BE332F148A72351279E2E1E32522AA8C0731F2F312B893D4F24A35BF2C42279DB8872E70E987CA680DECFB29425A5C51709216A5F69C00166B9C971E9E02B52731AC8DA8988A8A7878CD368085244678777C7C1DC7B0C6340C71FAD6BE4EDB0ADD161D5F701B56E98CEC853AF23B3695AF8CA7493BCB3B405B2A3A5F247FED50EF3F0E5679C2AFA4C2F613AB73CCACDB655A97E00AD5F7F1320468B089D5CAB0CD8F29FD284ED47E7546D39B4D6124B431B7190FE5D5489DF4C39914BFC951CCE080444FDB4D4BFDDDEBF80A22412911D5CB7DF5CCF5434E2E9C7094FF22B5924EB967324E73090832FB75FAB896104DABED028C4D096234B96BEFDEC7E669F850CD731ED2782B60512E2F83B3E063719F2A0F984C9EAB52C8BB7672F4A7E75231855BE3B541BE8BDF4638136802A83225ECB0020B956B690 remain = 1152921504606846974 -max = 1152921504606846975 \ No newline at end of file +max = 1152921504606846975 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-3_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-3_256.rsp index 7410c6ae5d..86915f5431 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-3_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-3_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHA2_60/3_256 - pk = 000000065FC7351ADB3E5E78B0A1EA06ED988995BFD8960B36F604AC8F03600F0F15E05004562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 000000060000000000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A5FC7351ADB3E5E78B0A1EA06ED988995BFD8960B36F604AC8F03600F0F15E05004562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5832CE029A1A95FFCBD5C8B157282F7364E680C60B252C49483FCA03529693B074E0D2B1F6DFD6463B974DE6829A616F20C839B0D2B8BE5405623B5B722EF22F7A3BB78E91315F715D9DCDB0C8639CB8A90685BEE7969671789047083CACF24FBC4B601B1B23B2E79E42176B2438CB405BDF46369F4DE5F411B2ACD32BEE3065DF9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD09000000000001D5DA3370DA40FE4B2AA8D93A4C52E009ED16134083746A63365266ED868E33160A0000000000010EB7A75A56A1497F0FC1FE5B3F6B396014CC9357B7FE8A6D2BA1B553EE3518610B0000000000011B23B9B57C09E7B440346ACFAAB7028D8821AF52CA85D5CEEE66FA4E95B45CA40C0000000000016AC8FE7754C3CBB4F71F8514603EAE30A764437F404409A1283CFF4B7159C0F80D000000000001CC6FF52DE53BEBD4E1D3DD11D0BE5FFEB977CA63FF2ED1099705AD3D5BEB1AE90E0000000000019B6C3951BCA1748DC7B89630F962DEB3937A4F8D15BF5634741113C38D2699F10F000000000001F21F01A1F02A9D105C71E89A189791BDA7CFB7BC89003D2EEB2AC6E7DBC26814100000000000019CD3ED9E3D49C10FE36B3813045F452DD0B3CEB702EA9FD3DE2289FEA46C9E41110000000000010CD4EC639F5FA5159D505EFD1215E62E35B38AC9A8B36077EB263B10F5BB4B741200000000000111A178357024706621EF264E4A66422A6F5B9F4C24A35579CB17DC686277D0591300000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F7F8F9EAAA74A5C910DD60B2FA5179B3FC341BEDAB53B1E957F40AFFE59FD454EE839D34EE92ED029C1B5853A46CC8B48B58DC4F74EBE2164B7F867B17ACD180761BBD5017870DCC53B0ADDCBB8DD1A6F5D014B1A789493C53C3D7B304F6237F836AA9372B0CD7007588A7EE166C1F8BC1C7826CA9D6E2D73B1B217E238FFB65DA1671204B7137B3C91D19ED0DAA12A98AB71C239C6F0E6B29D3F61DE3F71688560646DCBB9846A8F28BD1E7606E2C93CC0CBAC8A85BB578671BB01347E7B2BA757AA92131B2693D7F9501E87FC7C1BBEE1B8BF15E28DAF9B74487ED12BE8A4075FDE22DA018C0531776136F0FAB5ABF372E160CF51685CD0B8FEC7D63D39F4A7EE635051E54EEBEC7E8C4A408EBE848B7255685201592E3730C4DCCC6E7DE956B4FF296E76D0052EC6C037ACACA6E6474CB17AB271FFCA98A688D224C3A25425F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E7040000000000017D93C20AE191054626B3138F02E186A4607EDEF6E32DD3B2D788325E88FB01E90500000000000159008B71F97B67D9710ACBCAD0DCEB434823D0DDE4E8526701AF9ADE23FBCDC406000000000001410E6F39D12638391198E1827F643E6547AD7438BE85774B713D8FF3D8CB682507000000000001030C34B96241353C81CD7DDEA97ED6CBED8C9F9FB86DB60A6B78E39A253C001B08000000000001B07CBF5330F3B30963D6B0A4AC7AC4DD77585E4EB8A08B62B9AF1FBF42B76FE509000000000001D62A2ECDA2D153580BB57CB3FC1EDFFE89B6C06DE234962509FDD49A5A2438EC0A0000000000013792F4A440FAC20AF31472E40F1E79BD1E1C5DADC93FCA0319589FC55A542CBF0B000000000001FC454756AAA4BF5A8163937BA2E80D39CEF46D765C11FD66664120A83A61838E0C0000000000015DD4A3768F248125F414048EBD3F6AA793AAE4CA471DEDF5A9890841DF6DD56B0D000000000001CF0D1BF19096E3DE0950E9EB4C435D0C6B3DB4604FEBB60342D5B7C30528D4730E0000000000016ADD9B858AD6562C3B812B026D9BCE050D5A40ED6D936B1034C036AA490CFF910F000000000001925FBBBD85D4CB4AA7F5D18D703449AEABB18A5D32CEF076C16B7131DCFC08D8100000000000018DBF8B67F11FF96E3229EF8CBDD85719101DC3D8E6F636CEC6D19E63ADF5679011000000000001AE3D1E12FA31B287D509FBE36C261650C199242799057289B96E8D67301B473312000000000001AB1B5ABFFCFA0D28692F1FE23A1C1C3C31133714D112C66E05A09912A1CE32C213000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549619B2CE208EEF551E81A9AE87029B4302D012853622BB3BCD47FBB055E048923FF9ACD043DD40211F720396E02E71DB06FCE4E8D757DC264B4F5AC3089FE49361710B3FEBAE56D82E67A6C29504D6B061DB48FFCD3AB91E7B6B870AF8042312735EA06532FA075BA5DCCF6C9E92AF59BAD50EF0A3797C335F50FC43DF22481EC203C13BEEEB42DC753BE45EC74C10D40CFB3D55B68602D288855C63FCE824A2F4A02E88916DC8ED98AFD66F79E221DEFBEE75A5F18AE06DE81B8FCB94F06AF90A6E36B516E95723A80EA6651490B492765305BACF3DD8EBE02F583A32BD1537CDB034B4DF991724F7B078E55124D36BED20F8846C7FACE620FC7ED376EBE80E7B7122931848C35D74251572804688C127A1AEDAD1003741525A657B5C2901A753E0D14EF5F9A0D5782597165DFA12CD98F310CB2C667C34350C4C5F8E3C31C295C79F9561C0CF3DCCAA0E146799F097185974B77D76EBD9C40646648BCBDD85F00BD7BE65EB0B86C45236BB3EF4FBEDF9063AB38DEACA2ABC25C316C62A8FC0AAB8804D54A84CA6602AC2415383AF59495ED3FB5238B5CAD3D30ED637A6F2D1AA90447647D9B1231825578EE75493A63DAFD2985E8363295A0F24F454C3D59464527CB63F05213AB34DF7B134BB172E3FCFF116BC5BBFBE3EBA5B09E652A4C023400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113CD47F2466A56323209409FD7FCF7485A71CD8CE96D61298A20473D9ACBF99C010000000000019AB3950B30D3E7877159B364A25B214B41B8AA32E293E2DDD44AEB7DFC560A82020000000000019C359D104347B69607EB28A02E6924C24BD2A26DE4CFFF3FF98E48688E291E58030000000000011EC9B78F3B1189A5482238BCF700922D642E45D07E7EA10833E31A4CBC3CA08F04000000000001F37353B4AAC3DE6FA6FA583102CC2F35D6CC95325A07AB88D9B0304EF6F8103305000000000001E087F84EB8A6A13A9581B22CDEEF8942E186FE62896C636D0503675B28692B72060000000000015FDAFB6EEAA60CDFFD2E2D1C034AF7306D60B106F145206FADB857BA565C66FA07000000000001CA463E7885C94740495E419265530662D2D8B0CF6C9E7C290FA86E8E136261DD08000000000001761CA5CF20BB11D4515629D8BEC9D72E02E0D3392C20084723610CE22260DF9209000000000001DAE3E662F52740958363C199EF0CB5F0828BA7D720A1C22E48024697A752BBE40A000000000001641A9FF6624F56629B9AC0BCA35CEEF5426CD40B73E5E6E976CD805B626351340B000000000001970701CEDDB32F91B1653BA5C933B6F57C7F1FF99BC31B459A16CD76024DACF00C000000000001BD84277343BEE7E83CAD70FDEFF5A5DFDD0F9A3AA1FF342DE85C27889AA6D5730D000000000001AD8BF136C3B7CEA71632789EE3D7E8FB2C3AA2548574A403838DDC313CCE97F20E000000000001B4135A97848AFDC9B96FBEDE4501CCBF1B855C542A7165D3EB5E3F0F2303ECB90F000000000001AC2898B9C17C21ED20A550122441FC4ED08A7D669CA1F3D8768DDAD0E2F6BD3310000000000001FF86FB42353270642E15587334A17E39AA7DC9CFBB4C829CB4B16510DAA83F6E11000000000001EBF5F05C9D7C61C2A99BAF7478A73E89B5CF10CD25174F1EE5FD61DA26DE7EEE12000000000001F9F5610037B38150D3AA10BA9EA0592CA0A21714CE0926F3D8D8BADEC020AB55130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087DFB8B692D4548E69E8F52A40B52D87261DAAEA3F734803A146D4622D4C8B17E1D98A7B04CF346B99E512072176F7A8811405EF38E007181DA3563CABBC577F41D6B8EEE36B0D67FF4AA525185A5821F2ACE2DD7F0607828ACF8AB08FE940D7FD268225449F5D20ABF61D2C7DB585A8513AEF60841E1BFD4AD3C47D3A00F68F71DCD9236D7E0FBC428C7095CA12D8D10B2E69C9FB6C976F4831246C9C0E2686091FB040E21C594960A1F6734A0B84BAAACE4EEC7FD1FABCA7F71373620EF656309B93B9D768970B0A03B9E07FA9C888A01D85B0B92F6550534E528BFF6289CC398003AC6A91CF86329B6BEB13854C20A8A75DCBE7A470B216C334CFE6AC120B8AA42EF5A9BC9FD224967218F17A334DB9364F966DA366BE08CA2D1C6DBAD769ED1537C3F5528CA849841BA495B78D07901481631E624DC0656F7F5D0B4820B6FC2269E404ABD245B49EB4FE7FB119E88663C8B8E75EC63C9C5A8EE478313B3B058DF1ACA81F65DB0F2E3E411A30158178585699BE52B6C11A2DC966753D7485AFBC75AB6EB6D0443DAD871D0BF43128A057593EBD325466AFCA3EA492311A31788F75372B5321217937AB4FF23D37D3A01E3578E758A2087941120E801C12F26FCC55D089C712C0A05E67122E28351745998168D1760B16D105D854BF2EFF369971D100CF448D3D00C2C34D5F6037A07522DE2EBE014E1E60D7A535B4CAC42EB69F7856E7A259627F4492A0CDA142D743D7BB90F78EDCC15B1EDF8DE7D0D4366367E581254AF959768265DAC9175E18F133DFFEF628CF769EE7E9BD0E07259AFD067AD441ABF81FA7726FEB1140C3146BB510185AF098DB53040DB97F1EF894CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318E413A87250637B5C4A4BF18A2D661BB2458CA7C7F9E320228FFFEE614E88838DE28767053DAF289E9BB8073D60114D20309CD17A6EBA5FF2FC47B49402DA3600DBC4323559761781818334D1C0CAF34FAB5A940C83D6A363433E390C3B589E1B6D09A2F4276547FB279D1F0E2D1ED91A3AFC953F9E7942BEFCF2AA66B19AE877A6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291D560067063A6EBCB1EABAF7FC12F66BD94F1BAD021254D0CE1F1F850B081262A446E84188C3A9A3CB89A80BC9E8F597EA247A39A6F59BE2D76CCDD6C96DDEB9EB0A272D02C5327DF20934FF8C0E26C71F6736FBD5B85A56F15E41F03DF2713DA70DEC489B962A1F7E119465FC8D72AD1DA559EE0F25FF661AD2F62C6BF172C4B7B0891FF05D0C985FBDCC4DEF2DFC3A73AEA39EAE9010A080DD47BC1268BBC1B5282DA83C62A9FE25CBC62E611951A411B03FA8832E227D761A35F4FB902E54083FD05142177B5D2987BE26FC4F9C5D13FFA21E7488F19245FD19D9FE2DA32608B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE5BCC31B508B8177B41775B459DB06F4AACB419F24EA979AA24C996554DEC91EBCB16E9E1B754DCD221E02231F10FBAABF79E362A514D54670DE7493B7CD7B66BAEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBB0A1E0563E934CB60493FD19327C71D824F361B1133A15E47857567979B5F8288D5FABC9D1D47402577CFAB60BF840EEF0D9173D47757BAF197EE10941704811690592F587BC7F532446BA10B875CB7994CA2613A25F65D16A6735E9CC0C4238036F68FFC1A893DDE19859CCE3F5ABA348F769D122DE567889C14924B243B1379AE65238446E7294F293F0DF1751C166CCF58B4F76A4A7A6178A136E3F72D120FCCFDD47311A340A0734C7DC77664B6D7BD87EA93215C69CA59F0DAD8E258637B49DF9864B84B76089E4F50B6C2BC496835D701C6F106B2B96CDA03A7F118AB5AC2F7073E7596BAE489C83FE68A8DB1E9A5427A31E8A6DC4E2962E5571FF061908EBBED929D64B2505C1C491CA277C2917E0A964218059309167716F47FF2699FEE7248ABFC6723085934D706ADBA0BE046CE3156EE682A5E0ED51534CFEBFE9B7118577F6D3157F31E8D849071E31A734BCC1DABDEF02B7D817FBFFF2CF120ACAF9BE403C35D92B960CDABB7242115FFBC4208977E19BFFBF250DE7C71814EC7206CB8F2E1D523E293E557D49801FA6D9E5AE279D396F91021690DF5EA153B3020CA3E08D8C53DC9DCD731315CB24C9394C6DEA84543806DF231011B086BE37A57CA2B888A74FBE7379EA346ADB56D932BA4B7B857A7918116B70987865FEAB8A42792F788F8CE13F75670B36029660F68A7E27FA23EBD2CC06C7CE9A51FC7B92220D44C4E9C7900E1FFD77D08D35B34B201EC5DCE6348FF7AA08F0DE5A4AE7C664F8E70D3531E181B4B5F7D74E8B6FCA7AE776AC73C4620B77C1C2397B987C241CC139C6407FEBF5B912A407695EE8AB6612C8C3D610D6E11E107E43AA6C638FF86104557546FD5CA0098C44C4EFEF0825DD5E8B33E5311238A32672242BD19ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDC05256E7B9EC23FA6F460956174696C9283AF19A615B7FD209C25EEA0587D15765808D7814EA792B7C31F469AA7004FB9A78EA5E59459C6E3F75E9E4DE961B5FABE5149967C9F97B1BC5DBF8E297DB4B25FC55241FDC189E9488FE06F71E9D1D4E19D50E7A3B81FCFA4799B127AA0D8C12FAF48811D52E4EA08D965813E20A7CB532F3EBEA5CB60601DDBFB1CD19FCE3F0A9CD1E452D1BCDDD215B91160F6EF5892280D847E32600F50E5DBB0DA83A650FD17E4A58EC02BC05DE23CD3B2C04172708C15A96A3D43A212FFD4401EEC87861C35351A0BE9D7D4D6AC5D60DA8AB5E1BBC7D943F4439AEBD7A6B022C8EFEB712BE5EAB7A1802CDD2FB9D93FA6E4383586E517A4D79D9FD2F6BBFEF8C65F1F3111067670E6A059A1308948697F5650C1C9BBD708D6DB1AB7F44BC2473A4897D83DAEA510BADD3ECC8C9F2E4F889D5AB483F7999C92CE3962C6527BCA9BCD8AA4BC4358E39DE5D52EAAB2FCDB3D23E5FDB643B9967374A140DC0813D252B1730B592100644AADEF3DD4BA506B4D4B95F3F95D2984783B7EFE70888FEDC2F8BA40338F5727171F1D799BD2E214D18AFDEF078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DFB179E6FE98B1C807944E610D3A1516646509316FB8E95E16D0E368B0E95370989BC1C46E6764AA8C8E2396E4FD1A65A171D9EEDB2B04843DD2845B5E5F5BB71410EB0ED1462BD35E503C47AC3DC9E9915C28E375719CCDC8F265898EFFB5A5B0212D18F96E473E185736ABF8B9C7DB9E75681B0CF51697CD4C44B0BE03C799CFC37EDADD455AB3C8EB0F334679EF94E6ED2E8BFACF20DECAC68B3AFF3979869B578E146EE63A9FC66C147592E35C3E7785F3883D458746E1FA6E05C928CEB6E4894CB9E2B7C860E4D2BD42D0053B2BC8C7F3C11FC0DAF6DECA58CA37526095779C2092E817BB119F33C436D107F97EE21363AA6D16A8D7C3735F4C9995180C4B5854FE73C1C961A0E178F047DE9EC62C589C2D7E30929DEA6CE37C4042F046151EEC6F1BC5A7CEE799165259DEA61A25806F16B82C0FCBD046ECC5597A92C4FA14B6BACA60BCC65AF37A12AA67AD84239FF680AED031EE172D1EC34231230960B5F7887F9E3E44FE4C156E7472EE8D9C327587A0704A8035E519B1C4A9D2E079FB5833EE071F22593511FEC1620797AD8A38BEC92A5C958A47CC030CEADB4E60CA548C946BD7B2D663B5A34F11E335ABADDE0126BB632F87518103815FB41C3B30C1162EBD9A23A40A2B1E47C1E8530C4E308BAA4EA544F5416D3C2B19B8D75B87396123DD962FCD143732645E3CBCC799D52A889ACC0397AC81405174220EDCDE3CE13663FCF49CD05018BCD4C8E085D8B055BD4A38386222164FEC91589493238047F1CFA07E7C2D8D34775BB61DAC79F301F0942127C6787CFD093620687E9A5C8E0B7146153759272866DD82A69A178D3BBB3AD2AE177DE91B44A0C0CE6C4DAFD78B7F2D3B3C54AE60062DDCEEC2BF3A579A53E27A72402BED5DA167815801985FB7A952CBE74331B6EF9F545A8D958BA7120898C02DAA3F7CC187C81DDF09B5E9F281CEC29A0F012F8EB726DFD7B193833CDA2B0CBEA378E6FB25C84C8CE85E7BAC610B75AE5CFA9DD39290DA4DADF4F61BEFE0F87959174D2BC28BD76B6C933E397A7153D950BD58C62E8233D1D1C276157386488A275508CEEEC7E9896F8B15726ECF4CF837328D80E8E1A4382B9029C26CD3D9205C66E8007EB5C07E51DFD1E90C612FADD09B2985D352FF0F423F45A9E35E4ECAB14E1FA851A060286A131ABDBC53DB24CAAABD058E356751BD847919A68991CDF865BC959F4F5106E21201360A7FD64CE70D102E0615086133262296E48308D05AB0310AEF2C07E169164ABD3DCB8B023145BDD480F927AF80D87E7A088568195585CE2D8BB484F70353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB517B9738E423B8A779C6AE71E3FA4D2396FAA0B00703FF9EB574FABF0A1EB8AE1E59CF6F87D1172094C9FC02F027A8383C25C1CB186D5F2CFBAFB208ECA37B1E5267527F8F29F91C0FA10CA75AC7FBBB397021A44DE7DFBE23D639DD1954190897EF00D981A0E12335FA7DD99C20C3DF0A8E35CE108180046AFDD4EBE56B2DDFC3872F128BCB4D131C339BFD52DC1694BE3CC63C390206DA62F597F54E69954C495DD683A25503F8E37F3CB9AD436FCCC3966D34430A5751D9EFCA4948E7A038D54A8443203C374F1F58A2203BACAA6A0C93783B0BFD8E85A869ECA37AE0FA0349B2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADBFBC26542CD0335EE21852C8CAE8DBE734028D2F6BF457CB086172F176456A64AA18B2C2162F8EBFCE0CECBB57C2516C1933D72FCE029413FFD07B9CD3B8A005C4DF20CFB4542C1B5EE33991EC20CDCA0348935CD698012F9D195DFA690C160FF58054B603119C0C986DBB69C2AD7FB64BA7EABBE0DA6E538B6DCE1097982BEF1676F2E1F6F82CE729BC38EC4CF9E04BBC1AB178040E055B421ED4EE8DA8CE1049037A1C8050AC7981609799BC7923C0BD995B0EA79E9567D192564AA11A88BC6459146968D0D70849C4C8FF6B7BE1E7EDF8DE8D2C3F12F5E6A86EDD30D0141F520FEC5E0695E7A806415B1140A5B29D4B8794A38ED6D2DC039574259ECF15E79FDE234C8C6614F347F9B07F8E5EDFF0B931CD68C5A5D711D4A69DD1193F67F56B66ADFA32C26E4D251D169ED47F769B061B9E9973AA5EEE68F8AB555277D164739D365D93D507B05707E400C7365EFCEA4282D3079F4504FC88CE9131AA9D8ECF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0F4D12EA7A891284AA94DC0A55154C7F4B33C6A0D905ADF95AEC20253E8477272C77465237E1EE73B675C37F656EBABF91BA91A79FC679C5566A637F6417B8981D6EECAFE8534E2538E22B627D3974100CD9F2633782F4799F7CF1D8A4454AED2C61452924632D0A4B78D9C88CC1E9DAA6A02FC37D49A4423B4FC5C52A82BAFEEA48D41FD835314AC901A6BEE00D5910C4A6F5BA8F375B8B2E0F9E9633BA894D16926C76D88E3256A3337829BF81245CF173801D3F964D96BB23EDD9772B1623D79DADCECAAFA80505AC2E0ECBBDBA3679A483BC7B92A54BDEAADFA7F386BA0AA9076B979D66AD9FCD914D0098092FC24DA2D956E1ADD473F5D5E97B81CBF9F42A45DD6CE06682BEB5B740C0872BCD90D6468129848CE45B8C70F176035CB05236795A369F5E6F910F706986E7F66A84B100C265BB5339972BBDF6B770B694B8D2DD8323E86A90E83EE039AE031A331E6D7B99E75FDE0E8E42AF855F52C925F1D21C64D6EB1AE468490B50A06C706D32CF44A483219FB45E14C654CD2ED13E0F3 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 8392 sm = 0000000000000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA7010591AF601BF50208B6C5968D4F692F07279A9C6AA2E66590F7D2E54DCFB47261C040A14FD137EE498C24B0DC750905F56FED22A393C31815CAF6ECFA1D3BC458E8715C21A26FC1E7A951C54A30ABCDB7EC71AAD92F2662BC900F9E9A93054CF39ADF736B5C6988A42FAAAB94F7911C85A9B081A35349FACE8BC499CA287720E65AF6BD9DE79A988F24DF6B71B22E8E50F3DFD73CBEA35CBA762C7D846E79CE6D29562D5B58D74A5EBEC8F6AD3D6D8CDED91F9FA51CDA414D653852E50C13C0CF35BA4B0955661EA3FC882D9D64954405502E2BEF7D3063D36F993460D2557C79729E510FD11DA67C0C0D3B6448B88B96E0834210FDDA112F57C7B4FA60EC32332EF80BB3601C44E35C901ABEE1EE25BFAAB80639021377FDA25672D97ED4126B888B571BCF4A34CE363BF227A5830ACB4844CB17A942625686FEB09DBDA47AF755D050E219A6031573126971470E90C947BC06E3F76A8E7354D2A87114187F9CF92824C5D9F9938FD4E861397294A51035B91B14D9786762BB11AC06C6FD0C6285F48FA30DE2E92AD9D0EAC1F4B2F6B8DBA9D1F8CCB77367706BBBF6A04658E8BD775633D41470CCFEA9283AC792FB671F6E1BCDBCCA7600910D3127BCCAA772AEC184137C31D2F41DD1FB349EC1AC61FED09B068DD382CDE422B65FD5FA8E17247B0A3B8D1F115CE27C50B8BC81665A65D97C2991F5078F1A33ECB61CD11AA7F503DD53FB1B3AF7ACFE24C28A700632DD3934A56129B66BA60E6BE40B7EC27DA47D20C4427ECD55AF940037B6D3485F6D6C7B3CDF5A5C19C958655A51A34BA738D8CDAD826645020A0BC02F5F6F3B6BFD28319B84B5A9F3FD9D99DA363E0267D5B1F83087C603CA6D731A4AE32346FFBF5BBBE7FFCD206304CA468789748789EE3798D4CDD773DCB6E36B719EB4B6B164287FF5C6D837A25CD01DBC826399C54E3242BC1BA4078FE683767FF48114262E30C2D1B55C983DAFACADCD92552039F9209DECF6F1CD358590E9C0DE9CF1A5AE165FDB700A9B4B14C959CA89001BBE933F84F17D6C15B50AF1684C8F4044CA7BA2CC196C7F3CC9AC2603194A9A536347975AA3A6B8929A3E4EDC681AA1A0FC410C54CF1CF561C6741E245B269AE605C8460D5D3C427E39CD5AC141104D0FB6A3D09F71BD5D57EDAB310998EF776BA3E124B590A373920DB5A24CCD39D66562EF2909F19046FBFC0BA04D2CF7A9CA47D87BEA4D52FB263B57AE5ADD901CADE838B1D7347D9E47EAF6456148C6C4E44B0B3AF44E84EBA5997051F779812941DBDEC0309FE593B55963647CCC0954E8D57F85D73CB40792FF03F8F20427D951444990CA3976A71368A7DC1455E880722F0300029FD0D41FB427D0515FF9AA3344F5F3E4811431191A1AC406B7A16DA106310002B3D710DC236EC8D68027C56FA74F71482643230330B6FDF0306DA1A3980689E09376BF39F4C562ECB1A68E02D5D91318EC0C91D38E8E480B8A0E65F452500B9471B5BB0CBC8D62AA1AD1A74AC26884557924123193F3F7540906676F61AF2E5B8879D61077A83925E92D1C3106A85A7815F9CC0A00D536475C5C63263C255F9CA097AA6C3B65C5CD659AAE22F412427C2918AD8C309342C8369BB454C508B82F2761B1AC648469993DC8770D77AEC80AD8A05129D20EBF2AB9CF7D5739A4F0B796FA3E18D0B3C862254D2D1EF0C1141EF2A665FCBBEDA2BD28B70BD0C4123DCEE5A1D81F1E20ABD1DEA550546C1D13ACB5AAEA1E6F2304541F641343DDE809B1A99E617BF85395C38D7B367F2C2AB5E26A156437E7248DF2E9F2F617049A7ECAFE220784990CE695E1C32EAE4F10BC988CFC2B56742FA299C57394432DA7B7615487DE8858DB8A45448140CF4A9D2152E12279DC7A6AE1DE1239BF9B1ACA841B2EF96801D464F6EA1053BF96F6E69F495D45535AC3FD4411C27FF7DEE1ADC490D79B073A0D4A04A903D84921A5FA52859B9DED1F1EE674256F2A57DD5E6616AE1EE474D3F1C1DD7BC7F282E6DA92731914758830B8AF74345719259AC8398F56A7F9663EC9CE82C2C0864DCDDA13DC99CFC527C2F42F86DAE54811B29589E8CEE39FB9496CCB77190F052B8DC58C76C5ECE6F0FB81A47088D8AA2085533F7D6427AE4A09570D48AAB9446FB0A49A36AD6003420C9B64A27FA2DEEA97D1D4BE804FFC6B0D772DD5757BEDF361C340C9CA3D9449895E9AFAD2BF923436FC4EDD59550F149304B3F9D24448FEDC4593A0F94EDBBFEFA223EC3FEFE59A34E94B985DA3E652070EDD15A60D47A6C319D1CCB7129E77F28A9E6536AC00261E6BEF5AC25DCE824C508AA0403E063A8562FC21A25FF7F99D4C518A32A99D3E41C8DE7518484F9CBC19EAA901C9B4359152FCD7C0E51C82C962FF3F9A68B4F8B30440B23AD28725612F5FB98FF740AFB457915740084644120ADD17B445078AAF54123FDF28F3A9CA137DE547F35FBACBC8F23207A7A3E6BF9CD001E18BC590C757E05144C3D05918E358FFAECC0B51B2F0B06E3869667B1DBBAAAC4AB4167776CCC2FAD197BC60BC76BA35F1FF80A96013054323266E972FD51C1610F8C04E01E16266C271B3B10695A6321BBB5DFF292DE959CBF408916903F8E0C9CFD2A2744016E934D66314506B7B791F5F9071C60545022564D64D7DDC92EF9D6362A0CA8F7FF48AE9B71A3A14738A7AD925653951A1DEDBD16EEC484417E92496276CB73AEAB964842CCA5A527EB0787680648B9932927D7EB2627B3D73D254C1904139D8A2C764F72CC114E249FBADEB2B0F590830E8EEE33ACF36AAFB08E1A83C9FF28E6D6D623EE44A0B86713015BA15D74BA7431EB5BA91C739028B83133C5AB36CCF899E10440F06BC626856A2015DD832F087A72864D390131A760B46BFE305E3B4E9912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70D8A18A427BE88BF379EDAB2E45A1AE5F3199C5D6C0BDF55A8CD1EDEC7EAF92F0D011CBE8E48BFCBC428382A66B103B905C0CAB36A7511B1BD6E23F4C69073CBE6C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1ABCC7BF5184638350478FE05829DCD0C5190BF84804D293190C08140A600415D691DBB652DE950481258ABD45E76B9668FEEB94EB6605DF5900501BDACB58F4CE0F6B0120CAB51933633EF98DE5471774EA6BA1642AFB0DF6C7041A8C05555A5F1D0212EC753E23A7CF68CE52417C9D7CA5F9C180D04C6B64F70CB860D2903E843B956807A682500805ED38DE3DB09B05C5E31C4E78C72F83F1446F69441E4D9D9168B4F97EE394586A683D38B9FC72FBD5D92D976C70A407E0B1E25F3046B5832CE029A1A95FFCBD5C8B157282F7364E680C60B252C49483FCA03529693B074E0D2B1F6DFD6463B974DE6829A616F20C839B0D2B8BE5405623B5B722EF22F7A3BB78E91315F715D9DCDB0C8639CB8A90685BEE7969671789047083CACF24FBC4B601B1B23B2E79E42176B2438CB405BDF46369F4DE5F411B2ACD32BEE3065DF987DFB8B692D4548E69E8F52A40B52D87261DAAEA3F734803A146D4622D4C8B17E1D98A7B04CF346B99E512072176F7A8811405EF38E007181DA3563CABBC577F41D6B8EEE36B0D67FF4AA525185A5821F2ACE2DD7F0607828ACF8AB08FE940D7FD268225449F5D20ABF61D2C7DB585A8513AEF60841E1BFD4AD3C47D3A00F68F71DCD9236D7E0FBC428C7095CA12D8D10B2E69C9FB6C976F4831246C9C0E2686091FB040E21C594960A1F6734A0B84BAAACE4EEC7FD1FABCA7F71373620EF656309B93B9D768970B0A03B9E07FA9C888A01D85B0B92F6550534E528BFF6289CC398003AC6A91CF86329B6BEB13854C20A8A75DCBE7A470B216C334CFE6AC120B8AA42EF5A9BC9FD224967218F17A334DB9364F966DA366BE08CA2D1C6DBAD769ED1537C3F5528CA849841BA495B78D07901481631E624DC0656F7F5D0B4820B6FC2269E404ABD245B49EB4FE7FB119E88663C8B8E75EC63C9C5A8EE478313B3B058DF1ACA81F65DB0F2E3E411A30158178585699BE52B6C11A2DC966753D7485AFBC75AB6EB6D0443DAD871D0BF43128A057593EBD325466AFCA3EA492311A31788F75372B5321217937AB4FF23D37D3A01E3578E758A2087941120E801C12F26FCC55D089C712C0A05E67122E28351745998168D1760B16D105D854BF2EFF369971D100CF448D3D00C2C34D5F6037A07522DE2EBE014E1E60D7A535B4CAC42EB69F7856E7A259627F4492A0CDA142D743D7BB90F78EDCC15B1EDF8DE7D0D4366367E581254AF959768265DAC9175E18F133DFFEF628CF769EE7E9BD0E07259AFD067AD441ABF81FA7726FEB1140C3146BB510185AF098DB53040DB97F1EF894CDF900B1632F65393977D69F5FD1FDEF8E6A2101281D4997C7E4F821A421318E413A87250637B5C4A4BF18A2D661BB2458CA7C7F9E320228FFFEE614E88838DE28767053DAF289E9BB8073D60114D20309CD17A6EBA5FF2FC47B49402DA3600DBC4323559761781818334D1C0CAF34FAB5A940C83D6A363433E390C3B589E1B6D09A2F4276547FB279D1F0E2D1ED91A3AFC953F9E7942BEFCF2AA66B19AE877A6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291D560067063A6EBCB1EABAF7FC12F66BD94F1BAD021254D0CE1F1F850B081262A446E84188C3A9A3CB89A80BC9E8F597EA247A39A6F59BE2D76CCDD6C96DDEB9EB0A272D02C5327DF20934FF8C0E26C71F6736FBD5B85A56F15E41F03DF2713DA70DEC489B962A1F7E119465FC8D72AD1DA559EE0F25FF661AD2F62C6BF172C4B7B0891FF05D0C985FBDCC4DEF2DFC3A73AEA39EAE9010A080DD47BC1268BBC1B5282DA83C62A9FE25CBC62E611951A411B03FA8832E227D761A35F4FB902E54083FD05142177B5D2987BE26FC4F9C5D13FFA21E7488F19245FD19D9FE2DA32608B34833D55E1761FBEDC88E644D7CA5F8D33E86EE25C65C2A6DA4F57D2B580FE5BCC31B508B8177B41775B459DB06F4AACB419F24EA979AA24C996554DEC91EBCB16E9E1B754DCD221E02231F10FBAABF79E362A514D54670DE7493B7CD7B66BAEEC1D3E5B7DF7AA1564E1D8294F454E439B7F102074AA586FF5931827B7F7FBB0A1E0563E934CB60493FD19327C71D824F361B1133A15E47857567979B5F8288D5FABC9D1D47402577CFAB60BF840EEF0D9173D47757BAF197EE10941704811690592F587BC7F532446BA10B875CB7994CA2613A25F65D16A6735E9CC0C4238036F68FFC1A893DDE19859CCE3F5ABA348F769D122DE567889C14924B243B1379AE65238446E7294F293F0DF1751C166CCF58B4F76A4A7A6178A136E3F72D120FCCFDD47311A340A0734C7DC77664B6D7BD87EA93215C69CA59F0DAD8E258637B49DF9864B84B76089E4F50B6C2BC496835D701C6F106B2B96CDA03A7F118AB5AC2F7073E7596BAE489C83FE68A8DB1E9A5427A31E8A6DC4E2962E5571FF061908EBBED929D64B2505C1C491CA277C2917E0A964218059309167716F47FF2699FEE7248ABFC6723085934D706ADBA0BE046CE3156EE682A5E0ED51534CFEBFE9B7118577F6D3157F31E8D849071E31A734BCC1DABDEF02B7D817FBFFF2CF120ACAF9BE403C35D92B960CDABB7242115FFBC4208977E19BFFBF250DE7C71814EC7206CB8F2E1D523E293E557D49801FA6D9E5AE279D396F91021690DF5EA153B3020CA3E08D8C53DC9DCD731315CB24C9394C6DEA84543806DF231011B086BE37A57CA2B888A74FBE7379EA346ADB56D932BA4B7B857A7918116B70987865FEAB8A42792F788F8CE13F75670B36029660F68A7E27FA23EBD2CC06C7CE9A51FC7B92220D44C4E9C7900E1FFD77D08D35B34B201EC5DCE6348FF7AA08F0DE5A4AE7C664F8E70D3531E181B4B5F7D74E8B6FCA7AE776AC73C4620B77C1C2397B987C241CC139C6407FEBF5B912A407695EE8AB6612C8C3D610D6E11E107E43AA6C638FF86104557546FD5CA0098C44C4EFEF0825DD5E8B33E5311238A32672242BD19ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDC05256E7B9EC23FA6F460956174696C9283AF19A615B7FD209C25EEA0587D15765808D7814EA792B7C31F469AA7004FB9A78EA5E59459C6E3F75E9E4DE961B5FABE5149967C9F97B1BC5DBF8E297DB4B25FC55241FDC189E9488FE06F71E9D1D4E19D50E7A3B81FCFA4799B127AA0D8C12FAF48811D52E4EA08D965813E20A7CB532F3EBEA5CB60601DDBFB1CD19FCE3F0A9CD1E452D1BCDDD215B91160F6EF5892280D847E32600F50E5DBB0DA83A650FD17E4A58EC02BC05DE23CD3B2C04172708C15A96A3D43A212FFD4401EEC87861C35351A0BE9D7D4D6AC5D60DA8AB5E1BBC7D943F4439AEBD7A6B022C8EFEB712BE5EAB7A1802CDD2FB9D93FA6E4383586E517A4D79D9FD2F6BBFEF8C65F1F3111067670E6A059A1308948697F5650C000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F7F8F9EAAA74A5C910DD60B2FA5179B3FC341BEDAB53B1E957F40AFFE59FD454EE839D34EE92ED029C1B5853A46CC8B48B58DC4F74EBE2164B7F867B17ACD180761BBD5017870DCC53B0ADDCBB8DD1A6F5D014B1A789493C53C3D7B304F6237F836AA9372B0CD7007588A7EE166C1F8BC1C7826CA9D6E2D73B1B217E238FFB65DA1671204B7137B3C91D19ED0DAA12A98AB71C239C6F0E6B29D3F61DE3F71688560646DCBB9846A8F28BD1E7606E2C93CC0CBAC8A85BB578671BB01347E7B2BA757AA92131B2693D7F9501E87FC7C1BBEE1B8BF15E28DAF9B74487ED12BE8A4075FDE22DA018C0531776136F0FAB5ABF372E160CF51685CD0B8FEC7D63D39F4A7EE635051E54EEBEC7E8C4A408EBE848B7255685201592E3730C4DCCC6E7DE956B4FF296E76D0052EC6C037ACACA6E6474CB17AB271FFCA98A688D224C3A25425F1C9BBD708D6DB1AB7F44BC2473A4897D83DAEA510BADD3ECC8C9F2E4F889D5AB483F7999C92CE3962C6527BCA9BCD8AA4BC4358E39DE5D52EAAB2FCDB3D23E5FDB643B9967374A140DC0813D252B1730B592100644AADEF3DD4BA506B4D4B95F3F95D2984783B7EFE70888FEDC2F8BA40338F5727171F1D799BD2E214D18AFDEF078A9E3A5823FD097F6860AF7B8E224D3C5222A049D22E7B73CE6D9300530DFB179E6FE98B1C807944E610D3A1516646509316FB8E95E16D0E368B0E95370989BC1C46E6764AA8C8E2396E4FD1A65A171D9EEDB2B04843DD2845B5E5F5BB71410EB0ED1462BD35E503C47AC3DC9E9915C28E375719CCDC8F265898EFFB5A5B0212D18F96E473E185736ABF8B9C7DB9E75681B0CF51697CD4C44B0BE03C799CFC37EDADD455AB3C8EB0F334679EF94E6ED2E8BFACF20DECAC68B3AFF3979869B578E146EE63A9FC66C147592E35C3E7785F3883D458746E1FA6E05C928CEB6E4894CB9E2B7C860E4D2BD42D0053B2BC8C7F3C11FC0DAF6DECA58CA37526095779C2092E817BB119F33C436D107F97EE21363AA6D16A8D7C3735F4C9995180C4B5854FE73C1C961A0E178F047DE9EC62C589C2D7E30929DEA6CE37C4042F046151EEC6F1BC5A7CEE799165259DEA61A25806F16B82C0FCBD046ECC5597A92C4FA14B6BACA60BCC65AF37A12AA67AD84239FF680AED031EE172D1EC34231230960B5F7887F9E3E44FE4C156E7472EE8D9C327587A0704A8035E519B1C4A9D2E079FB5833EE071F22593511FEC1620797AD8A38BEC92A5C958A47CC030CEADB4E60CA548C946BD7B2D663B5A34F11E335ABADDE0126BB632F87518103815FB41C3B30C1162EBD9A23A40A2B1E47C1E8530C4E308BAA4EA544F5416D3C2B19B8D75B87396123DD962FCD143732645E3CBCC799D52A889ACC0397AC81405174220EDCDE3CE13663FCF49CD05018BCD4C8E085D8B055BD4A38386222164FEC91589493238047F1CFA07E7C2D8D34775BB61DAC79F301F0942127C6787CFD093620687E9A5C8E0B7146153759272866DD82A69A178D3BBB3AD2AE177DE91B44A0C0CE6C4DAFD78B7F2D3B3C54AE60062DDCEEC2BF3A579A53E27A72402BED5DA167815801985FB7A952CBE74331B6EF9F545A8D958BA7120898C02DAA3F7CC187C81DDF09B5E9F281CEC29A0F012F8EB726DFD7B193833CDA2B0CBEA378E6FB25C84C8CE85E7BAC610B75AE5CFA9DD39290DA4DADF4F61BEFE0F87959174D2BC28BD76B6C933E397A7153D950BD58C62E8233D1D1C276157386488A275508CEEEC7E9896F8B15726ECF4CF837328D80E8E1A4382B9029C26CD3D9205C66E8007EB5C07E51DFD1E90C612FADD09B2985D352FF0F423F45A9E35E4ECAB14E1FA851A060286A131ABDBC53DB24CAAABD058E356751BD847919A68991CDF865BC959F4F5106E21201360A7FD64CE70D102E0615086133262296E48308D05AB0310AEF2C07E169164ABD3DCB8B023145BDD480F927AF80D87E7A088568195585CE2D8BB484F70353661988C85A63C489C30724588FE31CBDB00FDC94A011F2D2A269B872CB517B9738E423B8A779C6AE71E3FA4D2396FAA0B00703FF9EB574FABF0A1EB8AE1E59CF6F87D1172094C9FC02F027A8383C25C1CB186D5F2CFBAFB208ECA37B1E5267527F8F29F91C0FA10CA75AC7FBBB397021A44DE7DFBE23D639DD1954190897EF00D981A0E12335FA7DD99C20C3DF0A8E35CE108180046AFDD4EBE56B2DDFC3872F128BCB4D131C339BFD52DC1694BE3CC63C390206DA62F597F54E69954C495DD683A25503F8E37F3CB9AD436FCCC3966D34430A5751D9EFCA4948E7A038D54A8443203C374F1F58A2203BACAA6A0C93783B0BFD8E85A869ECA37AE0FA0349B2A98243675E5887CE67C324C1894250CEE560A971E8C32D69205DB2D932E9ADBFBC26542CD0335EE21852C8CAE8DBE734028D2F6BF457CB086172F176456A64AA18B2C2162F8EBFCE0CECBB57C2516C1933D72FCE029413FFD07B9CD3B8A005C4DF20CFB4542C1B5EE33991EC20CDCA0348935CD698012F9D195DFA690C160FF58054B603119C0C986DBB69C2AD7FB64BA7EABBE0DA6E538B6DCE1097982BEF1676F2E1F6F82CE729BC38EC4CF9E04BBC1AB178040E055B421ED4EE8DA8CE1049037A1C8050AC7981609799BC7923C0BD995B0EA79E9567D192564AA11A88BC6459146968D0D70849C4C8FF6B7BE1E7EDF8DE8D2C3F12F5E6A86EDD30D0141F520FEC5E0695E7A806415B1140A5B29D4B8794A38ED6D2DC039574259ECF15E79FDE234C8C6614F347F9B07F8E5EDFF0B931CD68C5A5D711D4A69DD1193F67F56B66ADFA32C26E4D251D169ED47F769B061B9E9973AA5EEE68F8AB555277D164739D365D93D507B05707E400C7365EFCEA4282D3079F4504FC88CE9131AA9D8ECF0EA404D9BDD7F4AC2E61DCB5286BC8B66483D5459E273EAAEE8E77A5EC02A0F4D12EA7A891284AA94DC0A55154C7F4B33C6A0D905ADF95AEC20253E8477272C77465237E1EE73B675C37F656EBABF91BA91A79FC679C5566A637F6417B8981D6EECAFE8534E2538E22B627D3974100CD9F2633782F4799F7CF1D8A4454AED2C61452924632D0A4B78D9C88CC1E9DAA6A02FC37D49A4423B4FC5C52A82BAFEEA48D41FD835314AC901A6BEE00D5910C4A6F5BA8F375B8B2E0F9E9633BA894D16926C76D88E3256A3337829BF81245CF173801D3F964D96BB23EDD9772B1623D79DADCECAAFA80505AC2E0ECBBDBA3679A483BC7B92A54BDEAADFA7F386BA0AA9076B979D66AD9FCD914D0098092FC24DA2D956E1ADD473F5D5E97B81CBF9F42A45DD6CE06682BEB5B740C0872BCD90D6468129848CE45B8C70F176035CB05236795A369F5E6F910F706986E7F66A84B100C265BB5339972BBDF6B770B694B8D2DD8323E86A90E83EE039AE031A331E6D7B99E75FDE0E8E42AF855F52C925F1D21C64D6EB1AE468490B50A06C706D32CF44A483219FB45E14C654CD2ED13E0F32F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549619B2CE208EEF551E81A9AE87029B4302D012853622BB3BCD47FBB055E048923FF9ACD043DD40211F720396E02E71DB06FCE4E8D757DC264B4F5AC3089FE49361710B3FEBAE56D82E67A6C29504D6B061DB48FFCD3AB91E7B6B870AF8042312735EA06532FA075BA5DCCF6C9E92AF59BAD50EF0A3797C335F50FC43DF22481EC203C13BEEEB42DC753BE45EC74C10D40CFB3D55B68602D288855C63FCE824A2F4A02E88916DC8ED98AFD66F79E221DEFBEE75A5F18AE06DE81B8FCB94F06AF90A6E36B516E95723A80EA6651490B492765305BACF3DD8EBE02F583A32BD1537CDB034B4DF991724F7B078E55124D36BED20F8846C7FACE620FC7ED376EBE80E7B7122931848C35D74251572804688C127A1AEDAD1003741525A657B5C2901A753E0D14EF5F9A0D5782597165DFA12CD98F310CB2C667C34350C4C5F8E3C31C295C79F9561C0CF3DCCAA0E146799F097185974B77D76EBD9C40646648BCBDD85F00BD7BE65EB0B86C45236BB3EF4FBEDF9063AB38DEACA2ABC25C316C62A8FC0AAB8804D54A84CA6602AC2415383AF59495ED3FB5238B5CAD3D30ED637A6F2D1AA90447647D9B1231825578EE75493A63DAFD2985E8363295A0F24F454C3D59464527CB63F05213AB34DF7B134BB172E3FCFF116BC5BBFBE3EBA5B09E652A4C0234 remain = 1152921504606846974 -max = 1152921504606846975 \ No newline at end of file +max = 1152921504606846975 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-6_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-6_256.rsp index 98d33b6b08..f775441ed4 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-6_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHA2_60-6_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHA2_60/6_256 - pk = 000000076948691BBB3D39575B96EB00BBE25665738D3B70378EC25AB76CD8D200F9BFDB04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 000000070000000000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A6948691BBB3D39575B96EB00BBE25665738D3B70378EC25AB76CD8D200F9BFDB04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001BABEE5DDEAD48C384DD12B603E7DC662BECD05787E659B7A4F42C219604631E9010000000000014FAF3A985C827CC08F0D3F4B0931AAA529DEA84CAF9C6EE9906E2A940BA1E327020000000000010F8E4B4F87A6782C5EEC46137A8A8C6E86E11F46C241FCFD839218BB0305105203000000000001D49255A7D48890564ACBEE0BD3619157B47C374DEEC424D7430636AD855D145C040000000000018788654A63F4B5743A54543D6EC5B5DF61BB9756223D195F0C9455B82BB8AB4A0500000000000175130597769A70C420AD21016DF456DBC65C8DCFF50B371F703C779010DB61E006000000000001A4BEAA773590472545884EA0AFDC81800943A8BC91B4FFC76E5ECDC6B878866B07000000000001E4760EF548991A02F056AD9A34AFEEBE6BF1568F273258BAA58FD72DD9D5E7E90800000000000170A8D3850B38CC15CF6F3D5774DA66E93CD09EA69E3B90B6B5E24A0794C523CD0900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001679E9E3F9DCC784BF6B061A699870789E78B2AEE2C1D9F082DD7FD241A53647F010000000000013A62723E901C4C50A6D05799DAE9C4F804BD9F01AA226EDC129C77E962D909B502000000000001F1F2182334ED10684EF22D59127FD103A216EF4CB169A4615C1013B2D00D143A03000000000001916D09F583779651E6B192ADEB350B07714F00E125E51013C6A4F41EAB50C2E7040000000000017D93C20AE191054626B3138F02E186A4607EDEF6E32DD3B2D788325E88FB01E90500000000000159008B71F97B67D9710ACBCAD0DCEB434823D0DDE4E8526701AF9ADE23FBCDC406000000000001410E6F39D12638391198E1827F643E6547AD7438BE85774B713D8FF3D8CB682507000000000001030C34B96241353C81CD7DDEA97ED6CBED8C9F9FB86DB60A6B78E39A253C001B08000000000001B07CBF5330F3B30963D6B0A4AC7AC4DD77585E4EB8A08B62B9AF1FBF42B76FE509000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549619B2CE208EEF551E81A9AE87029B4302D012853622BB3BCD47FBB055E048923FF9ACD043DD40211F720396E02E71DB06FCE4E8D757DC264B4F5AC3089FE49361710B3FEBAE56D82E67A6C29504D6B061DB48FFCD3AB91E7B6B870AF8042312735EA06532FA075BA5DCCF6C9E92AF59BAD50EF0A3797C335F50FC43DF22481EC203C13BEEEB42DC753BE45EC74C10D40CFB3D55B68602D288855C63FCE824A2F4A000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000113CD47F2466A56323209409FD7FCF7485A71CD8CE96D61298A20473D9ACBF99C010000000000019AB3950B30D3E7877159B364A25B214B41B8AA32E293E2DDD44AEB7DFC560A82020000000000019C359D104347B69607EB28A02E6924C24BD2A26DE4CFFF3FF98E48688E291E58030000000000011EC9B78F3B1189A5482238BCF700922D642E45D07E7EA10833E31A4CBC3CA08F04000000000001F37353B4AAC3DE6FA6FA583102CC2F35D6CC95325A07AB88D9B0304EF6F8103305000000000001E087F84EB8A6A13A9581B22CDEEF8942E186FE62896C636D0503675B28692B72060000000000015FDAFB6EEAA60CDFFD2E2D1C034AF7306D60B106F145206FADB857BA565C66FA07000000000001CA463E7885C94740495E419265530662D2D8B0CF6C9E7C290FA86E8E136261DD08000000000001761CA5CF20BB11D4515629D8BEC9D72E02E0D3392C20084723610CE22260DF920900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000C96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A3928351163E04D8BA817C168A0CE68CAA6FA744E7E30A2670B2BB88F27810C887E48E90EFAD40F9735B5767F60EC515C146D56EA534C970E04BDD10302D85A2317C478BD195FC93499C051F5AF61A6C5CECB89A1D67BF5BE2CA7EFBDCC20B884597EB2BB0799DB9B86E2EB8FD93389AB91A391F2D68A057FDE361AC97A87F4406F40A7EE2E7709E46DCD756617DCB0DBBF43E6BD4851F3D834BB53CB150D2FB7B00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000019C1A7BFD8300283215BA57DB5CDD95EDCBD04E1C41419317BC2069C2AAAE22130100000000000143ED646E32FC21554D8DAD350C5732270CC220F7E264ECB5B7A8E8A4586D0CD002000000000001762D040EECA13E137753604D099809D946063368BFE1C7CF0E6549FCA746F7C6030000000000015FB7406F1B25A2B4A6A1666269772EB08D6FE78D8A8395C56AD80FE6924DF08204000000000001207155BDC49069839D60C0C74C9F57C739D2F36E6AAD0F698CA840A48FB11EFE050000000000012B5052F4510570C5839D41287DA3BD24DE8CBD40BA9E159E783C5812A28606A7060000000000015C07001390BCC398A47CF40395338496D66003B5E0C1DD7187A5D605984F79ED07000000000001285C8B2D9B398B8A212B3CE0FA820CE44048C2105C067AB9FE6FA70B1E712C33080000000000016F81A741E38029A214AF0CDE4C75E79A618C7B4942F7819A53CBF8EAA263EE49090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044E3C9C3413B4497ABA623AFE3257572D979FD7234C04292B8EC507187752446AD11D10DE925035D368AF83D202AF6979123C7F3B7FCB8D83812728A890B5C09B482529FFC0737FB59C35B552AD7C5820E27332D2E44F2A31ED972E2E5C834FCC652204BB401557D6FEC656BD9F63B9226056E2D025988ED1312A2A767D418F1342BE489B463AA4BE823D471648D9893364758DACBAA63BED8B3D8D4DE1E4A768B07A9912E72515AC62BACB31DC0EBECCAA1360330949EAD48841D91C61B13E2EA79C1891C9290FEE2F779EA4EC57692960A91913AE591D6550BC59CFCC5EA68483E4066EBBF11C2D9647E7B5ECE7845996AAF856A1BC1458EA7C88E73B1C19FCE34B68DC2BB0EB2CEFD4506D674C92A2BE87429BC026542F6F8F48CB088F945D76C07477009F8F9D2B41552CD688E00D2A977C67003989D0A2FA7688B410C6C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017F7DF0085A4DAADCB03AB4E8241B0E6DC05E727E817C3B6FA27F05AE1FA2DE1601000000000001BCF2F650C31EFD6F2F09775A3B4F87BBB33AD0D51537DAF37E0D1C1AE8BE8DC00200000000000174F4FE7914F390776AF328164E738CA8EB0751EF9E535BB1B0E80B05762E683C03000000000001241535B940156367A4ABD922871FB10B37235B67CA38CD8B2B02AA8064C5CAC60400000000000158C4427DF89BCC228982E6BB71C9037890E11D302D9C0378108AFA067D58D55E05000000000001384D1A0B27013C6337247C54AA3DCCD045A950C606E556515E5055243CCE916E060000000000012318CF2B5CDD3ED1DAD6013254844671FBED69801D2017AB776CD63FA76F14E907000000000001179C26EF68F54F7CF842BAAA6E1D70CD828DECD748E792E5689C2BC065D3FE2D080000000000011085411CB66EC413039B45DC41D9098C2EE6981718081DE0A120AC81043DF7AA0900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D4FF586D6CC300F09F878FF5FDD7E7BFD0AC3AA2AEC0C223DE23D190C6F67AFF7C00001F7DE39C907235BF8D5EC16A34AD2D2E6DDC419F5B24EACE1A17BEF5CC52AAA05F04D5AA8BB018210354282E98DABB918100165E7D962A6F396F22753B1FB928AE3576A91CE62216E9E6214ABFF91FCA2E6E77611AD13F70CC87E67A1E6D886120CD2C2404E0312A57635D1C2524C97EC0BDD9DE011D158F8FCA7AD1A23B38A0E6201B3A52E5BD893BEF169D6E665829DCC297E9BF3DDE2974EF56B848D62499354AC81D756C3CEA6F0E5EED1E0E58EA69F3843B09E11F3BBF8898F1724E4BE566D1AC9AB166CA7D5CDC3BAC80652CC469E048BEDFF5444254926930835827E5FAF2CB16AF0E0CB13A3653AE4EE9C49D838F84D3464EC035DC31E025F30A12EA7630A6A630A351E06620774E7CD342027BB9AABFE167CBBA7D526F0767000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000186A69EB284CFC56C72C2C83351D5CCDBEC831992175BC2D2D91B3F9378E0DE9E010000000000010A318F954C197DF2DF39A85C4B322E7EB1B16B0B4EB8C8A492F4F3B904C47E7602000000000001A9204F8E84112663772797AF87ED34C559ED4D6D37E634EFACE6A18C700CD53A03000000000001D2E20083FA11E157A2E5B72C9A986D3F47348E54C1935F48A86F7A9D78B2BE600400000000000142D78126E30680B5A226E280A30E4A2F47AF1C173AE745B1A3BF3A129452BB9F05000000000001C63B321575E217F363A1936335817B6BE75E1776DE1123AD6737CC50F99C7876060000000000011CE036EA27D47B8F7AD9F59C21D3402E6026F55694410ACA06A2972ED23F24DB07000000000001B12F5BB6C6A34E4011BC807F2A09656EBFBDCFF75F962C93B647842AD5F390A008000000000001BA14498E89CD4B4DEB6E14FCB1E51605AB6B7899F804195839EF2E0BA9FE3759090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014BCBE4FA64052B0853EDE00CD41BF95B66DA2A519216FA1A0A8BA5F10B4EAFD8BE62C40DA2A76DFD8A5EE8EF42A8B808C55A533FC488A2B33A935A635E24F3E0C717E2320FF575ADDB18C567B1333DECB0855E069D5759C48FE6D8C6A9D217BFCB7A9D40735A3151382E3456CC4BEDF6C7EC94F186FCB6BF9398FEC934714E8E231402FC7BD5153981C7C789B26208DDD77E4796F70D6A72B7B9C5EC75E4E3CD122F72621E92B1AC515A33B12B1801B2C3E461AF788661815E6BAD2E6472116B89B941A0E68A232089C6F831229BE2EB0CD244BE4FED78C8371D2DC614445C76907F4A3EDF18722BF0998FD03209C31C348CC79A2AD06ABB1B3CC549E73B206A05345EC801A1C5C42D794BA1A35747493D76CA8567B62F0C2151923D8D9CD2F37D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB385C19D6AC3BDECA5BE59F322A17FBAFF466E945FBB943BFE35854802837FEFEA3937069240712886742E890428C0C21BC057E82D5BB961095A5A18DE149CD19F79E9DC3CF0FEB5149F856C5A7BB82B6AFD4B5310993D9E4E1D33B4CC601265906186B98CAB4AF1570CFDC928C0A221A3BBFFE8E566D580A689AB51BB69826FA60135F60C1A1EA97CCCC9AE96CC93B66942370BCF910D916CBB7F87A0BF5EF46DFEBB050637754B0E40509441E19465B238EA45270D7BF5E0610A89B4A47AA821D9A3BA58127DDCEE4E7204C38E0EEDDFF72B07FA5AD8EB1FA89554D940C2C88EF588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE5966743689380FD336A081B8C7F753B889BD73F10345B8C4988A7A4C865250E3707A8424B606059E3ACEA75F2F732058477097D5BF8F5A2DF82E4AF0EE9C4BB251A5657C15808B7EF26806E2F3D61137B44C9DF4196A9208065ED1C70F9DCE3C75AFD719F14D79818812360E4709E521E78B983F99B31863039069D3F86FFAAF318853EB4A1AFFC5E598ACB6B15198E016C779BB7D77C54971E4566C2071EDFC0D19B41827913C5F7EE5D8A9411AB2706F3C9DD8E2CF4AF497765A647C1AA42E3645485AD6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291B3530D6094FDEDB782E1C927C11235EE632F6C3FA150DE1BC1125FEB330079EDB0733B58F1CDD3D20904F85DE31C06FE375E7D1E20F4C79484C5431A026EF8F5C8AC47E7FEA2A80E17256ED956484E9004BD99AD8ECD0D1EE5790A83CF9A14827C3B5D5C25AA18255F5D512917BC1FA868AF35ED3540BF0C10CABB267F612C26AE27DEDB5665A4DE3913AA2631C034C1BD22E5A721194BE6D1E4337D1CF488E9F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA498B7DA996B2692EB8C3D1D8BC9BECCFECC8EC67EE3A87DF5B0B9C7C887DCB0CBA7F5E1372399F3A4F4CC7DF247752994CE0D024D2C6E620EDD0B8CD30891FAF58D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB074AA6092A1F23DCD01D8B8C70674D55670C07A6D0655CF37D0516E6E1102865F0C53C5AF80A45B09B078337D61AFBD12DA2820AE45CC4B213C00576FF3D5FC21D0DB8D877757226F81078653EB4C90C0D2C7D304A6E0C4265DC3C1DB343202664008385964C6C56FA11532D7CF41E93F92EF28F3DE2CA1D5817AF2114A97BDA7F6504EBB2A6EE6BF4753274BE064D3CE467673717AD7350DE4E83A1BA27306F11DF36A2E30572E3FEF2EF6B2518419395DA9B7D4B191C88F3A863A477A2D226E5BCC04E39AAF1AA042A7B115CA26BE8DA52A162FDCEC6E511B1497FFB8B8AD23D3C429F71236DCAF9DE275D7B1D2DBE83822FF7D8C9BC7BA3AB5CB517228AFE2E30C53E64C44D02CF9CB51CE371827CDBDF798B1723B418EC7CDF66CF09F444A06DDB94355F529337D6A3178D754D68BE658934FEABD4F4874B11E739F0EE4E95D2D23B41F037B9668C9F74D2B3D31027861779FF8516A29246D766D2A61A02CD5B8E338B9630E8E0ED5BDACB017A6D3B89C8A1108E525BAD96E203E7A0C0B7F2148274FD20F9B53601F2B38DF303D7F8785D06260485D7507782E11855EA62F44C755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E695CCF3818C69AE16DC71782D99440EC9AF4A9C33FFBC728C9C62C47E0D37CEA661064246A8B2BBA14ABF5767F33E490AEAD721929515F091663B4437BDC34F5B15C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFFBD90B13035960ABEF4E3CFF91B9871E49B16A6F0FF86445C441921D2E698117109D810C864F024F62F8D25C263CADA33916763373D76EC8955ED113F71C40834E79A1BD5E21CC2373598C66168492FFCD083D2A8E7E480F76274C048719AFF98C5E2774BB1039646BD25A240875655A77023B7F884F5852DCD9C5DA173DACEF7F01F6527CB7F5375FEC1FD2D5C90A46D3D0501715B2D4CF51166226D8F35DB7A9ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272AC230107F230E29845C2E2283763A5832809AF2428C304C07CB21A96D7B7CDADF857F54C91A22B8AE6E4EDC0DEE01FA60697269BB1299F9FD7D3699D4D865A25BF0F31F93DAE1D51C42FE755219BC2A4B2505487483A1B81BFA86BF6A99642C51AC3DC78D5E42FEA4ADCC51C0501A8FD543217134694262E0FF5957CE719766EB0CB34CA2E541992CC2619C65822A763FE6572E3B33C4C8C216B4A62A13BE7FE6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156D49ED44C7713B7A50EEEBC575166A1B6CC3AEC2CA98398971F648242C35E8EAA21257BFAC587485D48AC54BC306344EDEBBF2A42B7E37B6086B1D9F54255742F1C9BBD708D6DB1AB7F44BC2473A4897D83DAEA510BADD3ECC8C9F2E4F889D5AB62334F4B56AA20F9BB57C09EBF41BADB20D36485AD613C790428C382B437866A681635BB509C97D4AA12387C320F6CEFD1838459F0DABA3DA54684B83E3ED10C07B8CE62549A876A13D86D8F3D001504D939500462E64C94B6EEAEDDB8856D13AB345659CB16C8B977B6670208B70920BA34E31E6A10EC724CC6FB3C299ABE890047E1F6B3D5A69BF731EFE803088FC8D3B9E69DF3102AABBEBE90C3EE20DD829BC1C46E6764AA8C8E2396E4FD1A65A171D9EEDB2B04843DD2845B5E5F5BB714212BBF4237C6D69B1D61531257FAFB41BCD74462C292880AA396FDB392A42C4AAD9B5492EE4F2A076CEA42927C22BF7CA54FCA135A0FF512CAFDA620DA75DF70C37EDADD455AB3C8EB0F334679EF94E6ED2E8BFACF20DECAC68B3AFF3979869B755D1BA8476CF0553AA3B5049EB57DF8F00AC5DAC2C1DEF316793E5DDAF9F352894CB9E2B7C860E4D2BD42D0053B2BC8C7F3C11FC0DAF6DECA58CA37526095779A89119240A8E28D1D44AE57D7D3252B69192353D745AE1C066DB60F6C6E82F35854FE73C1C961A0E178F047DE9EC62C589C2D7E30929DEA6CE37C4042F04615F48FC178E8CD389A2DEA13C83E2534271AE7DB54D7C89B8714666381C388D37BEC8102F8497D8A820C70C47254582C5C27D3D97A6ECE379315D5520BA346E8F5B5F7887F9E3E44FE4C156E7472EE8D9C327587A0704A8035E519B1C4A9D2E07949F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DB9D6E9AB3A0926402DD8095AAFB46217FC41A2E0D7C5960C1FC814E461B1F1F219CBD0A97D50180BB017229AC9F884896F357900724A3A7A8E4D479CF6A093FC30778F755C63CF618073C40F6042FB2143DECEE8DC32CE9D3E0064EE378F78B8F945A05629C118D60A6AB5DE2DA55A06B7325FCCEE42C01A5C408F0291E3610C44684BE1F66D3FB8F6BE43EDAD2EA87FAD50C993CC447DCAF79AB19DD406B20974363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D024DAFD78B7F2D3B3C54AE60062DDCEEC2BF3A579A53E27A72402BED5DA1678158142C023B3C238A93F3D1CB8E48EF84C168E27E6645DC6DC6689E89CA0A74D07087B760743BB526662636725B7FB700BBC0B3A73793C291EBBBCD4970B27370C2E85E7BAC610B75AE5CFA9DD39290DA4DADF4F61BEFE0F87959174D2BC28BD76B780BF58A5656928CC6684D80B728FA0C1570B8268DFD57EC9168CF7D39997BC8458A5D4126FEB278B26769C4F55EE77EBCD778D00F836BFA6EB13307BA2D7417B0812FDA4CEEDA359BF73865982622728D7EA8BAE1620A63483DAC957E4F8E082588E12FFC57A2871119AED0B43DE4ED1EDC4AD6434A485C64D9FAFBFC7F01A8793E5649BF33A7186BDBDBA5DFEEBCC16F2CCB67E355774B8C32B932119DA7158A4D131F560491BB42B47C9EF1594FF6F09BF29E972502A7D62A2240FBBBE55C3D82050B374EB42E433CDBABC163A95A6492A7F7DA6824B5A20527C9D0933B97C753932ED9ED277E40CCB8C4A042FD5B88E9C5D569A48F512ABA1DE68C821BD20C1A995235727654ED6E59B063EBA5F4046E7D047B886A22A7D7C5BE009F3E14629FFB78F8555B7376AA2B7B4B360F0D3C295ABC2590CE1AA36943A46379C1085D66FFE0DCF3C37C89BBF1C7D76B6D62D5D2D265EAC52164E4799C52D9A7E67836B66532608870BCF43815BA0633B82CF8E92FDD0A4DF829039370202BBD93541D4D398C42900F96D70AB85AEE46D4AE2CDB5BC61B0E57DE8AF9BC4A366730CC4A8443203C374F1F58A2203BACAA6A0C93783B0BFD8E85A869ECA37AE0FA0349E9A943B50EA190BF7E28B4406FC4B14E77203739F8DF7D168EC43FE06D0645ADBFBC26542CD0335EE21852C8CAE8DBE734028D2F6BF457CB086172F176456A64E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC40509461C2CEE814F7E26684AB01D51A1385EA51162E9CE43172A1564809B328A45AA68BC14BF38692467DE23B8908FB07BA05C90DD44A372477233DEEC84BF89287B1F8E1FED4F275FAD98265AA76F0D798266081567140ADAF2A9C64F41E053D1F329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB03F8A842A1FF048CFCF92A8D77409DE43CA455C5ED59F89358559BE214EE1B531915180697A948C945A9924FD6864D9CFF00E1D47F38B54092E4CFF1F92A65CCABF206A7D71F25A66969E37EA7D52EFD74B80E93CD7A048F71EDDE1EAF82A24F20145528EC96BF1857E0F1D8F19812EAB34E07D4262D195D1BB4D20FF3E226C2468B90E951C8212023248340ED5B7E4EDF3C6AF6A6FEE63F8DE613EC6F1526E3F6A9327A17C2279BEF50B6CCF1569A86FA56DC4B8866C365DC5D16B9BA888234D6860885B2A420401C0E3F8A971BE2CCF46FB27EB58D6C8EDE207B703FB7EBFEAC77465237E1EE73B675C37F656EBABF91BA91A79FC679C5566A637F6417B8981C93D4B2B08DD6DD375D4C84791CE66913FD4E3D6B01287F258E8EB01A223CD222F81B1412BAD3DF60D89E29F4FCED352A1DC0D52A296D6D8145BB66BCC936BAC362F309AE4520552C369E4BBE918F20C4AEDF8F037EC9AE0A3BE8BA1BA0CBD40949CEB55F41C8728AA639789BD51539F1AFA46F71106F428C9FC659F34F6BAA879DADCECAAFA80505AC2E0ECBBDBA3679A483BC7B92A54BDEAADFA7F386BA0AA79EB4AB02F6134488DF1220F8FA56D2C14630DA6F79094DFEE7180D218C621A32C153D6E5AA82C318BCBEC16FD901CB860793B8B3E9E357D0F008EA80BADACA56795A369F5E6F910F706986E7F66A84B100C265BB5339972BBDF6B770B694B8D2DD8323E86A90E83EE039AE031A331E6D7B99E75FDE0E8E42AF855F52C925F1DE1A2B10D241ECAD1523291D88D5D0EFE1D5CA4DE89F22AB2605BB5AF0CC6564C0FEBBCAAE5A19E133CA77B6C4AFE98FA12CFEB1A87D38463C35DE33D5B7D2E08C3DAED2A32A25502AA2B4E2F2A330F06294E202466F0701D4B361C71DB74253ECA3148CC5E1119591830C19DE38FEF1A5F9302B766F68E4E6616611EA940522EE92E6625C8783357799CB4B9F6A56A84976EDB84939B94A676D4657DBD04F7D754A901CEE47AFF04327CF6E0193DD3EF8CD61ECAB28CE8CDE2A56ED422C47BBD5E4B1C005EFD6C982E1601461DFE8EFF46797FCA8B79156473C7A964515B4A0B4373513F5DE44B5088663F1B9D235681C2A0F31675B7BD215F95D42216FC76E5C93A2C8929163064A58FCAB39F6A8700820BBC9EB62588C0377C15BD74E5B7E4F11559E54EAA502404D245774A51F17A9CA804C570941434AE4464CA23D8CB2D042633395BB951DF71EFCE0FEB7AA66CB0EBC83321C73AAB08C45F89D8DD625753795B7BDABB1CC042A4EA7BEEBA6AD585ABE6849B63C9630142B7191742C772BEDBDA162F8B4101824D6F16D189D65446852A08B37F359617ED6B0F2DC1A5648983AFC78D3D4009BFBB088F85D85B551DFCB0C99B46C65130CF3A25EEA02FAD2159409FEA41A7F3BF71F020CE618D82E4A2D5DD005E1E8839EF6B43D864647D89502AC44A7517F0D0E9E06BF9F55BE677F11F7A4689D51E5DC4892181C32AB56A831AD8E8691C9DC7C8D59FB0098C7581BF682298C353CAE2242C7BDE5F5933B48E88624CFC605A87E401D4B01FCE73BCC86D9FDDE138A185AB4B79B2394FC0718A30D5B8FAB24C2A67DF7C57690E380B21B9BD08674E49328286D6CD82FD782FF7BABEE169FCEF38BD5DC8ED8ACB324A374F426B0D835A5A947627DD5D026DACB3669212EAE997EFA073A3800694A8470BA89780C06F034BD1ACA26229A7C13345B4514B3C48A810C8A017062BA454688349B3244A3022F86EBD132636D566A899C38D183C149E8C9EE50F7F254409A4FA45ABB9B74750B0FFE552845BD460BDB3FFBF6259FA6D048B59198B4FD2B135A9DD870881D24109F95CB1B0857B395683A40C358ADFBED50D70A8FA540F6006D2493B59AE4BEECC8BE3E70396BF298B2F49B468B64DDAF12FD0C594DC243A782FB8862B2B73BF1F59FF1B812DCE96AD72D73D928EDD5D6D384CF214C7EBBE25676FE612556461D465BD1D1C8AE96BD8F349371553AD9E9B80623B49D5C8C38489415ACE7DB17DEA495DB1CE9B68AE228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023C8C898A4A7D16063A2F7FB6F6C00EBEBADE4B5A79A9814803CDA526D542E0C4C44DAFAE06659E810969F48EAB6EB002F7938B62157E85E1BF258D2B81ABD9195EB828938D84BCD92C9793BDA17DCD6ECB92068BEA49626C4595EE621E192309156F9B0127FA44454075F7C73A94992400B22CAB60A056EED2E04045E74494017E601F044245A2B64B83EA8BFEF2A02A32029224D3C9F5DAE64E4A3298688C1E4205FD9038743CEF33B08CD9366560AB57EEE937008332B6A4224476A759B07D04DEB016DDB8EDF3665BA71053A894F98DBEBA95EFEE3F46AFB944601CC71C39315012B024E672E7CEBA843F35C6F435983AAB0F14BDB63B2D130A91AF9F72CDFD73EA39DC02AD3074F0E4B3780E81732B550B298998169B1640D80FD56474FF655A233E3ED6C48E5D94A4C6D31ECBB5257DC07F29D5A4C98177DE0A4DE1BE24D2CA3CEF4DD2A3FFBD818E75023732E1F1D3F9051AF6E8047081FE588E2492E5EB4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F933819140A786527AEFC7A872908B98E8356286485E2ADA68D8733129C32FE7E0D0B7AB63E890DE8AEC5DB2D52F88D328E1DB56FF586DC2026817A277844C18228D01C4A792C6D27D72D4E36AC852098685807B31A411B62DF550CE9C5080F1BA5CEB1634B8EE7CBBDA91DA660CECF740A502064AF7781F544A2A9F6527CB431A33A905262210B977C09374F03C360642BB200F00F13EFCAB19685DBAAAD7EFBD4D42A8B428342F44A61D9D58808B9E7620ACE2D4FA47D16FA98950485E67EA182414D9C7B78C51CAA4960A79B1BEF4B6BB5CBA79515042433C7505B5038C4DD0CC8805CB9C1AA93B2BF96402909E229C46A5C2C7CB18F0B7747642714BF204D42A8AF263AA6C8F1DED9414FD0E6586D7B680D4BF1CB6CB6DD90D63511150A76C2C40384A4F156E827A22D0D207611E84477254E492397A85643BE2EFA36371F9DF6119813B2CA7F31D099B0715927919FFABE384400D3AA0869AF2E95B525D9A1453679B1624C4F2718AF080BE493D1DF583843CB08C5FAC4587627805AF278A009530F8545958E7C04ECD445240A70C6D0450DE5A3F3CBE710E610D8EEEA17F97381119B8A53A62EF7F4B0D8F84BDC86BCA2245664DA120E7E36945038F7973099B1ED88113E6594EC0CBE05B5CF5ECEFD58D48FFE4C16E0F941FCFFFDE6D3E584584EC8A03AEDB6126EF5F479E4FE8C97BA01A4980F78D12717DF17BC4E9040B105B2D74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7566DC65863A7E07D0D8774305019C67D504E7FC4DF77A8821AECBFB762EF377DFDE75F24A9DEF9CA7997E8F4AF3B4E60071F11DBA6303A964B7F9C3FD443C766346B4B1E50EA1D79357CA76ACE991F4760184016A12C2368F7D4E6BAF0C8EFCF4A869F3973B41564F52D762BECBC7FA49B40D6FCA22052287E1B10DD8FA257423F984FF4CA38BD49F322C84CA37874056055B3A0C51060360F05BE3E1DA6E1829B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F3171151E6F5442468D000FA46F17DC7437B058242696056ACAAC06AF22742452798DA226D91074DEFCAC6C3D770DC54CF7ECE9ADFEDB3B421ABCD9DF305D412A71FC77801FAEA989C03A0D633C4B06766491F4C0DC67FF8DEB16AFC8BC7E3D41601BF7B964B91A8638DDB7CC08B68691D5D501B5D3D72915442F0D1B9EA4DE4A84F8D037672EA110B3F93C3AC7EDCC5B5211DCC6BF4685C2D711AF156B82961C5369170E2E76ACF126B3036492BA13A920E126E7CA29791835CFCE00B3EF7AE43ABA16123C386FC3AA80F7F55F094F1664D67FCB5B990A1B93AC8D9FD02595A6005B8CE100F00F9818D7C2313416A65FC916B102A019EB2C7DE91A346F6E3CBF7CD85D2E8FEBC968AE7CF4E6A64400C45C7F71CC17BDFCD337C726028AD4F1956D8AF94345E2FF8F1C9E57AEA206DEEC8A93010DE204CF6F3D9CDE952FB8E4955EE2708B8B19C5788865CACE48EAEAB016AEFCF9FCE16621401B9B14F01BAD76AB32105CFD3C5A3EC7E7CEDD9A64C0B2AF82072F95D2762333ADC34CCAD8B93DE773FDED0AF8569A4ED1032A10D522056894A78C45B0C1FADC66A29CBBA8AF0600B416497EA782E66C42A4B1B518B7DA3DFA17E2EC7BF70208F1911CADADF3173E26A9285466819AFA7E43CDA3E79C3379ADB9F88A8C460AECDEBCFED326E15F01E303A0BB62615B2A2CB097B045DEF6AB46F799A70EA5F4C54B215A0BA6BC2BDFE5846A65D620BCEBD2607DBFC74BCEFC9712B8AAE5BC6C179B2971829F9EA1EF896FE1F6EED7D4A3B6D04A0B96848599BBD3A5A4AE6431AF6921A26726EA8B5651B74CD5C5723D8610CCC9E9220532D22E4BEB538A7E7EA50B7FE7D21E4F7EDA1A6E232C8DA603BD8A40DD5A9E87778D5EE4E2711C229E5F66F7C19CC263A38A184B437846BA2945CFCED1C270FFCB2C9C03D8EBE37F9E2199FD4084E94A02F74C3C2E3D577470B3F3F4B0B7CDA7671722B1E900A49096AF21F74E327D4B9204FC3D7E3AD6DE2A5037A2FED9BDB1100870156824C3E2B736F55E200F84EF5C0B6D39FF0A929F20749413DB40418EA6A764BBAEA67EF31C107F7F23A1193BCD26297EA37CA92CF90973BCC7BC548C62EF44BD5FBAE7CA281C5447895061540CEC586CBAB07CC6835253C332BE03CD64CAF6CFBA2C5768AAEE682614AEDAE4CA6BF839963D13970AB2D37BBD203FC8F5197A62C183B76BCBA09E5E47D686ED98A652A176A90284D0034391003C5BF6E9C6A091108A3107E128BF3465BBB72CD50C374A343C714E7AE5599915411D31CCEDC7ACA1734B5F23783839CD46D0786814D52037477FFD7600129FE5AD39C8601C30088977D58C83B2D0B5B6AC14579F5C52BE795726F126ADBD2742BE107CEF59ACC94B78DC7A51AB01B4A3B212F10768D35C3CA5CE6D4EFC33995ACD07AFDA29782EB4D86447F622B2592F7D18E835D5F922FC7FCFCA5F12251B5A3DFAD7ED2B6C9F3C6B734F34991C30C700EE325CD9752D68D4DB9B5DD98F91348C1DFF570DD106D0CB457C4108580FB341BD44DA99F4AD058B064AE955B584627DCA083785EBC199607782B5B096DDCF3A0EC0C5F4FB69DD11814016F8AFC30F853DCF0B793E150C3B796CDE2B1B43B3E346E257331504D6571E35C7E2953D0B1EDBC4B1C48F21012DBDC773107FF4B459FCD253425217787310AE7D8F74F77E60A4511B8B23A6A1714BDDCEA8694F2A8508991C555D6C1DE281244E229377BB4FDB9CBB38AE483A3569F735AC438C492DFE9414F26D70F154CE91D99105D5E34340D34764482934F3F3145436CD3AA2DDCCEBA06D0439C960E7D16BB68113560CABB3611F2CBC43D79915CFF16CF0BB72EDFD858830AF8C790F7F1C18409C4C48601F24454BC986B12540B74EBE53F5F3AAED84C8DD523702B0492BC34B98F2AF02C856882F37D1234C04B42060DFDA8FE106CF570235BF1169F163501B400DB5A48D7FF08851543CA92A0E8448F98BE619F41F4C820CD5553B0132BDA47AE8C0A85874D1FF5D23AE2158B85206E9F95CBD6DE6F2092A31D700E8E86ED0009F9780B1D349E01944FD5FC58A95CCC7502C6B1385AB36D24C663C8316F2F453E88A98EA61D721FBD4B018F43B84DD5B5C83316488AF78ABBD005C15399B7F94F6AB6F5239B10CF44B82FA774ECCBB5CB932A51B1C5202F112198FF20A160DA0DD130510C4540AF4C9ECB078C38AFE183911E2116F130DAA83432E3B05F76DAFA8C9285CB7237B57407F2C4999D4ACBAA916D2887D2ABD50590B5F761D3995A3D484A632696156ED00346555A19AD569E80F2DC6FEF929F3AB753AC9F451D991D1F9C614CB562F9AD1B984E94BF00204B8E0411D9AD0D374A9752B6989CB7AD969B047E60F5D371FE4FC3D17B4DDE42878C758FF19EE3FA205FFA1E5A3ED709AF71DF3527F26F712462C0AB5815A447EF29BD1887D7CB8FF44C2752A9E1BC890A80A5444E8384BED9EFCD06F26C467FAFBB01B97EA07CE0B5091605780D9770A00252C92C4DEDD4D8B942E14C90DFC5BD612D85CE24C5CEFDB3EA964FFF256B20A4DC2C0EFD50DA4BAB56BC846B09DE27F341EE42EAF0545CD82BF62FC699298C98D9B9947D436D234DF8333E144C207D0DE124707A1A3262CBDF544C5C6FE70F2137EDF11BC8A3E2E7B6C35909DAC8C160CCBF3FF25275B7F97E5E0D56349A1AB617E944BBADEFDBBA8BD06B26468C961756F0E1506F5D2C5C332CB7D18155B3964343C682A5721C97BD5F6D675D44FBB9B5C9AE58A02BB327AD51C927CED9F3E27C8DCFA2EA7F4F20867DE29279B5DA09E70B6B6ED9C2C21502D185DAAE79A792F5D79C8814375643B4E69440EB7AED63285EE40ADB2A43111BB8E45D109B955B309FBDA17862D551F72C2EB06BABCFE4BCF46468789347AEA8FD0CF3E2938521DADC71D0EEE1F435B38023B69022FDF00B3D1AA0A456DCB917056F934240BD6C899E8E0D36E4F1C8135F74FFB493B7591BF9C2DD47E2C2B64A5CB0D34A0DDF8486DC9CDCF85E8D5FB8327A486076AC1AFB63681A253CC57B65DB36619DBDA966569822860B30D9DD55BE869766BB1986D254A1C486E6990EB6CC4D22E829230CC0B5CD80B6E0C3E4465CBF7AC3480BF67E671B31E38F24800A61B0C98589FC4D98BC896C27D4A9F8EAD8CA7D567AF1796A82C64F3A9876B921B4F9F009EC821DAC29B54AF75F0F5F59BA04AE753A786D0FDA22130A1036FC1AE46A86DA837812C7FD4539985A05346319FD809739255705BB1BBE7791F520D43F33F06493E50423C6418BF781834310AD40B92E396722B1C67EC08FB5FA918351C89574D5A47D31D7F6D25A30712BF53AE5410B587B9CDC0D652F993ABCADD6442E5F52229C5011D36980BB01D0053433DC64E02F535EB87F04F2FDFAD3A4378477E4A0BE652FC73E3604285CC0721796206461EC07608C4A8C0C913924525EC5DCF185891F1740E56E4E88E3C957D028D5BEBC5DC6AA9CFD3B6A94CA9B281DEB7FD816C7DD27AE5FECACB499A764C58CEF0EA4A18999B80D89D2074754894613FF9A019639CB6E1A31B91F6389894454B884F1F76BF3A20984E908C60BF36D3CCF439D9B200C3C97E076A75B5209C363FB23DF3FE4A8A792CC9FD93527667603AE461FCE62593DD7DAF62D1D78060E4AB4DC2424BCA29A0C96ED4978987C8D4F2791F61AFFD6300415F0E4DE0764AA88C672EBB55D765FD9382875CF67B176C8BC422F613D22605BFC24C2D69DA0E7CB76AF9378DD04C21E76BD30E9F923D724F6F3633928EAE801001F869B7BCCF9EF79B6FF8E8A741EFF812B31E140A7C798D8738D272068FE9A5468EA0CF60D339DD3D56A73D3BADF14504FF3FC2816A0BB816806B5CEE3164998712B9460C4227117261169E1B4C20AD79049980017BB1CACAE8EDFE29252C782485A5BAF0599796BB5004FBB2101CF98470B60E8140B828E7DDF8D3B561AA5A147739DC01970DEBFF008D85ACED07EA28D10E594E60A3569C6A13D9619FC2F76D279143D829383549772E09F3E275840913B08E0FD33C24CD38760D585FBAD94FF3B0355D247B1A5D8F22E67E34803F1D454D979BD9576F36F816005BE186FB6D58BDC8FA63935D7E4CB00A0F6752E1121241A67095E77A3231034C7D14649276638DFB1DBAF56AE7BBF54C64B817E10B6EB7E974208B16C658FBF3480BA6C86F5BDCFFD2F830801C95F5D9677EA593BA221A9E7D2F09E1E19FF70AA4A73E2FCB455583F3E21618A50CAA4B53EAF90F0AD1A47BB59B77EA66DE84A10E6D5FCB7A9CA221BA0DC44452E7074206ADE1C1B02E520B6D481C27D4CD833EE7D985B20FA5BF7A21E4DFCAD092628EC0A6E2DC8718EDA1408151C9F4C1FF4046A444CD0F8F10C82BF697013DA572E3EC04726E89BC96ED083C2387EF5DC80AC9D74144D0AD906BDCD4608974D57F515101973291804C5180C348EFD6C91AAF5433A6BFACACD657BB7C579A195C6EFEDBEF3E6746FAACF6AED5975115AF77843A5497EBBF4F254D13D82321B29A6EE275AD3389B828D1FA19FFFFE79123A579B45B78D3F0A5AF0EF44A19F07513426CBFFA519F93A4A4DB52628A2FD56DD3A323382E5DB171811EA861E2D46537D0A4E545C65F2310C2A4EFFE0851C1260C26F2ECB491BD2EFCC41F06EABF26B48E9E61FC3C550F6CCAB762B0FAB75DFF6353F814E55E98A3AAD5C82CF9A891AAAC5112D38C6687E30610AC3379222517D90CDF1AB77E96B16E4EBCA8B0E8719205FF3D308550E3BA58A9CCE5FC6BF05A4DBECFECEBF1F4B7722C6AAC9FBEC2EED1C90466147C022C4B2150D6DE9B76BE278F43197479C5D0CCBBF0CBEB22C31308982105A95A5841AA37DA3BF81F8F7602C9E68C059A36BD0DD395EBDE7616091E3753AA1397A0251EC887FB27A166DCA318DA3EDFF3E29320AFABB616813DC83D4641F3664407C3DABDACA9F5EC3FF32B6538624C2F10415019168777C2BF58D51E619C872F1FBCDC8363C69AF421E6B6C046B8EACB1233A634F492189D114FC3B17B3A6FAC0CB04BE2FB6CED8D3DBF570B66D7EA390C11D2FFE35A8F675CCA65026CD83809D8C60480A25536A9DFBAE0D1229F2D563FBA86229F6B7F7CE9A9C12E6CF024402A8DF251BD5F72EC415621FCE91148DB266EE1BDA0885827E96E8A9AD9C50F43D9B6462E6A24D508013457E7D4E3D7030DEE74216B3EB93C676CDB9F5E6754A10A635950D60C9916D00565C50A33EA1BBFEBF02BB60483B6DEDF0481C054710FDEA23BE9FAF9DBFF407E7766C84CCC3F281C6383079DC3188FBE8F9675D0A26831FE4090EE8C8E87DC459B1CE8480E64B78A5F15EB30FF165CC9F5F261B42E5EBF469A2319A405E8CBADD241C475A5AC949BF372A41B060353FA3EB8C79B969874223CC14B6E5B3EEFE72C0CB8C8E1B114AB6B7A435B786D8A8FCC935C8BAA5BAC879B50D8180B65FD0DE78CA05D750591F479FB953FD55BB00F1D50EB99AFE348B00A63DE9E79B12C5C32F257C97CA0CF00153C8C3D8AF3988200052059CF3C841296651EC607D910D661EAA1078FA7EEB6738A8484224A29CD0463649275D117997768C75660D469691278A111D50A72CEE9600124E3850507C0B963E9121C8BE1B269448FE8A4DF87DC1EED33FA1EAB13DCADDFD7F2BB0FFB042FDC6EA8C00A6379B640CA2855112F86F6FA5B2A622079AEA2EFB9D9063AC89D7F94AE3CD7551F3FF99B5A3C41D3770C44E9555969B97D719A3C5590B3D8A1F65995AB57BE3FA7D55524CCFFF8018EE1A587AAB9FB5D3E33FE7BAF2642CF9421540C134F9BDE97680458FFE5A18DD2D3CBF178E91629F050DBA86E31E5A42548E1582E271B399A6DC512CA068153BE53E78A5A6F83C8C39FA6F92626B000E8066A1BEAF2C21975B2FC29959C3AA239CDD2A4B47A55E0EC54495769A9293F33F23FE19A886DE5AAB35F3BC80C9CDD0FAD599DB6359B84F396E9DD06848EC5844B44AE00478C8C1FD5E964031EE21158F6FA1784A07A09E6173412180C5A0354B11480F780C1E3CC436BCF5D3FC2B5E094C1A45AE192369966B103D700B955D0FDC49733525BE13D82164C5A2996F0FF900DC890ADDE848305ED6D225460FB75CDC1453C513EDAB63E576CE7CDFA755055AC07036627843E640E20767EC35B45C69A28151210BC3F93EBB880C6419D545316029814C22D2872E8B0B4B4ADED8E44D0035CF687BAF0C593C2B947CEC9770E19E28B62537B3C463F582084CDAD9A704D8E4CCE851D @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 14824 sm = 0000000000000000404DFF9B9F3931FE6158FFF355A8EE715C9BC6A87FE6627928F3CA1055FA70108B307B55E90F36943261B10F4D92A0F4AA0696D42E7766CB9EAA67647A56DEC2E7A09B0DC1E96F31870177ABDD7AB42345B9BF49CA7689F703557EECD4C9FF32076C999FFA0461054EA4A1E863A1FAB50E5FE03A9EA847E4A5B476A41885B53EB9A6E98D556765100FECE8CCAE704D7AE90AEABE735C2FF46DC9FB302D2A1F4CB21C6552D41F5F3865791CF993DD00FE3A036175178B6407E88A3F76605B5EAA96A944CC1878D4FBA0A59E308F18BB3A90F9704B0342262BB5FC542743D246CD503A2438B438344D55FAE0A0CBF3F6061F2AB5685E9C3210FC441B3DA673E3F029510438E87AB06D786CF52C18D7F9C95D7B82F4F0E1AEB59E4221D40C67EB131A23B8EE4F3EC419BA999054325BEB9B8BFCA6A2BBDF11FF7F8A170E9C5481D7CD71994D48CEDA477BF92043B7E7C743DFD9E32948D29632C6C47355A5701C0E3343E73C5FE2CC524A7FD21FA547675C86F6C8D4EADEB1AE29060EF687EF65344A45A5F1033DA0B50A5529AC43435DC3A8BBBC986F1ACC1AD60CC13F9BB26A1F7E6AA6D434BAB8FD8B67091BE465C3BFB21CA9D16D794635422DEF832911110F75CC152316E26583F4E3E9852B62D535029CF5E0F17381282F84B1D658B96F6047C813C1B4F4A16C6E7FE523D3397CD89A5A92D85813703EBC6F3FE6EE26DC55D4E6FC2CFF5A94DF26DA0C0170FD8713CFC44391EB96DA0957FD5066FD83C6A49B866653FAE1FE64ACAE482337978125F0DF84D9A85A5E932E940C2661A898DB130F0F2573F50D1FEBE92DC828BCBA9F7C01D56F6DB226890D911DDF82BD5D4240B66EBFAAE4552283904FC706E9B7683884AC5B893F4F81D2E14A0E4AC57BF98703DB7F13859B5137BCBA8FF977ED7AAD69BCBCF9F2CA845D008CBA0EB29D9C8155D3924964150439144860C1E5B6864506FE3EEC30FAA801B458516E35DDB4BA7A25D6C3E4B7D39A28A65A5628A93556FA9F54E273B583F9A197BFF4731E043ECFF72D42580294D9D3C8CF910D424C636850E61AC0CCF2AB7866EFF4913D36690C765230DCB89993C60885CB1850754DF50C48538A5EBA8AAB821F9B04C0A1EC786BFE2AFD21BCB353A1F77030A18BAE47C0D2B9F396BD8E5FF560328AEDB237F2717BD16C62163FA242D09159E03AAD5590CB151143CA16E6DB3F4C4BA5C64D08B9D0A5A3F6009F660E9B15456060AC696B025F2A874623DBF0B61F73C56AFFEB1227FD01AA4AE0CD5A4FA29EBCD6C0997EC7E973C3F98C4674370EF456F0FA3DFCF5C9CEC2D80AD509A65AEF0E3E663B7F31BCA437311BA799D4C2ACC138D97F323B19BB892BB18C8C530250B082F14BFB41EA7A1BEC5FEA64404E3C55617C0D7AE9E6AC7062BF0E32260C11266C4AEB1815B9D80CC2C7F5898A39D5C1CD115DAFADB4F258D8BBED23B21C65486E46D8BCA833B6967A09FC7DA038DE1464A993EBDD656682B6DF928AC9BC8079B08F9AE5E4921BA288D8234209C7E68091460A20EAA7AE055D8D71770CE9CCBE116CF81917E004306693A483A49459114295DF86CD25D3F8A716C4752F1276385906C5B141C267EE5C065802EEF3FC35AA6CF37929B5F2D4827B72B8B27B64DC91EBAB724047EF3EE1D4304B98D74984EC1CF561C5011B41F749403684937CF80B0A47392C9A1C0098C189DA2E070FAE819C907F1ABD8F0040B4BC30B0A5B8A1894B7140F8A41ED377CA4A4B94A19B762BC2205D49227CD8D9C500CFC32F70A4CF8D7188D73C377F57A9435B8BD01C875E0C8354A3E599CB7217AE688647A72985606BBD0720F6FA5C5B6F70E88234EE545A5A5DA495171254A7C4EEDBFF6C527D58C8B2010B0BD8AD0437D24E58D5DEA089B198A28F6AD355B74455297DDA5CBC8B88DEA9B7AB7D59E2C78363EC25A2602B45DE7A3F9E3C01FC51BC5D6A0E15B7B8B52A545154A2598B038C74F5873360386424FEC7650D8CC97CDD7D3E00F4C890614D359CD60FA0498E97F4AC282AA6EB56F968F9814E62F40C71033B32261344CD2269D7DCD62F7A9C9C14089C5F4966C65C61697E08F06B61AAFB4C247C6FC8412F815114AC9C3D9172C1B5CF2286CF987E323EB63EB61FB83F76123FD8CBE6155DD251E20F090991CD6489A6F4330D8D0BFD1C49F9B69A3D6A4325EA85EC2D7332D47FEB73B98F82EE9738E07F40119820C5F429E298EA348A200EB48C74CE2F0CD36756498B06C90F299FD52AF06FC80E0DD67566CD3E2651F4852A85CAE74D7D5F16E4AD53DA41D3932175FCB840A64ADC463ADADD53CE215AA2F0C4DEC4E0BB2155F874D7B60F46F671A8EAF31FC446ACA59071CC077F86F8C4723A9E227EB5E9091A504B641B459D38EB852295F33EB9706B28E8EE393710D80077306E5E83B1F23B621473F83F97BCAFB61F7E2CB455011B3E98F8CB3799F0B0600E74AC1214454C9F6D1DBAD9EABF89C060B05A54F710BB049155BD727BD117E934CADEAF3C118DD6C1CE927AA84675735E695731DDA77CCBE59CA2DEC2881046C519251731B60AA43EEE29D3F0FE2B0EAC2FAD197BC60BC76BA35F1FF80A96013054323266E972FD51C1610F8C04E01E16839CE80CEA428581B6CE720C459D6D2961C5A7FA8256FEC4951B69C04FD5383BA3FB66C2A40D85B41EE3F215A96F35898045E1DA96127C205C124C1C805814C3EFBA495E0499587494A9B6E4974C37F5C006A34FF102A23985FA9F660326DA3979A43BEB2A0C7CE97F1A180C300FEE0228AC673E5AF3D65BC5F01A722E03876D5608A8216E5C8E91E1E89EFEA60DC1306CFBC26529D23619E354A7F1332E790CD59271BECE083922C4E18B01560F9BD9C0AB1C891529371D295C1A524637A804FB84DF86BF95F7B65F3B54022725BCA40A65474F2ABBC9BF737F20BD12CFF5619912E5991C713532E81FA57F9BA562E1D3026D2D2D7373D99871BC62768AD70D8A18A427BE88BF379EDAB2E45A1AE5F3199C5D6C0BDF55A8CD1EDEC7EAF92F0DB2F3B18A2035973F56757DC09EC3CB32FCA024C6A0045077D4FC0AC0F6A26A1CC22F2E9109F9BB35426BDDB4A69EB8F45CD5B226F92E8026F1E62DE1DE435A4FC0CAEDA91C38A88F0037BDB296CD7B07FF040B1E08F02711E946B307A5A38487F53070985B8E28BE6CCE809F34100F0CA780996CD38E91BA7773BB632D0BE7978F3AF3A92B961BD3A8759590726D6C1811F9E0BCA87377334E7C1F12FE37401CA0200823938C816ED98981521470F7F2CCDD69D85E7530EBF39E3A592B1C09BC6C352C3FDB108FB26E7ACD3D5A4FC0442962E2C09651AC0D026E370F1EE1A8219C4833D70793D6E581FD25B0E95FAB1EDA67232C2FA12C4E379A6627E75AD408C1D2526005F2567CED8608E88CF53064FCDC58007198ADFA860F9FED1DF80EFACC768A0A063E1AFEE6DF1BE3483105B1C45EB50BF7863B4278422CEBA9001EA00299AC0415BF28A9C49CC2E92FC15565B547538A027886C6EB0D83B71138CE1A14BCBE4FA64052B0853EDE00CD41BF95B66DA2A519216FA1A0A8BA5F10B4EAFD8BE62C40DA2A76DFD8A5EE8EF42A8B808C55A533FC488A2B33A935A635E24F3E0C717E2320FF575ADDB18C567B1333DECB0855E069D5759C48FE6D8C6A9D217BFCB7A9D40735A3151382E3456CC4BEDF6C7EC94F186FCB6BF9398FEC934714E8E231402FC7BD5153981C7C789B26208DDD77E4796F70D6A72B7B9C5EC75E4E3CD122F72621E92B1AC515A33B12B1801B2C3E461AF788661815E6BAD2E6472116B89B941A0E68A232089C6F831229BE2EB0CD244BE4FED78C8371D2DC614445C76907F4A3EDF18722BF0998FD03209C31C348CC79A2AD06ABB1B3CC549E73B206A05345EC801A1C5C42D794BA1A35747493D76CA8567B62F0C2151923D8D9CD2F37D77E70EF7E12A80A3DC73CE284F2BAAE3816C351BAF037F5FBDF29A970BB385C19D6AC3BDECA5BE59F322A17FBAFF466E945FBB943BFE35854802837FEFEA3937069240712886742E890428C0C21BC057E82D5BB961095A5A18DE149CD19F79E9DC3CF0FEB5149F856C5A7BB82B6AFD4B5310993D9E4E1D33B4CC601265906186B98CAB4AF1570CFDC928C0A221A3BBFFE8E566D580A689AB51BB69826FA60135F60C1A1EA97CCCC9AE96CC93B66942370BCF910D916CBB7F87A0BF5EF46DFEBB050637754B0E40509441E19465B238EA45270D7BF5E0610A89B4A47AA821D9A3BA58127DDCEE4E7204C38E0EEDDFF72B07FA5AD8EB1FA89554D940C2C88EF588F62EA602BA30FA9ECF3462711612B3E1AC0CDC4C11C85ABB04AE5966743689380FD336A081B8C7F753B889BD73F10345B8C4988A7A4C865250E3707A8424B606059E3ACEA75F2F732058477097D5BF8F5A2DF82E4AF0EE9C4BB251A5657C15808B7EF26806E2F3D61137B44C9DF4196A9208065ED1C70F9DCE3C75AFD719F14D79818812360E4709E521E78B983F99B31863039069D3F86FFAAF318853EB4A1AFFC5E598ACB6B15198E016C779BB7D77C54971E4566C2071EDFC0D19B41827913C5F7EE5D8A9411AB2706F3C9DD8E2CF4AF497765A647C1AA42E3645485AD6598A776E2A46C9609C73AADC67A7477172D9F497556348B5CC055D8A6A0A752E5B9A508BCDC346BD1AD8643FA19EB36D922A018690D37D0E437857A78C47291B3530D6094FDEDB782E1C927C11235EE632F6C3FA150DE1BC1125FEB330079EDB0733B58F1CDD3D20904F85DE31C06FE375E7D1E20F4C79484C5431A026EF8F5C8AC47E7FEA2A80E17256ED956484E9004BD99AD8ECD0D1EE5790A83CF9A14827C3B5D5C25AA18255F5D512917BC1FA868AF35ED3540BF0C10CABB267F612C26AE27DEDB5665A4DE3913AA2631C034C1BD22E5A721194BE6D1E4337D1CF488E9F438BF7F77A856295E0D55A3AF7F55BEF0D7643D85B8892A69304AB1FECE1EA498B7DA996B2692EB8C3D1D8BC9BECCFECC8EC67EE3A87DF5B0B9C7C887DCB0CBA7F5E1372399F3A4F4CC7DF247752994CE0D024D2C6E620EDD0B8CD30891FAF58D6603D01C8308F95620A16B4B993AEC83DC9E71A16C2D22B89E7CF8290DB074AA6092A1F23DCD01D8B8C70674D55670C07A6D0655CF37D0516E6E1102865F0C53C5AF80A45B09B078337D61AFBD12DA2820AE45CC4B213C00576FF3D5FC21D0DB8D877757226F81078653EB4C90C0D2C7D304A6E0C4265DC3C1DB343202664008385964C6C56FA11532D7CF41E93F92EF28F3DE2CA1D5817AF2114A97BDA7F6504EBB2A6EE6BF4753274BE064D3CE467673717AD7350DE4E83A1BA27306F11DF36A2E30572E3FEF2EF6B2518419395DA9B7D4B191C88F3A863A477A2D226E5BCC04E39AAF1AA042A7B115CA26BE8DA52A162FDCEC6E511B1497FFB8B8AD23D3C429F71236DCAF9DE275D7B1D2DBE83822FF7D8C9BC7BA3AB5CB517228AFE2E30C53E64C44D02CF9CB51CE371827CDBDF798B1723B418EC7CDF66CF09F444A06DDB94355F529337D6A3178D754D68BE658934FEABD4F4874B11E739F0EE4E95D2D23B41F037B9668C9F74D2B3D31027861779FF8516A29246D766D2A61A02CD5B8E338B9630E8E0ED5BDACB017A6D3B89C8A1108E525BAD96E203E7A0C0B7F2148274FD20F9B53601F2B38DF303D7F8785D06260485D7507782E11855EA62F44C755E11DC4E5E06CA263A2E6D229726B08A66962C1AAFE0B85A896D3A21AB0E695CCF3818C69AE16DC71782D99440EC9AF4A9C33FFBC728C9C62C47E0D37CEA661064246A8B2BBA14ABF5767F33E490AEAD721929515F091663B4437BDC34F5B15C7816B7C5CC8035F4FDDB37C9A09712BA1A8E1FB4E0D8B37F0BEABA9D1ACFFBD90B13035960ABEF4E3CFF91B9871E49B16A6F0FF86445C441921D2E698117109D810C864F024F62F8D25C263CADA33916763373D76EC8955ED113F71C40834E79A1BD5E21CC2373598C66168492FFCD083D2A8E7E480F76274C048719AFF98C5E2774BB1039646BD25A240875655A77023B7F884F5852DCD9C5DA173DACEF7F01F6527CB7F5375FEC1FD2D5C90A46D3D0501715B2D4CF51166226D8F35DB7A9ABE320E88F04F460F239DC2C0B65987ADB734C1F9068B89F56E3ABB3B35C1EDBF72E5CE393330FF905F02DA9C591FAC66CBAF1FF1DABB3B199AC4A764EB5272AC230107F230E29845C2E2283763A5832809AF2428C304C07CB21A96D7B7CDADF857F54C91A22B8AE6E4EDC0DEE01FA60697269BB1299F9FD7D3699D4D865A25BF0F31F93DAE1D51C42FE755219BC2A4B2505487483A1B81BFA86BF6A99642C51AC3DC78D5E42FEA4ADCC51C0501A8FD543217134694262E0FF5957CE719766EB0CB34CA2E541992CC2619C65822A763FE6572E3B33C4C8C216B4A62A13BE7FE6FEA1DA8EC1D45CE65C4DFD09532FDAF74F99152DDBF0AAA53806F2C4EB3A156D49ED44C7713B7A50EEEBC575166A1B6CC3AEC2CA98398971F648242C35E8EAA21257BFAC587485D48AC54BC306344EDEBBF2A42B7E37B6086B1D9F54255742F000794155E7245F6CAE1088C20619158F78F7B9554B43C2872DC68AAB415F3065688612EC88D83577278C8A7B64334993F80BE7EDCBF5CEF5B00A2FC5B0CA04564DB35EE027BFB28DA1A7EEE4E72E366A22F6B50780F70355DA825FC2101BF7A057E5D26BF4216269A4C807F6B2055367D88910FBC65533CD0EDE915232B023D039AE21A53217DCF8398A5B70C3F2F1820F5CE459DFBFE7C3C9387F93D488D001F20B039229A704FF0193076F164C378E0AD63A1F11BD3332FAD6A4A6F39302C69607400E8A4B9D9EC1682E88656CF619DE7BA7384B1FD26850B80702BEE5893A4AB526F983AE3F8AD933B2D60CAF51BAAA828B87F55357DDC75A69F41F46493810EB69B9289F0954C9B9AA0A9C4B5B739BB75617C38ECBFE977BE182BE7EEBA3DE73A9F25E491756D4AE3BA047A9542BF62A8AEF9BA9025AAFECBA1F25590F71C9BBD708D6DB1AB7F44BC2473A4897D83DAEA510BADD3ECC8C9F2E4F889D5AB62334F4B56AA20F9BB57C09EBF41BADB20D36485AD613C790428C382B437866A681635BB509C97D4AA12387C320F6CEFD1838459F0DABA3DA54684B83E3ED10C07B8CE62549A876A13D86D8F3D001504D939500462E64C94B6EEAEDDB8856D13AB345659CB16C8B977B6670208B70920BA34E31E6A10EC724CC6FB3C299ABE890047E1F6B3D5A69BF731EFE803088FC8D3B9E69DF3102AABBEBE90C3EE20DD829BC1C46E6764AA8C8E2396E4FD1A65A171D9EEDB2B04843DD2845B5E5F5BB714212BBF4237C6D69B1D61531257FAFB41BCD74462C292880AA396FDB392A42C4AAD9B5492EE4F2A076CEA42927C22BF7CA54FCA135A0FF512CAFDA620DA75DF70C37EDADD455AB3C8EB0F334679EF94E6ED2E8BFACF20DECAC68B3AFF3979869B755D1BA8476CF0553AA3B5049EB57DF8F00AC5DAC2C1DEF316793E5DDAF9F352894CB9E2B7C860E4D2BD42D0053B2BC8C7F3C11FC0DAF6DECA58CA37526095779A89119240A8E28D1D44AE57D7D3252B69192353D745AE1C066DB60F6C6E82F35854FE73C1C961A0E178F047DE9EC62C589C2D7E30929DEA6CE37C4042F04615F48FC178E8CD389A2DEA13C83E2534271AE7DB54D7C89B8714666381C388D37BEC8102F8497D8A820C70C47254582C5C27D3D97A6ECE379315D5520BA346E8F5B5F7887F9E3E44FE4C156E7472EE8D9C327587A0704A8035E519B1C4A9D2E07949F7B23EC43C839B4B963BC694E34AD8F363615405D3297F051BA1B16CB53D4DB9D6E9AB3A0926402DD8095AAFB46217FC41A2E0D7C5960C1FC814E461B1F1F219CBD0A97D50180BB017229AC9F884896F357900724A3A7A8E4D479CF6A093FC30778F755C63CF618073C40F6042FB2143DECEE8DC32CE9D3E0064EE378F78B8F945A05629C118D60A6AB5DE2DA55A06B7325FCCEE42C01A5C408F0291E3610C44684BE1F66D3FB8F6BE43EDAD2EA87FAD50C993CC447DCAF79AB19DD406B20974363E31FB88FC21F83DD7C34DF85ADECFFF23FD036F17F0AA81FCF008CA4D024DAFD78B7F2D3B3C54AE60062DDCEEC2BF3A579A53E27A72402BED5DA1678158142C023B3C238A93F3D1CB8E48EF84C168E27E6645DC6DC6689E89CA0A74D07087B760743BB526662636725B7FB700BBC0B3A73793C291EBBBCD4970B27370C2E85E7BAC610B75AE5CFA9DD39290DA4DADF4F61BEFE0F87959174D2BC28BD76B780BF58A5656928CC6684D80B728FA0C1570B8268DFD57EC9168CF7D39997BC8458A5D4126FEB278B26769C4F55EE77EBCD778D00F836BFA6EB13307BA2D7417B0812FDA4CEEDA359BF73865982622728D7EA8BAE1620A63483DAC957E4F8E082588E12FFC57A2871119AED0B43DE4ED1EDC4AD6434A485C64D9FAFBFC7F01A8793E5649BF33A7186BDBDBA5DFEEBCC16F2CCB67E355774B8C32B932119DA7158A4D131F560491BB42B47C9EF1594FF6F09BF29E972502A7D62A2240FBBBE55C3D82050B374EB42E433CDBABC163A95A6492A7F7DA6824B5A20527C9D0933B97C753932ED9ED277E40CCB8C4A042FD5B88E9C5D569A48F512ABA1DE68C821BD20C1A995235727654ED6E59B063EBA5F4046E7D047B886A22A7D7C5BE009F3E14629FFB78F8555B7376AA2B7B4B360F0D3C295ABC2590CE1AA36943A46379C1085D66FFE0DCF3C37C89BBF1C7D76B6D62D5D2D265EAC52164E4799C52D9A7E67836B66532608870BCF43815BA0633B82CF8E92FDD0A4DF829039370202BBD93541D4D398C42900F96D70AB85AEE46D4AE2CDB5BC61B0E57DE8AF9BC4A366730CC4A8443203C374F1F58A2203BACAA6A0C93783B0BFD8E85A869ECA37AE0FA0349E9A943B50EA190BF7E28B4406FC4B14E77203739F8DF7D168EC43FE06D0645ADBFBC26542CD0335EE21852C8CAE8DBE734028D2F6BF457CB086172F176456A64E0186ABE46D179477CD209BDB5EE46DF3D36DBA69F5453C9AEB1E1DF4FAC40509461C2CEE814F7E26684AB01D51A1385EA51162E9CE43172A1564809B328A45AA68BC14BF38692467DE23B8908FB07BA05C90DD44A372477233DEEC84BF89287B1F8E1FED4F275FAD98265AA76F0D798266081567140ADAF2A9C64F41E053D1F329EF62E543C4E18C1587F6203711CFA12253211CE4521AE01F2273FBA71CFB03F8A842A1FF048CFCF92A8D77409DE43CA455C5ED59F89358559BE214EE1B531915180697A948C945A9924FD6864D9CFF00E1D47F38B54092E4CFF1F92A65CCABF206A7D71F25A66969E37EA7D52EFD74B80E93CD7A048F71EDDE1EAF82A24F20145528EC96BF1857E0F1D8F19812EAB34E07D4262D195D1BB4D20FF3E226C2468B90E951C8212023248340ED5B7E4EDF3C6AF6A6FEE63F8DE613EC6F1526E3F6A9327A17C2279BEF50B6CCF1569A86FA56DC4B8866C365DC5D16B9BA888234D6860885B2A420401C0E3F8A971BE2CCF46FB27EB58D6C8EDE207B703FB7EBFEAC77465237E1EE73B675C37F656EBABF91BA91A79FC679C5566A637F6417B8981C93D4B2B08DD6DD375D4C84791CE66913FD4E3D6B01287F258E8EB01A223CD222F81B1412BAD3DF60D89E29F4FCED352A1DC0D52A296D6D8145BB66BCC936BAC362F309AE4520552C369E4BBE918F20C4AEDF8F037EC9AE0A3BE8BA1BA0CBD40949CEB55F41C8728AA639789BD51539F1AFA46F71106F428C9FC659F34F6BAA879DADCECAAFA80505AC2E0ECBBDBA3679A483BC7B92A54BDEAADFA7F386BA0AA79EB4AB02F6134488DF1220F8FA56D2C14630DA6F79094DFEE7180D218C621A32C153D6E5AA82C318BCBEC16FD901CB860793B8B3E9E357D0F008EA80BADACA56795A369F5E6F910F706986E7F66A84B100C265BB5339972BBDF6B770B694B8D2DD8323E86A90E83EE039AE031A331E6D7B99E75FDE0E8E42AF855F52C925F1DE1A2B10D241ECAD1523291D88D5D0EFE1D5CA4DE89F22AB2605BB5AF0CC6564C2F0EF9A0EB57779C157657D9A1BCCF0DE21B60DCA9EA29FB5D6D36C7973FE0D8FB8CFFB812B2C3080BF0F0DDCD99BF9832A3161F14FEB8863777E8EE65B8F88B2262991CEA2227E360DE1F384A9E4C722302C42F9ED9CE1ECB1225BC3180B4CA27552F940E6D3AC102CB0EDF13951506103BF790CA9923937C7AD9661B13617CADDD3F1D81944A87AEC9AC06202EC18EF736DC325C55E21D33A313DACEF549619B2CE208EEF551E81A9AE87029B4302D012853622BB3BCD47FBB055E048923FF9ACD043DD40211F720396E02E71DB06FCE4E8D757DC264B4F5AC3089FE49361710B3FEBAE56D82E67A6C29504D6B061DB48FFCD3AB91E7B6B870AF8042312735EA06532FA075BA5DCCF6C9E92AF59BAD50EF0A3797C335F50FC43DF22481EC203C13BEEEB42DC753BE45EC74C10D40CFB3D55B68602D288855C63FCE824A2F4A0FEBBCAAE5A19E133CA77B6C4AFE98FA12CFEB1A87D38463C35DE33D5B7D2E08C3DAED2A32A25502AA2B4E2F2A330F06294E202466F0701D4B361C71DB74253ECA3148CC5E1119591830C19DE38FEF1A5F9302B766F68E4E6616611EA940522EE92E6625C8783357799CB4B9F6A56A84976EDB84939B94A676D4657DBD04F7D754A901CEE47AFF04327CF6E0193DD3EF8CD61ECAB28CE8CDE2A56ED422C47BBD5E4B1C005EFD6C982E1601461DFE8EFF46797FCA8B79156473C7A964515B4A0B4373513F5DE44B5088663F1B9D235681C2A0F31675B7BD215F95D42216FC76E5C93A2C8929163064A58FCAB39F6A8700820BBC9EB62588C0377C15BD74E5B7E4F11559E54EAA502404D245774A51F17A9CA804C570941434AE4464CA23D8CB2D042633395BB951DF71EFCE0FEB7AA66CB0EBC83321C73AAB08C45F89D8DD625753795B7BDABB1CC042A4EA7BEEBA6AD585ABE6849B63C9630142B7191742C772BEDBDA162F8B4101824D6F16D189D65446852A08B37F359617ED6B0F2DC1A5648983AFC78D3D4009BFBB088F85D85B551DFCB0C99B46C65130CF3A25EEA02FAD2159409FEA41A7F3BF71F020CE618D82E4A2D5DD005E1E8839EF6B43D864647D89502AC44A7517F0D0E9E06BF9F55BE677F11F7A4689D51E5DC4892181C32AB56A831AD8E8691C9DC7C8D59FB0098C7581BF682298C353CAE2242C7BDE5F5933B48E88624CFC605A87E401D4B01FCE73BCC86D9FDDE138A185AB4B79B2394FC0718A30D5B8FAB24C2A67DF7C57690E380B21B9BD08674E49328286D6CD82FD782FF7BABEE169FCEF38BD5DC8ED8ACB324A374F426B0D835A5A947627DD5D026DACB3669212EAE997EFA073A3800694A8470BA89780C06F034BD1ACA26229A7C13345B4514B3C48A810C8A017062BA454688349B3244A3022F86EBD132636D566A899C38D183C149E8C9EE50F7F254409A4FA45ABB9B74750B0FFE552845BD460BDB3FFBF6259FA6D048B59198B4FD2B135A9DD870881D24109F95CB1B0857B395683A40C358ADFBED50D70A8FA540F6006D2493B59AE4BEECC8BE3E70396BF298B2F49B468B64DDAF12FD0C594DC243A782FB8862B2B73BF1F59FF1B812DCE96AD72D73D928EDD5D6D384CF214C7EBBE25676FE612556461D465BD1D1C8AE96BD8F349371553AD9E9B80623B49D5C8C38489415ACE7DB17DEA495DB1CE9B68AE228CDA2CED81BA796890764881DCF4C9907BF8477F939F43C8AA173CD3044023C8C898A4A7D16063A2F7FB6F6C00EBEBADE4B5A79A9814803CDA526D542E0C4C44DAFAE06659E810969F48EAB6EB002F7938B62157E85E1BF258D2B81ABD9195EB828938D84BCD92C9793BDA17DCD6ECB92068BEA49626C4595EE621E192309156F9B0127FA44454075F7C73A94992400B22CAB60A056EED2E04045E74494017E601F044245A2B64B83EA8BFEF2A02A32029224D3C9F5DAE64E4A3298688C1E4205FD9038743CEF33B08CD9366560AB57EEE937008332B6A4224476A759B07D04DEB016DDB8EDF3665BA71053A894F98DBEBA95EFEE3F46AFB944601CC71C39315012B024E672E7CEBA843F35C6F435983AAB0F14BDB63B2D130A91AF9F72CDFD73EA39DC02AD3074F0E4B3780E81732B550B298998169B1640D80FD56474FF655A233E3ED6C48E5D94A4C6D31ECBB5257DC07F29D5A4C98177DE0A4DE1BE24D2CA3CEF4DD2A3FFBD818E75023732E1F1D3F9051AF6E8047081FE588E2492E5EB4273A8BC3E031CA33BC4DE4FE367B0BBE3530C88C0DDD7F55A358F933819140A786527AEFC7A872908B98E8356286485E2ADA68D8733129C32FE7E0D0B7AB63E890DE8AEC5DB2D52F88D328E1DB56FF586DC2026817A277844C18228D01C4A792C6D27D72D4E36AC852098685807B31A411B62DF550CE9C5080F1BA5CEB1634B8EE7CBBDA91DA660CECF740A502064AF7781F544A2A9F6527CB431A33A905262210B977C09374F03C360642BB200F00F13EFCAB19685DBAAAD7EFBD4D42A8B428342F44A61D9D58808B9E7620ACE2D4FA47D16FA98950485E67EA182414D9C7B78C51CAA4960A79B1BEF4B6BB5CBA79515042433C7505B5038C4DD0CC8805CB9C1AA93B2BF96402909E229C46A5C2C7CB18F0B7747642714BF204D42A8AF263AA6C8F1DED9414FD0E6586D7B680D4BF1CB6CB6DD90D63511150A76C2C40384A4F156E827A22D0D207611E84477254E492397A85643BE2EFA36371F9DF6119813B2CA7F31D099B0715927919FFABE384400D3AA0869AF2E95B525D9A1453679B1624C4F2718AF080BE493D1DF583843CB08C5FAC4587627805AF278A009530F8545958E7C04ECD445240A70C6D0450DE5A3F3CBE710E610D8EEEA17F97381119B8A53A62EF7F4B0D8F84BDC86BCA2245664DA120E7E36945038F7973099B1ED88113E6594EC0CBE05B5CF5ECEFD58D48FFE4C16E0F941FCFFFDE6D3E584584EC8A03AEDB6126EF5F479E4FE8C97BA01A4980F78D12717DF17BC4E9040B105B2D74DB5A8DE17226344C0D3769F1DF6B6B9C494783121EB3F42B8686D7FEF027D7566DC65863A7E07D0D8774305019C67D504E7FC4DF77A8821AECBFB762EF377DFDE75F24A9DEF9CA7997E8F4AF3B4E60071F11DBA6303A964B7F9C3FD443C766346B4B1E50EA1D79357CA76ACE991F4760184016A12C2368F7D4E6BAF0C8EFCF4A869F3973B41564F52D762BECBC7FA49B40D6FCA22052287E1B10DD8FA257423F984FF4CA38BD49F322C84CA37874056055B3A0C51060360F05BE3E1DA6E1829B2AD90DA73CF2B0FFF812ED813AFE0934EFADC2CB387678B5A2D6C0E640388F3171151E6F5442468D000FA46F17DC7437B058242696056ACAAC06AF22742452798DA226D91074DEFCAC6C3D770DC54CF7ECE9ADFEDB3B421ABCD9DF305D412A71FC77801FAEA989C03A0D633C4B06766491F4C0DC67FF8DEB16AFC8BC7E3D41601BF7B964B91A8638DDB7CC08B68691D5D501B5D3D72915442F0D1B9EA4DE4AC96C6E10238113B17AE11147C1BF46D1D0E16BF333B1A12BA3D2C34F69CE34186FADFEEB02418D227AB09DD8F5B50664B97BC1ECB70C28C79FDC3B16FCE85D63D1A59107BB62594C2FD67438D6448FDC8005FB3BD2BE1E7CBBB35FC5F1E6B1284641E1B520AFC98F158BFEE2D20A6B03541AB11A19B0D02D9F628C4A00C25A03457C2A17D3B1E11A8AAFB4BC26ECFB423BEAE0F68EE89AB2C7FEDEA2FCAC00A3928351163E04D8BA817C168A0CE68CAA6FA744E7E30A2670B2BB88F27810C887E48E90EFAD40F9735B5767F60EC515C146D56EA534C970E04BDD10302D85A2317C478BD195FC93499C051F5AF61A6C5CECB89A1D67BF5BE2CA7EFBDCC20B884597EB2BB0799DB9B86E2EB8FD93389AB91A391F2D68A057FDE361AC97A87F4406F40A7EE2E7709E46DCD756617DCB0DBBF43E6BD4851F3D834BB53CB150D2FB7B84F8D037672EA110B3F93C3AC7EDCC5B5211DCC6BF4685C2D711AF156B82961C5369170E2E76ACF126B3036492BA13A920E126E7CA29791835CFCE00B3EF7AE43ABA16123C386FC3AA80F7F55F094F1664D67FCB5B990A1B93AC8D9FD02595A6005B8CE100F00F9818D7C2313416A65FC916B102A019EB2C7DE91A346F6E3CBF7CD85D2E8FEBC968AE7CF4E6A64400C45C7F71CC17BDFCD337C726028AD4F1956D8AF94345E2FF8F1C9E57AEA206DEEC8A93010DE204CF6F3D9CDE952FB8E4955EE2708B8B19C5788865CACE48EAEAB016AEFCF9FCE16621401B9B14F01BAD76AB32105CFD3C5A3EC7E7CEDD9A64C0B2AF82072F95D2762333ADC34CCAD8B93DE773FDED0AF8569A4ED1032A10D522056894A78C45B0C1FADC66A29CBBA8AF0600B416497EA782E66C42A4B1B518B7DA3DFA17E2EC7BF70208F1911CADADF3173E26A9285466819AFA7E43CDA3E79C3379ADB9F88A8C460AECDEBCFED326E15F01E303A0BB62615B2A2CB097B045DEF6AB46F799A70EA5F4C54B215A0BA6BC2BDFE5846A65D620BCEBD2607DBFC74BCEFC9712B8AAE5BC6C179B2971829F9EA1EF896FE1F6EED7D4A3B6D04A0B96848599BBD3A5A4AE6431AF6921A26726EA8B5651B74CD5C5723D8610CCC9E9220532D22E4BEB538A7E7EA50B7FE7D21E4F7EDA1A6E232C8DA603BD8A40DD5A9E87778D5EE4E2711C229E5F66F7C19CC263A38A184B437846BA2945CFCED1C270FFCB2C9C03D8EBE37F9E2199FD4084E94A02F74C3C2E3D577470B3F3F4B0B7CDA7671722B1E900A49096AF21F74E327D4B9204FC3D7E3AD6DE2A5037A2FED9BDB1100870156824C3E2B736F55E200F84EF5C0B6D39FF0A929F20749413DB40418EA6A764BBAEA67EF31C107F7F23A1193BCD26297EA37CA92CF90973BCC7BC548C62EF44BD5FBAE7CA281C5447895061540CEC586CBAB07CC6835253C332BE03CD64CAF6CFBA2C5768AAEE682614AEDAE4CA6BF839963D13970AB2D37BBD203FC8F5197A62C183B76BCBA09E5E47D686ED98A652A176A90284D0034391003C5BF6E9C6A091108A3107E128BF3465BBB72CD50C374A343C714E7AE5599915411D31CCEDC7ACA1734B5F23783839CD46D0786814D52037477FFD7600129FE5AD39C8601C30088977D58C83B2D0B5B6AC14579F5C52BE795726F126ADBD2742BE107CEF59ACC94B78DC7A51AB01B4A3B212F10768D35C3CA5CE6D4EFC33995ACD07AFDA29782EB4D86447F622B2592F7D18E835D5F922FC7FCFCA5F12251B5A3DFAD7ED2B6C9F3C6B734F34991C30C700EE325CD9752D68D4DB9B5DD98F91348C1DFF570DD106D0CB457C4108580FB341BD44DA99F4AD058B064AE955B584627DCA083785EBC199607782B5B096DDCF3A0EC0C5F4FB69DD11814016F8AFC30F853DCF0B793E150C3B796CDE2B1B43B3E346E257331504D6571E35C7E2953D0B1EDBC4B1C48F21012DBDC773107FF4B459FCD253425217787310AE7D8F74F77E60A4511B8B23A6A1714BDDCEA8694F2A8508991C555D6C1DE281244E229377BB4FDB9CBB38AE483A3569F735AC438C492DFE9414F26D70F154CE91D99105D5E34340D34764482934F3F3145436CD3AA2DDCCEBA06D0439C960E7D16BB68113560CABB3611F2CBC43D79915CFF16CF0BB72EDFD858830AF8C790F7F1C18409C4C48601F24454BC986B12540B74EBE53F5F3AAED84C8DD523702B0492BC34B98F2AF02C856882F37D1234C04B42060DFDA8FE106CF570235BF1169F163501B400DB5A48D7FF08851543CA92A0E8448F98BE619F41F4C820CD5553B0132BDA47AE8C0A85874D1FF5D23AE2158B85206E9F95CBD6DE6F2092A31D700E8E86ED0009F9780B1D349E01944FD5FC58A95CCC7502C6B1385AB36D24C663C8316F2F453E88A98EA61D721FBD4B018F43B84DD5B5C83316488AF78ABBD005C15399B7F94F6AB6F5239B10CF44B82FA774ECCBB5CB932A51B1C5202F112198FF20A160DA0DD130510C4540AF4C9ECB078C38AFE183911E2116F130DAA83432E3B05F76DAFA8C9285CB7237B57407F2C4999D4ACBAA916D2887D2ABD50590B5F761D3995A3D484A632696156ED00346555A19AD569E80F2DC6FEF929F3AB753AC9F451D991D1F9C614CB562F9AD1B984E94BF00204B8E0411D9AD0D374A9752B6989CB7AD969B047E60F5D371FE4FC3D17B4DDE42878C758FF19EE3FA205FFA1E5A3ED709AF71DF3527F26F712462C0AB5815A447EF29BD1887D7CB8FF44C2752A9E1BC890A80A5444E8384BED9EFCD06F26C467FAFBB01B97EA07CE0B5091605780D9770A00252C92C4DEDD4D8B942E14C90DFC5BD612D85CE24C5CEFDB3EA964FFF256B20A4DC2C0EFD50DA4BAB56BC846B09DE27F341EE42EAF0545CD82BF62FC699298C98D9B9947D436D234DF8333E144C207D0DE124707A1A3262CBDF544C5C6FE70F2137EDF11BC8A3E2E7B6C35909DAC8C160CCBF3FF25275B7F97E5E0D56349A1AB617E944BBADEFDBBA8BD06B26468C961756F0E1506F5D2C5C332CB7D18155B3964343C682A5721C97BD5F6D675D44FBB9B5C9AE58A02BB327AD51C927CED9F3E27C8DCFA2EA7F4F20867DE29279B5DA09E70B6B6ED9C2C21502D185DAAE79A792F5D79C8814375643B4E69440EB7AED63285EE40ADB2A43111BB8E45D109B955B309FBDA17862D551F72C2EB06BABCFE4BCF46468789347AEA8FD0CF3E2938521DADC71D0EEE1F435B38023B69022FDF00B3D1AA0A456DCB917056F934240BD6C899E8E0D36E4F1C8135F74FFB493B7591BF9C2DD47E2C2B64A5CB0D34A0DDF8486DC9CDCF85E8D5FB8327A486076AC1AFB63681A253CC57B65DB36619DBDA966569822860B30D9DD55BE869766BB1986D254A1C486E6990EB6CC4D22E829230CC0B5CD80B6E0C3E4465CBF7AC3480BF67E671B31E38F24800A61B0C98589FC4D98BC896C27D4A9F8EAD8CA7D567AF1796A82C64F3A9876B921B4F9F009EC821DAC29B54AF75F0F5F59BA04AE753A786D0FDA22144E3C9C3413B4497ABA623AFE3257572D979FD7234C04292B8EC507187752446AD11D10DE925035D368AF83D202AF6979123C7F3B7FCB8D83812728A890B5C09B482529FFC0737FB59C35B552AD7C5820E27332D2E44F2A31ED972E2E5C834FCC652204BB401557D6FEC656BD9F63B9226056E2D025988ED1312A2A767D418F1342BE489B463AA4BE823D471648D9893364758DACBAA63BED8B3D8D4DE1E4A768B07A9912E72515AC62BACB31DC0EBECCAA1360330949EAD48841D91C61B13E2EA79C1891C9290FEE2F779EA4EC57692960A91913AE591D6550BC59CFCC5EA68483E4066EBBF11C2D9647E7B5ECE7845996AAF856A1BC1458EA7C88E73B1C19FCE34B68DC2BB0EB2CEFD4506D674C92A2BE87429BC026542F6F8F48CB088F945D76C07477009F8F9D2B41552CD688E00D2A977C67003989D0A2FA7688B410C6C30A1036FC1AE46A86DA837812C7FD4539985A05346319FD809739255705BB1BBE7791F520D43F33F06493E50423C6418BF781834310AD40B92E396722B1C67EC08FB5FA918351C89574D5A47D31D7F6D25A30712BF53AE5410B587B9CDC0D652F993ABCADD6442E5F52229C5011D36980BB01D0053433DC64E02F535EB87F04F2FDFAD3A4378477E4A0BE652FC73E3604285CC0721796206461EC07608C4A8C0C913924525EC5DCF185891F1740E56E4E88E3C957D028D5BEBC5DC6AA9CFD3B6A94CA9B281DEB7FD816C7DD27AE5FECACB499A764C58CEF0EA4A18999B80D89D2074754894613FF9A019639CB6E1A31B91F6389894454B884F1F76BF3A20984E908C60BF36D3CCF439D9B200C3C97E076A75B5209C363FB23DF3FE4A8A792CC9FD93527667603AE461FCE62593DD7DAF62D1D78060E4AB4DC2424BCA29A0C96ED4978987C8D4F2791F61AFFD6300415F0E4DE0764AA88C672EBB55D765FD9382875CF67B176C8BC422F613D22605BFC24C2D69DA0E7CB76AF9378DD04C21E76BD30E9F923D724F6F3633928EAE801001F869B7BCCF9EF79B6FF8E8A741EFF812B31E140A7C798D8738D272068FE9A5468EA0CF60D339DD3D56A73D3BADF14504FF3FC2816A0BB816806B5CEE3164998712B9460C4227117261169E1B4C20AD79049980017BB1CACAE8EDFE29252C782485A5BAF0599796BB5004FBB2101CF98470B60E8140B828E7DDF8D3B561AA5A147739DC01970DEBFF008D85ACED07EA28D10E594E60A3569C6A13D9619FC2F76D279143D829383549772E09F3E275840913B08E0FD33C24CD38760D585FBAD94FF3B0355D247B1A5D8F22E67E34803F1D454D979BD9576F36F816005BE186FB6D58BDC8FA63935D7E4CB00A0F6752E1121241A67095E77A3231034C7D14649276638DFB1DBAF56AE7BBF54C64B817E10B6EB7E974208B16C658FBF3480BA6C86F5BDCFFD2F830801C95F5D9677EA593BA221A9E7D2F09E1E19FF70AA4A73E2FCB455583F3E21618A50CAA4B53EAF90F0AD1A47BB59B77EA66DE84A10E6D5FCB7A9CA221BA0DC44452E7074206ADE1C1B02E520B6D481C27D4CD833EE7D985B20FA5BF7A21E4DFCAD092628EC0A6E2DC8718EDA1408151C9F4C1FF4046A444CD0F8F10C82BF697013DA572E3EC04726E89BC96ED083C2387EF5DC80AC9D74144D0AD906BDCD4608974D57F515101973291804C5180C348EFD6C91AAF5433A6BFACACD657BB7C579A195C6EFEDBEF3E6746FAACF6AED5975115AF77843A5497EBBF4F254D13D82321B29A6EE275AD3389B828D1FA19FFFFE79123A579B45B78D3F0A5AF0EF44A19F07513426CBFFA519F93A4A4DB52628A2FD56DD3A323382E5DB171811EA861E2D46537D0A4E545C65F2310C2A4EFFE0851C1260C26F2ECB491BD2EFCC41F06EABF26B48E9E61FC3C550F6CCAB762B0FAB75DFF6353F814E55E98A3AAD5C82CF9A891AAAC5112D38C6687E30610AC3379222517D90CDF1AB77E96B16E4EBCA8B0E8719205FF3D308550E3BA58A9CCE5FC6BF05A4DBECFECEBF1F4B7722C6AAC9FBEC2EED1C90466147C022C4B2150D6DE9B76BE278F43197479C5D0CCBBF0CBEB22C31308982105A95A5841AA37DA3BF81F8F7602C9E68C059A36BD0DD395EBDE7616091E3753AA1397A0251EC887FB27A166DCA318DA3EDFF3E29320AFABB616813DC83D4641F3664407C3DABDACA9F5EC3FF32B6538624C2F10415019168777C2BF58D51E619C872F1FBCDC8363C69AF421E6B6C046B8EACB1233A634F492189D114FC3B17B3A6FAC0CB04BE2FB6CED8D3DBF570B66D7EA390C11D2FFE35A8F675CCA65026CD83809D8C60480A25536A9DFBAE0D1229F2D563FBA86229F6B7F7CE9A9C12E6CF024402A8DF251BD5F72EC415621FCE91148DB266EE1BDA0885827E96E8A9AD9C50F43D9B6462E6A24D508013457E7D4E3D7030DEE74216B3EB93C676CDB9F5E6754A10A635950D60C9916D00565C50A33EA1BBFEBF02BB60483B6DEDF0481C054710FDEA23BE9FAF9DBFF407E7766C84CCC3F281C6383079DC3188FBE8F9675D0A26831FE4090EE8C8E87DC459B1CE8480E64B78A5F15EB30FF165CC9F5F261B42E5EBF469A2319A405E8CBADD241C475A5AC949BF372A41B060353FA3EB8C79B969874223CC14B6E5B3EEFE72C0CB8C8E1B114AB6B7A435B786D8A8FCC935C8BAA5BAC879B50D8180B65FD0DE78CA05D750591F479FB953FD55BB00F1D50EB99AFE348B00A63DE9E79B12C5C32F257C97CA0CF00153C8C3D8AF3988200052059CF3C841296651EC607D910D661EAA1078FA7EEB6738A8484224A29CD0463649275D117997768C75660D469691278A111D50A72CEE9600124E3850507C0B963E9121C8BE1B269448FE8A4DF87DC1EED33FA1EAB13DCADDFD7F2BB0FFB042FDC6EA8C00A6379B640CA2855112F86F6FA5B2A622079AEA2EFB9D9063AC89D7F94AE3CD7551F3FF99B5A3C41D3770C44E9555969B97D719A3C5590B3D8A1F65995AB57BE3FA7D55524CCFFF8018EE1A587AAB9FB5D3E33FE7BAF2642CF9421540C134F9BDE97680458FFE5A18DD2D3CBF178E91629F050DBA86E31E5A42548E1582E271B399A6DC512CA068153BE53E78A5A6F83C8C39FA6F92626B000E8066A1BEAF2C21975B2FC29959C3AA239CDD2A4B47A55E0EC54495769A9293F33F23FE19A886DE5AAB35F3BC80C9CDD0FAD599DB6359B84F396E9DD06848EC5844B44AE00478C8C1FD5E964031EE21158F6FA1784A07A09E6173412180C5A0354B11480F780C1E3CC436BCF5D3FC2B5E094C1A45AE192369966B103D700B955D0FDC49733525BE13D82164C5A2996F0FF900DC890ADDE848305ED6D225460FB75CDC1453C513EDAB63E576CE7CDFA755055AC07036627843E640E20767EC35B45C69A28151210BC3F93EBB880C6419D545316029814C22D2872E8B0B4B4ADED8E44D0035CF687BAF0C593C2B947CEC9770E19E28B62537B3C463F582084CDAD9A704D8E4CCE851DD4FF586D6CC300F09F878FF5FDD7E7BFD0AC3AA2AEC0C223DE23D190C6F67AFF7C00001F7DE39C907235BF8D5EC16A34AD2D2E6DDC419F5B24EACE1A17BEF5CC52AAA05F04D5AA8BB018210354282E98DABB918100165E7D962A6F396F22753B1FB928AE3576A91CE62216E9E6214ABFF91FCA2E6E77611AD13F70CC87E67A1E6D886120CD2C2404E0312A57635D1C2524C97EC0BDD9DE011D158F8FCA7AD1A23B38A0E6201B3A52E5BD893BEF169D6E665829DCC297E9BF3DDE2974EF56B848D62499354AC81D756C3CEA6F0E5EED1E0E58EA69F3843B09E11F3BBF8898F1724E4BE566D1AC9AB166CA7D5CDC3BAC80652CC469E048BEDFF5444254926930835827E5FAF2CB16AF0E0CB13A3653AE4EE9C49D838F84D3464EC035DC31E025F30A12EA7630A6A630A351E06620774E7CD342027BB9AABFE167CBBA7D526F0767 remain = 1152921504606846974 -max = 1152921504606846975 \ No newline at end of file +max = 1152921504606846975 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-2_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-2_256.rsp index bbf9b3b078..8693856dba 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-2_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-2_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHAKE_20/2_256 - pk = 00000011CC3CD3FEFBB5188AE538CEAFC0E64816F394C351FE22AA134A3EC20A6A25FB5004562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 00000011000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94ACC3CD3FEFBB5188AE538CEAFC0E64816F394C351FE22AA134A3EC20A6A25FB5004562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D933090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000018F224E19E61C8A7076585BF7780AD32D73D04D66A52F0B4CB6D35D9496906BFB05000000000001C0F7248E24BEA5635FD0F3F3411F1A20316CD29E2BDE6DCCBDEF8AFD463CADB306000000000001BFE2E0B4F4BD9B2B955C3CE73D4D0E703C44BE5168224D99756D865D86689E1607000000000001EB5D1F16948BBDEB3335E0F93C3DAC5C3FF7DCB33B16BB28D3826194192729F80800000000000194BC268989E8C957203F60EFD29089692A7FA0980912BCCB1FF3D6921B9805610900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB931516966BA24D9585F1C0B04D660E629B3A2A3F31AEB6AC3EE8DF4DB67DABB5C332B61CC10887A0A207201703DFC4C27B774468F2CD9C6EFC711426E248C33EF946923D4C1AFA7B608F9F080410AE8F9F08CB38D5C0F6664EA0F630D34DFC55462334F617F3E4AE640E6C2D27597D4967E08EDC91704B9E3EE49EC4F0506994C3DD1027F8BE7FC46589CC21F9BEAF4F4130BC7D8325FD638235372E12CBB84FC424BAFF7D301855839698FE2E38B63BE461E681B43A02F99E466319E808084BDEFF59DC9DA0BC5F523A21D4525D81501A83F357BAB3633C061D403C7ADD90CBF38C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A36918612009A7CF4A981971AB37B767BC120AA994494DA75CABF22D1FE63F1464E981A0FF2BA93D3AAF2CEEADAFCB80FB7D012A588D4E409051A44F7287EB74B23A7F9A4302D2E7EA81F9FFD74D72807123DC3529B24DA2AF50619784A32B75985FE5AF8191B1CCF65322E266C37555CC3A971BF53E46DFDBC336CE5DAB6A84AC0F17F219C1DB9BD42A4F9662C74AF602347DE8A4EF176A34EAA287C9615F90FC02ABB78D80A6327768932976729CC4BC564E870C58EE9889C877CE31BA913EA7E454C0868D80335CC063C57D0BC1FB3C5E09B3A20F8166F8BDC41B01A8EEB62127C5BF88686BB8D0350F7BE6B56E0CE6E66B0998140C6F839A1AB13D68EF718809E2973CBB24BF5D927E83DD6C16C292D94B6EFE4A1BC9E050E8D6992BFD1C6F906C0A7B81474293A86ED095FD785C5BBA70F51BA7D49E9A5FFCE8193DD10914F642178026F159AE536FC1FABC7B78A3C2DF55D0C8E1EF23883C6FDBC053B447825E75F945D8157A967B58B0574C6E0615387CE1652DC027B72C45A8E9A4287219D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF71E8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B1A8277D00D5F8C835AB2820DFCFC4C8AFB2CB247B6DACFCDFB3765002D7D6EBA358848E7C7C63DA066252A81CC95E38A556ACD239ACB010A8169696B347EE86AE99CC7386155ECC56277B39192742ED8C959F142209943A017FBCE130FBDC3A491E7F650C98DAA0497D6C9CCABFD02921ABE4CFF254FB1521C702FB19F3DBBA1B691F7E44003C618C1B0C1B68A840B9763D43295E0CB779A59EEF7ED63AA1020069B2EF88BBCAB1D03693FE34C4C497F7936878D4DAB7B75BFF0FD8A0509D9A3B0CF209C9B7D09732CA0914617778AD289AC2110692D502C8DC75316530280FC926A62D46620A91EB4C89377C47ACC72884CAE39545022290B0D0EFA74045E4FFE5B7950E421091808852738371BAF20E81ADEE43642303C0F979B8EDAF4B47ADFB135B60A3E4F0BD2340A03D9F774ED36135C7C7241A89B2E9C71979E6BAA1E4D272BEA996623E399F2DA2AAAF6D0CE10191BA0853C08743DF8F9C98575E4F398BC3F19CFCBDB00B6C71E6B2B86A0E3BB72811DA873A3A318F6F334B64992648C9DA43BE0DB9CBA43FB1191DB64EA575DB1FA7F5E345ED532AEFC9F878894723ACC25CFEA3765FD8B4445453AB184E6C5A33FE8C136C8B401ED890A840BCC8C13CE2560D86119D74B6258D4381A4813572B6AEE5DB91BFA38F1E36EFF3DE17E255F8302A3A8161AD44F095659EEBB8E99100B7A19BCB8842ED58C474D1FFC28FD87A032D583050C09C64D4AE5F937743FC5E4705D9EADC758DF2CE55F240A40267311278E9198452030917F0ADB64226D6D413BCCB02C9A5C830AE5F2DBF73BCD8161132CCF43553B8FBA8E5283C953AEE50DDCE4EB59D29E4A2E5DA0530B922286F3588848CAFE9182175706266C466D65F41C3C18B000789C74952E3E2FEE44CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D58C6E04B24FDA2C3239210393254B41DA390EE357C7C175EA1DFD32FE5AADE666337542E508FAD05AA818E37539322BE1320FB587B83E86AA18434C47CA39E9850984F7339BD164FD46557BE86FB71B18CCAB5C34449AA65150D6F47A8117453D706F30DEDEB127BBA56F23193113CCBEB626F61BC4EA2D5053B489414A7F9731010D4333E72690C936D00367C343DA301A455B4CA7DCFC4215B0EE5185F1DFEAD2F09542D42C8CC1BA6ACFA452C6237454C5D115C0F5E04479131F9F1ACCA098EF0ACDFEF6FA39E4AEE14B0823E911EF2DAE145E261AE05A117E5A52E9DEDAC73742F90B4EAA8AA944F14679B0F72AADF6B56B31F3A2AA0AFA243C3DCCF6FFD2799FFA1F9861A5C04B0A8F68CC1BC8C90703AB05FBE50C15F06B04570370DEBB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832121C0C078E6BA4A80F1A20BD16BA90FCD04D43A0927C164582A796C12545CBD0BE45745F9E0090A47F31AB9B11E1496EED876912B13A841C06B6A5E812B11EC912A83D6B8663FBA403442AB4C70D3CCB76BE6686CD55D831E8DCCD05594F47FD58A835E3132D95EF4B4E8EBC275280999BF68305531A7F9F5EF2E8ED77C42227D0ED07B337CEB70317037ADA07819791A04BBF73646CC89806912EB3E2BABA0C80C7EB7BBAB7CE68583B609A5152A39457D51EE0A3CB4E897EB6363CB767057ADD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C63F474F26E2917A9A1B025C28BAC7D53E4E150E981E0D5BA4129911F99588369CD97444E871D47141AA795560B9576AF7870E3F62BC6F010869F6CA393E48A0BF5BE7ED218D65D942EC0F815F2258A47F7A509B6BB999C17B28D46B7D3CA59061D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C09FB9C3782471D5185D98077B9CD560F0F2D8109B8F2DFA711892BAF0A4A828E506417EECDAD332975E49F3E9019CE173E2ED3985D7C241AB4F7AE082E8EF49FD @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 4963 sm = 0000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6429AAFF05B285E06B6EDBBA11503F92E15E17C582FDE9CCF8FB0E5BDB90FCABD06FA41D595338274EF14442E5C967BA01C008D19237429ED719B99E0BA91D580C514F5DB69A428FCE3592C4928A1461E736B86804529D3AB6535C3DEB873B45873A5037153C910492CB49EACC2B24931700DDB0962B1AE245FEFB4345D58F90F62CA12C27CA2E25F5C1799AFC3C56C20D8763361A7AA8757AE5C1A90FA05D6625430682E22AC918051D97466B12D2FC559413DEFAAFC677C8351565ACC58D481ECE4C96410219AA2370A23C6E92E5322E0CD81840622A3C20D7243711074E19131246F16CC261A56C9F1903B0B4498B849B4598E5F8C73A6A1521F7D75628427099DB406303D3634EBA7F9EF84D42F8B59753B8C55B71DBC82E06F6D674B979C1F2E6BEAA7180B7DD54525F52523DE6F98A205A6866C5B7489000B5CE17FF49A645C1A7763F5BA271F9023A89DBFF7189CDFDDA48F112B14E7907795A7C92AA678727144332A7276950BC3A0548E270CBD4FC31004AF248BEA3BF61558946A2D26131D7D51C3221D6C24A9EA4C05827290AA1A66C9011153C120FC8F974620A2988266C9B2D49652CB8CDEC30866F81F41B8F6EB6C6F5DDAE07C5E405A42EC21383BEFDB77CEF1664E01F11EBA2513A4C3EC82362321C163730079A59933D9CB173C93ADEC1E111F387845B826C3523FC184B5F1D1D830191C88D1F9F3C3A81309BA06825E1A32451CA92D7B58785E22C755B2083EEEEBEB7071E62A3AC45C09151E1961C11F7D8CCCE4F08E9BADDA88E17BF2DB02A6D1E1D2827021DB4659211453388E6A2E01080743D9A836F20FC93663C7E4591849A616ACE98011E52BFDDA1D6A0C82EF62F0B0A9F1FBC427D200F636E66DE934401583B67DB03BB8492A8952B7DC0473151EC0D9571297FA6AB0793D3EBB4AD559E0E367DE90BD20B96ED7AD6F608976654F01E1DF2A5B7B7A54D448714D6E1BE40CC6C76564A8CFB5ED8D0859AC3B6541B286B5794C4B2AE7B4BB4C91ECF560E085C6626C9388E031F5CE2B09BCACBD1E67B946FA5CB736B2A641A0C5E8D152EBD752F4CA60C49827FD6EDAF3A6A71C48FA89786E1A76FE326B90AF058B1627040851A517242451CFC3194FD5C959E05BCA2B9B93B4A8EC90C078AD381B57075B5B4C83F0C17A67F8DF5901B4968C46EAA98D824B6A9FB2CA5E583E3AF6718C42B47420838BDFA070DD8350D320C2439D92BA252BC89405731261FFC9F2B5EF3AAC944770321193DA5EB16924C3108FDEDF07D7940CA3C8E46A5E76F5A358E7927976D16BF55B9E54965F8CC13A89E775AB6123C3A1D8301FBA857F30B65D1961FCCDF1C0A1E5410920E84B4C8BFE12E3B1B84721F6CFDB26FD8D39AB82756BC29725DE0B632F556C167705588C5D03A64E33DB87F0432B67C1AB69143592EAB3A832AD7375AE3397DDE149ED361E30C807C308875164B475E46CC14E278D7C129F0D909E2C06D5CDA851D6534AE73B220CA73A13917887367D055D38A65273890D1FB7A3AD50A7BEC306BEC9F246D6025499B69389AADF76741B4665031E74E1C836028D815ECFFEC3E974476860D49A2BA734DC223B46D2C25797CC55E16A37D56B5021A9413F7F651B894ED06E313F1B4BBA00F7D5DF43AB472D66CFE6CE3B96B4F37F3D7535603510353CFCE64882BE681C9C8046A403EC89BF47A3A4561226B84815C3661606210EC8AD191BF0B1D8C6D027A7C176BCE1CA7CBBA0C336D80411D9A61A5E4D093F5C27F1B5233F2C78E908DC396F097744D841C8BF1BD732255BC62E601A9E50DA36D18AFC8DAB6866EA201DB358B45AA0CDCA0959B4F0BF7ADDCDB0CF61ECC7FB075EFB21E937AD32E4FF503475CE0374E064460B5A0B4F955395D59C474CD9BD3250C92F063C641BE91C5D3820B9D2C39466B24BAFBF05001BBC0BC63E00D7EAB41CDBCDFFF1216F45CE0741C53B57059C2F55F8D2529C6B0E760FA3BB04A38130B3326F0BC0E59869282E6E6870A1435DE8D83D9174F2314B6D007A6FCF177661AAB80D756D36813FA06D86075306817D37856F1F60BC2DD52342AAAA26CA611EAB00BBEC675FF7EBC347B2B3078CFC8E827E04A3AAA3E5A2F06DE077D32C6D51A6AFBD1EF6E49CE8FD350DE872090DE73F0C124AE014920F104EC5BC7EA0FC49DBFDB3EB4E0FFC5AE893D46E0A98343B1C7D25EC74B9EF16BF54D211C3928852873CD0EA39D3A2527B72BF325B02D5A8AD1B50320FD2513D89D1A164F5F8E770B329BEDA67EC4F75441467D2D45A3F4BCD6051BC851CBFCCF7F1644C8462127BB68067FFC32F23B443864EC5104D7AD3A1B68FC59FF2C9775D4A9C1D0F25F084AB49FC4849D497AAEC8FA2A8C8DB244001F4348AE47425932E61A64C79846C4DD33F99680081AC5F25B0B3FD815ADC0DCF5AB104931F58860E77B4C620A8E18A68B3F068CA77CA14D60E815745802DBAA1E6650A2D337A8B8FC33217467F61AB87909D9D5B21508BBD0D5D3876F754FE9285CA3208CA501606F0EB6B7FA6720D9809A6799A6E7B2DDB84AC602BF3CF936E171E16F5B4EE3BB6F1F8D70A121E129ABDA16B2871303DA6FCEBED15C3340C072584C7F306AE44D7037C8EE5ED6935D675F308939045FB0522E5560262A425BA5D23AB0A7E3A26DD7930E88CC025293E48E8B72BFCD134B8C3613753A9AEA514B79BEB1828D08E928B94EFC93952D401D4FC5E97CD40B375D0F6302502B3BB83098A6BFA378373FB0042E15783729329225E1BCB7F680B66729BEAAB9C5AC5A2120C8D427E349F364F595BC1D72866A1A60777897D0636344B4A3A6D4B891BC5E066A422AD6CB0514D1E9D708885573A7CB1C938876CA58C9DEE64B7EDCB6BACA85C9E20AFAD6B68054B862DDFCEB991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EA1E51FDD737CB5103920F8B27DDFC3FBF47480793A68EBB780A1BAC9141D609EE1B40AFF393D6177502756D15DB5232BCD58ABDB633EFEA7390FF8BEA443BFB32F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD5894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB931516966BA24D9585F1C0B04D660E629B3A2A3F31AEB6AC3EE8DF4DB67DABB5C332B61CC10887A0A207201703DFC4C27B774468F2CD9C6EFC711426E248C33EF946923D4C1AFA7B608F9F080410AE8F9F08CB38D5C0F6664EA0F630D34DFC55462334F617F3E4AE640E6C2D27597D4967E08EDC91704B9E3EE49EC4F0506994C3DD1027F8BE7FC46589CC21F9BEAF4F4130BC7D8325FD638235372E12CBB84FC424BAFF7D301855839698FE2E38B63BE461E681B43A02F99E466319E808084BDEFF59DC9DA0BC5F523A21D4525D81501A83F357BAB3633C061D403C7ADD90CBF38C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A36918612009A7CF4A981971AB37B767BC120AA994494DA75CABF22D1FE63F1464E981A0FF2BA93D3AAF2CEEADAFCB80FB7D012A588D4E409051A44F7287EB74B23A7F9A4302D2E7EA81F9FFD74D72807123DC3529B24DA2AF50619784A32B75985FE5AF8191B1CCF65322E266C37555CC3A971BF53E46DFDBC336CE5DAB6A84AC0F17F219C1DB9BD42A4F9662C74AF602347DE8A4EF176A34EAA287C9615F90FC02ABB78D80A6327768932976729CC4BC564E870C58EE9889C877CE31BA913EA7E454C0868D80335CC063C57D0BC1FB3C5E09B3A20F8166F8BDC41B01A8EEB62127C5BF88686BB8D0350F7BE6B56E0CE6E66B0998140C6F839A1AB13D68EF718809E2973CBB24BF5D927E83DD6C16C292D94B6EFE4A1BC9E050E8D6992BFD1C6F906C0A7B81474293A86ED095FD785C5BBA70F51BA7D49E9A5FFCE8193DD10914F642178026F159AE536FC1FABC7B78A3C2DF55D0C8E1EF23883C6FDBC053B447825E75F945D8157A967B58B0574C6E0615387CE1652DC027B72C45A8E9A4287219D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF71E8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B1A8277D00D5F8C835AB2820DFCFC4C8AFB2CB247B6DACFCDFB3765002D7D6EBA358848E7C7C63DA066252A81CC95E38A556ACD239ACB010A8169696B347EE86AE99CC7386155ECC56277B39192742ED8C959F142209943A017FBCE130FBDC3A491E7F650C98DAA0497D6C9CCABFD02921ABE4CFF254FB1521C702FB19F3DBBA1B691F7E44003C618C1B0C1B68A840B9763D43295E0CB779A59EEF7ED63AA1020069B2EF88BBCAB1D03693FE34C4C497F7936878D4DAB7B75BFF0FD8A0509D9A3B0CF209C9B7D09732CA0914617778AD289AC2110692D502C8DC75316530280FC926A62D46620A91EB4C89377C47ACC72884CAE39545022290B0D0EFA74045E4FFE5B7950E421091808852738371BAF20E81ADEE43642303C0F979B8EDAF4B47ADFB135B60A3E4F0BD2340A03D9F774ED36135C7C7241A89B2E9C71979E6BAA1E4D272BEA996623E399F2DA2AAAF6D0CE10191BA0853C08743DF8F9C98575E4F398BC3F19CFCBDB00B6C71E6B2B86A0E3BB72811DA873A3A318F6F334B64992648C9DA43BE0DB9CBA43FB1191DB64EA575DB1FA7F5E345ED532AEFC9F878894723ACC25CFEA3765FD8B4445453AB184E6C5A33FE8C136C8B401ED890A840BCC8C13CE2560D86119D74B6258D4381A4813572B6AEE5DB91BFA38F1E36EFF3DE17E255F8302A3A8161AD44F095659EEBB8E99100B7A19BCB8842ED58C474D1FFC28FD87A032D583050C09C64D4AE5F937743FC5E4705D9EADC758DF2CE55F240A40267311278E9198452030917F0ADB64226D6D413BCCB02C9A5C830AE5F2DBF73BCD8161132CCF43553B8FBA8E5283C953AEE50DDCE4EB59D29E4A2E5DA0530B922286F3588848CAFE9182175706266C466D65F41C3C18B000789C74952E3E2FEE44CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D58C6E04B24FDA2C3239210393254B41DA390EE357C7C175EA1DFD32FE5AADE666337542E508FAD05AA818E37539322BE1320FB587B83E86AA18434C47CA39E9850984F7339BD164FD46557BE86FB71B18CCAB5C34449AA65150D6F47A8117453D706F30DEDEB127BBA56F23193113CCBEB626F61BC4EA2D5053B489414A7F9731010D4333E72690C936D00367C343DA301A455B4CA7DCFC4215B0EE5185F1DFEAD2F09542D42C8CC1BA6ACFA452C6237454C5D115C0F5E04479131F9F1ACCA098EF0ACDFEF6FA39E4AEE14B0823E911EF2DAE145E261AE05A117E5A52E9DEDAC73742F90B4EAA8AA944F14679B0F72AADF6B56B31F3A2AA0AFA243C3DCCF6FFD2799FFA1F9861A5C04B0A8F68CC1BC8C90703AB05FBE50C15F06B04570370DEBB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832121C0C078E6BA4A80F1A20BD16BA90FCD04D43A0927C164582A796C12545CBD0BE45745F9E0090A47F31AB9B11E1496EED876912B13A841C06B6A5E812B11EC912A83D6B8663FBA403442AB4C70D3CCB76BE6686CD55D831E8DCCD05594F47FD58A835E3132D95EF4B4E8EBC275280999BF68305531A7F9F5EF2E8ED77C42227D0ED07B337CEB70317037ADA07819791A04BBF73646CC89806912EB3E2BABA0C80C7EB7BBAB7CE68583B609A5152A39457D51EE0A3CB4E897EB6363CB767057ADD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C63F474F26E2917A9A1B025C28BAC7D53E4E150E981E0D5BA4129911F99588369CD97444E871D47141AA795560B9576AF7870E3F62BC6F010869F6CA393E48A0BF5BE7ED218D65D942EC0F815F2258A47F7A509B6BB999C17B28D46B7D3CA59061D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C09FB9C3782471D5185D98077B9CD560F0F2D8109B8F2DFA711892BAF0A4A828E506417EECDAD332975E49F3E9019CE173E2ED3985D7C241AB4F7AE082E8EF49FD22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A remain = 1048574 -max = 1048575 \ No newline at end of file +max = 1048575 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-4_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-4_256.rsp index 7a37a6015f..07fb5d5c3f 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-4_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_20-4_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHAKE_20/4_256 - pk = 0000001253040139BB0C869F0B49F12B2ACB6B6E78731BF48B976D5668CF38EA836868E404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 00000012000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A53040139BB0C869F0B49F12B2ACB6B6E78731BF48B976D5668CF38EA836868E404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001521B6795E3B31C6F469147CDE5776D1FAF80EE268B570DD87C1895E195F358E50100000000000135050ED1EAD3E799B63D5EDC01FDE9B7E3E8036A429C0AB56C909CC2B6378D6F020000000000010D93E097DE2D5330AA792D234007668B3E7F9E699621D298D2AB7577E8518A0703000000000001F2616B47D5F8376AF6A5FC658A75A52D032F7A1710630905C152957F41FA24010400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE5900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011420B60C54314ED8291B4F251FF32674EE6A3C3609140380F6B20865B7AE643401000000000001DA6EC89DAF2B01E86C06ABE8043C9A6EA0562A18C49B4A9497D347FAF8EB910002000000000001A0A42481338E08706BAC35F7B5F5D93432D40144F47A0F6790DF4B68525ED740030000000000014A9507DA8B4941DFD3D5E9A02EA050B97F9887A65D93FD8723FDC30C7E2AA4E0040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB939E6518A5122E37D4C257B0A0FD60CE0BA3BD55C9CBF369DD315A3C0609933D25DA403DF7E69FEB7EEE64DC3C13DC83217C2834B42876862CD48E99E69564B336506B85FDB493CF8FA87A7FE48DFE6778DDE8E8DD066FAA745C121480B5BF9D5F301B358D18FCCCBD24069E71836981F168FC49E6A4F27B00F6259B183B62CEAE0BF4AC0F53FCEBEB9052C0B48EB0666F361C5DA674B20B06AE2EA8783C2DD7EA74D98AC98C55748A368DF5B433C39538365EAE8DAE5E032A2008768FEB01F65D001AAC437781F742F536EFE2B3AE59EA12A6DC7F2712BA2D9D1C253D29B419A765985ACDB42BCCE5D64F6AF8368A5D122BB16B525A80C8BC5355A53917CC82262254378CFFDF1C7D6355F114E4FC013A5E4DD9AB373A0EFDC470854E20330BC00960ECBE882098D6D0D429A7AD19D3E5D4B78AC5E568C722A21877DA617190CB43123FB04333FAE5846953E33407080D04DF1417E740E7E7A14B0E3CA7D5B693F9615E1F7D417B9004F28D5002325B851C31F5EB31E1DAA80E6CFF22F11221E5180BB050888B6564A381E54401AF9409FE12A818B69BA34E1916092A0EBA24457EF994A1B0028649C9803045EC93CF416373F6A568856B771C3BB076AC265045ACE8E9BE3C3074D8806BEAA3B8B21F7E37F50B16221E14FE5503C615A13738CCDE39E2395E292119959CF686532CC3C9F9129E62ECFB43A091B06FD48ABE8C2CBE2D9691C8907881991CAB9D0D9CC7B2699F2261E5D799D26A7C8A4AEC40789B34CF5FE7BC8D24D6F0BBA7A5870E37F4D9B2605BB56ED9BAEB780CC74097DD8AA8741A97E22EC7B7434F81DE9D83CB9816A33C5A79D718C76A3442FE50C68FE1CE7AF728F2177F88E5168D4668518897AB050B57FF42AAC731E484B440D0D7B254383C74BE41C2AAEC02A8D8C7020355C4A1FAFAF4BBF56C74D78949D087259FE8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B179B32F9F94BBD8371B973B19E60C3CE2206A2061C7BCF159BC3A50163924774BB13C708A573472DA73B4C78DB30FEF310EA3643BC75D9155762D5B87809E2A727AC0428B746801D693074ED5245F29B8FF9FB782F2E57BDD89DD700EDBF12E8311946CAD9BCC98E3B1D581E678BEB1D0A6EFE15CF4052A1AECD328B2C4A8D5DDEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA36145D1653D108813E42654CB5350FFDB33BD2FDF4E416C6C0A61784E2327F42B2DA2AF040822C291D63645B0AC2377D0DE3FDBD99FF9CD9AAAE2B978C4DBEA95E330E90EAB0C4C34E88855C7C62C40B231AA1A9EB409D18CAA1C612A98F1B7BC25B18E3A89CAF96AA4BDF12F865EE7DB20273D7CA11970219BE997DD0EDE7A8ADFECFF1D90984694EF152346402207BD7D9166DC1B09F3C3520D109824442B8AB08869B0A4850BE3227E746998925CECCB422C4C05047D890E291B4E5478967A42BEEE34BA2765D86D183C71FB6A3CD86EAF457756FC000FAFDB24AF3C968E547A5223821BABF91B31B3F970D9F7C1FBFD16CC63D14243DB22CDBC266BFA4DE4B15D23B17D34C674649A695E80F84F6FEBAC0255BB155BD8B8D46FF7AFC532117E26985D99B0E23345F9A0247D834697804C6644501CA7D2726DA563C7F02371B5CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438DC67DF57A5B11025EDDC8915C57C8C72F6D6E71978496E206201184593506E39582DD2C803CE9204D2AC833C35BC683E0BD3CAD30BBCBF584AD38DAD30C9A400DE22F0CD6199FA6C622941E79F8C5C500389E9FBDEB8E1C926443B6FB0313DA9AABB163F5319C0164C1E58864827E38C18B7ECF6FB44274CCCB84B10F1A1BD76C8740F479777BDD7C557DBEFA9415B7FD50CA659E304EF4FA22680980D0FCEFC75E36231F740F38E9B4AC55BD8307F8AD9FE45B046B7BFF0F1B9FD5EEB82D474DC311A8418BB27CFE324426CD3311D65513B0A4D58515B94B8EE5ACC6815D6D1246527188E7B6C579CE42B28E1F273887FAFAA96D44FE6830E96081ED562FF4A08416DE4213A89CD666E2814FA290A5B1FA5AD6DB86B9E4DA85486E11BB36382C13607F50EDC83909F47A7D089CFEAF4680A6F2F10A2D9D9A679AE82D2DB387C5B7BCA11161E49E01C28D0FB7FEFE1C9A4BEDE994DEA4087F3B74906EA8E49153ABA49BE0F35C0572E9CE0C68B2267884C4BC4AD32BF28CE64DC7C825BDB2D8561C69161E075F48A40220159BFF1C4158187D4DE23C85979304DD4DBB98BAA57DBE6B7C55C271B134D61906F6ADBA4639BCAD3C1A70DA04A9409A4A35FEF1BC103D4F17BAFEC37C3F108B31327E0FB227E0E2C5B5410726ECC93B56D4D153572C2DB4EB4757F5B2232C475EB9802FEFB53EAC7BE6A090AAE98027AE13D2B338442FE6EF2DCF141C4D1AF00C7B3E973467FADDF6F1950ACF2BE908FED354EDFB147D6AC4B0740F87DE06E768293CC83AC995760FE0015CAC682036CCABA9C86B9B06924369E35688F7255F5D5422AB808D023B150D62D9A7DE4F7A5D28689EB038E9EF9D3366C3D777AB6D1C33878327018CC51EEDE65BB5FEEFDB1442B9006C76B10B6CE9EE1B6E43306DBB0D9030E3A191DA24634A80063F6A5269E77543525E11BCF02DF82E5921E3225EC97FC5F9174E0225E8C5D08B4C093EA28A19D03E908426578661E107E5E2C5371D79C31F11468112A6050703BB8FD9ACDEEF8D0BC31E82FB4F7DD0DFE8AE0216582E6C86FCBC1E7B3FFDD921F220702D827F145D79D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CE8D216DC6F19C3AC0A1017837C31D76ACDBD48F018A1CB14E98848B66A59F09AE557964888EBFCAD45C491A2A3C44B7085FCA7C983EA4AA22F62B99109F6E425CDFF5D87105EDC065810CA3E055F62FB80F5CAFEC57F7CB47A95B14A215714FB345FC73E57C1574E38657755CE991FCEEDC5ED84824E0E4AFD43205E126A3402910DCE16C59C8840FC7FC5ED9FE6379F9A388601D57B366FCF44FBD2D0C15A3D8A4A28D71ADE5965C137996748EFC7FB68ED165D2480FE34EF58A3169D03D0395D94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB08391412A812DBBE4FF09E10661B7DD604481AE6EB2F89A1FC04E393B3353F7547AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6222D7DC2F78B2E3FC4C8CEAE02E3FC9D7972CA803061F534D39E4F02809C7A18A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F9536829157F62BB003C2E45042DBEBA9622508F9AACA5FE89F665A5F35BA7C26D93A84F9DC744354C73885BC59EFB657317594D34B561FC2A789C919EE08D5D68185BFB2A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E1866ED93157270FB47C81CC3076E5B381E6B03127E7AE78C54F5F35B2474F18A2461297462FFAE651BDBF3D438E30420A3BA5686483DA2EACD874CC44102C09319C10FFE87AB2099A185DFD0FDDB6393B2F61490D65F93CE565C6575C877246044FD52ED475831AFE194BB163D0FE5A023BBC435497C3C16C8C7A85FF92426B59E588978E29EC0DAD032330035B797471B74BE366FA75D79D35228004D3231654D5F301D6597B83258DBE9284121A2BB21EF66F40C17FF135201D18092FA6A72B511A456786ECE1FCFC986A28C744DD4DEBCB552C638043B0602343CC796834B13660A86C5E3CCAAA1845C5165074AEFBA7C52190845A95DC59B1E8D6B052D253EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D1B478E24D9EDAC7EC8816FA54DFDAB0F181E9E1A8A6CD77A9EC29B3E35544898EAA311411BA22E8BA6418CF252675917A88572E0CE98CE03457996BA4FD86D07C4FA2D3487400E484F4CE0A83CF490C49588DB83ED1EE2A93B78101144586427FF43F434D3A40268920A4FA3C64C0F5F4600A8E52E01CD8210965C4B212DCC942C68D589D21FEF433904C26239698EA85C32423EF7AE1ADC90744996C956FD5D0683674010173EE4A110DA2642C8E1C4BF7B5DD3DE268A3AD0A261A30AFB6AD7D54210702C635C3E707CB1F17053D475A026EF57852DEC1FDA4252FDA2E69BA95C866BD432139CA8A4E367960F85B2FBC75420737CA4843B89F053192BB086BDC0D739B2753DBE42E1D45877097F3B97FCA6F43AC15DF883C3B42D9F472F910DE579301FF7F57D9857890651B64B6C1E8A7E2227ACAC7154D97252EACF8BC5FF430E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD637170756688D9AD3002B3148ACF0009CB1C0802EB04197FBD2FCE168B5FACDD052DD46F9F0B0A34295557CF741102E7592C24FA56DEDA63ECB7A2149E406C0943E5E554767D166EBC95FAF0E9B20C1E530633CF8BD7AB2A66CB105E108C1793B0D87ABBBBA9A4679A05C94BE6A698F4758B8BD38C51371C8043FC79E749D7E41C04DC6D815B0D32A779D0AC6E80C1D56B03C8EF30F6F6CB73A089B149F46BD4671D7C13B41A5B1BCAD94C0552C12CF23352200198CD876615EDDA7257E3CC94B732D75AF6D67A67929458E2639BA4A2967D05F76C4EAED429AC246CAB410B0FC8806B84EBFE1159C88D6E71EDDCC3B956F33739AD9FF6C43168B54FD592D845A54307AD16E42AAD4621D33A037D47D1002DE1AE0BCF2ADD9B01895EB0E63742FCBB5CFDA14EC9C63D94E3387E0FC22FB1B93D9065DF33D03AFA7D156BA719EB9DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF1DF5023719932492A5EE2B7A3B40B7C7F6814D179AEEFA584D317D536645921799727CED4C3D658D5A425D2D3EB1359C975FBE1A2FB2D11F37098B7234A19628624F07698EC3658799436DB5CCE6AC18702D4F27548F61BABC4807826E95D23889575EE119A88256D4326D4BBB48D0F589C6CB22E7F95D49F6607BE258753A6120CEFBC2E6C502138AEA689B4EDA13FDC39CC0759F392860168C2BA881FF70632D05E797A4F52453418035DFE9D072F0593E8029FFC25D75FC7DE13309B0AE4509D8A315C31F0FD0F480B598ADDB0D5A8F945FE6C28C2421DDB4A0DEB478478A49D5E628799ADC5E489FBDBC9DD38686EA7943969A5AC97497B2C380CAD367A8DF3DADD2E31F759AFA47A422D2A5F7C44CCB028AEC63EAA0727231A8BB4FAC096D19BA50AEC9522A00DDBEB86ED6DEB298AB433CDB7B4F15EA4AE08EB01782B70CD59C57D485848B16B9C55BCCECC876AA99071A9A7599868A9BB42F178BF3DD0FBB7EB52A796801D67E250148584C46F3E96898AA264BCC3826317B5BF7DFF55B6F3C3F3929FB552D79FFC1D014C52965F50B446DFC1CFB3302D8C7367A6F64C93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B787B24028E369C59743659E28980F3776146D88956F5E02B3E3116B8292C2E578C8708D4B518B95E8FCB7C7D5C3B16EF976B20FD0E53DCD6D92301061F2588F693A84052F8C776D033ED7A5EC71E928DD7CC7EED8DFC585AA94D8C9CF92D9694377C0268A53536DB64565FD9F5652B0A3634B381121BDA48C2D1FD9E189991D092178D79AEE8333BB0EC988417AD6CD9DD0DCBF6EFDB0E4E8D1B38E2A3DD01B3EAAD55E1CCB1291C87E2A835E86D2E0C0C3642166D2E9BC98CF354E28B6CD3F121606F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174BE4D5805F128D4A9B00266CB6CC792C45CA4E506C8B2504D13AC93044BF3FB332A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B275680E933FB83760E66AB8BBCD67108A95111001B9F8E85B6C96B4BBF952517D6330EB1C6AB68317C91468E90237214C46A5F496EE46E2E8069D65797581C01BA0B2DD1DFEE0F95C0AD7E426F877D0CD294CB0F3ECD1C65659D20594153630E46E4A32CA7D3B408B33227123C6449C4644192BAE44916FE60256703EAB9B2821973C8A37F2FC6B3B18FFE0E4C8036583B7E63E60A5EA8FE89401C8633BDC355FDDAD733A74922E73333FF9B2F9EAE2ABF957105197D92E7CAA56F91767E282E0910608FFA0E651B882398F8187E5203F8B56F788A4DE4130D211BAEDBE44B1DE0D729B926D5FBC98A1FA9EF01E415BE3795F085E28E1B32F86B0EC72DB22414EACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E947CA8092F4480FEC3CE1D8A6D8C4CBE3F7EB35919888B729C1CADAA559A42E1BBDA600C713EBB3487FAF3CCCC40CAFDEAE9B9C6EF40D5041B83973133A03156CE65E33173CC6EC41F0061D31797BF2D58C95B5B4E218AA783E09AAD39682072C6EAE7C52E3491E8B0345D3F6DD019D7DA6D9AE08FE40461B81D414B8D5BBE0672D892793121DDB345A2E5B1F8F3EECFFFEE5E425834717D59506DAC94BB9F31F00AC84767700A6FFBB6D93D4A9FC6F02C67F2710269A4162C284E0D9BF486ACFDB55A33CE915B41F167D533B268F96CE0C70A54377A5A76B1C8E992BD4908F6C9AE1B8A1129A6A94F2C1FA3EACE58297AB6E83568F0857FEBA399FAECFAC9FA94217BAD28BE66B04EF4EF7862DBFC7F9D86A69D63D84665C826910849A959626B2F95B16FBFAB29A97876BC2F43A43F841F6161648AA9D1689D67A4BEE2C859702320B726B0219DCC859A330C6C337AF2EFB0B9C8C689D2A7B92DC615BEF81F9488AC5E678E63D3E9C4CD4D2138F500D7967745773C58A8704107771E6AC93AA2307D387AF3CCF853E572E74624A7E40305FF4F57266A6BFBEEC78BC8CC981479D5A80F351588B5E378EC89F193C02A92E5BAB45E1C12BE0DBCAA00E85E73FF666690C4133023ACCD88989AD44530D63D54B090E115F6A25111B4F006B0EDBC73FFCA5B037240E88F9F4FDFF79F6874B6D6865B3B93037E272D66F1BB1EA9AD7952CE8F8F353C2910FBFC6F73626986970C6B1FA3F7D010A7DF2AD27ED28F727F9B6E10E08E9F23278C2C6ACA482528DFDD42021B690D777444DED9C912B2CD003DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D5023540D6CD04777ECAF4F4D58C64C158042656BCA7DFBBA61D7551154DC1535618FB3576C6A634E79E80BC56D4A77A32480711DCF387CC963BBC7A339C907928DBA6545BFEA6878A58236DC95D439F8F3061C099AEF80CB7128E0C1D3AC5841B65C0A738A16BA2EF4649CB510F512A819CD03BE1174182022DDBA30AE32DB5AB9ED29B2FCAF259886A4E479D5B5C118DFFA5529CF83978DBDC1B233C410279CC031E0EFD98F95DF6A32C1FB854F7DA54F12E0D0078F9287622542E551863DCB0B534DCA8EDE06545D0860957FF3A0C13495A47A669355FFF55DAC93C3357E5FC17274ACFCF9905705D6F32C7C6E6FCAE6086384B4939C70128CC73540E47ADC633EF01CD9E59A14EDC10AB0A9313ADC2123A4F3F3B4207CC9564D39F7CE86184505C432B568E4CCAEAA1BB93EFE4C696CA690F4B4EAC21A83E1860C5F26C6ACEE315F139E8C7543B2075D3FBF446058A1F0E0DC7893D9C78FB25914ACECE4664F58E03209D0EE1FCA892A9002B32FE67B0CD27E60F35706FC2BCE8A0F77E89FDD67DCAF4073DE5B72BFB56A87525875B0E27042175EAC158AB2D5A7B85C041FC13F81A9E78911686B33488DB258E31630B4D779F6F40E079F5094D31D70E74F2220ACCE407CB3491B80DCA95CF6126E9D2E955683F0B6BBA28885065E50309BD5E3429C626D547A87ED33769F9BFBB514F8792EB90F90C956F0148B9928189EE06BB40CE18932DB44AD96E226B6BB6A313DDC8CE4FB50C6C548BFA794FDD1EE7EAEA2F119CAA2E0DC7664B0136EE7F50B88FA4F4B1F0A665F36C56AAECC77D637637ABD7EE25BFC8B638430370B0F92FADBFE5C4F166A0B1FFDFDABA98EB3E5D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3C1578D7F6DFBFF09D46817D7C61EFDDFEC6AEB1A21EBD5AF1A0F399A2096C8E30821DCFD15298AB26911D40A97E78421AC35B6E8B47C483E1538E1C110540E6B23095AFAF8CCC9883C1BA2810AFDBC488849BF8E2BD2B63AA036BCE1BF9E6FE84C7C830C65CB9870A441512C55557F371276F3CA97910118271DC35F5A46454B02318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3FBF9F7DDEBC0995B90104C717FA2977F9559887204B56298813EAEFCE587F9D2DF49378B38F71833410D667351B1949CF406F18B0727666AA94DE7EA90B093CEEABA95EEE4D2DB043CFD3504F59CF36374C48E804535A76BB8BF67DFB39E03CE613D53D7515BBC8DF04062A185B7825FD3260B1B377B5D3CF470603B1900FC978329FE4F050A62A0440FA26E9B3D2CDA32E7F9FCFE6446B29FEC3639F068E56D446765B606D7B4FDA46826E8BB9E3FE9ADD93EBF3848B70C759922B63ADAFC8E71CA051A07FCDA3126BC8B4EAE41DB2031017A6794C6784FD8B93672BE6206ECC5F1396078719C45CEB31BDE4A3D503A56CD1BA60A875E2A5AC7CF340A79F261480A2A36EE4FE88106DD0976B8FD47010119D6D21982AF0E8E58AEF1BA68D4BF979DE633E719AAFC7A6C8AC6D127BDABFC3660711DAA2962D639D46747BC03BB269789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411923F9FC45FE90EEA617A4971AB81153088F58B488C507F5C230586CF967833C9A0DEA1CAD7FC139A9710382C46136E4F4007BBD729ACF06FBFEDFF5144533FBFE @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 9251 sm = 0000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6FE5428C1B38A2155B8EF1FB9DE8440D993A1F197229DF83843A1615CACF924D4F7C034A07E8D99E7F548B998DBE686E6F146747163419D911CDF36891B5CE67FCE30A4EE54EC1D1BDA34E8F5BE6FC86445C4E732ED6A2F3717BCFDBF1EC5952AC6DFFEB95D5F828ACA606136DCA17F08C38DE5AEBF9CAC54646BF3B7809882E94D6C58C88F8FD5C2C018CB53B7BBDA343D9B0F76F9057BA0C56DE12931A55620810B03806BA5E0F9C9F764CF3EFC1772C1624A7C8D63A6295339488C2FDD9CBC4069AC1646996731948816530C43C82CC1346A5614222B29B4C635AAA4542F11023B3A0B4EE1A22D367CD4E000A7067C2C7DD162FA09E777CA9DFD3B331ED20810EEBCCE92C9FE28855527751A9567241135557CD840556FD141538AD228677F0EEBBE54BB463D23A3C7E6E71E1CC6DF3104CCEFC7124BE31C854ABF06071BBAFC55C8986FBEA375F95A3E2EEA5595322FC1079823D49731A6713DD270B3AD1DBBA724670050F31569813630709AB6A4E35D66684AB154CF647FD64DA3B2E5533BA26B80AF62D1328351A6E0045A82BFCEB153B0F6B8FD5AE3B2056006C5EAA15E87B7916E5FDE15BB2E41FF1A75C926AC7E64C93FE1451CD75F3AEDD49B1132383BEFDB77CEF1664E01F11EBA2513A4C3EC82362321C163730079A59933D9CB63937ABDAFC11529A49EA5BC69A0EE1C86D3E5FA6367170D2D5D45A4BF164D4DE3B8F7196A03D3E74AB3BDE2DE84D00D112D489E6133A0FCAE2ACC8DC59062CB45E8ACEEF3FACEC55B716E1D4FA8B926D7A96200B00AABB668752FDB0A7ADBC136279390A03AAA2D41CE2F40EA4005F1EA2A87D61354A932E70E8677BC0D6E67DA1D6A0C82EF62F0B0A9F1FBC427D200F636E66DE934401583B67DB03BB8492A8952B7DC0473151EC0D9571297FA6AB0793D3EBB4AD559E0E367DE90BD20B96E53891BCA1195D4B5CD305ACB28479FB1BE4550E16F85D9285EF98B1F325D755FB51E1749ABCEB67C4DBF13794C49CBA8259AECF2C8843C57521BA6AEE603516ACFF629B995D28350AB8417C87F07E31C622EDD406BAAFE489FB5443F93C9583EB8C510AE49205FB361487B47B63F0EE9CBBC9BF3983A75A1080CBC7FDCC58AD8490221F8F42CBE5DD49461942A233D7D9A4F4F121C14C1A48F90F4F39D6A32E8ED8C312FF9C43E4C1198E0B3EC0044EF37FF9A9EDAA4F4CCECD98E910022A8793A61C5997051349524161204FDCA085DB451FB0C3E67FCADE5E78EC0A356B2BDCA48B903DA92B5D86FA1C5E8DA5C12CD2C030F11A8F670E028AC1E3925B5D70EA2F7D8C162BA7F7F4601025685E59E261826B1D9E9A9AC5B4AA1DD947CDAE896AADECCE2E41880CD5D368ECA94F5AB91D24AE62880ED25ACBEE0AB61E9DE6E3CC31FCAB40497A4F5FE4F15BBFB53599D08806AC825A4E67B5B6352F1DD87241B5728E4A8CA6264070A7F1F09CD093CAD71FE3263B0E60C73F5F8641AFAF0767642B074B80978D810360C6461ED3EDF9472658F910B055DE3DA84C0F9D864887B06BEC9F246D6025499B69389AADF76741B4665031E74E1C836028D815ECFFEC31E016610038E514FD8C40543D51044F15914C46629E4AAFBB375263475D8CDFBBC16608AE86EF265A6F96C3DD8ED50EE43654691CEDD9D56D1953EE8E79FAB98B00C125CB7AB7263C045BC9C084DBE1082F5BF4185FCA92A8A86B02824FFB27908B08D008E6847395C57EC721BCA98DC0B83462956092D8420C6D8FE788AE977EBE07F8E35BF47CF0139F21D472E866AC90A0F9934D889720BDBB0B6758FE460E433065DA58947840B243B5C1D7DBB77B3F5647E6B1E5E431D7377E97A5BCF0F075EFB21E937AD32E4FF503475CE0374E064460B5A0B4F955395D59C474CD9BDC172757C4E8C43F87A05741B0454DA49A357EBDDBDE8BD4D5EEF757E273F78CA03D759940F88FAF5EB05BE1B90273FA0BC0048267B43376CDD718399A354E3B39AD1AAC43D9C2B70E451C8735865EAE9FE002A29CCF21E110FDC8143F7F6F6F561AAB80D756D36813FA06D86075306817D37856F1F60BC2DD52342AAAA26CA613E00A9115D57C1E17A0EE160B6594FA15A508BCCC75D4AB1A92550FC7D3EA97C95CA005C1A19AABB3CBDBA66D69363BC654DD41E108155EE7876EE35D0131231DC0C5363795788CEFC6210B502DB88C434099C46316476FB3FB07E701E29075AA3BEEE3253FB58D7B532C7885549593BF2984B3D6FCC2E70105FC34A1CD9A85B9B2A48FA806BB1FE35675ECD1BA10FD998068C0797A6874B02F3759F9DCD3B7702F687B52B7C266357544355534B01A42AD2C4D72F8BD9BDDBF19E907B4AAB42AFB9C50EA8B1C2D24086613B04E95C864564B0F144ADA774B34B26CD69629D0D2BCE8E0D611E1C6993589B529400771332F16F123352198A4D6872CF63F4401A69480FCD587D115B1D7951C75225493628CB4963EEF967CF17C509540AD2B76528A6512C270D08F57DE18F0604DF6A7F0FC6EA83D446EB3C281357147AFE5FB70D9809A6799A6E7B2DDB84AC602BF3CF936E171E16F5B4EE3BB6F1F8D70A121E2073DDE647EAB354AA4B41CA00B804C86C1F0E43E5B0121F340AD5B2AEE00092D931A5E3273F4F5BEC1CAB03D56A297B5EB5AF99C83F60C70873CB17A1ABB1668103E96C8FD9B5A2AA8B31BD9AC07C2EBFF610B224102C28626D812CA223F77817F11254DBE77FA55F77CE54550ACC8F6C4F725C5DB72F56BC4BB1AD86DBCF26C1D2120A35AA49657324A01423524C5A5311FD6D80ECA89B78221AF91A751637FD590293CDCAAD1BFB5BBD6473F1D3D600B9A921145B691088A88BCA7D1038BA83A7FCA224EC74713DA1B07688D053980AEF766325769F8AB513B03F813F5530B991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EAD16E1125A10C75C47056683C86956E741DA2772431C6436CF7B385DCE6509239E2CB3E61134E6B4CF5811150F4276945BA08D0779468902DB915F36620A54536F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D265894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB939E6518A5122E37D4C257B0A0FD60CE0BA3BD55C9CBF369DD315A3C0609933D25DA403DF7E69FEB7EEE64DC3C13DC83217C2834B42876862CD48E99E69564B336506B85FDB493CF8FA87A7FE48DFE6778DDE8E8DD066FAA745C121480B5BF9D5F301B358D18FCCCBD24069E71836981F168FC49E6A4F27B00F6259B183B62CEAE0BF4AC0F53FCEBEB9052C0B48EB0666F361C5DA674B20B06AE2EA8783C2DD7EA74D98AC98C55748A368DF5B433C39538365EAE8DAE5E032A2008768FEB01F65D001AAC437781F742F536EFE2B3AE59EA12A6DC7F2712BA2D9D1C253D29B419A765985ACDB42BCCE5D64F6AF8368A5D122BB16B525A80C8BC5355A53917CC82262254378CFFDF1C7D6355F114E4FC013A5E4DD9AB373A0EFDC470854E20330BC00960ECBE882098D6D0D429A7AD19D3E5D4B78AC5E568C722A21877DA617190CB43123FB04333FAE5846953E33407080D04DF1417E740E7E7A14B0E3CA7D5B693F9615E1F7D417B9004F28D5002325B851C31F5EB31E1DAA80E6CFF22F11221E5180BB050888B6564A381E54401AF9409FE12A818B69BA34E1916092A0EBA24457EF994A1B0028649C9803045EC93CF416373F6A568856B771C3BB076AC265045ACE8E9BE3C3074D8806BEAA3B8B21F7E37F50B16221E14FE5503C615A13738CCDE39E2395E292119959CF686532CC3C9F9129E62ECFB43A091B06FD48ABE8C2CBE2D9691C8907881991CAB9D0D9CC7B2699F2261E5D799D26A7C8A4AEC40789B34CF5FE7BC8D24D6F0BBA7A5870E37F4D9B2605BB56ED9BAEB780CC74097DD8AA8741A97E22EC7B7434F81DE9D83CB9816A33C5A79D718C76A3442FE50C68FE1CE7AF728F2177F88E5168D4668518897AB050B57FF42AAC731E484B440D0D7B254383C74BE41C2AAEC02A8D8C7020355C4A1FAFAF4BBF56C74D78949D087259FE8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B179B32F9F94BBD8371B973B19E60C3CE2206A2061C7BCF159BC3A50163924774BB13C708A573472DA73B4C78DB30FEF310EA3643BC75D9155762D5B87809E2A727AC0428B746801D693074ED5245F29B8FF9FB782F2E57BDD89DD700EDBF12E8311946CAD9BCC98E3B1D581E678BEB1D0A6EFE15CF4052A1AECD328B2C4A8D5DDEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA36145D1653D108813E42654CB5350FFDB33BD2FDF4E416C6C0A61784E2327F42B2DA2AF040822C291D63645B0AC2377D0DE3FDBD99FF9CD9AAAE2B978C4DBEA95E330E90EAB0C4C34E88855C7C62C40B231AA1A9EB409D18CAA1C612A98F1B7BC25B18E3A89CAF96AA4BDF12F865EE7DB20273D7CA11970219BE997DD0EDE7A8ADFECFF1D90984694EF152346402207BD7D9166DC1B09F3C3520D109824442B8AB08869B0A4850BE3227E746998925CECCB422C4C05047D890E291B4E5478967A42BEEE34BA2765D86D183C71FB6A3CD86EAF457756FC000FAFDB24AF3C968E547A5223821BABF91B31B3F970D9F7C1FBFD16CC63D14243DB22CDBC266BFA4DE4B15D23B17D34C674649A695E80F84F6FEBAC0255BB155BD8B8D46FF7AFC532117E26985D99B0E23345F9A0247D834697804C6644501CA7D2726DA563C7F02371B5CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438DC67DF57A5B11025EDDC8915C57C8C72F6D6E71978496E206201184593506E39582DD2C803CE9204D2AC833C35BC683E0BD3CAD30BBCBF584AD38DAD30C9A400DE22F0CD6199FA6C622941E79F8C5C500389E9FBDEB8E1C926443B6FB0313DA9AABB163F5319C0164C1E58864827E38C18B7ECF6FB44274CCCB84B10F1A1BD76C8740F479777BDD7C557DBEFA9415B7FD50CA659E304EF4FA22680980D0FCEFC75E36231F740F38E9B4AC55BD8307F8AD9FE45B046B7BFF0F1B9FD5EEB82D474DC311A8418BB27CFE324426CD3311D65513B0A4D58515B94B8EE5ACC6815D6D1246527188E7B6C579CE42B28E1F273887FAFAA96D44FE6830E96081ED562FF4A08416DE4213A89CD666E2814FA290A5B1FA5AD6DB86B9E4DA85486E11BB36382C13607F50EDC83909F47A7D089CFEAF4680A6F2F10A2D9D9A679AE82D2DB387C5B7BCA11161E49E01C28D0FB7FEFE1C9A4BEDE994DEA4087F3B74906EA8E49153ABA49BE0F35C0572E9CE0C68B2267884C4BC4AD32BF28CE64DC7C825BDB2D8561C69161E075F48A40220159BFF1C4158187D4DE23C85979304DD4DBB98BAA57DBE6B7C55C271B134D61906F6ADBA4639BCAD3C1A70DA04A9409A4A35FEF1BC103D4F17BAFEC37C3F108B31327E0FB227E0E2C5B5410726ECC93B56D4D153572C2DB4EB4757F5B2232C475EB9802FEFB53EAC7BE6A090AAE98027AE13D2B338442FE6EF2DCF141C4D1AF00C7B3E973467FADDF6F1950ACF2BE908FED354EDFB147D6AC4B0740F87DE06E768293CC83AC995760FE0015CAC682036CCABA9C86B9B06924369E35688F7255F5D5422AB808D023B150D62D9A7DE4F7A5D28689EB038E9EF9D3366C3D777AB6D1C33878327018CC51EEDE65BB5FEEFDB1442B9006C76B10B6CE9EE1B6E43306DBB0D9030E3A191DA24634A80063F6A5269E77543525E11BCF02DF82E5921E3225EC97FC5F9174E0225E8C5D08B4C093EA28A19D03E908426578661E107E5E2C5371D79C31F11468112A6050703BB8FD9ACDEEF8D0BC31E82FB4F7DD0DFE8AE0216582E6C86FCBC1E7B3FFDD921F220702D827F145D79D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CE8D216DC6F19C3AC0A1017837C31D76ACDBD48F018A1CB14E98848B66A59F09AE22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB96557964888EBFCAD45C491A2A3C44B7085FCA7C983EA4AA22F62B99109F6E425CDFF5D87105EDC065810CA3E055F62FB80F5CAFEC57F7CB47A95B14A215714FB345FC73E57C1574E38657755CE991FCEEDC5ED84824E0E4AFD43205E126A3402910DCE16C59C8840FC7FC5ED9FE6379F9A388601D57B366FCF44FBD2D0C15A3D8A4A28D71ADE5965C137996748EFC7FB68ED165D2480FE34EF58A3169D03D0395D94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB08391412A812DBBE4FF09E10661B7DD604481AE6EB2F89A1FC04E393B3353F7547AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6222D7DC2F78B2E3FC4C8CEAE02E3FC9D7972CA803061F534D39E4F02809C7A18A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F9536829157F62BB003C2E45042DBEBA9622508F9AACA5FE89F665A5F35BA7C26D93A84F9DC744354C73885BC59EFB657317594D34B561FC2A789C919EE08D5D68185BFB2A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E1866ED93157270FB47C81CC3076E5B381E6B03127E7AE78C54F5F35B2474F18A2461297462FFAE651BDBF3D438E30420A3BA5686483DA2EACD874CC44102C09319C10FFE87AB2099A185DFD0FDDB6393B2F61490D65F93CE565C6575C877246044FD52ED475831AFE194BB163D0FE5A023BBC435497C3C16C8C7A85FF92426B59E588978E29EC0DAD032330035B797471B74BE366FA75D79D35228004D3231654D5F301D6597B83258DBE9284121A2BB21EF66F40C17FF135201D18092FA6A72B511A456786ECE1FCFC986A28C744DD4DEBCB552C638043B0602343CC796834B13660A86C5E3CCAAA1845C5165074AEFBA7C52190845A95DC59B1E8D6B052D253EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D1B478E24D9EDAC7EC8816FA54DFDAB0F181E9E1A8A6CD77A9EC29B3E35544898EAA311411BA22E8BA6418CF252675917A88572E0CE98CE03457996BA4FD86D07C4FA2D3487400E484F4CE0A83CF490C49588DB83ED1EE2A93B78101144586427FF43F434D3A40268920A4FA3C64C0F5F4600A8E52E01CD8210965C4B212DCC942C68D589D21FEF433904C26239698EA85C32423EF7AE1ADC90744996C956FD5D0683674010173EE4A110DA2642C8E1C4BF7B5DD3DE268A3AD0A261A30AFB6AD7D54210702C635C3E707CB1F17053D475A026EF57852DEC1FDA4252FDA2E69BA95C866BD432139CA8A4E367960F85B2FBC75420737CA4843B89F053192BB086BDC0D739B2753DBE42E1D45877097F3B97FCA6F43AC15DF883C3B42D9F472F910DE579301FF7F57D9857890651B64B6C1E8A7E2227ACAC7154D97252EACF8BC5FF430E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD637170756688D9AD3002B3148ACF0009CB1C0802EB04197FBD2FCE168B5FACDD052DD46F9F0B0A34295557CF741102E7592C24FA56DEDA63ECB7A2149E406C0943E5E554767D166EBC95FAF0E9B20C1E530633CF8BD7AB2A66CB105E108C1793B0D87ABBBBA9A4679A05C94BE6A698F4758B8BD38C51371C8043FC79E749D7E41C04DC6D815B0D32A779D0AC6E80C1D56B03C8EF30F6F6CB73A089B149F46BD4671D7C13B41A5B1BCAD94C0552C12CF23352200198CD876615EDDA7257E3CC94B732D75AF6D67A67929458E2639BA4A2967D05F76C4EAED429AC246CAB410B0FC8806B84EBFE1159C88D6E71EDDCC3B956F33739AD9FF6C43168B54FD592D845A54307AD16E42AAD4621D33A037D47D1002DE1AE0BCF2ADD9B01895EB0E63742FCBB5CFDA14EC9C63D94E3387E0FC22FB1B93D9065DF33D03AFA7D156BA719EB9DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF1DF5023719932492A5EE2B7A3B40B7C7F6814D179AEEFA584D317D536645921799727CED4C3D658D5A425D2D3EB1359C975FBE1A2FB2D11F37098B7234A19628624F07698EC3658799436DB5CCE6AC18702D4F27548F61BABC4807826E95D23889575EE119A88256D4326D4BBB48D0F589C6CB22E7F95D49F6607BE258753A6120CEFBC2E6C502138AEA689B4EDA13FDC39CC0759F392860168C2BA881FF70632D05E797A4F52453418035DFE9D072F0593E8029FFC25D75FC7DE13309B0AE4509D8A315C31F0FD0F480B598ADDB0D5A8F945FE6C28C2421DDB4A0DEB478478A49D5E628799ADC5E489FBDBC9DD38686EA7943969A5AC97497B2C380CAD367A8DF3DADD2E31F759AFA47A422D2A5F7C44CCB028AEC63EAA0727231A8BB4FAC096D19BA50AEC9522A00DDBEB86ED6DEB298AB433CDB7B4F15EA4AE08EB01782B70CD59C57D485848B16B9C55BCCECC876AA99071A9A7599868A9BB42F178BF3DD0FBB7EB52A796801D67E250148584C46F3E96898AA264BCC3826317B5BF7DFF55B6F3C3F3929FB552D79FFC1D014C52965F50B446DFC1CFB3302D8C7367A6F64C93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B787B24028E369C59743659E28980F3776146D88956F5E02B3E3116B8292C2E578C8708D4B518B95E8FCB7C7D5C3B16EF976B20FD0E53DCD6D92301061F2588F693A84052F8C776D033ED7A5EC71E928DD7CC7EED8DFC585AA94D8C9CF92D9694377C0268A53536DB64565FD9F5652B0A3634B381121BDA48C2D1FD9E189991D092178D79AEE8333BB0EC988417AD6CD9DD0DCBF6EFDB0E4E8D1B38E2A3DD01B3EAAD55E1CCB1291C87E2A835E86D2E0C0C3642166D2E9BC98CF354E28B6CD3F121606F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174BE4D5805F128D4A9B00266CB6CC792C45CA4E506C8B2504D13AC93044BF3FB3357F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B82A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B275680E933FB83760E66AB8BBCD67108A95111001B9F8E85B6C96B4BBF952517D6330EB1C6AB68317C91468E90237214C46A5F496EE46E2E8069D65797581C01BA0B2DD1DFEE0F95C0AD7E426F877D0CD294CB0F3ECD1C65659D20594153630E46E4A32CA7D3B408B33227123C6449C4644192BAE44916FE60256703EAB9B2821973C8A37F2FC6B3B18FFE0E4C8036583B7E63E60A5EA8FE89401C8633BDC355FDDAD733A74922E73333FF9B2F9EAE2ABF957105197D92E7CAA56F91767E282E0910608FFA0E651B882398F8187E5203F8B56F788A4DE4130D211BAEDBE44B1DE0D729B926D5FBC98A1FA9EF01E415BE3795F085E28E1B32F86B0EC72DB22414EACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E947CA8092F4480FEC3CE1D8A6D8C4CBE3F7EB35919888B729C1CADAA559A42E1BBDA600C713EBB3487FAF3CCCC40CAFDEAE9B9C6EF40D5041B83973133A03156CE65E33173CC6EC41F0061D31797BF2D58C95B5B4E218AA783E09AAD39682072C6EAE7C52E3491E8B0345D3F6DD019D7DA6D9AE08FE40461B81D414B8D5BBE0672D892793121DDB345A2E5B1F8F3EECFFFEE5E425834717D59506DAC94BB9F31F00AC84767700A6FFBB6D93D4A9FC6F02C67F2710269A4162C284E0D9BF486ACFDB55A33CE915B41F167D533B268F96CE0C70A54377A5A76B1C8E992BD4908F6C9AE1B8A1129A6A94F2C1FA3EACE58297AB6E83568F0857FEBA399FAECFAC9FA94217BAD28BE66B04EF4EF7862DBFC7F9D86A69D63D84665C826910849A959626B2F95B16FBFAB29A97876BC2F43A43F841F6161648AA9D1689D67A4BEE2C859702320B726B0219DCC859A330C6C337AF2EFB0B9C8C689D2A7B92DC615BEF81F9488AC5E678E63D3E9C4CD4D2138F500D7967745773C58A8704107771E6AC93AA2307D387AF3CCF853E572E74624A7E40305FF4F57266A6BFBEEC78BC8CC981479D5A80F351588B5E378EC89F193C02A92E5BAB45E1C12BE0DBCAA00E85E73FF666690C4133023ACCD88989AD44530D63D54B090E115F6A25111B4F006B0EDBC73FFCA5B037240E88F9F4FDFF79F6874B6D6865B3B93037E272D66F1BB1EA9AD7952CE8F8F353C2910FBFC6F73626986970C6B1FA3F7D010A7DF2AD27ED28F727F9B6E10E08E9F23278C2C6ACA482528DFDD42021B690D777444DED9C912B2CD003DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D5023540D6CD04777ECAF4F4D58C64C158042656BCA7DFBBA61D7551154DC1535618FB3576C6A634E79E80BC56D4A77A32480711DCF387CC963BBC7A339C907928DBA6545BFEA6878A58236DC95D439F8F3061C099AEF80CB7128E0C1D3AC5841B65C0A738A16BA2EF4649CB510F512A819CD03BE1174182022DDBA30AE32DB5AB9ED29B2FCAF259886A4E479D5B5C118DFFA5529CF83978DBDC1B233C410279CC031E0EFD98F95DF6A32C1FB854F7DA54F12E0D0078F9287622542E551863DCB0B534DCA8EDE06545D0860957FF3A0C13495A47A669355FFF55DAC93C3357E5FC17274ACFCF9905705D6F32C7C6E6FCAE6086384B4939C70128CC73540E47ADC633EF01CD9E59A14EDC10AB0A9313ADC2123A4F3F3B4207CC9564D39F7CE86184505C432B568E4CCAEAA1BB93EFE4C696CA690F4B4EAC21A83E1860C5F26C6ACEE315F139E8C7543B2075D3FBF446058A1F0E0DC7893D9C78FB25914ACECE4664F58E03209D0EE1FCA892A9002B32FE67B0CD27E60F35706FC2BCE8A0F77E89FDD67DCAF4073DE5B72BFB56A87525875B0E27042175EAC158AB2D5A7B85C041FC13F81A9E78911686B33488DB258E31630B4D779F6F40E079F5094D31D70E74F2220ACCE407CB3491B80DCA95CF6126E9D2E955683F0B6BBA28885065E50309BD5E3429C626D547A87ED33769F9BFBB514F8792EB90F90C956F0148B9928189EE06BB40CE18932DB44AD96E226B6BB6A313DDC8CE4FB50C6C548BFA794FDD1EE7EAEA2F119CAA2E0DC7664B0136EE7F50B88FA4F4B1F0A665F36C56AAECC77D637637ABD7EE25BFC8B638430370B0F92FADBFE5C4F166A0B1FFDFDABA98EB3E5D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3C1578D7F6DFBFF09D46817D7C61EFDDFEC6AEB1A21EBD5AF1A0F399A2096C8E30821DCFD15298AB26911D40A97E78421AC35B6E8B47C483E1538E1C110540E6B23095AFAF8CCC9883C1BA2810AFDBC488849BF8E2BD2B63AA036BCE1BF9E6FE84C7C830C65CB9870A441512C55557F371276F3CA97910118271DC35F5A46454B02318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3FBF9F7DDEBC0995B90104C717FA2977F9559887204B56298813EAEFCE587F9D2DF49378B38F71833410D667351B1949CF406F18B0727666AA94DE7EA90B093CEEABA95EEE4D2DB043CFD3504F59CF36374C48E804535A76BB8BF67DFB39E03CE613D53D7515BBC8DF04062A185B7825FD3260B1B377B5D3CF470603B1900FC978329FE4F050A62A0440FA26E9B3D2CDA32E7F9FCFE6446B29FEC3639F068E56D446765B606D7B4FDA46826E8BB9E3FE9ADD93EBF3848B70C759922B63ADAFC8E71CA051A07FCDA3126BC8B4EAE41DB2031017A6794C6784FD8B93672BE6206ECC5F1396078719C45CEB31BDE4A3D503A56CD1BA60A875E2A5AC7CF340A79F261480A2A36EE4FE88106DD0976B8FD47010119D6D21982AF0E8E58AEF1BA68D4BF979DE633E719AAFC7A6C8AC6D127BDABFC3660711DAA2962D639D46747BC03BB269789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411923F9FC45FE90EEA617A4971AB81153088F58B488C507F5C230586CF967833C9A0DEA1CAD7FC139A9710382C46136E4F4007BBD729ACF06FBFEDFF5144533FBFED92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE59 remain = 1048574 -max = 1048575 \ No newline at end of file +max = 1048575 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-2_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-2_256.rsp index c9042e164a..5fba789ede 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-2_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-2_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHAKE_40/2_256 - pk = 000000139671F9E99FB4EC6B22DCD31B932FA6A76204CF58477B1B054F10C47913D088D804562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 000000130000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A9671F9E99FB4EC6B22DCD31B932FA6A76204CF58477B1B054F10C47913D088D804562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C7D176B37A7DC26214FBBF555DDEF8D970B6AA840AFCEE7B674EE05845118A6FB277ABEB1A792B61CA4D24646DBBFD623564F93B74C1277C1AE4CB326411850F0371D6A848ED0BBFB8B0BC3254398F513E630D075CDD277E0AE10D8D13EBDD0CC60AB0FFC61631C5D17989AD9DDF25BADAF0BB87FD0E32975EB673434812D58CC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D9330900000000000121C29A3D4E6C5DAA979424FCA26B0EBE6D3FEA8F078FA9A98B0F55503C2541CE0A0000000000015EB6FB8267689B81BC8E2C8950E5F59F4B43194AB167C4A60EC9BCDA7572E5980B000000000001F02838F27F104405AA4D9E111D3A0B1849F6725926BA5B3A6412DEF900E7259A0C000000000001BA1EE79A04487C5639BA096A60E3E17F7A0E9C0238FA049EA7AFF52FAF5890980D000000000001B63504B794C356EB44A98DE32960830E6B275526432F232A7729ADA72571E8D90E0000000000014DA82230B909123D34E30FE0722BDD93EB6D56243518275547CBA7C473744E6F0F0000000000017AD15652FFFF1B8B9E752AD4A07EA737B8D79DE25D7F194E19ACF003E62C48F610000000000001D6819E585CEA52B14299092F01E66E9A6E7AFC9613A69B89ADE061890A230145110000000000017FB1A159FFBC19461AD72D4E385722A08E9A942BDBC3CF8352CAECD938737D89120000000000017B2C7FC20B3305327D2F0FC3C4854B0053D00E56EE4E005E43CBE807A619BEA8130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A86CB037675575D46C48D89A7B644810666979BFDDE595E1A2362B9961A71D9F75A4A72ABF56BBE2C07844E774123A5DEED0116677B286BB3F8BCAF92D501A5FF375487D2694B089FAF47D8632DA9E213A9C914689D9FD8B0DA5320F6A89787E198248FA523B9B2E910FE55F6127ABFE1FF1EDFBAFF132A06AB9FF0F2E368AEFC6AFAAE9F61068AEEFCAF427D37CD93FC0B0D226CDCF6A7C1F007BE2E59568970AB644D475E62D7B8E7E5F7BBCEA4D007BDDAAFCF6B84E09BCBC5553F516E2E5DFFFEB66C9F5EF34559251705C736FF66A96AD2CA2C40A368602DF65045808D87B7E24CE23C67906BF64C90CF0E0F8621537D08A09290E431737F9C493DBADF98C9E250E094C6F0F7E850F5EF65E71967F69159ADD14974C1AF501C74F01D1C36AEBE604A32DC02B676BBD7CE4BC3967FA8899F3B1F654E7F3E425ADB5ACF59B6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000018F224E19E61C8A7076585BF7780AD32D73D04D66A52F0B4CB6D35D9496906BFB05000000000001C0F7248E24BEA5635FD0F3F3411F1A20316CD29E2BDE6DCCBDEF8AFD463CADB306000000000001BFE2E0B4F4BD9B2B955C3CE73D4D0E703C44BE5168224D99756D865D86689E1607000000000001EB5D1F16948BBDEB3335E0F93C3DAC5C3FF7DCB33B16BB28D3826194192729F80800000000000194BC268989E8C957203F60EFD29089692A7FA0980912BCCB1FF3D6921B9805610900000000000182B44F3F72EC96002984E059C46042E3085A35BBBA6A0CA79700D29DB34DF2FA0A000000000001174A1DED5F222EB3573B2A6CC27870F2FAB30A64FFB9601B5B8167314CD3C4AC0B000000000001CEC1E018C94D354F99802059603298AAB121FB0D1CE89A6C90B945D90A6233560C00000000000184D0355AC86A5E83CCA4300AD4EF13DCF7D6185ADD1B29F22FF24B446B6A184C0D000000000001EF0BF8DB8426844A322EACD3C79500078561868864057744206E70294F1B4FBF0E000000000001EA649E4FFD3B7A864E5C9177F8B14D91BE4CFDB050B6EBC86571996AFC1AF62C0F000000000001F80F14346EB4A8387798C08955A0CAF061B367B1F969D28F833140663D9A4B24100000000000010990AE38170C318A1CB81B1C8C6D980077F153C1C0403EC9645459C3C222225011000000000001DDF5AD2829966C243C523B4B91800973741F27929353122DFD2F0F9DE717F31D12000000000001254C2BE70DF73E405F76FFAA6BF442F41018C0C2D3823AC64CC175A601ECE527130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000665137D5D47667E1CA8F1B70A9029441013DB1E00D4FB39DE01E275ADE1AF6E6483B18C34D78AD814C71F370A0AF1E681C1041FFFACF9685BABB03923BDB41701F927F3316ED4DA8420A373F5471BE4A7215CFE5683EF16855C748D8FBD21DD9A6C36EBDA9BC5497F5C0C93DDBD40A717DCE151B87E8D5CCEFE5E8A0A66B3F92739B24915DA4B87BC7E555AE0554A8FC1D2514A7979DCC78E92D79C6908005648F90E5E4AB32CBDE27EF1BDE91C49C5184A3CE134D7AD33A1AC03F4A09CC245DAB6033C99636D9F6E9A723429F5EDFE118C045EDA721EB21387225EE2764A00D99625EB4FDDDAE398DBB4D8CD926310601CB34D38B7BA4BF60C66925B2E66B838C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A3692F3176BEC212C8CDDA63B223901AFF8E3CA0612978B7D97E8F2E1C000B0D2FB992BE80BE6906A967BE9949853BED6333CB070A1384B5A26ADF28D3BC5ED2236C6699909AC8EF3CE18997A672EFA2087DC9C0C38BB416613F206E136D3135C4E39F98C7C1F50DBBD69337069248EC64C3E5C6EE0EB7618396BFBC2BA26667426721DC84D3A53129AF465CAB586A54924BD35CA4BB250865AE0EFE67BDF060D8F947141B55502BD264BE2F24B40DA59C45FA59620F207E10FE94013B6A9F94182CFDA5694E19B1ADA22B18F183D7DF0A51AE2876A5D6B79D911B0B8A0D3EA283DDE8F0FC0DA1D77498ADC4DE901F89F11DE2753E8EF674622BF03110CB519AE4F6CD0ADC41A43D1929CBE5047D9B09FE60D9075C85CEAE9C825EA53585D180FB610BBA83BBA2E590AC5257DF858E7F11B8298C848F2F79D78C37F00474AEF9B5E9AEDBA4C81ABA062F24531171F8137F7FCF50FE09A38F60404B03CD1BAA934D6DB5CFCB1DC552BF873C6AA9B5FE76FAE92D4C3674E20DCA7BBF430C865F6E5FB5D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF710D288F760D8E6A64D9E2E53F680C21D30AC1439A4A90469D0C6271AB6EFBB90A4F4DBFF7D5F3875C6507DB321D81C3510D7E7F48B297881DB6FA0AFCE41645FC93A37FF04FCBA7FC19B9089BEABCF9BDF44E2C4614A73FEC80C1234162B41BDF1313F6E13AE2C48A6C4CABEF5EDE59AD461384DEFAF1935E23F5CAB3829A81E2DFFBBCF2FFB141D975EABF78FB4BD484F75E08318C08B2104A468E670786397EEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA360AB78FD9219EA890695CE44CC785A3A4DD39CB8F3C82FA5C6A3167055CF3309EB06EB90826159619E65C5E29D46D35E61C961AEC002F87B44A2B7D5C0E2111D17268FC3B147434264112A2E95AADA6ED860C50359372609ADB174741CC3AAAAD1FB50A42A560BB18D12C228F10D2776DED26752930890259A5C0F64C7D30C49383F92F1EAC6B1E8D6BA05423368AD3A8BD145D397389720E80F6EE11965E467D4D5864E164E51437277F698BEDA846AEB66DA3DEF39CA3288D30C001D3B0BCA113AFE8AD333A08D801A9E4C52DF0DDD4C63D8DF7EA938014336BDCDFA10E960DDDB4B5471263D096A49E3C83A188C46AD4EA8D2AEAAD3B1BA78CF6F116D0818BD2F38DB39D74D340546233ABC52278B381B7DEDC3A3B5DAADC8A4E7519AC9F3572A35C016CC7A8E0FABC029801012DD7454D7475E5D8B492A119AC583F4043D25CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438D81219D292421651600D48C2BD291766ABA14ADDC9186764DD212446D27C3738D2F606A9654BB310288F37CF0ECD5D38590E4D887D9D5C523527007F6501ACBE7CF36803727022D98CB15BCC0A88A509DF3B9A84E99B41843283FF2E10FBDA3C14CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D446D278BBC90D6A56B71D6DA6FCA49F332776F402F58D180482B2EBA5132D8ED67144DA06AAF952EF5B9BEBBF0CC8101E93F3BE05E58EB75D55B3CE72B9C8A07725C61C24C34DEB9A7349E51256EECB7DB61510D8BF55798B060EEDF9F9551AA615F1661F544B0779B2974A54BE8BBA388D6D7FB8E2C0956DCB23F834025CAE4BF26B798CBD5938A517C4C3B8FD3B8FE920558256C391433854481944BE487AFBD226853E385D942014B393488D554FBC143B44F7E9F348FB79920D4AB758CAEC55ED8CD388DCE4B4381D5C3A9FF36ACF9948993CF2B2E03030646852CB4193585AC6C56947193F96292D813FCF3671D46B9DF2D99D43E0AB4F1994B81235A50D5D977FA3560CA3D46CF60945C8D3E1103B6B1D13CCFAE43741BE65EAFFB9DCAB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832D381248D668B0A5ADC623F2529B02CCE42442E86382E03BA3FAF21F86FDE1C633C9A17426EF1F4923824A1E394BBAF5058C00950968357FEA01AFA8303DAA21BAE4617293B3B19A50C88C8F7D8A677A3314640452734E7FE4BA483C8AF87356E6822D943C23705352F458ED80B8375DA6F1F0DD7688CBC6101727F2AE7FE500C98A185F29DC71EE3506F8425B8D7EA94BE228679F42ACED5C9162D6A0E9AF148E5903C0ACC117C2BAAF1EC4A73A0BF73CDC646D1559EB1FA607044B5C7CA60FBDD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C6F2AE696330DD7C816130134AC101764D6B4FAFA1E71A404CEBA3406E1996391AC35A28F18E05DA188AA8FB52712696C986C25F70A31DA73957B238FAE89EE0BE4F77ED34ADFF62BB5C0838F9B645F6851BCA9241ACBCD3038BC40F40F076D1CCD8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CEC2A8424E383ACE82322B3629ADA77D454B677A60A2932B49F844A9389E73FCCB @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 5605 sm = 00000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6DAC51184D2E4216B689657E98DE08E43946559C194B79D61BCAD87EED916B16CBBCC675AA586D085AAAE1C4C330ECCD5175C5DA952B32829871E231AB5DF21664BA023C2BCC5E6A8E23448E84431B33CBB812A458DD44EC9C2C10E7570B2657F30354434A7E3B1BF99467D1067CFB19264ACF52D2524511F0FB34AB02BF1266B66A0D5672F44DBB9632CE082C47A1191092030F878A87D3007016131038259D301FD9F8C8FC0CF2C5961F669207E6BBEE6F8BAD3B1AE3DF6E88C679BCD425CC1ECE4C96410219AA2370A23C6E92E5322E0CD81840622A3C20D7243711074E1914424E503C694D3360129ECDBE6ADA3F8D0FEF9BD08B3638B1B2076462013954855C6DD4C888FD4C8BDEF806EB73B632B3C27697F2410935EBD0B4EB7D4FE85D9961BA4254B0FBC7E8A37B1D610C74A511E52A8A50F4943217493F7EA4C92CF2591CF5AF0075C2B16BA82F2072C9419430FF672963FA85340B43818E9643DDC3CBBA724670050F31569813630709AB6A4E35D66684AB154CF647FD64DA3B2E5533B01944B68487B3A43C12094B7F4BDCE13FB2C882BE4EDF31F6CEAE8B8C9B0BE50BDFA63BE7C492FCD5E2A1A1334546D3937FB47D9673832B4E4015C43D199CD23FD99DA24210D8F5A4EE00D85FC2AE1F439009A21CADBEE4A699D5886ADB1A91DB87C1BEFDA40A6BAAF785B98971D733B5237497B86E89CCEFF4047BB0EE4AF2C0CCE36561758781EB57877CDA69BA5118EBF885452A682B2F650FB9C650884151E1961C11F7D8CCCE4F08E9BADDA88E17BF2DB02A6D1E1D2827021DB4659219A53F4F2C4C3512C48663CDF1EC31B6DDD6E35924EAA021247103348AEE988E84DF07EFD4A4BBDD190878F81047F477A4FF9B89DBA8ACA2B5058528061CC13CC21BE921E1C2CC0ECBA29139E304A0BDF7123670D3FF614F1F0E22C7C8E161E91167DE9D2380AB6D5B0807DE6032472D838B3F681E7ACBC75D71426F33ED97C79F1AB866C0EC37A66D86CED0DCAA7DAD8A4E71E08A856A7E8809F918430DD063868814754D5F91CBC9BB551E5663948A692D12D054D90840580C1D66423931FC56EDAF3A6A71C48FA89786E1A76FE326B90AF058B1627040851A517242451CFC337B7DEA5192657F498A96A2D405C7AAFD57EE39F6BE2C82A53FB2B744F8A003B689A394B8F61F7536B86985B684DA6C8C1C2B167481C309D1A85FCC85D1516138C86D028F556465D987D2F811892889E529E9ADA83956DC4741F939445B2711AA890B29BA3E9FC52C4881A9A34400B4B94126E07955BB03129FBDB971A00A45684921527E0431A3AB6B216B29F71296C1244DD9AD2D6D1A87E5CA6320CAA8EB347CE4D9F8AC77A5B3E43929F5F4847B4410A434B372FD317392AA7800C5E54946220CE06C2089E7CAA8F993A0A7C75FF2AC9137B272AB3CD4E320F03DD9B8E8EBF53B4A4B3E0A2AE1C07B14CDAB8F2BD7876E4D4FB45C950531E2ADCB7A4C41AB0ECFBD596F875E032C49705595F70A6A7B37A07484B5B173F9C611156BF564727E494572744D779FACB63A81CBFD2C18FDDF4883B35F19FAF86B48D5CD2DD91B565F6F3F7774A9CE75488FBA6FF0205FD45334A09906A3774718DDF36BB668C690438A5CC2F8313F8D8B35002CA267F3FAE2ACAED9FD4AC11F8388FF7CA27C3546763398E70BA97BF84F3DE6EE6C9C674772ABCC1D8FF097688E3BF3AAA181156E4FF135A1496F57BF70B4A953C9ECBB173E540EB285C140A6ED4CB5396B6958B799FAA589F3560CA7827B256A3001D465F3FA74BC5F397B5234A3D94DF962411DC97DBE8A6C554F9542FB6902B2D7E51B3D4B94559088F825C10A800FE6A1A8F56AFFFD51EA286DBB923E624FC7648B59CB8C78EFF8BED0E9B0DFE3E17CB1CF59658C0D73D1E63F8FAF0FBE8A8C2040111959D5A670BCC211CCAE5F5F687C59D558CB2D1DA9EE891F338DFF31CD3748B61CDE572EC77997A2BCD420E58ECBDAAFD9BDBA4BD815108B240DEA39524C501079A2815C04018C444AAC8AEC51B9271EC59D2C2647CC924B55E236369BA5C9F100EADE87928D10820D2C7B24CD9F76C8051F01577D24C318FEBC2762DEE56090A69FA567D0C5C78126420F1A05ADA26E940B72E6A1F9E107E8E42A9DC82FF74987C9C874B5C1714AD51AEACA48C79B0A6AD85F5CD06E4B59918DDA9C1EA1356480AB1D7254B2AAEEFBDC3AE61F995820C8D25218B7AB81957686E1BB2C02A72AD3B067589E7E454232E6D4AED6D531D31F29F7E297056681AEBDF65EDED3D6AF07161B5701231D7BF81A5ED366BFB24B287E1511840B5D4A91ED9317892FBF9E9684291E2A3D7F86C1B50F20EA98B41430AAC502011A616D454CA4673C0C3B3E188AFFAC0ADE22C470D99F216F912236252B0F1C3FAF39F5559E3D0172EAD6CDCF9300933A0B2C8CAE0C69503B978ED984A7657A5D9C1D1AB5F6ED5AB23FA6CC4941C8CE4B8C60E709C7AB5C4FC7D0D4679F9D78F4276DF36A375CB2C50BAD8BC2C807EFA5BC82B013E7126D008BAFA34C4701D464A9F05DCD14482A95871046B385D87F0CE6BE103A45B7E8F10E410548842655E088F270E443633B1A4515EEF5ACDA58551D97321492D14B0DE243A40813210D712442091D9A5624F353739618540511E6B51C9C5CB2798594AB428A87041F739E13504103A1A8324392800C0F640D6A7D75DCE2D69607864529B6A37750619565E885A3FEFBEA701E877A4095F1B519757A8543A598BBEB843CBAF01F3882AAD3C86F85E3256CDBE4209FE15ABAF88058FA199B21918C064B40EDAEA01CE9C99BAC79F55E0CCB1C03AF2EF2C56D45E06D33F9D3ABBC6CB4BE09793A386048112071548CF0A71C9991DBB3A11D93483E3716D9A8BAAF62BC5BB58E24D982E067547936FBB57F2C25218A230EFB1A665F3D948CDEAA9F8659900F10C43437C01BF081D2664641DB6FD5B0CBE2004A96DD26D999937817B3A8DFF742DDC33FADFE21A034F29F62E5EF6C502CEC5014A10A68A2DCD1998C74D620E84F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C7D176B37A7DC26214FBBF555DDEF8D970B6AA840AFCEE7B674EE05845118A6FB277ABEB1A792B61CA4D24646DBBFD623564F93B74C1277C1AE4CB326411850F0371D6A848ED0BBFB8B0BC3254398F513E630D075CDD277E0AE10D8D13EBDD0CC60AB0FFC61631C5D17989AD9DDF25BADAF0BB87FD0E32975EB673434812D58CC665137D5D47667E1CA8F1B70A9029441013DB1E00D4FB39DE01E275ADE1AF6E6483B18C34D78AD814C71F370A0AF1E681C1041FFFACF9685BABB03923BDB41701F927F3316ED4DA8420A373F5471BE4A7215CFE5683EF16855C748D8FBD21DD9A6C36EBDA9BC5497F5C0C93DDBD40A717DCE151B87E8D5CCEFE5E8A0A66B3F92739B24915DA4B87BC7E555AE0554A8FC1D2514A7979DCC78E92D79C6908005648F90E5E4AB32CBDE27EF1BDE91C49C5184A3CE134D7AD33A1AC03F4A09CC245DAB6033C99636D9F6E9A723429F5EDFE118C045EDA721EB21387225EE2764A00D99625EB4FDDDAE398DBB4D8CD926310601CB34D38B7BA4BF60C66925B2E66B838C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A3692F3176BEC212C8CDDA63B223901AFF8E3CA0612978B7D97E8F2E1C000B0D2FB992BE80BE6906A967BE9949853BED6333CB070A1384B5A26ADF28D3BC5ED2236C6699909AC8EF3CE18997A672EFA2087DC9C0C38BB416613F206E136D3135C4E39F98C7C1F50DBBD69337069248EC64C3E5C6EE0EB7618396BFBC2BA26667426721DC84D3A53129AF465CAB586A54924BD35CA4BB250865AE0EFE67BDF060D8F947141B55502BD264BE2F24B40DA59C45FA59620F207E10FE94013B6A9F94182CFDA5694E19B1ADA22B18F183D7DF0A51AE2876A5D6B79D911B0B8A0D3EA283DDE8F0FC0DA1D77498ADC4DE901F89F11DE2753E8EF674622BF03110CB519AE4F6CD0ADC41A43D1929CBE5047D9B09FE60D9075C85CEAE9C825EA53585D180FB610BBA83BBA2E590AC5257DF858E7F11B8298C848F2F79D78C37F00474AEF9B5E9AEDBA4C81ABA062F24531171F8137F7FCF50FE09A38F60404B03CD1BAA934D6DB5CFCB1DC552BF873C6AA9B5FE76FAE92D4C3674E20DCA7BBF430C865F6E5FB5D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF710D288F760D8E6A64D9E2E53F680C21D30AC1439A4A90469D0C6271AB6EFBB90A4F4DBFF7D5F3875C6507DB321D81C3510D7E7F48B297881DB6FA0AFCE41645FC93A37FF04FCBA7FC19B9089BEABCF9BDF44E2C4614A73FEC80C1234162B41BDF1313F6E13AE2C48A6C4CABEF5EDE59AD461384DEFAF1935E23F5CAB3829A81E2DFFBBCF2FFB141D975EABF78FB4BD484F75E08318C08B2104A468E670786397EEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA360AB78FD9219EA890695CE44CC785A3A4DD39CB8F3C82FA5C6A3167055CF3309EB06EB90826159619E65C5E29D46D35E61C961AEC002F87B44A2B7D5C0E2111D17268FC3B147434264112A2E95AADA6ED860C50359372609ADB174741CC3AAAAD1FB50A42A560BB18D12C228F10D2776DED26752930890259A5C0F64C7D30C49383F92F1EAC6B1E8D6BA05423368AD3A8BD145D397389720E80F6EE11965E467D4D5864E164E51437277F698BEDA846AEB66DA3DEF39CA3288D30C001D3B0BCA113AFE8AD333A08D801A9E4C52DF0DDD4C63D8DF7EA938014336BDCDFA10E960DDDB4B5471263D096A49E3C83A188C46AD4EA8D2AEAAD3B1BA78CF6F116D0818BD2F38DB39D74D340546233ABC52278B381B7DEDC3A3B5DAADC8A4E7519AC9F3572A35C016CC7A8E0FABC029801012DD7454D7475E5D8B492A119AC583F4043D25CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438D81219D292421651600D48C2BD291766ABA14ADDC9186764DD212446D27C3738D2F606A9654BB310288F37CF0ECD5D38590E4D887D9D5C523527007F6501ACBE7CF36803727022D98CB15BCC0A88A509DF3B9A84E99B41843283FF2E10FBDA3C14CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D446D278BBC90D6A56B71D6DA6FCA49F332776F402F58D180482B2EBA5132D8ED67144DA06AAF952EF5B9BEBBF0CC8101E93F3BE05E58EB75D55B3CE72B9C8A07725C61C24C34DEB9A7349E51256EECB7DB61510D8BF55798B060EEDF9F9551AA615F1661F544B0779B2974A54BE8BBA388D6D7FB8E2C0956DCB23F834025CAE4BF26B798CBD5938A517C4C3B8FD3B8FE920558256C391433854481944BE487AFBD226853E385D942014B393488D554FBC143B44F7E9F348FB79920D4AB758CAEC55ED8CD388DCE4B4381D5C3A9FF36ACF9948993CF2B2E03030646852CB4193585AC6C56947193F96292D813FCF3671D46B9DF2D99D43E0AB4F1994B81235A50D5D977FA3560CA3D46CF60945C8D3E1103B6B1D13CCFAE43741BE65EAFFB9DCAB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832D381248D668B0A5ADC623F2529B02CCE42442E86382E03BA3FAF21F86FDE1C633C9A17426EF1F4923824A1E394BBAF5058C00950968357FEA01AFA8303DAA21BAE4617293B3B19A50C88C8F7D8A677A3314640452734E7FE4BA483C8AF87356E6822D943C23705352F458ED80B8375DA6F1F0DD7688CBC6101727F2AE7FE500C98A185F29DC71EE3506F8425B8D7EA94BE228679F42ACED5C9162D6A0E9AF148E5903C0ACC117C2BAAF1EC4A73A0BF73CDC646D1559EB1FA607044B5C7CA60FBDD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C6F2AE696330DD7C816130134AC101764D6B4FAFA1E71A404CEBA3406E1996391AC35A28F18E05DA188AA8FB52712696C986C25F70A31DA73957B238FAE89EE0BE4F77ED34ADFF62BB5C0838F9B645F6851BCA9241ACBCD3038BC40F40F076D1CCD8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CEC2A8424E383ACE82322B3629ADA77D454B677A60A2932B49F844A9389E73FCCB22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A86CB037675575D46C48D89A7B644810666979BFDDE595E1A2362B9961A71D9F75A4A72ABF56BBE2C07844E774123A5DEED0116677B286BB3F8BCAF92D501A5FF375487D2694B089FAF47D8632DA9E213A9C914689D9FD8B0DA5320F6A89787E198248FA523B9B2E910FE55F6127ABFE1FF1EDFBAFF132A06AB9FF0F2E368AEFC6AFAAE9F61068AEEFCAF427D37CD93FC0B0D226CDCF6A7C1F007BE2E59568970AB644D475E62D7B8E7E5F7BBCEA4D007BDDAAFCF6B84E09BCBC5553F516E2E5DFFFEB66C9F5EF34559251705C736FF66A96AD2CA2C40A368602DF65045808D87B7E24CE23C67906BF64C90CF0E0F8621537D08A09290E431737F9C493DBADF98C9E250E094C6F0F7E850F5EF65E71967F69159ADD14974C1AF501C74F01D1C36AEBE604A32DC02B676BBD7CE4BC3967FA8899F3B1F654E7F3E425ADB5ACF59B6 remain = 1099511627774 -max = 1099511627775 \ No newline at end of file +max = 1099511627775 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-4_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-4_256.rsp index 7f15d5b83b..38e4a7a962 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-4_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-4_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHAKE_40/4_256 - pk = 00000014A855A0EF256ED6B3F83CB4938E1BCAB172AA13D2FF813E233B4C2E3DB18D27D804562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 000000140000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94AA855A0EF256ED6B3F83CB4938E1BCAB172AA13D2FF813E233B4C2E3DB18D27D804562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D933090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000018F224E19E61C8A7076585BF7780AD32D73D04D66A52F0B4CB6D35D9496906BFB05000000000001C0F7248E24BEA5635FD0F3F3411F1A20316CD29E2BDE6DCCBDEF8AFD463CADB306000000000001BFE2E0B4F4BD9B2B955C3CE73D4D0E703C44BE5168224D99756D865D86689E1607000000000001EB5D1F16948BBDEB3335E0F93C3DAC5C3FF7DCB33B16BB28D3826194192729F80800000000000194BC268989E8C957203F60EFD29089692A7FA0980912BCCB1FF3D6921B980561090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B832C73668D17AF4C29F2A72A1E8DC0D74C9F2446DE7A42F50A5DCA2F12EE84A91F75004E452A4E5FC799176A42B4D0A0A0CDAD9B44CC246872114650941B08315BA68E4B39A713B08A66F1715FE9300E5AAC533E37AE289B74341BC1DC7C75725C9838412E48A4CE312DEBC345B16A3A1F6388F350997448653448F6C7C91B7BE24118C3A0F4E431E88766E5A6C6113C8A2D1D2646B5EA5821C90CBE2CCB6CCA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001521B6795E3B31C6F469147CDE5776D1FAF80EE268B570DD87C1895E195F358E50100000000000135050ED1EAD3E799B63D5EDC01FDE9B7E3E8036A429C0AB56C909CC2B6378D6F020000000000010D93E097DE2D5330AA792D234007668B3E7F9E699621D298D2AB7577E8518A0703000000000001F2616B47D5F8376AF6A5FC658A75A52D032F7A1710630905C152957F41FA240104000000000001806EBD8412403D61AFCBD000376F11695F17BD253F82340C13342F750D09B2D205000000000001207581737977FDD59550FE1E0E62692061E1E37C554529C52E427434D2BC50AD060000000000012C3C45D74BE1C78902947B902756864EFD771DAF34009F91281FBAD0636A74EE070000000000014DC0E1A0DD7194009DC2FC5355C4D62179DA0010E19737654D7DC0E4C9761DFD0800000000000112F03C455D30919DCE22D2F8A0D4B5491A8188A32F17059A6AF994ADE911EF750900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE59F8968E30E844A031BC745FED8550EE78B1266A91694B967E66785403F9FDE097DBFF047A171318C43FB2472127512463FA79877B475C7F810D28AE0BA7C5966102673F9F55653D9E546E378D2BB17CD35FAD2F50C5372DF7871B1F1DE78A72FC84F2AD1BACFB45712FB13E3773B3565B021D30A31602528EF16FE6D83795A1A8620E06BE25AAB07A8F3F1EE979687840B7C863D0D8A547A5F7197FB72024DA7F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011420B60C54314ED8291B4F251FF32674EE6A3C3609140380F6B20865B7AE643401000000000001DA6EC89DAF2B01E86C06ABE8043C9A6EA0562A18C49B4A9497D347FAF8EB910002000000000001A0A42481338E08706BAC35F7B5F5D93432D40144F47A0F6790DF4B68525ED740030000000000014A9507DA8B4941DFD3D5E9A02EA050B97F9887A65D93FD8723FDC30C7E2AA4E004000000000001BDEA75F9BF80695B677BD7E643AAB0D6DEE791B64A29E66D796C51176B9F718C050000000000014F174AE6AE0AD2D1C856FD802C756287A8496B907E56C4BE48E85864F71DE7160600000000000131702A4AC2D7BD2722AD083379A254918CF9EE0656A5DAD6B07C11A74BBEC85207000000000001C2F54B401EC9CFC51F249ED76CF09A24665D8603D3747E67778075CC7817C4D708000000000001A1D56697DB12706AEF7EF31B1584DFB73FC269AEDE8C438FE9B6FE17C7A65986090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB931516966BA24D9585F1C0B04D660E629B3A2A3F31AEB6AC3EE8DF4DB67DABB5C332B61CC10887A0A207201703DFC4C27B774468F2CD9C6EFC711426E248C33EF946923D4C1AFA7B608F9F080410AE8F9F08CB38D5C0F6664EA0F630D34DFC55462334F617F3E4AE640E6C2D27597D4967E08EDC91704B9E3EE49EC4F0506994C3DD1027F8BE7FC46589CC21F9BEAF4F4130BC7D8325FD638235372E12CBB84FC424BAFF7D301855839698FE2E38B63BE461E681B43A02F99E466319E808084BDEFF59DC9DA0BC5F523A21D4525D81501A83F357BAB3633C061D403C7ADD90CBF38C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A36918612009A7CF4A981971AB37B767BC120AA994494DA75CABF22D1FE63F1464E981A0FF2BA93D3AAF2CEEADAFCB80FB7D012A588D4E409051A44F7287EB74B23A7F9A4302D2E7EA81F9FFD74D72807123DC3529B24DA2AF50619784A32B75985FE5AF8191B1CCF65322E266C37555CC3A971BF53E46DFDBC336CE5DAB6A84AC0F17F219C1DB9BD42A4F9662C74AF602347DE8A4EF176A34EAA287C9615F90FC02ABB78D80A6327768932976729CC4BC564E870C58EE9889C877CE31BA913EA7E454C0868D80335CC063C57D0BC1FB3C5E09B3A20F8166F8BDC41B01A8EEB62127C5BF88686BB8D0350F7BE6B56E0CE6E66B0998140C6F839A1AB13D68EF718809E2973CBB24BF5D927E83DD6C16C292D94B6EFE4A1BC9E050E8D6992BFD1C6F906C0A7B81474293A86ED095FD785C5BBA70F51BA7D49E9A5FFCE8193DD10914F642178026F159AE536FC1FABC7B78A3C2DF55D0C8E1EF23883C6FDBC053B447825E75F945D8157A967B58B0574C6E0615387CE1652DC027B72C45A8E9A4287219D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF71E8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B1A8277D00D5F8C835AB2820DFCFC4C8AFB2CB247B6DACFCDFB3765002D7D6EBA358848E7C7C63DA066252A81CC95E38A556ACD239ACB010A8169696B347EE86AE99CC7386155ECC56277B39192742ED8C959F142209943A017FBCE130FBDC3A491E7F650C98DAA0497D6C9CCABFD02921ABE4CFF254FB1521C702FB19F3DBBA1B691F7E44003C618C1B0C1B68A840B9763D43295E0CB779A59EEF7ED63AA1020069B2EF88BBCAB1D03693FE34C4C497F7936878D4DAB7B75BFF0FD8A0509D9A3B0CF209C9B7D09732CA0914617778AD289AC2110692D502C8DC75316530280FC926A62D46620A91EB4C89377C47ACC72884CAE39545022290B0D0EFA74045E4FFE5B7950E421091808852738371BAF20E81ADEE43642303C0F979B8EDAF4B47ADFB135B60A3E4F0BD2340A03D9F774ED36135C7C7241A89B2E9C71979E6BAA1E4D272BEA996623E399F2DA2AAAF6D0CE10191BA0853C08743DF8F9C98575E4F398BC3F19CFCBDB00B6C71E6B2B86A0E3BB72811DA873A3A318F6F334B64992648C9DA43BE0DB9CBA43FB1191DB64EA575DB1FA7F5E345ED532AEFC9F878894723ACC25CFEA3765FD8B4445453AB184E6C5A33FE8C136C8B401ED890A840BCC8C13CE2560D86119D74B6258D4381A4813572B6AEE5DB91BFA38F1E36EFF3DE17E255F8302A3A8161AD44F095659EEBB8E99100B7A19BCB8842ED58C474D1FFC28FD87A032D583050C09C64D4AE5F937743FC5E4705D9EADC758DF2CE55F240A40267311278E9198452030917F0ADB64226D6D413BCCB02C9A5C830AE5F2DBF73BCD8161132CCF43553B8FBA8E5283C953AEE50DDCE4EB59D29E4A2E5DA0530B922286F3588848CAFE9182175706266C466D65F41C3C18B000789C74952E3E2FEE44CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D58C6E04B24FDA2C3239210393254B41DA390EE357C7C175EA1DFD32FE5AADE666337542E508FAD05AA818E37539322BE1320FB587B83E86AA18434C47CA39E9850984F7339BD164FD46557BE86FB71B18CCAB5C34449AA65150D6F47A8117453D706F30DEDEB127BBA56F23193113CCBEB626F61BC4EA2D5053B489414A7F9731010D4333E72690C936D00367C343DA301A455B4CA7DCFC4215B0EE5185F1DFEAD2F09542D42C8CC1BA6ACFA452C6237454C5D115C0F5E04479131F9F1ACCA098EF0ACDFEF6FA39E4AEE14B0823E911EF2DAE145E261AE05A117E5A52E9DEDAC73742F90B4EAA8AA944F14679B0F72AADF6B56B31F3A2AA0AFA243C3DCCF6FFD2799FFA1F9861A5C04B0A8F68CC1BC8C90703AB05FBE50C15F06B04570370DEBB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832121C0C078E6BA4A80F1A20BD16BA90FCD04D43A0927C164582A796C12545CBD0BE45745F9E0090A47F31AB9B11E1496EED876912B13A841C06B6A5E812B11EC912A83D6B8663FBA403442AB4C70D3CCB76BE6686CD55D831E8DCCD05594F47FD58A835E3132D95EF4B4E8EBC275280999BF68305531A7F9F5EF2E8ED77C42227D0ED07B337CEB70317037ADA07819791A04BBF73646CC89806912EB3E2BABA0C80C7EB7BBAB7CE68583B609A5152A39457D51EE0A3CB4E897EB6363CB767057ADD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C63F474F26E2917A9A1B025C28BAC7D53E4E150E981E0D5BA4129911F99588369CD97444E871D47141AA795560B9576AF7870E3F62BC6F010869F6CA393E48A0BF5BE7ED218D65D942EC0F815F2258A47F7A509B6BB999C17B28D46B7D3CA59061D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C09FB9C3782471D5185D98077B9CD560F0F2D8109B8F2DFA711892BAF0A4A828E506417EECDAD332975E49F3E9019CE173E2ED3985D7C241AB4F7AE082E8EF49FD6E7D8241F8BAB4D68DE3288296539D0DDF68497D7634A964B76E82AF13767129B7FE5BF4C85685F9C1649B8A52FCBAA9B2AF0C0C2BE1904DEB98ADA34507734E7937BE5E686F6DDD4E57D5EEF9FDC2164D60CD06AB5C9D11B840625837703C3CEB44B6542B684CFC5EB9B3297D946E7F698FD75C5A824EEA9328EDBA65225623ECF3B1F560C0D9DD03CA404DDEB74F901FA06FF4D2B0972C31F94450036B01DDD94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB0AC0CF31A27014816177F79DBE703195F44C47205EC4A5CBE62146B5246AFD86660BB52A30FCC16AC9D773E97F581C7518D007FE0489C09FDFA334F49313FAC2B579C7AF47F9946A85247DC902ACD5E0B22949F45945DDD51DF6AB0FBC225603D7377F93D29F2DF9500194E614F93DEFECBCA3AFB03D22F8FD7661D9D41D62D3F34476EDB8FE887C37129998A21E92F020460D3AF85356DAA577666F5DC0BCC5986DAAF87F5A9E602BA73B7392923FDC5B81A6BAE67BDABA7F7D2E9410D160455BE2CC6A833BA1B0F8FE54852A576BCECECF9BDAEF1C9B426B3DBCA32353CEF2D782F9FF8C8DB114C65E259BD077E800BBF0AF92AE1083501FBCB6D736C848AFA2C836F2E20EAC0336B58D10000EE1E6FE4AF2C87B2DB73F0F695508E653A3755D0CF17516575A25E8960FFDB7B1A00FBED460A8BC7EDC370A52E214885B7DD496596F52B1697C11D5127906C27EEA91E5D3E948E752D54EDC1A8284B9330F1BAF79C2B31C41136602FB4D1A7418EE586E7386677F90D185CF9D61FD7178055651AAB6AFAF6B955469C05B619297155F922B97B7FD28FDA0C0FF3BF34081177EC83DC0433EFB8A1417D60691D76E15384DADDFE66566032B722D99F959653F5C68D4FACDEB4DB5F9CA52CAB9D78109D66D75ECA67FE82A790ADABA4C8F8EDC5663FE77361E78A43189D2B89D1F26535B1E860C9F18E7A3BC6892A68C68AF96C1F4730192CE3BF69D4E7048912FFAA309913C054E041306B4B0079D606F9EF3E08020379FC3A11CE22436F7C8BE6C5F5EE2C1C1778320456C18A68F306AD1B55954389F635A502169454E7C432BADF0A68F529903CA29C2B836DFF01B67CB745A77A9E7813A52B92C810B51BC3E71D7AAA9A9F31EE4542965AA0F6F9907D1595A31E720D4A7098FB2D72F01F8B83BF3A93D05157307E2B595F0609BF2C8B94EF6A5D60E53F20C1559A9476CD2391127B12D77357269359C424A769021D139860DCA4136B718B65880234089C1138705945AB76C815ECB06C01C73C60312FE6DE218F09C1607F528CEDD2898E077008FF6E47C4FB6B2C103BA92C399A24CC38B373B3D7F00D63E6A42412F710C62528106482F703ABC7CD198A24723A6BE730E6DC971D468EA20D76800F938E651FAFD425643ECCDE70BB4DC1D6FE4E9B3D3624C330E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD6847C7DCD156F805A9A513F17CFB60F16925F4C587744E4AD35C7127757AAD37B73E5277D6614F0C315BB9E3BE48F654AD2D343B3967FCCF5387EE8297F2F74214B7B154E1D715C8FEB898A1DA31D5A8ABAB9CDBAB991459E62BE9F0E0A69791265ACD8F7AEDAF736FB944D3CEA82A1B3F23ED9AC0025760D260009668580A7FED8B073D52EB9D1847445D2064669D9E03116C2D999F3274876F37552E2D8A04E4409EFB415FFD9571BBCCFDA01333286A5A934E32D7C6D7EF3A20DD86ED5391AF91188FC2BBA388067FA443275DF1C06B23BEBEB418CCF1A7CA0E4BAD57780AD7D5528BD18362F273F0D97C081E502F32EFE1508B343268F1D2EB3F12914313283E40F4EC9F02AA17AA8A310FF50DF2712F49896FE31BA07A188488E45EB59D6BD6B858D527BBC0892580637EE631FDE8EAC14EDEB1E73EC75C8C241294EA628DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF47606C4D632B57BF57812D2B2CB85C631F239710C05C7743C2F4515F6C64CBBC8109E7FFA421A5A637256FFE7F44413BBDE5787EB92060591282ED69794E9D64356A585D5E293E705EFC493596D08F3E68CA984532F71A20D81C4BE0CA989A19C2FC268CACE37F8F2D5B481F2A4F387043A4715FE805C6FE2D4AB89DEBE10CAFD406F37450F0E477859629CE2B957F3415CC4E2CDB795EB766193DB9CC1E5D34B022FF9C01B7ABAB66A08EA5A0983E6E85954C92A6D3B2AB9D45BA49B21D45A3468B53440BB45283D3251613D162A9CE508A5766740BC16F13842C2F89F2396E3363A1934E3AF2E7221957FDBC5F2BAA72B6E62BAEB9E6D33B248A5102714178A60CD3A02B6E121E1CE591185608500C11AAAEB039497472C12F766386647573D2974687D3B63D655D412B1DC0D3084791DC9CF5BC4A42D6D3787A187D4765E5C65894BA159FCFEE27FB3B36A54A9FA312C81EA09C6762770B9649872A738FA0111D745A1F9A0BC53FA819D6E7220FB07293058C8EE51270F86D956780BB52984745B68DA948F7F936345F770F38661F35198D5BED466C3E1C7A23DD56D543CFC93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B7871339ACAC858B546C9139F4B917CDA356F04B779BBF803351C1B452BD9EDD0E2DA226A5F930C3C97F43D4633BF11B8BCEBF646B8608685E36F0ECDE7C7FB5F977E4D61038C745DE151D832D47C979224CADCFDB0C82650055F1519B94680A840FA14B55B2190C71AC1F7A7AEED989BE8C8AC61149A0C809449B677AC353867D0185EB15322792A3A7E328FEE3DF2230E4B70551FD7F9BD57BBEAF02E40124C58F019EEB66602B9EA10094839EFA9070F5C2DA3AAB6CDE6EB58246A59AFFA0352106F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C013843CFEF1EDA266283A5CE4A6ACD7597519FBD097E9E460D9B071D34EDC61672D14E6D9D4F9A033B5B473A1B13476C3C447E884455A5D168DA793F9E2F09612A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B2BD0A2D4978F82258687586F9E6EE6AA21877D8A2C7AE37332573C420DB9C8754CC20EB937A8B94056D96EF571162B0106AEBFC344B5F28D52B8CD02F6168F45B321639DDDFBB333C5B872E80370F408EFFB5CC7394767F8CEC0CDCD7C9189E1B24FD29C7FBA4B14F30B8F5996155855C08A749B6AAED58C55271223A53D1E8714549EEA65B9A9245D9F5AD2EEBAE82637B9E3C78A24B5262873759CAE9AF9054C3230F88509E71CAE2238AA2DA1C25F0DCBFDE9BCC7B234BF1EA6697DD4E8B020B099CD92492855F1B528BA0B359BDEC1E77245432B7B1B2A5A7B969947A2FCFEAB2E94762E2F3F524E88E6FEFC4DBECED7EA550E6BCEDFF229E69D9C7C7803FACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E9847ED6D3A7874015F0AE87EE37FB6C478F7330A07D4C59E314847065E2F1F5F7F6DAE557F85B03FE6BB31B28A40263B64218FAD4572BC5FF2FD4E3F8F9A8894795658466BFB5DAFFCD99A69D532713CE072D81A42045933CDD30DD257F6C9848577D9F8B09B5D7BF71CF202AC4CF296E05C6A7ADF77D8FC670B88DAD02DE5A80D4168F7F72A7252B0E421F9734012AC8A8188677647D35ED6199EB300A6B71111D7CC77F04AF5E559A0D34CE1E1490576716A861E79902678C1241CB6F614176147ED88C82A99CCF2BBF62AE65572300CD4FB12DED4B6B0901D5F6BD02F036BF66B095215AAA76BAA4A07E2C0CAD2B2D76BEB56956C26ACDC11FDEFE9D42C6A698C09F0ECAC502F2F7E00233329DCA9595A191DF6C87B728E8F9B59105B9074992A62F2DFB38852C7F4BA5BF782395E906AF48136AB2DEAB4BBE7F0F79867696DDAA4176F14C9DC7A301B0DACA30332F73CA3356A62A4832A12DCCC3D696505F59E73148ED6401A34F6986428CB1CF18FD61DF1455A042455FBD97A76A404E65CD0BF41E26465281A0BA11EAA39CB48B99F2354BF5407629727B52DBA14B29C65083AE8B8891AECA5500BD15DE9E66E7D5C0104891C17A108B79D8D96D35F12170E2C930F8F16068AE3CA8511016203A1A4726CFEC7B6AAC959B67F3FF1E4AAEAD667487299703D38472B5085FC55B9BB775574AAA118BC81076CD53A4AA7E927482B1D617C09C6C24DEB07DD41C2C42B6A0BE168493CA5A40266AF5B992B9B2C65CFA82A2EFC515948A5FC521A7F49DC4BBAD296BB6FD4AA6FE1B7A7726229C03DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D973867CC37DAFE8FC39332DFD321B1ACA45587EB6D4727F5AFEC4178CDD8AF03FA0629DA84844B5131CC2AA07E2FBB8F80D3320AF5C1734031AEB68DB8B6C7358F775E8538C260FE6A79DDAE2BC7D40222B2942A2D8ADD3F295A135B5FBBA319FA3636F56D1BC8CBFA175EA61C1F53980664282E56291B4ECE5B5FF33C2141F04A3FF83EFC062CF6C635497FD03D6E56E405C43C4A31DDE872C4E277AA190D1D8350A298F16BE75BE305891F9D1084146199960A881C34318CFCF1366E82A487CEE95D5EC9F9756FFFC9DF3A1058E367160B321753C937D587130F9AAC766C19F033CCB2D886AB532683F50D360D10DF559AA16DA2C0E3203337B46EA1FCC1407675C5057052EDEFFF36BB2A6331522DC5CBC871C52CC35E95DF677771084A6E3E10A56111E6B9F7DAEB1FAA11B9CE5EA450A7D75F2B7266193CEA51A9532D8A32A2D4C275ECE75C3A59C3F02E3F9F40968642D6387F752C801A761F121A3EEF4F6B0AB83B7E815E5BB9D67EF85BF9DBF72E5E6DAEF4A6F7519130BD4F826A82D23332BC291A3D320CBFBE4BF1A143B78FAF7C1BF61F30801BCF715A05F2F7429F0D1A3B9F90D191754FE3D761A77CEA46082D3D2CA5BF26EF05257DBC8B72D156920EBCB1E064FBEC3CA43AF31CB2A53B246BA02E3F8AD4E07DE794CC1D8E3814DE61807A116F768CFFB159D16CB7214EAF1F52452B768380F4E16E2BCC10E82A027148477F2C717844DBB1677D6F2559AACA58E4759D40C7D62610399D6EDBC6DD4DA7904D2C53E4D9E07928FE181D503C5D45D6DE07E767025D9B0386F8C123C38CAEF00BE2223E8B1F46370B1D20FF0DBF78CB6A016D0F72F07820238885D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3A1E6EADFE7066FC6A5781AF310597B333977E34D01483A860E7D986357107DADB4F5D040550E524D9D1AA456CAED45FB5F6475160AB01C8AEC46EEA735384E4FBF205BB117F68C03F6D301E5C469033B05360DA23CF49DA36E050D627B2067B30983B2B426DCE0B78C0500BD15B3D2572537DC9B5F0BC0E1A12F533F58B2E21102318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3F5C33BF53D2A951EA7BE7FE2D487362EEC1DCB93920B266C5AD39FFA0FC6D4B335B1355A6D8AD3CFE51E9F69C8961A82831BD27F727C9030A816E817783DF89B519D6EC14C9CD88B73FD6152250E229BC6CD8C952777CC5D670051B18F5AFC99860FF7387C5880564703541C2883BC93C5C0EEFA57AF9E9D9D04EAB3BA87782807C37D299789C60C63CC2E86B5610ECA54D3949E17070B1978781F705E32042AFF28FA979979A511C5D14ADD08AFF7DDAE858415D7B0CBA138BF6D1C72C99A9564FE6CB5C9ED554B98D21CB796FC053CAFB4B3E8214F44643C99D9C92EA847A1B6DF3BC21FBF810F9D04B26771BC6DBAD0BDE30265D402E62EEE8ADC84CE8AF0FECBE8F68D13501515B8C28F68AD45D9D1A454904DE944A90C7500049FB74979AE952EBDCBA09DE543283CCA44D3F00EABF99DD714B8FDE3755D30105AC8CBC4569789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411935E2773E3B03C5E4959D9A2F7D55B05B8574768DF40B5EBF76FCAA69F463E0FAFC9F02B01C7B89C1AFB661B43AED07A9D54A6669DCD9022A4EA628CA69577EB1 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 9893 sm = 00000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6AD447A5EA848807453245A18CC01A94E648515E259B4B02F4CB014A3064FACFB443FDD5FBE6890778BF1BFC187A67A07BF1296F0847C5F3CCA1A7FB1FD9023E9BCEFD889D3361070C554580F55CDC11D8572F0E0F241E24FF7A7AC9E3BFD197FB2D92D18C1A9520CC21A0A17908D121E1EA426738CFE364AB99172E83544AD0F868149F65E73EF30210B36E03DCD6257185F671F78904B3F11EC67EAF994D1B9D8E83842D91853C8E1A4E123A8BAA85CDC3BEF892DB683E3CFB4D60DF60CF4704069AC1646996731948816530C43C82CC1346A5614222B29B4C635AAA4542F11023B3A0B4EE1A22D367CD4E000A7067C2C7DD162FA09E777CA9DFD3B331ED208390BEAF62B72F91B502F69B6340B31F9D76A961DED774B471ADE78E037785CB71F2E6BEAA7180B7DD54525F52523DE6F98A205A6866C5B7489000B5CE17FF49A0F7DFD04029531B2B11444442249E7EC5E3AFC17C625C1518D4572F25A430957FA54D60EC4408C15DA7FC4B5BEC5120F1966279A400F0AF374CF6ACD439AB030AAC07D59B03A06086E043466BACB5E4DDAB7AC7F43409219F27561CA6168DD1793B0896752FCAE3699AF03C2E8C8725BE6073251317D1EEFB497336A32C511CA0B7C50EC84D8C0000D09632545965D732E921D01DAE77512180C12B01A2791BDA2E9D5A6B8D5DDBCDC0663306EF3064C548CE33CD8A644884C48ABCD720EFA3535EA50DC699D5233C7C07E22FA98EACB905820F49CB77A44374C0219D53B7570F655867F45720C67D422D5D284328E5439C2BE923E7F9C5307F30E5091A88A028D854EC9C6EDCA171B4E22C3510AE398B72498DDEC9A789612017CA366B164BE9E9FF5B29C0119111C7E194CC862333007578AC87C0A31254C758E96819FF2058952B7DC0473151EC0D9571297FA6AB0793D3EBB4AD559E0E367DE90BD20B96EC20ED1097E1670E2B93FA14EB1BA35D7B2C047E6BE110205B80B6F169695CDD43E5CAA8BC694B50F502DA1EE6CF34B148C124CB9F9A7C126FDAFAD4A5D7C10EC37376BAE08A0C313E5AE477A8DC6E0B54DD81E44E4E892F50EAB30D7978402C58B18890976C506E91D31F7FB3BC77EB0B08B99B12FF9572A673DEF5D64C16A1550E16E7027880D8853F1174E4B6A6E58BDD3277BC2B3E956FABCFA1633528BBD412D3E2F6C95AF02600C32B350543F091577CC486749C1ADD068F99DB36D8C4C59E35F94A4492867F7A94B9CBA5348F7071C5732563F8C1C008AD8C1767EC2D2ED2F3461E08EAD719760B6F43A811C31C2FFA680BE036C0982E60FBF9CF3FA705C58F3B2270A78E69A252FE4837E7E94DAD4842E9028DD986E5AAD6A8F16F9F138220F5672F8BEF56252D8E93E693A43FFC9AE96ED514D7405F080AC39BE1BC1F7BB117AB555E88AA0B934AF842719315E9C4CAC0FA685487177D3873EF1ADE626432E99402AF7ABD96CF8885DE3905BC9A2E4E755BE83AAD7C9280D0658507C51D6534AE73B220CA73A13917887367D055D38A65273890D1FB7A3AD50A7BEC3E7B693C41F717FEC260DC06486D04822DCD3BA1CEB89F12DFFE3534B51B107E75A3D5A0CB2436E8C9D8D85EA68ED5A5122F037785AEBAF31CA3BD4D001D8E9151B894ED06E313F1B4BBA00F7D5DF43AB472D66CFE6CE3B96B4F37F3D75356035546763398E70BA97BF84F3DE6EE6C9C674772ABCC1D8FF097688E3BF3AAA1811A2328704DFA7347CE5F938B3B4668994AD8A581E922DC72B14208BDB9671D73960B0747CFB99B09D25B1C0EBDDD5CE383A703FBE27C8A497B3C97FE7DF05CC6F36D18AFC8DAB6866EA201DB358B45AA0CDCA0959B4F0BF7ADDCDB0CF61ECC7FB7936AC13C35553CAB1747877424EC9FF34B7BF34172C1F65EF2D3F43DA07CF42D391577D3C7C28A0DE98276CDF9601CD0D4A8E79B7D27DFB2A31D57B86874B4E03D759940F88FAF5EB05BE1B90273FA0BC0048267B43376CDD718399A354E3B3AAFD9BDBA4BD815108B240DEA39524C501079A2815C04018C444AAC8AEC51B9243CBCAD6F5857BAAE18071F291C3D742C9FF3FC54A51D1CB8061D5A0ED4358E8AE0266816DEB0F3BA03299C533D554AFF476259527D312F3E6EB7E28290475F9E59C93E72BCDE6D87961B3185CA3ECD7D6A913D9F86EDB5017F5A1F28FBFF054D4058752C43C58B7599D697EE97FD109A46E627EBE3943B5044A18F1E08EC23E83B4146A39DB9ACA7CEEB0A93C4B5F1E625978CCA15C8C357DEF852277E400DC2D1BB52A35052545FA899B73D5DA8D6340B3C2794D4A24A4FD388C8581C384407EA9429D048B67D56B413B9002434DEFA4F2F025658778DFCF9BF148E70A2A70A185EB62720EDF55A36BA9C9359C49DD6ECED5E8CBCBFA03FE06416AF5AF976B8F33F4F73F6260DAAB08BF5A02A2F664E62BC3BFAA6A4800EEE8423D93ADB90859C7B9BD07FFF6433631AC5C062DDFE499E0C22DC5E3A10AB8D8D0C5D9A09833E106F1B8092E6A32B663C6EDC54366B5DFC4D1757DBDAE9F8E33B05A669DD692EF340F6C1BE587DFAED8EA010542245C17684A9944E53BB33C776507D940D699553C645E1E8AD6AC0BDFC48F9179909E135B6055FA9CBA44BA072D2A538BE604F88CAF5C2928BEF611C41113AD14CD4D92B45C3B9C0B8F339C7219E8982B9AC9C8063AEBC9FBF1978C1559D174EF9C55A74C7208114F94F2ECE9214B02D50834D401D4FC5E97CD40B375D0F6302502B3BB83098A6BFA378373FB0042E1578372BD4C2485B886668646E164CD67132C6D187490F3B18BD3A339FD5FB07DFA9F1F642E179872A32FEA44803F1728BD9EF3C177C047615E19B84BD6F8F61D368B32F78D2943AA14FCCB8D7551E69F02BCE1F438830583A0012B5A2B2A6AA8453208B991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EAF5C7A2FE46CF8DC6C729F18BDB361405C6D336725999A4CC76C94B5668A471861B40AFF393D6177502756D15DB5232BCD58ABDB633EFEA7390FF8BEA443BFB32F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD5894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB931516966BA24D9585F1C0B04D660E629B3A2A3F31AEB6AC3EE8DF4DB67DABB5C332B61CC10887A0A207201703DFC4C27B774468F2CD9C6EFC711426E248C33EF946923D4C1AFA7B608F9F080410AE8F9F08CB38D5C0F6664EA0F630D34DFC55462334F617F3E4AE640E6C2D27597D4967E08EDC91704B9E3EE49EC4F0506994C3DD1027F8BE7FC46589CC21F9BEAF4F4130BC7D8325FD638235372E12CBB84FC424BAFF7D301855839698FE2E38B63BE461E681B43A02F99E466319E808084BDEFF59DC9DA0BC5F523A21D4525D81501A83F357BAB3633C061D403C7ADD90CBF38C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A36918612009A7CF4A981971AB37B767BC120AA994494DA75CABF22D1FE63F1464E981A0FF2BA93D3AAF2CEEADAFCB80FB7D012A588D4E409051A44F7287EB74B23A7F9A4302D2E7EA81F9FFD74D72807123DC3529B24DA2AF50619784A32B75985FE5AF8191B1CCF65322E266C37555CC3A971BF53E46DFDBC336CE5DAB6A84AC0F17F219C1DB9BD42A4F9662C74AF602347DE8A4EF176A34EAA287C9615F90FC02ABB78D80A6327768932976729CC4BC564E870C58EE9889C877CE31BA913EA7E454C0868D80335CC063C57D0BC1FB3C5E09B3A20F8166F8BDC41B01A8EEB62127C5BF88686BB8D0350F7BE6B56E0CE6E66B0998140C6F839A1AB13D68EF718809E2973CBB24BF5D927E83DD6C16C292D94B6EFE4A1BC9E050E8D6992BFD1C6F906C0A7B81474293A86ED095FD785C5BBA70F51BA7D49E9A5FFCE8193DD10914F642178026F159AE536FC1FABC7B78A3C2DF55D0C8E1EF23883C6FDBC053B447825E75F945D8157A967B58B0574C6E0615387CE1652DC027B72C45A8E9A4287219D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF71E8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B1A8277D00D5F8C835AB2820DFCFC4C8AFB2CB247B6DACFCDFB3765002D7D6EBA358848E7C7C63DA066252A81CC95E38A556ACD239ACB010A8169696B347EE86AE99CC7386155ECC56277B39192742ED8C959F142209943A017FBCE130FBDC3A491E7F650C98DAA0497D6C9CCABFD02921ABE4CFF254FB1521C702FB19F3DBBA1B691F7E44003C618C1B0C1B68A840B9763D43295E0CB779A59EEF7ED63AA1020069B2EF88BBCAB1D03693FE34C4C497F7936878D4DAB7B75BFF0FD8A0509D9A3B0CF209C9B7D09732CA0914617778AD289AC2110692D502C8DC75316530280FC926A62D46620A91EB4C89377C47ACC72884CAE39545022290B0D0EFA74045E4FFE5B7950E421091808852738371BAF20E81ADEE43642303C0F979B8EDAF4B47ADFB135B60A3E4F0BD2340A03D9F774ED36135C7C7241A89B2E9C71979E6BAA1E4D272BEA996623E399F2DA2AAAF6D0CE10191BA0853C08743DF8F9C98575E4F398BC3F19CFCBDB00B6C71E6B2B86A0E3BB72811DA873A3A318F6F334B64992648C9DA43BE0DB9CBA43FB1191DB64EA575DB1FA7F5E345ED532AEFC9F878894723ACC25CFEA3765FD8B4445453AB184E6C5A33FE8C136C8B401ED890A840BCC8C13CE2560D86119D74B6258D4381A4813572B6AEE5DB91BFA38F1E36EFF3DE17E255F8302A3A8161AD44F095659EEBB8E99100B7A19BCB8842ED58C474D1FFC28FD87A032D583050C09C64D4AE5F937743FC5E4705D9EADC758DF2CE55F240A40267311278E9198452030917F0ADB64226D6D413BCCB02C9A5C830AE5F2DBF73BCD8161132CCF43553B8FBA8E5283C953AEE50DDCE4EB59D29E4A2E5DA0530B922286F3588848CAFE9182175706266C466D65F41C3C18B000789C74952E3E2FEE44CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D58C6E04B24FDA2C3239210393254B41DA390EE357C7C175EA1DFD32FE5AADE666337542E508FAD05AA818E37539322BE1320FB587B83E86AA18434C47CA39E9850984F7339BD164FD46557BE86FB71B18CCAB5C34449AA65150D6F47A8117453D706F30DEDEB127BBA56F23193113CCBEB626F61BC4EA2D5053B489414A7F9731010D4333E72690C936D00367C343DA301A455B4CA7DCFC4215B0EE5185F1DFEAD2F09542D42C8CC1BA6ACFA452C6237454C5D115C0F5E04479131F9F1ACCA098EF0ACDFEF6FA39E4AEE14B0823E911EF2DAE145E261AE05A117E5A52E9DEDAC73742F90B4EAA8AA944F14679B0F72AADF6B56B31F3A2AA0AFA243C3DCCF6FFD2799FFA1F9861A5C04B0A8F68CC1BC8C90703AB05FBE50C15F06B04570370DEBB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832121C0C078E6BA4A80F1A20BD16BA90FCD04D43A0927C164582A796C12545CBD0BE45745F9E0090A47F31AB9B11E1496EED876912B13A841C06B6A5E812B11EC912A83D6B8663FBA403442AB4C70D3CCB76BE6686CD55D831E8DCCD05594F47FD58A835E3132D95EF4B4E8EBC275280999BF68305531A7F9F5EF2E8ED77C42227D0ED07B337CEB70317037ADA07819791A04BBF73646CC89806912EB3E2BABA0C80C7EB7BBAB7CE68583B609A5152A39457D51EE0A3CB4E897EB6363CB767057ADD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C63F474F26E2917A9A1B025C28BAC7D53E4E150E981E0D5BA4129911F99588369CD97444E871D47141AA795560B9576AF7870E3F62BC6F010869F6CA393E48A0BF5BE7ED218D65D942EC0F815F2258A47F7A509B6BB999C17B28D46B7D3CA59061D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C09FB9C3782471D5185D98077B9CD560F0F2D8109B8F2DFA711892BAF0A4A828E506417EECDAD332975E49F3E9019CE173E2ED3985D7C241AB4F7AE082E8EF49FD22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A6E7D8241F8BAB4D68DE3288296539D0DDF68497D7634A964B76E82AF13767129B7FE5BF4C85685F9C1649B8A52FCBAA9B2AF0C0C2BE1904DEB98ADA34507734E7937BE5E686F6DDD4E57D5EEF9FDC2164D60CD06AB5C9D11B840625837703C3CEB44B6542B684CFC5EB9B3297D946E7F698FD75C5A824EEA9328EDBA65225623ECF3B1F560C0D9DD03CA404DDEB74F901FA06FF4D2B0972C31F94450036B01DDD94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB0AC0CF31A27014816177F79DBE703195F44C47205EC4A5CBE62146B5246AFD86660BB52A30FCC16AC9D773E97F581C7518D007FE0489C09FDFA334F49313FAC2B579C7AF47F9946A85247DC902ACD5E0B22949F45945DDD51DF6AB0FBC225603D7377F93D29F2DF9500194E614F93DEFECBCA3AFB03D22F8FD7661D9D41D62D3F34476EDB8FE887C37129998A21E92F020460D3AF85356DAA577666F5DC0BCC5986DAAF87F5A9E602BA73B7392923FDC5B81A6BAE67BDABA7F7D2E9410D160455BE2CC6A833BA1B0F8FE54852A576BCECECF9BDAEF1C9B426B3DBCA32353CEF2D782F9FF8C8DB114C65E259BD077E800BBF0AF92AE1083501FBCB6D736C848AFA2C836F2E20EAC0336B58D10000EE1E6FE4AF2C87B2DB73F0F695508E653A3755D0CF17516575A25E8960FFDB7B1A00FBED460A8BC7EDC370A52E214885B7DD496596F52B1697C11D5127906C27EEA91E5D3E948E752D54EDC1A8284B9330F1BAF79C2B31C41136602FB4D1A7418EE586E7386677F90D185CF9D61FD7178055651AAB6AFAF6B955469C05B619297155F922B97B7FD28FDA0C0FF3BF34081177EC83DC0433EFB8A1417D60691D76E15384DADDFE66566032B722D99F959653F5C68D4FACDEB4DB5F9CA52CAB9D78109D66D75ECA67FE82A790ADABA4C8F8EDC5663FE77361E78A43189D2B89D1F26535B1E860C9F18E7A3BC6892A68C68AF96C1F4730192CE3BF69D4E7048912FFAA309913C054E041306B4B0079D606F9EF3E08020379FC3A11CE22436F7C8BE6C5F5EE2C1C1778320456C18A68F306AD1B55954389F635A502169454E7C432BADF0A68F529903CA29C2B836DFF01B67CB745A77A9E7813A52B92C810B51BC3E71D7AAA9A9F31EE4542965AA0F6F9907D1595A31E720D4A7098FB2D72F01F8B83BF3A93D05157307E2B595F0609BF2C8B94EF6A5D60E53F20C1559A9476CD2391127B12D77357269359C424A769021D139860DCA4136B718B65880234089C1138705945AB76C815ECB06C01C73C60312FE6DE218F09C1607F528CEDD2898E077008FF6E47C4FB6B2C103BA92C399A24CC38B373B3D7F00D63E6A42412F710C62528106482F703ABC7CD198A24723A6BE730E6DC971D468EA20D76800F938E651FAFD425643ECCDE70BB4DC1D6FE4E9B3D3624C330E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD6847C7DCD156F805A9A513F17CFB60F16925F4C587744E4AD35C7127757AAD37B73E5277D6614F0C315BB9E3BE48F654AD2D343B3967FCCF5387EE8297F2F74214B7B154E1D715C8FEB898A1DA31D5A8ABAB9CDBAB991459E62BE9F0E0A69791265ACD8F7AEDAF736FB944D3CEA82A1B3F23ED9AC0025760D260009668580A7FED8B073D52EB9D1847445D2064669D9E03116C2D999F3274876F37552E2D8A04E4409EFB415FFD9571BBCCFDA01333286A5A934E32D7C6D7EF3A20DD86ED5391AF91188FC2BBA388067FA443275DF1C06B23BEBEB418CCF1A7CA0E4BAD57780AD7D5528BD18362F273F0D97C081E502F32EFE1508B343268F1D2EB3F12914313283E40F4EC9F02AA17AA8A310FF50DF2712F49896FE31BA07A188488E45EB59D6BD6B858D527BBC0892580637EE631FDE8EAC14EDEB1E73EC75C8C241294EA628DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF47606C4D632B57BF57812D2B2CB85C631F239710C05C7743C2F4515F6C64CBBC8109E7FFA421A5A637256FFE7F44413BBDE5787EB92060591282ED69794E9D64356A585D5E293E705EFC493596D08F3E68CA984532F71A20D81C4BE0CA989A19C2FC268CACE37F8F2D5B481F2A4F387043A4715FE805C6FE2D4AB89DEBE10CAFD406F37450F0E477859629CE2B957F3415CC4E2CDB795EB766193DB9CC1E5D34B022FF9C01B7ABAB66A08EA5A0983E6E85954C92A6D3B2AB9D45BA49B21D45A3468B53440BB45283D3251613D162A9CE508A5766740BC16F13842C2F89F2396E3363A1934E3AF2E7221957FDBC5F2BAA72B6E62BAEB9E6D33B248A5102714178A60CD3A02B6E121E1CE591185608500C11AAAEB039497472C12F766386647573D2974687D3B63D655D412B1DC0D3084791DC9CF5BC4A42D6D3787A187D4765E5C65894BA159FCFEE27FB3B36A54A9FA312C81EA09C6762770B9649872A738FA0111D745A1F9A0BC53FA819D6E7220FB07293058C8EE51270F86D956780BB52984745B68DA948F7F936345F770F38661F35198D5BED466C3E1C7A23DD56D543CFC93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B7871339ACAC858B546C9139F4B917CDA356F04B779BBF803351C1B452BD9EDD0E2DA226A5F930C3C97F43D4633BF11B8BCEBF646B8608685E36F0ECDE7C7FB5F977E4D61038C745DE151D832D47C979224CADCFDB0C82650055F1519B94680A840FA14B55B2190C71AC1F7A7AEED989BE8C8AC61149A0C809449B677AC353867D0185EB15322792A3A7E328FEE3DF2230E4B70551FD7F9BD57BBEAF02E40124C58F019EEB66602B9EA10094839EFA9070F5C2DA3AAB6CDE6EB58246A59AFFA0352106F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C013843CFEF1EDA266283A5CE4A6ACD7597519FBD097E9E460D9B071D34EDC61672D14E6D9D4F9A033B5B473A1B13476C3C447E884455A5D168DA793F9E2F096157F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B832C73668D17AF4C29F2A72A1E8DC0D74C9F2446DE7A42F50A5DCA2F12EE84A91F75004E452A4E5FC799176A42B4D0A0A0CDAD9B44CC246872114650941B08315BA68E4B39A713B08A66F1715FE9300E5AAC533E37AE289B74341BC1DC7C75725C9838412E48A4CE312DEBC345B16A3A1F6388F350997448653448F6C7C91B7BE24118C3A0F4E431E88766E5A6C6113C8A2D1D2646B5EA5821C90CBE2CCB6CCA02A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B2BD0A2D4978F82258687586F9E6EE6AA21877D8A2C7AE37332573C420DB9C8754CC20EB937A8B94056D96EF571162B0106AEBFC344B5F28D52B8CD02F6168F45B321639DDDFBB333C5B872E80370F408EFFB5CC7394767F8CEC0CDCD7C9189E1B24FD29C7FBA4B14F30B8F5996155855C08A749B6AAED58C55271223A53D1E8714549EEA65B9A9245D9F5AD2EEBAE82637B9E3C78A24B5262873759CAE9AF9054C3230F88509E71CAE2238AA2DA1C25F0DCBFDE9BCC7B234BF1EA6697DD4E8B020B099CD92492855F1B528BA0B359BDEC1E77245432B7B1B2A5A7B969947A2FCFEAB2E94762E2F3F524E88E6FEFC4DBECED7EA550E6BCEDFF229E69D9C7C7803FACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E9847ED6D3A7874015F0AE87EE37FB6C478F7330A07D4C59E314847065E2F1F5F7F6DAE557F85B03FE6BB31B28A40263B64218FAD4572BC5FF2FD4E3F8F9A8894795658466BFB5DAFFCD99A69D532713CE072D81A42045933CDD30DD257F6C9848577D9F8B09B5D7BF71CF202AC4CF296E05C6A7ADF77D8FC670B88DAD02DE5A80D4168F7F72A7252B0E421F9734012AC8A8188677647D35ED6199EB300A6B71111D7CC77F04AF5E559A0D34CE1E1490576716A861E79902678C1241CB6F614176147ED88C82A99CCF2BBF62AE65572300CD4FB12DED4B6B0901D5F6BD02F036BF66B095215AAA76BAA4A07E2C0CAD2B2D76BEB56956C26ACDC11FDEFE9D42C6A698C09F0ECAC502F2F7E00233329DCA9595A191DF6C87B728E8F9B59105B9074992A62F2DFB38852C7F4BA5BF782395E906AF48136AB2DEAB4BBE7F0F79867696DDAA4176F14C9DC7A301B0DACA30332F73CA3356A62A4832A12DCCC3D696505F59E73148ED6401A34F6986428CB1CF18FD61DF1455A042455FBD97A76A404E65CD0BF41E26465281A0BA11EAA39CB48B99F2354BF5407629727B52DBA14B29C65083AE8B8891AECA5500BD15DE9E66E7D5C0104891C17A108B79D8D96D35F12170E2C930F8F16068AE3CA8511016203A1A4726CFEC7B6AAC959B67F3FF1E4AAEAD667487299703D38472B5085FC55B9BB775574AAA118BC81076CD53A4AA7E927482B1D617C09C6C24DEB07DD41C2C42B6A0BE168493CA5A40266AF5B992B9B2C65CFA82A2EFC515948A5FC521A7F49DC4BBAD296BB6FD4AA6FE1B7A7726229C03DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D973867CC37DAFE8FC39332DFD321B1ACA45587EB6D4727F5AFEC4178CDD8AF03FA0629DA84844B5131CC2AA07E2FBB8F80D3320AF5C1734031AEB68DB8B6C7358F775E8538C260FE6A79DDAE2BC7D40222B2942A2D8ADD3F295A135B5FBBA319FA3636F56D1BC8CBFA175EA61C1F53980664282E56291B4ECE5B5FF33C2141F04A3FF83EFC062CF6C635497FD03D6E56E405C43C4A31DDE872C4E277AA190D1D8350A298F16BE75BE305891F9D1084146199960A881C34318CFCF1366E82A487CEE95D5EC9F9756FFFC9DF3A1058E367160B321753C937D587130F9AAC766C19F033CCB2D886AB532683F50D360D10DF559AA16DA2C0E3203337B46EA1FCC1407675C5057052EDEFFF36BB2A6331522DC5CBC871C52CC35E95DF677771084A6E3E10A56111E6B9F7DAEB1FAA11B9CE5EA450A7D75F2B7266193CEA51A9532D8A32A2D4C275ECE75C3A59C3F02E3F9F40968642D6387F752C801A761F121A3EEF4F6B0AB83B7E815E5BB9D67EF85BF9DBF72E5E6DAEF4A6F7519130BD4F826A82D23332BC291A3D320CBFBE4BF1A143B78FAF7C1BF61F30801BCF715A05F2F7429F0D1A3B9F90D191754FE3D761A77CEA46082D3D2CA5BF26EF05257DBC8B72D156920EBCB1E064FBEC3CA43AF31CB2A53B246BA02E3F8AD4E07DE794CC1D8E3814DE61807A116F768CFFB159D16CB7214EAF1F52452B768380F4E16E2BCC10E82A027148477F2C717844DBB1677D6F2559AACA58E4759D40C7D62610399D6EDBC6DD4DA7904D2C53E4D9E07928FE181D503C5D45D6DE07E767025D9B0386F8C123C38CAEF00BE2223E8B1F46370B1D20FF0DBF78CB6A016D0F72F07820238885D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3A1E6EADFE7066FC6A5781AF310597B333977E34D01483A860E7D986357107DADB4F5D040550E524D9D1AA456CAED45FB5F6475160AB01C8AEC46EEA735384E4FBF205BB117F68C03F6D301E5C469033B05360DA23CF49DA36E050D627B2067B30983B2B426DCE0B78C0500BD15B3D2572537DC9B5F0BC0E1A12F533F58B2E21102318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3F5C33BF53D2A951EA7BE7FE2D487362EEC1DCB93920B266C5AD39FFA0FC6D4B335B1355A6D8AD3CFE51E9F69C8961A82831BD27F727C9030A816E817783DF89B519D6EC14C9CD88B73FD6152250E229BC6CD8C952777CC5D670051B18F5AFC99860FF7387C5880564703541C2883BC93C5C0EEFA57AF9E9D9D04EAB3BA87782807C37D299789C60C63CC2E86B5610ECA54D3949E17070B1978781F705E32042AFF28FA979979A511C5D14ADD08AFF7DDAE858415D7B0CBA138BF6D1C72C99A9564FE6CB5C9ED554B98D21CB796FC053CAFB4B3E8214F44643C99D9C92EA847A1B6DF3BC21FBF810F9D04B26771BC6DBAD0BDE30265D402E62EEE8ADC84CE8AF0FECBE8F68D13501515B8C28F68AD45D9D1A454904DE944A90C7500049FB74979AE952EBDCBA09DE543283CCA44D3F00EABF99DD714B8FDE3755D30105AC8CBC4569789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411935E2773E3B03C5E4959D9A2F7D55B05B8574768DF40B5EBF76FCAA69F463E0FAFC9F02B01C7B89C1AFB661B43AED07A9D54A6669DCD9022A4EA628CA69577EB1D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE59F8968E30E844A031BC745FED8550EE78B1266A91694B967E66785403F9FDE097DBFF047A171318C43FB2472127512463FA79877B475C7F810D28AE0BA7C5966102673F9F55653D9E546E378D2BB17CD35FAD2F50C5372DF7871B1F1DE78A72FC84F2AD1BACFB45712FB13E3773B3565B021D30A31602528EF16FE6D83795A1A8620E06BE25AAB07A8F3F1EE979687840B7C863D0D8A547A5F7197FB72024DA7F remain = 1099511627774 -max = 1099511627775 \ No newline at end of file +max = 1099511627775 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-8_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-8_256.rsp index 791dde71df..405000a405 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-8_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_40-8_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHAKE_40/8_256 - pk = 000000150C866CCF8B4C8031FC149A5B5C6C504B1DE97B1C9B8F84B9CE8BCF536E3BC15404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 000000150000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A0C866CCF8B4C8031FC149A5B5C6C504B1DE97B1C9B8F84B9CE8BCF536E3BC15404562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001521B6795E3B31C6F469147CDE5776D1FAF80EE268B570DD87C1895E195F358E50100000000000135050ED1EAD3E799B63D5EDC01FDE9B7E3E8036A429C0AB56C909CC2B6378D6F020000000000010D93E097DE2D5330AA792D234007668B3E7F9E699621D298D2AB7577E8518A0703000000000001F2616B47D5F8376AF6A5FC658A75A52D032F7A1710630905C152957F41FA24010400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE5900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011420B60C54314ED8291B4F251FF32674EE6A3C3609140380F6B20865B7AE643401000000000001DA6EC89DAF2B01E86C06ABE8043C9A6EA0562A18C49B4A9497D347FAF8EB910002000000000001A0A42481338E08706BAC35F7B5F5D93432D40144F47A0F6790DF4B68525ED740030000000000014A9507DA8B4941DFD3D5E9A02EA050B97F9887A65D93FD8723FDC30C7E2AA4E00400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164A3FE6DFD83DBEFCE4CFEF2250893E21030934A382A288C69BF0FC7E9C92280906A4BA331C652BC4F904B9B54DCF3DB0651E43A6C83FB9843F85F0DBCA8D2E7F492200039906CF62A95D7B1830FDECAC0306B1A98B6F7B399E406A172202E29FA157E168F4B9C6979150F5AC2EF7769E4A729B6D59DD8F944E9A4A118FD06355D19B28ABDF256B4390DCD5C098DE989678AC25659763FC22E05FC4EB5860F400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018BB8E296C7509BC115ABB151E123D4E0343D51087A3A7321FD6406381792A7DA01000000000001166966BACD855719FD325B6CB7EEE8DEC0ABA7479BEEC9A71F451BD9EC1886B002000000000001E480EE1888B362F2F00B536DC0FB57F3AA94097DD543F05D299341633DEFE5FB03000000000001522E3D23E82223C8085779A58B7ECF45EB835F4B8FF5294923C95EEC4FCA5034040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096F5B92139A4B5768CDF2E35810BD1AB3BB40DCE3F38853783F6856552BF95A4A835590582BB7206044086C1CA3BD9B8ADFB09C40A838DEE80E1B3756F98073651454C1567EBB9BB8D9FEA16E9CB0F30FA5E7944CCFE2732FB90178A6F439EF2C83D0FD90FA196CBBECA9DE1DA63AB609F53BF11303F3AE2283195AD62587795E7CE13CCB19132890CE25B085F7AE282F8DE315DED51D9E7B4652285ECB3929B0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D10E76AEEA90CDFF9F15085B0834F5C0339E4C86D2CB52C234F6B18B472E8A020100000000000195C0CD14484D08075EDA691EE42CD999A552CA1A62318D9765CADAB553C1C5B90200000000000157A8A577120F2AD134FBF0E0E061E38A768CF935F4D2AA9A541C7A3D033A991503000000000001A467DDA3824B40F0D0D861A12328735CB8C23D1726982BE71F4CF68EEB4925500400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B07C872596E0E48193D8B6513232AE14EC985E19B27E231B2EDA344957695939677A09ECB8C65C93C63C6B08FE5DA691AD51D463012565EAE07805134DE6FD09BA7B3659089DB2B16DAB68A89406E67D63B3F0BC70C271C7D0295293CF5E174FE0609D593810EFAD6CD648BDF6D3253E64DCD6D2FA70FCDCEAF24B7C96A3E3E4B078E1668E5F6CB9A598FA202F0AE1DAD0AFC54BB46BEE1105C69C535390CD63000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151D5FD68390EB99D8038558DDDF270C7B6F86FB6880610C1958EC697B28F07030100000000000110E17383D0E375BD799216DC0666186C133435744D4C0B5160341DE623FB326A02000000000001446011ADFF0A4CDC66D4AD0938159A880A250A728A209F32F3AFA46A2FE4644303000000000001656C05D7A6E564380A829747834E40FABF67FCA7B2388E9EA19CB553E670F39D0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F1CBC0EAD4BFBAD01E0651103DD17A534A2CCD00CA53C713F3045B2389B81651E8E2C2B6629D127505EAE2ABD26F2086E9D6BD48CA6FC3BF98F99604F221DC203BCE9D61B756A89BB0B418249889529F7E8F070F35D35E572EFA012DABB16A98D0AC8A99E596A91468A1AAC939629FE780A45D8406B60D04C8E2B31EB7E28294FB2595F4E7071CD906FDFEC3EC3CBB02B03E38AF71EBE9EBCAE3DFC9A37E6B540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001FC2D9E83F622B942A7AB522F9BBA979A17180C4905EC5D9373BA8CFB20522714010000000000016319A9C8C78226547F3DCA6A70375F911BE4AE9028FDCCA6D161C5E3698EF41C02000000000001B15AA0B323C0B86CC6F8D84E17A54A6198649F962EADC06CE71C2D0FCE0F3F57030000000000016849136962E7C523775EF2B7BFA1967E4C45FD1B5FA9927D5068CB7045F945F804000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB939E6518A5122E37D4C257B0A0FD60CE0BA3BD55C9CBF369DD315A3C0609933D25DA403DF7E69FEB7EEE64DC3C13DC83217C2834B42876862CD48E99E69564B336506B85FDB493CF8FA87A7FE48DFE6778DDE8E8DD066FAA745C121480B5BF9D5F301B358D18FCCCBD24069E71836981F168FC49E6A4F27B00F6259B183B62CEAE0BF4AC0F53FCEBEB9052C0B48EB0666F361C5DA674B20B06AE2EA8783C2DD7EA74D98AC98C55748A368DF5B433C39538365EAE8DAE5E032A2008768FEB01F65D001AAC437781F742F536EFE2B3AE59EA12A6DC7F2712BA2D9D1C253D29B419A765985ACDB42BCCE5D64F6AF8368A5D122BB16B525A80C8BC5355A53917CC82262254378CFFDF1C7D6355F114E4FC013A5E4DD9AB373A0EFDC470854E20330BC00960ECBE882098D6D0D429A7AD19D3E5D4B78AC5E568C722A21877DA617190CB43123FB04333FAE5846953E33407080D04DF1417E740E7E7A14B0E3CA7D5B693F9615E1F7D417B9004F28D5002325B851C31F5EB31E1DAA80E6CFF22F11221E5180BB050888B6564A381E54401AF9409FE12A818B69BA34E1916092A0EBA24457EF994A1B0028649C9803045EC93CF416373F6A568856B771C3BB076AC265045ACE8E9BE3C3074D8806BEAA3B8B21F7E37F50B16221E14FE5503C615A13738CCDE39E2395E292119959CF686532CC3C9F9129E62ECFB43A091B06FD48ABE8C2CBE2D9691C8907881991CAB9D0D9CC7B2699F2261E5D799D26A7C8A4AEC40789B34CF5FE7BC8D24D6F0BBA7A5870E37F4D9B2605BB56ED9BAEB780CC74097DD8AA8741A97E22EC7B7434F81DE9D83CB9816A33C5A79D718C76A3442FE50C68FE1CE7AF728F2177F88E5168D4668518897AB050B57FF42AAC731E484B440D0D7B254383C74BE41C2AAEC02A8D8C7020355C4A1FAFAF4BBF56C74D78949D087259FE8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B179B32F9F94BBD8371B973B19E60C3CE2206A2061C7BCF159BC3A50163924774BB13C708A573472DA73B4C78DB30FEF310EA3643BC75D9155762D5B87809E2A727AC0428B746801D693074ED5245F29B8FF9FB782F2E57BDD89DD700EDBF12E8311946CAD9BCC98E3B1D581E678BEB1D0A6EFE15CF4052A1AECD328B2C4A8D5DDEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA36145D1653D108813E42654CB5350FFDB33BD2FDF4E416C6C0A61784E2327F42B2DA2AF040822C291D63645B0AC2377D0DE3FDBD99FF9CD9AAAE2B978C4DBEA95E330E90EAB0C4C34E88855C7C62C40B231AA1A9EB409D18CAA1C612A98F1B7BC25B18E3A89CAF96AA4BDF12F865EE7DB20273D7CA11970219BE997DD0EDE7A8ADFECFF1D90984694EF152346402207BD7D9166DC1B09F3C3520D109824442B8AB08869B0A4850BE3227E746998925CECCB422C4C05047D890E291B4E5478967A42BEEE34BA2765D86D183C71FB6A3CD86EAF457756FC000FAFDB24AF3C968E547A5223821BABF91B31B3F970D9F7C1FBFD16CC63D14243DB22CDBC266BFA4DE4B15D23B17D34C674649A695E80F84F6FEBAC0255BB155BD8B8D46FF7AFC532117E26985D99B0E23345F9A0247D834697804C6644501CA7D2726DA563C7F02371B5CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438DC67DF57A5B11025EDDC8915C57C8C72F6D6E71978496E206201184593506E39582DD2C803CE9204D2AC833C35BC683E0BD3CAD30BBCBF584AD38DAD30C9A400DE22F0CD6199FA6C622941E79F8C5C500389E9FBDEB8E1C926443B6FB0313DA9AABB163F5319C0164C1E58864827E38C18B7ECF6FB44274CCCB84B10F1A1BD76C8740F479777BDD7C557DBEFA9415B7FD50CA659E304EF4FA22680980D0FCEFC75E36231F740F38E9B4AC55BD8307F8AD9FE45B046B7BFF0F1B9FD5EEB82D474DC311A8418BB27CFE324426CD3311D65513B0A4D58515B94B8EE5ACC6815D6D1246527188E7B6C579CE42B28E1F273887FAFAA96D44FE6830E96081ED562FF4A08416DE4213A89CD666E2814FA290A5B1FA5AD6DB86B9E4DA85486E11BB36382C13607F50EDC83909F47A7D089CFEAF4680A6F2F10A2D9D9A679AE82D2DB387C5B7BCA11161E49E01C28D0FB7FEFE1C9A4BEDE994DEA4087F3B74906EA8E49153ABA49BE0F35C0572E9CE0C68B2267884C4BC4AD32BF28CE64DC7C825BDB2D8561C69161E075F48A40220159BFF1C4158187D4DE23C85979304DD4DBB98BAA57DBE6B7C55C271B134D61906F6ADBA4639BCAD3C1A70DA04A9409A4A35FEF1BC103D4F17BAFEC37C3F108B31327E0FB227E0E2C5B5410726ECC93B56D4D153572C2DB4EB4757F5B2232C475EB9802FEFB53EAC7BE6A090AAE98027AE13D2B338442FE6EF2DCF141C4D1AF00C7B3E973467FADDF6F1950ACF2BE908FED354EDFB147D6AC4B0740F87DE06E768293CC83AC995760FE0015CAC682036CCABA9C86B9B06924369E35688F7255F5D5422AB808D023B150D62D9A7DE4F7A5D28689EB038E9EF9D3366C3D777AB6D1C33878327018CC51EEDE65BB5FEEFDB1442B9006C76B10B6CE9EE1B6E43306DBB0D9030E3A191DA24634A80063F6A5269E77543525E11BCF02DF82E5921E3225EC97FC5F9174E0225E8C5D08B4C093EA28A19D03E908426578661E107E5E2C5371D79C31F11468112A6050703BB8FD9ACDEEF8D0BC31E82FB4F7DD0DFE8AE0216582E6C86FCBC1E7B3FFDD921F220702D827F145D79D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CE8D216DC6F19C3AC0A1017837C31D76ACDBD48F018A1CB14E98848B66A59F09AE557964888EBFCAD45C491A2A3C44B7085FCA7C983EA4AA22F62B99109F6E425CDFF5D87105EDC065810CA3E055F62FB80F5CAFEC57F7CB47A95B14A215714FB345FC73E57C1574E38657755CE991FCEEDC5ED84824E0E4AFD43205E126A3402910DCE16C59C8840FC7FC5ED9FE6379F9A388601D57B366FCF44FBD2D0C15A3D8A4A28D71ADE5965C137996748EFC7FB68ED165D2480FE34EF58A3169D03D0395D94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB08391412A812DBBE4FF09E10661B7DD604481AE6EB2F89A1FC04E393B3353F7547AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6222D7DC2F78B2E3FC4C8CEAE02E3FC9D7972CA803061F534D39E4F02809C7A18A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F9536829157F62BB003C2E45042DBEBA9622508F9AACA5FE89F665A5F35BA7C26D93A84F9DC744354C73885BC59EFB657317594D34B561FC2A789C919EE08D5D68185BFB2A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E1866ED93157270FB47C81CC3076E5B381E6B03127E7AE78C54F5F35B2474F18A2461297462FFAE651BDBF3D438E30420A3BA5686483DA2EACD874CC44102C09319C10FFE87AB2099A185DFD0FDDB6393B2F61490D65F93CE565C6575C877246044FD52ED475831AFE194BB163D0FE5A023BBC435497C3C16C8C7A85FF92426B59E588978E29EC0DAD032330035B797471B74BE366FA75D79D35228004D3231654D5F301D6597B83258DBE9284121A2BB21EF66F40C17FF135201D18092FA6A72B511A456786ECE1FCFC986A28C744DD4DEBCB552C638043B0602343CC796834B13660A86C5E3CCAAA1845C5165074AEFBA7C52190845A95DC59B1E8D6B052D253EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D1B478E24D9EDAC7EC8816FA54DFDAB0F181E9E1A8A6CD77A9EC29B3E35544898EAA311411BA22E8BA6418CF252675917A88572E0CE98CE03457996BA4FD86D07C4FA2D3487400E484F4CE0A83CF490C49588DB83ED1EE2A93B78101144586427FF43F434D3A40268920A4FA3C64C0F5F4600A8E52E01CD8210965C4B212DCC942C68D589D21FEF433904C26239698EA85C32423EF7AE1ADC90744996C956FD5D0683674010173EE4A110DA2642C8E1C4BF7B5DD3DE268A3AD0A261A30AFB6AD7D54210702C635C3E707CB1F17053D475A026EF57852DEC1FDA4252FDA2E69BA95C866BD432139CA8A4E367960F85B2FBC75420737CA4843B89F053192BB086BDC0D739B2753DBE42E1D45877097F3B97FCA6F43AC15DF883C3B42D9F472F910DE579301FF7F57D9857890651B64B6C1E8A7E2227ACAC7154D97252EACF8BC5FF430E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD637170756688D9AD3002B3148ACF0009CB1C0802EB04197FBD2FCE168B5FACDD052DD46F9F0B0A34295557CF741102E7592C24FA56DEDA63ECB7A2149E406C0943E5E554767D166EBC95FAF0E9B20C1E530633CF8BD7AB2A66CB105E108C1793B0D87ABBBBA9A4679A05C94BE6A698F4758B8BD38C51371C8043FC79E749D7E41C04DC6D815B0D32A779D0AC6E80C1D56B03C8EF30F6F6CB73A089B149F46BD4671D7C13B41A5B1BCAD94C0552C12CF23352200198CD876615EDDA7257E3CC94B732D75AF6D67A67929458E2639BA4A2967D05F76C4EAED429AC246CAB410B0FC8806B84EBFE1159C88D6E71EDDCC3B956F33739AD9FF6C43168B54FD592D845A54307AD16E42AAD4621D33A037D47D1002DE1AE0BCF2ADD9B01895EB0E63742FCBB5CFDA14EC9C63D94E3387E0FC22FB1B93D9065DF33D03AFA7D156BA719EB9DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF1DF5023719932492A5EE2B7A3B40B7C7F6814D179AEEFA584D317D536645921799727CED4C3D658D5A425D2D3EB1359C975FBE1A2FB2D11F37098B7234A19628624F07698EC3658799436DB5CCE6AC18702D4F27548F61BABC4807826E95D23889575EE119A88256D4326D4BBB48D0F589C6CB22E7F95D49F6607BE258753A6120CEFBC2E6C502138AEA689B4EDA13FDC39CC0759F392860168C2BA881FF70632D05E797A4F52453418035DFE9D072F0593E8029FFC25D75FC7DE13309B0AE4509D8A315C31F0FD0F480B598ADDB0D5A8F945FE6C28C2421DDB4A0DEB478478A49D5E628799ADC5E489FBDBC9DD38686EA7943969A5AC97497B2C380CAD367A8DF3DADD2E31F759AFA47A422D2A5F7C44CCB028AEC63EAA0727231A8BB4FAC096D19BA50AEC9522A00DDBEB86ED6DEB298AB433CDB7B4F15EA4AE08EB01782B70CD59C57D485848B16B9C55BCCECC876AA99071A9A7599868A9BB42F178BF3DD0FBB7EB52A796801D67E250148584C46F3E96898AA264BCC3826317B5BF7DFF55B6F3C3F3929FB552D79FFC1D014C52965F50B446DFC1CFB3302D8C7367A6F64C93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B787B24028E369C59743659E28980F3776146D88956F5E02B3E3116B8292C2E578C8708D4B518B95E8FCB7C7D5C3B16EF976B20FD0E53DCD6D92301061F2588F693A84052F8C776D033ED7A5EC71E928DD7CC7EED8DFC585AA94D8C9CF92D9694377C0268A53536DB64565FD9F5652B0A3634B381121BDA48C2D1FD9E189991D092178D79AEE8333BB0EC988417AD6CD9DD0DCBF6EFDB0E4E8D1B38E2A3DD01B3EAAD55E1CCB1291C87E2A835E86D2E0C0C3642166D2E9BC98CF354E28B6CD3F121606F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174BE4D5805F128D4A9B00266CB6CC792C45CA4E506C8B2504D13AC93044BF3FB332A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B275680E933FB83760E66AB8BBCD67108A95111001B9F8E85B6C96B4BBF952517D6330EB1C6AB68317C91468E90237214C46A5F496EE46E2E8069D65797581C01BA0B2DD1DFEE0F95C0AD7E426F877D0CD294CB0F3ECD1C65659D20594153630E46E4A32CA7D3B408B33227123C6449C4644192BAE44916FE60256703EAB9B2821973C8A37F2FC6B3B18FFE0E4C8036583B7E63E60A5EA8FE89401C8633BDC355FDDAD733A74922E73333FF9B2F9EAE2ABF957105197D92E7CAA56F91767E282E0910608FFA0E651B882398F8187E5203F8B56F788A4DE4130D211BAEDBE44B1DE0D729B926D5FBC98A1FA9EF01E415BE3795F085E28E1B32F86B0EC72DB22414EACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E947CA8092F4480FEC3CE1D8A6D8C4CBE3F7EB35919888B729C1CADAA559A42E1BBDA600C713EBB3487FAF3CCCC40CAFDEAE9B9C6EF40D5041B83973133A03156CE65E33173CC6EC41F0061D31797BF2D58C95B5B4E218AA783E09AAD39682072C6EAE7C52E3491E8B0345D3F6DD019D7DA6D9AE08FE40461B81D414B8D5BBE0672D892793121DDB345A2E5B1F8F3EECFFFEE5E425834717D59506DAC94BB9F31F00AC84767700A6FFBB6D93D4A9FC6F02C67F2710269A4162C284E0D9BF486ACFDB55A33CE915B41F167D533B268F96CE0C70A54377A5A76B1C8E992BD4908F6C9AE1B8A1129A6A94F2C1FA3EACE58297AB6E83568F0857FEBA399FAECFAC9FA94217BAD28BE66B04EF4EF7862DBFC7F9D86A69D63D84665C826910849A959626B2F95B16FBFAB29A97876BC2F43A43F841F6161648AA9D1689D67A4BEE2C859702320B726B0219DCC859A330C6C337AF2EFB0B9C8C689D2A7B92DC615BEF81F9488AC5E678E63D3E9C4CD4D2138F500D7967745773C58A8704107771E6AC93AA2307D387AF3CCF853E572E74624A7E40305FF4F57266A6BFBEEC78BC8CC981479D5A80F351588B5E378EC89F193C02A92E5BAB45E1C12BE0DBCAA00E85E73FF666690C4133023ACCD88989AD44530D63D54B090E115F6A25111B4F006B0EDBC73FFCA5B037240E88F9F4FDFF79F6874B6D6865B3B93037E272D66F1BB1EA9AD7952CE8F8F353C2910FBFC6F73626986970C6B1FA3F7D010A7DF2AD27ED28F727F9B6E10E08E9F23278C2C6ACA482528DFDD42021B690D777444DED9C912B2CD003DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D5023540D6CD04777ECAF4F4D58C64C158042656BCA7DFBBA61D7551154DC1535618FB3576C6A634E79E80BC56D4A77A32480711DCF387CC963BBC7A339C907928DBA6545BFEA6878A58236DC95D439F8F3061C099AEF80CB7128E0C1D3AC5841B65C0A738A16BA2EF4649CB510F512A819CD03BE1174182022DDBA30AE32DB5AB9ED29B2FCAF259886A4E479D5B5C118DFFA5529CF83978DBDC1B233C410279CC031E0EFD98F95DF6A32C1FB854F7DA54F12E0D0078F9287622542E551863DCB0B534DCA8EDE06545D0860957FF3A0C13495A47A669355FFF55DAC93C3357E5FC17274ACFCF9905705D6F32C7C6E6FCAE6086384B4939C70128CC73540E47ADC633EF01CD9E59A14EDC10AB0A9313ADC2123A4F3F3B4207CC9564D39F7CE86184505C432B568E4CCAEAA1BB93EFE4C696CA690F4B4EAC21A83E1860C5F26C6ACEE315F139E8C7543B2075D3FBF446058A1F0E0DC7893D9C78FB25914ACECE4664F58E03209D0EE1FCA892A9002B32FE67B0CD27E60F35706FC2BCE8A0F77E89FDD67DCAF4073DE5B72BFB56A87525875B0E27042175EAC158AB2D5A7B85C041FC13F81A9E78911686B33488DB258E31630B4D779F6F40E079F5094D31D70E74F2220ACCE407CB3491B80DCA95CF6126E9D2E955683F0B6BBA28885065E50309BD5E3429C626D547A87ED33769F9BFBB514F8792EB90F90C956F0148B9928189EE06BB40CE18932DB44AD96E226B6BB6A313DDC8CE4FB50C6C548BFA794FDD1EE7EAEA2F119CAA2E0DC7664B0136EE7F50B88FA4F4B1F0A665F36C56AAECC77D637637ABD7EE25BFC8B638430370B0F92FADBFE5C4F166A0B1FFDFDABA98EB3E5D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3C1578D7F6DFBFF09D46817D7C61EFDDFEC6AEB1A21EBD5AF1A0F399A2096C8E30821DCFD15298AB26911D40A97E78421AC35B6E8B47C483E1538E1C110540E6B23095AFAF8CCC9883C1BA2810AFDBC488849BF8E2BD2B63AA036BCE1BF9E6FE84C7C830C65CB9870A441512C55557F371276F3CA97910118271DC35F5A46454B02318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3FBF9F7DDEBC0995B90104C717FA2977F9559887204B56298813EAEFCE587F9D2DF49378B38F71833410D667351B1949CF406F18B0727666AA94DE7EA90B093CEEABA95EEE4D2DB043CFD3504F59CF36374C48E804535A76BB8BF67DFB39E03CE613D53D7515BBC8DF04062A185B7825FD3260B1B377B5D3CF470603B1900FC978329FE4F050A62A0440FA26E9B3D2CDA32E7F9FCFE6446B29FEC3639F068E56D446765B606D7B4FDA46826E8BB9E3FE9ADD93EBF3848B70C759922B63ADAFC8E71CA051A07FCDA3126BC8B4EAE41DB2031017A6794C6784FD8B93672BE6206ECC5F1396078719C45CEB31BDE4A3D503A56CD1BA60A875E2A5AC7CF340A79F261480A2A36EE4FE88106DD0976B8FD47010119D6D21982AF0E8E58AEF1BA68D4BF979DE633E719AAFC7A6C8AC6D127BDABFC3660711DAA2962D639D46747BC03BB269789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411923F9FC45FE90EEA617A4971AB81153088F58B488C507F5C230586CF967833C9A0DEA1CAD7FC139A9710382C46136E4F4007BBD729ACF06FBFEDFF5144533FBFE8186E4905539B32F01DF3F0FA65E08B09F4F16719DAE9A987DAC3A28B2B9E001FAAAD0F03810E525D26529CBA1829D42796B65515D55BCD2315DDDB342591BE8E217286002741AD99A1565D106690A5D6277539266747D8632686C5C9061D5119998BAF8B6C09E61D13B2D91426AB98DDECE3EBC2CCA03A8B6591E2A1712FE71F847F486D6E177932521D9196CF0F637314E2329A86F733D95CAA0C2F7F08FA45A993F52B44077712B70116CA4A7DB6587E24BFEB70AFBF3A6F1A33F469D98278A6603810F6664B9BDF27388FA8C69CDD4127B39AD97A6E2432E3C2B6E0087EEBCCC54DA43837F112E61409D225BF5E5222DC107D698C0E571EE8D532C99C6CA353C02F2BC7233F1636D14FAE126DD4433CCBB5DA1C5BD079804FC920E7A7906C9579B18D7B78824CB39614E28A2091D1194C26DFBE86462EE24FA1FE24ACA85F912404458AE8DDCC5B03A0E0402BB689ECE763D0825A8D566713A013923627115705098D63351D22772A01D57BD39566F1EF058044281C3275AAB8C44F905DEA89F9D1ACD8FC3C5E9F2DF429637D635359D0A3D91D765C71E5DA37C2BCF29F1EA9AEE40BCF69C70168BC10F1E9576CD541325A8A729566CAD7C0483ACC8E23DDCEBD1114559AAA8C6621F7A7AD11AD19D6312097C99841A84C35772FF6ACF5E1028BD5885C73C78A719FE0D63D52E9F55509B7AEB252865C6720285208786A2439382CD03CA0BFA2FF1A45B734943CA586AAD35DDCFB075538B0850551967EE7D7E1261DEDE7016BAC7E1B447BED75C565A09D3F173B5F9DF4CBD86780F35E9D7D62E54A2FEFFA0FCFC5CBAB99D2F5EF5784EC92C6A9C8DF06FD4491E197B153B084BB9A5F629E4E7923220EA7981AEDC10CCBE387725C16BCD5A4CFFB3566525CB00B5295DEFA64574065D1173DAC40340878BDAED7D71811FF8EB1B55C9E3C8BB8BEB2D011A9D6DBA1522C969314EA2A7FF20000EEFAC8F760CD24975B2CD9D37FFF352B4B13CEC723C68A595E301D02E0FD881D3286582D5472DB230F77C644E02E4FD2118592D323D93CD22E55EDAEC15693758CA10E3F215E6814BC13E2DACC05A226ACAF6DACA3B9EE91B0CD0740A5B50E6E10013407A7AC9A58F2C2D41A8CC0BD39BEB52BB643AA89A1194312A69D6245A1844A03D0EE0BD92C46B5D8EA77927C48D23107C3D498427E8DCEAEAA36E368A58EABA0E06B97532BD8D2B17A03933D6BB6E00C1AA62CFEF7C7834BB0705A50205C4EF8D3270C4A0716A59CAF17D13F6E01699B1ED376095D3F6850ED50053CB56D83A15DF12887CC06E7B45D143CF738881A322557FBAA2381B355638DEC332B690F7A2C91AD96C5102819AC027304301756A1B970378FC0C627135DB8D5F6B0B75316DCF93F0955E37193575DD0C14961D776379DAC58F5FC1150785BBBA92D1009E1B49D7E3362CFA468D539203E53FE2EDF38BA68448A3520CCF623D8427DE666CFB05E0BC25452E528FC4BAE4FCB020F4ED5EF4F2A71B9D225F7B7E6655E60877D7B7F3DCFFD8C4C77A3A3B36073A69EEE8B35F49BFA43AEC19ADE9CC7DFBB1F6A7AAFC69B3210DD8B9D2D54268336896CC79F76B441391662909A9261AE1A5D75C4F9C360AB0C19A94F3930B33ABF6EF6D5AD18ECADDB1B477C019334C76E553210D4C89E4C32DB11EC281F61A34DC4C3FA81C4C11ABA995BD4EBF44373AB98B000C9F53E39A9E09607A88AAC7AE6A1AB1E735E1D0F8F8D34253718687CFE01212B0B818030EC3F1C8F79574580A44C571456C431C52BA9DD336B1A5F8753263FFBBF6005A7AC41B11814D8CCE8CA7C6B68C4F9A56845611FD6D46C35562176A9E14B357EE8DF2B3F76950986449C0AD69B0BFEF0641CFFEE6CA5112F71E1978592018BE903F66F340EDDDF09089FB1DA7C60F76B3D92527D470E11455137D94A80082FC1AB8DFA33F518E348D50068DC6BFA59015590904AE41CAE8E6A05F2A1296D97077A04DABEC3E27E25173C60F955161EA514178875427F4018AE8CE74578E79E80310F069A611AE281EA56517083EE94B5B37A1493E614AE495D28CC5D8E5A6EA4119FF599BC8DAC4167880FB7EC2FF09007E874ACBF9CAF516CBD6E305EA8492B3FEAF23BC6571A5B800489E07BDB1F2C800BAF3E7D35B4EC997B21A3C29960A9FAA177344E6F9B9C59489A67E782B630D9CB44FB0F82922839403A85C7AD53A9F32D163A64DC226EAA21E0994B218DB931E50BC31C0E1B5651CF2098EB00153DC510E086B1FEB74661932A95116E04BF13E9E302A4CD3783C572CF52249F5FDA51AEE054682E7D3E9BE99FA215853668F015F5F788BC6DE4261C7E53A2FB9B46FAAF6C821BC64ECE7AB00F059A65EA3EA9AC7C64971F504F26D97B48817B3DF9DC46B3C106C041D1A136B4731AA2922B97DEB83A3AD798A719BAA1CC2ADDE4A34D5EA63188A0CFBD3407F3930647C3993848154841EEEAEBCDC2149D942FB644A671D50A1B51ED937765C0C2AAB1B35FC6E4E6DE85E82B4D87727BF30085AD56A27A796F53CB4D3609F07BD7645F7B32EC8B72E51592714D78514941E217E6A8A393F91A907BBEBF9804CAF5925756BB3EB09D32E125469D4413DA437C8BB4CFF2F9C23C6ABA4B90395F55E94E0113E372FDFB37E7801F0AF52AACA367BF4BF90C58D093771AF0991244B91BE5C251F9380444AA86C221D06D0BC12BD1C2DB949E7DB4A5DF1EFA0A4BD339B8F1B937F2AF48072CF8F69E47BC2E20286D2524A59F271852286AF9B8BB57C5FED3E3010743E81629BD1C366D9350DC9329BC839F7B8AD5B7E570C85EF644413F0A6974DA2CE7FD7194C30A43780D5146942339CE2B186698B8CFA564998F0DA458E36F2B66CEDA779C9E9957D987676AD23A507730959ECC0016FF3A53167DB27B2F226A2B4B5EB7A409915DD46A882362462CB5BB7C3D2A75998AF280055E9105EF6A91BFDF40FC5FD0E6E97EDF27F96872351DD3E8C28F46AAC52365CF914A32E5C21626BE9E13BF80A1E7E616022639DB2A5ED92A119EFF891AF7D33883382B554819C5CBBA093B55E335D550DACD6AFF9DF70A2A92C1BA88F210224F8F1DFF0B420B6C2F673497B86A156F5F1C675D301F55D69E5D275BD43C850F39D321DBC76B0F153EF703DEF0FE7480D5C83EB1535F0FF92A37EB637DC3AB8D7C7965C8517131F5273B10A2B5E64C16C85791D41854E43BD503F0E52180E9C29499C45CE64BD97C0BA486377BFBE1C6EA2A84AE249C8AE40CF3E86989F0379B9D02694DA77F9E73560E0F38AFD05744E0A30FEC0D8DFF8A1CA3A0EC629144E96B590FD5F75D92F40E0FC0A1127486133218B844D932E038CD1B04DF12E1EC6CEC249345EAF4DACF0D38453A533E5193257BB55AA785666C64B91491B0A5DB93688FBE07D66D926759B669E18521210CAD05EF3F8972754DEA64BCA926D661B145AF5B8090D1A4E51D9CBF8818A4EBFC8FF1BD6CF2C76B914B8A7BEE0EB33F37ECA54E2DA3CBC29F1720DBF0A024C969D4B1E36326FB6F63C9195608C68A3D7C87AC394210D0F4CB7D858A88168FCC25B79E29197E2EA3B3D4A862B70A1D7F3251C75F02D476926DD863B778059B83198414E0672AA1F27898C8A6F035D26AA117F838EC83D453A0D5C49AA350B288F1FBCE59D86C8CCC99F14A221AA18A9F300DA266DCF084910890994ABCBD8185D28BAE4CCA4BD68D4D5790FEFBD7A6D56B8C78974F9A8675E6C410F6D5F7F6D254F1C7885F48F0391E1BEEAEC7437553D480FBA79F55DD5B19C596DC2089BCF9980959958F7FB7E6DB0358093379414F67BCE670BDDBC67BC8ACE419C2E48C5B57EC624C5693562B719C7E6B09F3A309D255D0B7A8B8430F7E9544A881EEB694C7282E20EA3E1ADEA50564B935D528C0372397F26B1497DFA3D0F117F7A6797C1626D1AACEC708302CB0C0E406BEF60B7F6578623EA59A005B804C009A38E0A615F1FEDABBCDA5269C9C48E148A143562E1A372C0DB9D8F249FB5A7ABE5928B4BBB17DBD747A57D9438774BAE2550A5B205FEA96912A2FFE3FBEF1D6DF372A31B1084F0715829C141B845551C086DCF8FB9BEFB43B417AF3426BAF6007DC2EFC3B4999D2A658B5A19CC61FCB3E2ED5EB14D1ADEF650C7254F5163A2FC01B987E3000517DCD878B3D9268E912CA3675000B10E53F5B8172477AF6FE3778CB0E5D279309245647970C216E2E608E25F1C4FAED708E98E1D88193FF5DE2D33B178BCD345DAAA3ADEB8B1B6D7C3E9C2468F943A4AF0596B0AA480A159BB882857360DD34CEB848F5CF3481A660F70E49916F9A952B001E60F11A31CEFB39D3F49BF76159FF3E8B3570BBF5D759F5626B1FACEDF4AD03E261A7E095044665CE61C3359BA5A046E44C8E5506E2BD7E5C5C61EC2EC722ACD680BA597A47ED44E937AA64C0E3523F1EA891BF01E2B92D54EE9A3684A122D33ACD2A6D14133A8DC35EBE37F49D59BB4BB5F24940C18E0B4B5F1349AB813E994AC43DD0420A52527147C9A0F4729F8BCFF0941B934253B98628403937D1E2DEA8BD23A2EDE0A7BCF3A2D66FFC7049C8D2D3D52B4F9479F6652462AC2D18DEBBA361721EF71168CC59501174444B5A2E58AF71E8DFC4E9F836156C1C844EE12FCA65ED97F8189FF34B8EED18C26508B5ABD7DC94DBFD37F18A514F66BEA2AB8F02DFBEF4D54850B589898EBBE0E68E9F864D4468C96BAA0BDF1C074AAF51CD47B20784CDD20DCFC3444802DF292D0B21D32A93F2DCF3154860EE0F469CF0E8BCB4BB474C2C0F6E2F97EE8C155EF5B270FAD06AEB3336087B314915E7CC95153698BC2E486441D1484052BBD641183C9F5495CE45B270E5D085F4DF45707C7615CC89197B2646196A2F382EFBB8436E3B0A09CB2384FA6D3D7E436D19DBCAF897D8A2B3B41D17163C52CCCCE010274A70B6B985545072CC776AA5DCD1D7D1F191AB56003FCCA1F90F9488AC0C010A6FBCF7CCC51AFC15BA2F9E678B9B2D2B44DE9B7C841C386126135E1871324C9C7D3648DCB8213473E4D006FBDD976D2854DBC257DC1C21E0199C10AA0FADFBFAEE03693930F970285460EAC6BCCDB873F2AE73A173F17CF6C07C26B3FEDC0E81E8EA4FF7D68CAACE34340EF1990F3BF44E23BF65CAC9F65B50E4AB2ED67F01DE310314B56B351691609FD835399C51AD9B35E4118BF3B26AD5DAA9A0609CE6A24C8D2A1244709F770A655DF9E80C0C7441917C8329446EB8FB371C506EADD1DFBF6646E0790637395A2C1429C60252D485BD99EB641F0FBCA951DF3698F69DA2B8E751BB02BA592AEA7DD21E7B961499C0238B93F6AC1FC73DD562C80D39493800D0A0A594F26D16FE54EE71B5AA5CCD70B5F1ABC79687AA87DD986F10FDE0002EF9D964E80940FFC39C5F2FDFB81C190A83B0AAB7BB176476712EDE00F6F97973B9FC6061EB404C24993B85BD7BDB4582903BE253ECC3C10C0B65232F5F681953B179E19D4246B0799477359E0496BE7925D46065E4AC4B5EACFA466A8DB0A62F1D1AD326063C89539BBD517FC53ED562D98D20D8A7CE4FC1404B3BCEC7D500F4573EF14C99BCD70F290E6F4206E9BF9E4052A8DF39BF57BAC1969CB4D85E43FEFC1907449AAD6475CD2A7B9F962C315ED6DCFE913A2FAE5E1A695C5BCBC0568797F5154AAC68A30E0EBB8D2F73E6975440421D001AE2076AD1C65F3ACA6C05144A65D535C89243D6F099CD26C54760517EDB1CE98AB4F9E0B6E3A06B3765D62E7812C38B23D6A92ADC6CAF95A256FB750DBAFAA6D3E937BCA9314331C3EC2BFB571E0D54D3A98D5D28522326681F2B91E5BCF4ED462CC90B4CC27225742E5C2286AD1FFADD8418B9B3FD71B3CAB178F34703FDB8ABDD8F5C1461F89446ADB1175E35428091CC0A3B5705C3BC66A1916D1424D631E588FCFA838C2BF8BFE2CA2F5F6648E79942E3DA4B064A22AD6A9BB05C15228E1D20D4A4E8D041BEF83790E9707A581DBB7689E032A083381899EEF508E4B2A897FFAB447F821C848EED8CA09616CE2EFD13966C479F17E1A29D5B6F18387D15E7AB024AAD60E6D68869726EC117084D8E0C42A3A18FEE5FE427610B9311F4173A555CC3D534439D074BB8153F99EF5C62288F9CD393B0C257FDF1AFA64BB68F3DCE632BF81FDFCFBFF93A4CF99D8D50805B18EDAFD09D086D586BF8A5D6A2026084C7DBDDE343F74C964ED3011E29C8683300EFBD9E93C68EE571CD156D8FE815579D8E5AEDB483103BED689A4CEB7EA73CB8E19A6994A01838E173EFE68E816CA53CE578B87754CB34961D83A611466478E9325529D6D15C156B2E2E06E1F624139D230DD3A32A90AD2C7097F43119E10A2E788F15795548B5470728DDDB77CFD86A6C3C6669B9A2217BC37B15B8EA558D2B9E99EEB37E105700A324FD17A5A00803F41C5317FC2445C7216FE28DD0F15BEF50566BFED945796D4F3DBB97D53204D5BD64478A75484912749D9407C09D01CCDC391BEC54A4D43C9157D0A871195C731EB746F61A3F82D6F1A9807C2BD3B275553AA6CDAAE509A3A350DA3F119521A3DF789E011E59EE8138C17EDFA2AEA5C15841D25DF2E3A1FBEE40A3CD98C275AE4FCAD2708F31D7354E4059D43FC5625858721409E990F1DAE7D7FF6B3084897B817D88A99C149497599957A667750E1CF446F5D24409E3CD2AE7F13197FA6705BFAE8C1BF36AA626D524EC10CC50F77B359D718734797BA0154CBC3CCCD88030C97386483EFFACEBA41E5061B95BEF6324AC98FD576AA2A8D264D05596B20200496C54C58146883B62C9051E5F52224294C996EA6B44F84EE277D029766D66AEA021467747DB5CE0597E5D91D92903B74DEF2A7100BFF8201F70D009B0963454C25351D8D43AF77A3E70C95BA5FF34747F55049243C06C036984C5C303378D475F841749BCB2DDE91A25C105501EEF479F2B6C68A60EB8F1A308E74EDEEF93E1E34A50CB272AC278ED9263C0DAE162B7C1FD035421A2CDA9774ADAF21B292C252B94398DF63894C88C4B5529FC5AA5A18E788D74EB6126C7FDEBE4D650E2871B25F37DB9EA8AB64FD4806121F4509D4FF190439B7A8690A81275D9C03CF2B51832B32DE2967485BF84E915F7BCA7647E09863CA48B37131815DF9E5F5A88535186C40F177A06B657B4437728EFA50AA22C45E49026053B3C2A3C554F1B2613EBE50F27CEBD3BB03C8CA17B22EE76C4200A0E85A70B6DFF7F511FA2265BB7D858556213C48436D573F120D4222BB1A5C924B2EF1605B4A1ED717EFAF63AE53B070D7C62B2F8CFDFFBD18DECB0C405E7575C6AD8CAEF4789D6164039F963F807C3B978CEFE718A83A68378F9156BF52F6A3F76E411CFFD88448BFB452ECC10CE99AE5F5E303EB099B89765A377868B0B2B3A0D631264AEE47BDA8FF3A92483D27CC269B16390B3ACCE3350DAA649AB53B9C1CFF2872B6C1F9BA67D9D22C6FBE01424A7DC815F968C77BE937563456A273992579C8E6AD585A0B3D38AAE13ED13B81D58599A43E86C4B4AE7825B358C6FB94BAD7F552544790377714DFAC7F17B9B6B3BAF2E5D6E87AE0D0769A39A5580D5347C78067D7D7C375A91B066A61E124E754549CF27779D43109D8E167423F13D05093CD1D31B7E6B76A89C6BA817D852775ACA8B385138C6CC73639FDA3AB6FDC5F84CD46DA221B2D437A51B54D43D98E6D77E31B07FF420AA12FD6FA8892C4220AFE432664F946E738DFF89EEBBFC16CB168CE1721738B4A1174265AEB27FF3808A80D3BFB6CB893D1B6B33DC27239E96108C6D0D20C912BC1EBBE7E245056220BE957E7B9D49EEE6C4D341AD73932D304798F0A0F04F31D8F70DB5E06E3ED2DA627D47E0AF1C2E14E56054A87AC9810B617A52D0DB5145FE4C2BF6D0D4AFB0F9314FE15167A5AD0FBA0C1454FBAB0705FB6BBFE5F7E39824E59DA24CC67B3AAD9491E7A40906487BF895E90F63CFE6D7C0984F1D2747676B82D09DFCCD2A8F6DD158C917DB81FDBE6213FE43780DDE17ADB969B3D64CD6BA6EF1F9ECC7D6F6207280078B10DBEBAD7581A2E8C2F83E4AAE8A26F8D1DF0F8CB45C690615EA304E5CE30D2A96C55696C6B1D82D274E9D5765C3E5D2D7D05EC6A202BFD0211B534B7C9FC684C7A72C2D619E9DEC4175477792BB930EB5888FB37198A6E1DCEEE6651038F5C0A15DEDCE6D1833CDA5CE4EE61CC144E7C5202FE532E0B274F2CE4E90D91F2BAF7808D0656D5A106EE157491277F92A36239D1CA7D26150C118F9ABCEDD5470A2A0069AC1BA97ED1CA9885FDF2B6750157AA5B72DB5E7C1140E1FDF78DC7FA04773F4570F4544281C2E9627E5F59CA9740A38B452C9F3A930956187079B4EE4C91B3E3D9F0F502F8558A092630BBA965FD8900E738FD1498FAC10E6AFDF58F32DC0824B405C0E1D962CB213D4D834D7D26199B9172CCA1A36D7A76DA603FE07CE0EB070AFD90E7A30D937A32D26419A002A32AD9043B1735AD3D0696AEDA5F47046F8A3134B8D45C090C0A54C70AE992A0916A49AE7F3006165FBC71CBA5F0611FA5140FC304CF49DF3081CEB754E9E87E4FB637D7E701D930EE23B6E7A739274EC3AEB90736D91745A92DCDC5FAEF42918E63079E07316C2F9E59D8B79062F1D816C536E8323F501A20A11D6FAA241A5CB4A04F8384206C1D4BA5BD2DC0DF41A69CCD6390270FF0451211B36B489AC95476493D812ADE03FD8EA165053401587F7A18C2F3FBF4960C82B30E9C7C30EA830FE7D052DB5A191C0F8DB73833839F0D7AE822027E19C3A899EDBB02AD49EA87E1A2D55EA6B010BD984FC6C5B12289B41264F9F2F23B8761F262598692F57DE1277F48B3EBD06762F791DAC23F5A5846795B4C4806EE0909163CF27111BE948EE0CB673F0B744707BE8189B059F6D33E52AC33BEC99DB223FD42F64BE1C3E8D505592A78D5F7D3E465A5E34C1FC7D7ADD80752A83CA5CFBDD7AE15AFFE7BC0A4BF3722EEC05E54482A88287D9850672C2DCDE120E0C7AF377659E5A3313D0FEAD9B350A80F0A5A4A480346AF02414FAD52E5108B911B7A4B877215E400B3FCD4E8786E962704A50EC2B2D2D7256777111EA6646AE8A57C84B56C30D704C4B914EBFCA60FC07CEE5DB943630C0A2BE448CFD70112A56A74AFEDC4CB48BD579FEE9039DF705869A1623B1596F77D7420B59F32801106F6AD8A16DB40B1ACD82415BBEADE36585C3BB47F37BFA7162C255542E8284D8EF8CFF88DB68A47249DCD14C1D2E8E5C44E258E9BA867902ADCD588A5A382A60A580458C8C59BD5F182742CA1BD6A52F35FAC26893D74C3D74429401712918098CCC493BD226EA8A9F8C7700123924131913453EF8069237ABCC4B851B0A868015162AB8B7B63B3110906B267DCCE5659F4FCA5298C4073BAAF392C5649B429D5E378557D5CA03C9A52B6208936AE2CFF83D7E28A3274398CB3586BEE9694A14396FA1D67BFA90524574B7DCF0E8C7B86C86A69FC0C2263B437016842743E7E1743802C4542DAC8E6A23D03A158BEE47F010F71E5D9A7063E26FE8C40B208160936B5CD4D13ACD22F928352902BF25A8C8D294B493907F6794A4DCC0E7CE621FE45CC6E5F33199D798FC6E833F9EA4EA54FF6A465EACF2EAC6864D3CD0057429D789466CC60CD853B829679FCC639446CB0657C15B869BFDF27AFB572303E17FF826F8C4EE2C747AE330858830F70879FC8FD6F8D7CA2BA986E5D4DA1B613DF88CE09212B99BA77FB3E3AF7AEFD4FACB02B3E3172AD43BA87A4433CE38E45C1DA3ACE463315CF5A87B14CF4745D5282B17B613A033A9FBF52A40D8265B49A49DFFFC6C71377C20F4B3EB43FE7D89D829477619A7E5B2F7CC9FD0299C838419661773087C7BB3573568DB256F94E57423B1AC21C0662B60F526AF49629B7A8F7E833F858E5C7423437ED22E6E704EA66B26E79878EDCE376E8BB682EF83EB4B9600015217C1219224381665C140C78374B80F47511C48B5238937464F3B0A5612D2F1FDCC91B74CD861CE655CBCF22B68F657EB7D8806DDDB03B4F08E52089938121B0F6B3ECDD2D23003C889FD2F9A4F6D3D4358976641511DDF513181B1C86DE10522AC021B6A301249FB9E6DB19DF42C5BA6D53F1FBF9A7A2249C516513522F8702636F688145B52B1FB6172CA96F59B9F845760677D91996B38371DAAC111D6BC59BF28F19B4E00B5E312191087255D008FEE158A8E1619CC0674E12DCAB593EAF6C99C9CBE9C700B498697A725E2F30EA74365F3CD3318AA1D0D7C07DCA4F2F6C3AC8EFF0501F8F65A07363621059517EF1BA27310ED930A1A1B0D4DA322D5FD13EF522D21A3A7D623FC499AB8648C1AA0CE2EF94316B2965A246AD7C8869E9C489AF1FD2DA40E3D688531CF77F083F281E012ECF83C4ADC97B5AE47CC38FDB41C7ECBF402AD42716821AE404A1D224363958B9E71DD4B3E77A16FC80598A3065E8E00F36F2DF940F4E99902A1D62D73470FB4923D3A46EF07E65D02963E1B5308121675F1C1973C656549030DCE1BAE145C7712A4879E2F3E219B72B673243BD71442B699F3A4E366C7B88C1266330282D0D9357FBCEC2F95AE54D87A50C8581597B0C24C2F77763B326A55EE924C4A492307610526A864CCDDF6FFC64321D570589BBC5F9CFBCDD95D0C7AD62DEC853875BA2F3C5E3FC20CFF99FF86539F37EDC56643EF7D70D0025B395061B83A100E1BE1D6096D007DC42082D4E793CCFB79CC5A06242518998D835B32B7E579AA14806AEB8A4F19E554FD72D2899617541C6B86B63AC60BD7B6185A7A86BC7702CCB91069ADA68EB4F117E239BB7A9581A56CAD59A618449EE02E2089CE3A1B97B22AE34BBB421F2194B00B80F1841480577415436FCC20FD60731E6E28138A320C9237FF656A5366890E492A318EFDAB7F22CDF81AE5CE56539034A8790E942E58118A8F141B2FC6E4559A04B9EF8827BB7C11D5A4CDAC22E42660082AEE184078053860369D354552F1CB9D798F3FDF657648A7D5BE4F41E6141FBD80732B6D3AB57C0F60D38848FD33F7E468BF7600E16F25B9552688D3AAE33DA731DFA536059D24AAD21AE940CF31E18A40508DD1623FC89EC11BE4B852EEEFD56C002C1388DCD5C54E0524BB681A25E076CFFF94EA7B5E0A0B7DA1DED8DBE3F9770536FFD43BB48C9E55E33554E5C0411BB823FE16AE3CFE51DFC9177764955DB39B08C627F74A7B9A16DCDCAAB1CC31E37B0D3B90ABA2F1EC00FD2EF6E4FF3A15358C551BACB93EF59361567E0834E72383F4EA2E8F76F000EE38B179F7F0F9A3351C5BFF81B49E8A5119C6CB5CFCF49A6875B3A99CF14E6CBABAC0F4F38FC97CBADE13BB807CEADF726AD565D65334539E879575702D58462BB2A7C7F322A16F3F1C4FE116CEDBA6094EB4712D774B8207189B700C8B84FC7D0DB49B02F7AF17A6270BD75AA54F8A79E4A1A6D588FEDF94C0829EC1496988507C8C5BB87A70DFC3FF6C7F985ED38CF6C23E04FFC8001C2958B5E0920B284A4A3A55023D13D4FB99D392A0F61281E6DE6AD1F907788504F80477B8C21454E4FF16236E42DF95C85E20DEC39B2920ED49AA540BF504E74627B678097B4EC800A37698C32118BFF564BDE9BE0E4B16A3D91A9A83FBE991DD88E7341BA96976F7694323E523B76DFE3C52F28188C8D64DFB1341EAFC98C9A28CE446C4983AC52A1C38F9CC5D8CAAABA4E8BF9B7E45E3521567A46AE5166642E89F8503F892F522A447B2FCB1BCE2EF4EC86E22F48FA99555DC193F080D3F0096A47BE3C2597FE83A27E8132D28EB55AE87B36C93F31A9E371BEF51E405037DBED6CC4916E5A855116586F7C34F33B3EE626DF600644EC881246E32B5716E9580A1733ABCB22346C4414E5FF2C085E2CBFB45BC77168F4164B7CECC874DA5594F6E8D0B7B6B36EDEEDA1342672A4D6925CA2864B93BC7F63994F8449929C3206E086738FADF14B1872973A6093B5916E565DC3B354FC544A44202598AC2326C5EB9F305C448CF68323DE4C5BD28472B340E43DEDCA0DC290CAA47238A7A26713869C6B4237D40EE2743BFCE74E5CADFC183B14075FC8088943F3B2E93FD3A96ACA364B9292413B2B67B43C855A898F877683FFA238C05E6F789ACCCC40C434FFFA494F2710C3DFA213DA7B56D5A4C273603ECE648F3E9D6E @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 18469 sm = 00000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E651324F8D245291EFF735334671EFFD85F3A823D972D2D49DF408A2AE09590B2477731B03EA3F8D0196A27D1C42405953F3CAD196E2AF5F897CB89A61F544FAD4AAC5D5560820714B57DEE68B1FC7BC9320D4E9ED476C79C8257B34570798C59A944B9F2B22F2D9419B5B5DB6301DDEA449F184552E9EF0F4B80893CE0D38184D0F8F2424E5B39E783D8CF5D3E40F8B822A5CB770E7C793EF70EC55F2DB527489D8E83842D91853C8E1A4E123A8BAA85CDC3BEF892DB683E3CFB4D60DF60CF4705644534E0F86ADE3417BE364CACDF76C0C906F64BD58A7B363C52870995A9DDE6826811C4DD77FD89B17FB35E2EA7C907A056063335AE03884B54E791EFC5B6855C6DD4C888FD4C8BDEF806EB73B632B3C27697F2410935EBD0B4EB7D4FE85D94F4EE29447A8424917FD3EBBE24F5128280697659EBE4569087D96AD8F0AC7B632EEDC65E0D807DEF82C028FF4DD9B179B761A6BBA1DD80F395A524036A7D50A786294AF71A1CC7783E789CA5E8DE21B1E3F771C5E9A256A2D0D12F911285E9F3BA26B80AF62D1328351A6E0045A82BFCEB153B0F6B8FD5AE3B2056006C5EAA1773CEEF4C7B3AD10BC12FDEA7DCC1891BCBDC9CD83ABD7DE6012ED3F07F1CE670B7C50EC84D8C0000D09632545965D732E921D01DAE77512180C12B01A2791BD0A32F4705C98818ACAC9A62F3421985687FC5107199B035FFCFFF5103D7B169AD346BCCD523B98475B92F9EE6DD954A6534913AD07DB45E620589AAE5F70A7B20F37D62442F711363C3AFF1F571B2A6471E08DB2CECF405676A1B73B7D768543B818B7E31A574796497C2AD22C79CDFF65DE6D4E12F165710A69D1474BC7FB5E34D64263543B02918CDFA271F53EB8B07A9859107D88153FD989ECAEF350E5F8572280261A6EBB9AE8A0D3777BE70BBA24CD737407541AEFF0EEA79C1FC0E73F167DE9D2380AB6D5B0807DE6032472D838B3F681E7ACBC75D71426F33ED97C7968EFB4FCE7D560363BC9F3A5A0086D87169AAB81B9736674E598CB301F84E7F0DBAE6B747B79B8F437746C713E1FBFA24DA920A4F3F3E92E914C271E3EA483D6BD7A4880B86A916605F059916F9D115C41A1BFE270D0C39D3C48B44ED9056712E0DA6F355D31666557247B6BB8AB41EA0201599F1EB9441E4B23284B8BE53B6BBBACF025A2BF597FCAE269E8B86FE4755B4692E0179281ACF62EBE8CD644B11159E35F94A4492867F7A94B9CBA5348F7071C5732563F8C1C008AD8C1767EC2D2A1C5F71AF0F2B8A6A8F9C2E4C8BBEA834A94F34114CEE3ED19E514449946DAEF5C58F3B2270A78E69A252FE4837E7E94DAD4842E9028DD986E5AAD6A8F16F9F138220F5672F8BEF56252D8E93E693A43FFC9AE96ED514D7405F080AC39BE1BC1E7052026B1FB0D65335FB7CBDE8E0EAAA2E29F28846C562EB741204CA105FACEE149ED361E30C807C308875164B475E46CC14E278D7C129F0D909E2C06D5CDA83303D57841E55DBA04C02702E226161DE69093472D07A2408DD87057A1E25D363CCF0B32025BF24DCBF54A0F54D62D6CFC870BBBCBFFFD1AF85A1EEE4532928FF130814E363AA0FD5ABB68BE0BC2CE6D0EB362BE0C106A017196F1295969EDB23739D139D5E629140BE6778F0C912343373F637A516E029047FCCECD7C99A59681772B981C48A3005D5F95D4EFCD6B17FA570122F2A68AC1E9EB11934578DD965D4FA0ECC39C94887E71903538BE9408E8DD1AF757ABC63097ED308C7F0EDF78E138ABA2002AE12DD317205ABE4FA332FDDFB4AAE669A71A0A6A402D3E8DB7E409A5FBEA41C86474057F5D46ACF35032AC331BC0F33FF002D23A7ED791C642D202019E62520710B50C76A82229A1075E52F918DB230C481D0350A33EA0E6C8A2C4672459266931B482AAAC2ACBB4542B22D3D25E2E279700167CD7AF03866E60CAA9A880DE5055A80E48A4EDC261C705EBECE13DF4F9AE7D8E33016A83B6A05DEEC44A0F6C123B8CF162E2814638BE4E22E8C65A8E9B2C6593EF39B915A86C7D43CBCAD6F5857BAAE18071F291C3D742C9FF3FC54A51D1CB8061D5A0ED4358E82CF93CA9750450352C4326F2B9B20F3D091528FD46A0ED40077C79EA0B12E70EC73A8CABF27E1CC7B33448B947CD339BDFFC9F377952D6249911F099F535E6FFB0A6AD85F5CD06E4B59918DDA9C1EA1356480AB1D7254B2AAEEFBDC3AE61F99552873CD0EA39D3A2527B72BF325B02D5A8AD1B50320FD2513D89D1A164F5F8E7C034CBD4718AE2C9C6D2839C144C47418636455CA4B9E674B3296AEDBD92C793091C4EB95FCB9EEC69656DBF47ACD54F0045644E95BC75168F17C797F9E54C420F05C6E45A5DA109F6A0EFB313ACBA155CB69F94F21439FAA4821B43A1CAC7172BCE8E0D611E1C6993589B529400771332F16F123352198A4D6872CF63F4401ACB9B5299A74E06FA83EA57797B29DC131C00B7E475927AA0970648E69CEE30ECF7D7D4162727D1A252794C85BE791A4DA538EF8B855182EAB0A724E0E68601A10D9809A6799A6E7B2DDB84AC602BF3CF936E171E16F5B4EE3BB6F1F8D70A121E76910CCDD79F252D4FA6DB1D4FA2AFF6D1F4A0246688F24B24114E97C1B758F96C485A679499AC15C89843802B844E9E5A280057C9A5DCE4D75B14DCB8CF4475E4619DE0734946BF920F58EA7C967CD268E287E9D1F8DCE855F5FCFBFEC88A8D7ECDED07030F6A3CF16B95CA2CA5635B17418D411C233930DB488CA4F7E287B255DA30A254D0B3C2EF633F5E04CDB10A20311D2846AB24749D78FAB6EC47F89E66A1A60777897D0636344B4A3A6D4B891BC5E066A422AD6CB0514D1E9D70888593A386048112071548CF0A71C9991DBB3A11D93483E3716D9A8BAAF62BC5BB58B991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EA6E323ED6E8A520C761F371CF760445A3E865E4B2524DEC48F47386A1E6CE55612DDC33FADFE21A034F29F62E5EF6C502CEC5014A10A68A2DCD1998C74D620E84F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D265894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB939E6518A5122E37D4C257B0A0FD60CE0BA3BD55C9CBF369DD315A3C0609933D25DA403DF7E69FEB7EEE64DC3C13DC83217C2834B42876862CD48E99E69564B336506B85FDB493CF8FA87A7FE48DFE6778DDE8E8DD066FAA745C121480B5BF9D5F301B358D18FCCCBD24069E71836981F168FC49E6A4F27B00F6259B183B62CEAE0BF4AC0F53FCEBEB9052C0B48EB0666F361C5DA674B20B06AE2EA8783C2DD7EA74D98AC98C55748A368DF5B433C39538365EAE8DAE5E032A2008768FEB01F65D001AAC437781F742F536EFE2B3AE59EA12A6DC7F2712BA2D9D1C253D29B419A765985ACDB42BCCE5D64F6AF8368A5D122BB16B525A80C8BC5355A53917CC82262254378CFFDF1C7D6355F114E4FC013A5E4DD9AB373A0EFDC470854E20330BC00960ECBE882098D6D0D429A7AD19D3E5D4B78AC5E568C722A21877DA617190CB43123FB04333FAE5846953E33407080D04DF1417E740E7E7A14B0E3CA7D5B693F9615E1F7D417B9004F28D5002325B851C31F5EB31E1DAA80E6CFF22F11221E5180BB050888B6564A381E54401AF9409FE12A818B69BA34E1916092A0EBA24457EF994A1B0028649C9803045EC93CF416373F6A568856B771C3BB076AC265045ACE8E9BE3C3074D8806BEAA3B8B21F7E37F50B16221E14FE5503C615A13738CCDE39E2395E292119959CF686532CC3C9F9129E62ECFB43A091B06FD48ABE8C2CBE2D9691C8907881991CAB9D0D9CC7B2699F2261E5D799D26A7C8A4AEC40789B34CF5FE7BC8D24D6F0BBA7A5870E37F4D9B2605BB56ED9BAEB780CC74097DD8AA8741A97E22EC7B7434F81DE9D83CB9816A33C5A79D718C76A3442FE50C68FE1CE7AF728F2177F88E5168D4668518897AB050B57FF42AAC731E484B440D0D7B254383C74BE41C2AAEC02A8D8C7020355C4A1FAFAF4BBF56C74D78949D087259FE8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B179B32F9F94BBD8371B973B19E60C3CE2206A2061C7BCF159BC3A50163924774BB13C708A573472DA73B4C78DB30FEF310EA3643BC75D9155762D5B87809E2A727AC0428B746801D693074ED5245F29B8FF9FB782F2E57BDD89DD700EDBF12E8311946CAD9BCC98E3B1D581E678BEB1D0A6EFE15CF4052A1AECD328B2C4A8D5DDEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA36145D1653D108813E42654CB5350FFDB33BD2FDF4E416C6C0A61784E2327F42B2DA2AF040822C291D63645B0AC2377D0DE3FDBD99FF9CD9AAAE2B978C4DBEA95E330E90EAB0C4C34E88855C7C62C40B231AA1A9EB409D18CAA1C612A98F1B7BC25B18E3A89CAF96AA4BDF12F865EE7DB20273D7CA11970219BE997DD0EDE7A8ADFECFF1D90984694EF152346402207BD7D9166DC1B09F3C3520D109824442B8AB08869B0A4850BE3227E746998925CECCB422C4C05047D890E291B4E5478967A42BEEE34BA2765D86D183C71FB6A3CD86EAF457756FC000FAFDB24AF3C968E547A5223821BABF91B31B3F970D9F7C1FBFD16CC63D14243DB22CDBC266BFA4DE4B15D23B17D34C674649A695E80F84F6FEBAC0255BB155BD8B8D46FF7AFC532117E26985D99B0E23345F9A0247D834697804C6644501CA7D2726DA563C7F02371B5CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438DC67DF57A5B11025EDDC8915C57C8C72F6D6E71978496E206201184593506E39582DD2C803CE9204D2AC833C35BC683E0BD3CAD30BBCBF584AD38DAD30C9A400DE22F0CD6199FA6C622941E79F8C5C500389E9FBDEB8E1C926443B6FB0313DA9AABB163F5319C0164C1E58864827E38C18B7ECF6FB44274CCCB84B10F1A1BD76C8740F479777BDD7C557DBEFA9415B7FD50CA659E304EF4FA22680980D0FCEFC75E36231F740F38E9B4AC55BD8307F8AD9FE45B046B7BFF0F1B9FD5EEB82D474DC311A8418BB27CFE324426CD3311D65513B0A4D58515B94B8EE5ACC6815D6D1246527188E7B6C579CE42B28E1F273887FAFAA96D44FE6830E96081ED562FF4A08416DE4213A89CD666E2814FA290A5B1FA5AD6DB86B9E4DA85486E11BB36382C13607F50EDC83909F47A7D089CFEAF4680A6F2F10A2D9D9A679AE82D2DB387C5B7BCA11161E49E01C28D0FB7FEFE1C9A4BEDE994DEA4087F3B74906EA8E49153ABA49BE0F35C0572E9CE0C68B2267884C4BC4AD32BF28CE64DC7C825BDB2D8561C69161E075F48A40220159BFF1C4158187D4DE23C85979304DD4DBB98BAA57DBE6B7C55C271B134D61906F6ADBA4639BCAD3C1A70DA04A9409A4A35FEF1BC103D4F17BAFEC37C3F108B31327E0FB227E0E2C5B5410726ECC93B56D4D153572C2DB4EB4757F5B2232C475EB9802FEFB53EAC7BE6A090AAE98027AE13D2B338442FE6EF2DCF141C4D1AF00C7B3E973467FADDF6F1950ACF2BE908FED354EDFB147D6AC4B0740F87DE06E768293CC83AC995760FE0015CAC682036CCABA9C86B9B06924369E35688F7255F5D5422AB808D023B150D62D9A7DE4F7A5D28689EB038E9EF9D3366C3D777AB6D1C33878327018CC51EEDE65BB5FEEFDB1442B9006C76B10B6CE9EE1B6E43306DBB0D9030E3A191DA24634A80063F6A5269E77543525E11BCF02DF82E5921E3225EC97FC5F9174E0225E8C5D08B4C093EA28A19D03E908426578661E107E5E2C5371D79C31F11468112A6050703BB8FD9ACDEEF8D0BC31E82FB4F7DD0DFE8AE0216582E6C86FCBC1E7B3FFDD921F220702D827F145D79D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CE8D216DC6F19C3AC0A1017837C31D76ACDBD48F018A1CB14E98848B66A59F09AE22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB96557964888EBFCAD45C491A2A3C44B7085FCA7C983EA4AA22F62B99109F6E425CDFF5D87105EDC065810CA3E055F62FB80F5CAFEC57F7CB47A95B14A215714FB345FC73E57C1574E38657755CE991FCEEDC5ED84824E0E4AFD43205E126A3402910DCE16C59C8840FC7FC5ED9FE6379F9A388601D57B366FCF44FBD2D0C15A3D8A4A28D71ADE5965C137996748EFC7FB68ED165D2480FE34EF58A3169D03D0395D94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB08391412A812DBBE4FF09E10661B7DD604481AE6EB2F89A1FC04E393B3353F7547AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6222D7DC2F78B2E3FC4C8CEAE02E3FC9D7972CA803061F534D39E4F02809C7A18A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F9536829157F62BB003C2E45042DBEBA9622508F9AACA5FE89F665A5F35BA7C26D93A84F9DC744354C73885BC59EFB657317594D34B561FC2A789C919EE08D5D68185BFB2A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E1866ED93157270FB47C81CC3076E5B381E6B03127E7AE78C54F5F35B2474F18A2461297462FFAE651BDBF3D438E30420A3BA5686483DA2EACD874CC44102C09319C10FFE87AB2099A185DFD0FDDB6393B2F61490D65F93CE565C6575C877246044FD52ED475831AFE194BB163D0FE5A023BBC435497C3C16C8C7A85FF92426B59E588978E29EC0DAD032330035B797471B74BE366FA75D79D35228004D3231654D5F301D6597B83258DBE9284121A2BB21EF66F40C17FF135201D18092FA6A72B511A456786ECE1FCFC986A28C744DD4DEBCB552C638043B0602343CC796834B13660A86C5E3CCAAA1845C5165074AEFBA7C52190845A95DC59B1E8D6B052D253EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D1B478E24D9EDAC7EC8816FA54DFDAB0F181E9E1A8A6CD77A9EC29B3E35544898EAA311411BA22E8BA6418CF252675917A88572E0CE98CE03457996BA4FD86D07C4FA2D3487400E484F4CE0A83CF490C49588DB83ED1EE2A93B78101144586427FF43F434D3A40268920A4FA3C64C0F5F4600A8E52E01CD8210965C4B212DCC942C68D589D21FEF433904C26239698EA85C32423EF7AE1ADC90744996C956FD5D0683674010173EE4A110DA2642C8E1C4BF7B5DD3DE268A3AD0A261A30AFB6AD7D54210702C635C3E707CB1F17053D475A026EF57852DEC1FDA4252FDA2E69BA95C866BD432139CA8A4E367960F85B2FBC75420737CA4843B89F053192BB086BDC0D739B2753DBE42E1D45877097F3B97FCA6F43AC15DF883C3B42D9F472F910DE579301FF7F57D9857890651B64B6C1E8A7E2227ACAC7154D97252EACF8BC5FF430E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD637170756688D9AD3002B3148ACF0009CB1C0802EB04197FBD2FCE168B5FACDD052DD46F9F0B0A34295557CF741102E7592C24FA56DEDA63ECB7A2149E406C0943E5E554767D166EBC95FAF0E9B20C1E530633CF8BD7AB2A66CB105E108C1793B0D87ABBBBA9A4679A05C94BE6A698F4758B8BD38C51371C8043FC79E749D7E41C04DC6D815B0D32A779D0AC6E80C1D56B03C8EF30F6F6CB73A089B149F46BD4671D7C13B41A5B1BCAD94C0552C12CF23352200198CD876615EDDA7257E3CC94B732D75AF6D67A67929458E2639BA4A2967D05F76C4EAED429AC246CAB410B0FC8806B84EBFE1159C88D6E71EDDCC3B956F33739AD9FF6C43168B54FD592D845A54307AD16E42AAD4621D33A037D47D1002DE1AE0BCF2ADD9B01895EB0E63742FCBB5CFDA14EC9C63D94E3387E0FC22FB1B93D9065DF33D03AFA7D156BA719EB9DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF1DF5023719932492A5EE2B7A3B40B7C7F6814D179AEEFA584D317D536645921799727CED4C3D658D5A425D2D3EB1359C975FBE1A2FB2D11F37098B7234A19628624F07698EC3658799436DB5CCE6AC18702D4F27548F61BABC4807826E95D23889575EE119A88256D4326D4BBB48D0F589C6CB22E7F95D49F6607BE258753A6120CEFBC2E6C502138AEA689B4EDA13FDC39CC0759F392860168C2BA881FF70632D05E797A4F52453418035DFE9D072F0593E8029FFC25D75FC7DE13309B0AE4509D8A315C31F0FD0F480B598ADDB0D5A8F945FE6C28C2421DDB4A0DEB478478A49D5E628799ADC5E489FBDBC9DD38686EA7943969A5AC97497B2C380CAD367A8DF3DADD2E31F759AFA47A422D2A5F7C44CCB028AEC63EAA0727231A8BB4FAC096D19BA50AEC9522A00DDBEB86ED6DEB298AB433CDB7B4F15EA4AE08EB01782B70CD59C57D485848B16B9C55BCCECC876AA99071A9A7599868A9BB42F178BF3DD0FBB7EB52A796801D67E250148584C46F3E96898AA264BCC3826317B5BF7DFF55B6F3C3F3929FB552D79FFC1D014C52965F50B446DFC1CFB3302D8C7367A6F64C93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B787B24028E369C59743659E28980F3776146D88956F5E02B3E3116B8292C2E578C8708D4B518B95E8FCB7C7D5C3B16EF976B20FD0E53DCD6D92301061F2588F693A84052F8C776D033ED7A5EC71E928DD7CC7EED8DFC585AA94D8C9CF92D9694377C0268A53536DB64565FD9F5652B0A3634B381121BDA48C2D1FD9E189991D092178D79AEE8333BB0EC988417AD6CD9DD0DCBF6EFDB0E4E8D1B38E2A3DD01B3EAAD55E1CCB1291C87E2A835E86D2E0C0C3642166D2E9BC98CF354E28B6CD3F121606F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174BE4D5805F128D4A9B00266CB6CC792C45CA4E506C8B2504D13AC93044BF3FB3357F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B82A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B275680E933FB83760E66AB8BBCD67108A95111001B9F8E85B6C96B4BBF952517D6330EB1C6AB68317C91468E90237214C46A5F496EE46E2E8069D65797581C01BA0B2DD1DFEE0F95C0AD7E426F877D0CD294CB0F3ECD1C65659D20594153630E46E4A32CA7D3B408B33227123C6449C4644192BAE44916FE60256703EAB9B2821973C8A37F2FC6B3B18FFE0E4C8036583B7E63E60A5EA8FE89401C8633BDC355FDDAD733A74922E73333FF9B2F9EAE2ABF957105197D92E7CAA56F91767E282E0910608FFA0E651B882398F8187E5203F8B56F788A4DE4130D211BAEDBE44B1DE0D729B926D5FBC98A1FA9EF01E415BE3795F085E28E1B32F86B0EC72DB22414EACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E947CA8092F4480FEC3CE1D8A6D8C4CBE3F7EB35919888B729C1CADAA559A42E1BBDA600C713EBB3487FAF3CCCC40CAFDEAE9B9C6EF40D5041B83973133A03156CE65E33173CC6EC41F0061D31797BF2D58C95B5B4E218AA783E09AAD39682072C6EAE7C52E3491E8B0345D3F6DD019D7DA6D9AE08FE40461B81D414B8D5BBE0672D892793121DDB345A2E5B1F8F3EECFFFEE5E425834717D59506DAC94BB9F31F00AC84767700A6FFBB6D93D4A9FC6F02C67F2710269A4162C284E0D9BF486ACFDB55A33CE915B41F167D533B268F96CE0C70A54377A5A76B1C8E992BD4908F6C9AE1B8A1129A6A94F2C1FA3EACE58297AB6E83568F0857FEBA399FAECFAC9FA94217BAD28BE66B04EF4EF7862DBFC7F9D86A69D63D84665C826910849A959626B2F95B16FBFAB29A97876BC2F43A43F841F6161648AA9D1689D67A4BEE2C859702320B726B0219DCC859A330C6C337AF2EFB0B9C8C689D2A7B92DC615BEF81F9488AC5E678E63D3E9C4CD4D2138F500D7967745773C58A8704107771E6AC93AA2307D387AF3CCF853E572E74624A7E40305FF4F57266A6BFBEEC78BC8CC981479D5A80F351588B5E378EC89F193C02A92E5BAB45E1C12BE0DBCAA00E85E73FF666690C4133023ACCD88989AD44530D63D54B090E115F6A25111B4F006B0EDBC73FFCA5B037240E88F9F4FDFF79F6874B6D6865B3B93037E272D66F1BB1EA9AD7952CE8F8F353C2910FBFC6F73626986970C6B1FA3F7D010A7DF2AD27ED28F727F9B6E10E08E9F23278C2C6ACA482528DFDD42021B690D777444DED9C912B2CD003DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D5023540D6CD04777ECAF4F4D58C64C158042656BCA7DFBBA61D7551154DC1535618FB3576C6A634E79E80BC56D4A77A32480711DCF387CC963BBC7A339C907928DBA6545BFEA6878A58236DC95D439F8F3061C099AEF80CB7128E0C1D3AC5841B65C0A738A16BA2EF4649CB510F512A819CD03BE1174182022DDBA30AE32DB5AB9ED29B2FCAF259886A4E479D5B5C118DFFA5529CF83978DBDC1B233C410279CC031E0EFD98F95DF6A32C1FB854F7DA54F12E0D0078F9287622542E551863DCB0B534DCA8EDE06545D0860957FF3A0C13495A47A669355FFF55DAC93C3357E5FC17274ACFCF9905705D6F32C7C6E6FCAE6086384B4939C70128CC73540E47ADC633EF01CD9E59A14EDC10AB0A9313ADC2123A4F3F3B4207CC9564D39F7CE86184505C432B568E4CCAEAA1BB93EFE4C696CA690F4B4EAC21A83E1860C5F26C6ACEE315F139E8C7543B2075D3FBF446058A1F0E0DC7893D9C78FB25914ACECE4664F58E03209D0EE1FCA892A9002B32FE67B0CD27E60F35706FC2BCE8A0F77E89FDD67DCAF4073DE5B72BFB56A87525875B0E27042175EAC158AB2D5A7B85C041FC13F81A9E78911686B33488DB258E31630B4D779F6F40E079F5094D31D70E74F2220ACCE407CB3491B80DCA95CF6126E9D2E955683F0B6BBA28885065E50309BD5E3429C626D547A87ED33769F9BFBB514F8792EB90F90C956F0148B9928189EE06BB40CE18932DB44AD96E226B6BB6A313DDC8CE4FB50C6C548BFA794FDD1EE7EAEA2F119CAA2E0DC7664B0136EE7F50B88FA4F4B1F0A665F36C56AAECC77D637637ABD7EE25BFC8B638430370B0F92FADBFE5C4F166A0B1FFDFDABA98EB3E5D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3C1578D7F6DFBFF09D46817D7C61EFDDFEC6AEB1A21EBD5AF1A0F399A2096C8E30821DCFD15298AB26911D40A97E78421AC35B6E8B47C483E1538E1C110540E6B23095AFAF8CCC9883C1BA2810AFDBC488849BF8E2BD2B63AA036BCE1BF9E6FE84C7C830C65CB9870A441512C55557F371276F3CA97910118271DC35F5A46454B02318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3FBF9F7DDEBC0995B90104C717FA2977F9559887204B56298813EAEFCE587F9D2DF49378B38F71833410D667351B1949CF406F18B0727666AA94DE7EA90B093CEEABA95EEE4D2DB043CFD3504F59CF36374C48E804535A76BB8BF67DFB39E03CE613D53D7515BBC8DF04062A185B7825FD3260B1B377B5D3CF470603B1900FC978329FE4F050A62A0440FA26E9B3D2CDA32E7F9FCFE6446B29FEC3639F068E56D446765B606D7B4FDA46826E8BB9E3FE9ADD93EBF3848B70C759922B63ADAFC8E71CA051A07FCDA3126BC8B4EAE41DB2031017A6794C6784FD8B93672BE6206ECC5F1396078719C45CEB31BDE4A3D503A56CD1BA60A875E2A5AC7CF340A79F261480A2A36EE4FE88106DD0976B8FD47010119D6D21982AF0E8E58AEF1BA68D4BF979DE633E719AAFC7A6C8AC6D127BDABFC3660711DAA2962D639D46747BC03BB269789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411923F9FC45FE90EEA617A4971AB81153088F58B488C507F5C230586CF967833C9A0DEA1CAD7FC139A9710382C46136E4F4007BBD729ACF06FBFEDFF5144533FBFED92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE598186E4905539B32F01DF3F0FA65E08B09F4F16719DAE9A987DAC3A28B2B9E001FAAAD0F03810E525D26529CBA1829D42796B65515D55BCD2315DDDB342591BE8E217286002741AD99A1565D106690A5D6277539266747D8632686C5C9061D5119998BAF8B6C09E61D13B2D91426AB98DDECE3EBC2CCA03A8B6591E2A1712FE71F847F486D6E177932521D9196CF0F637314E2329A86F733D95CAA0C2F7F08FA45A993F52B44077712B70116CA4A7DB6587E24BFEB70AFBF3A6F1A33F469D98278A6603810F6664B9BDF27388FA8C69CDD4127B39AD97A6E2432E3C2B6E0087EEBCCC54DA43837F112E61409D225BF5E5222DC107D698C0E571EE8D532C99C6CA353C02F2BC7233F1636D14FAE126DD4433CCBB5DA1C5BD079804FC920E7A7906C9579B18D7B78824CB39614E28A2091D1194C26DFBE86462EE24FA1FE24ACA85F912404458AE8DDCC5B03A0E0402BB689ECE763D0825A8D566713A013923627115705098D63351D22772A01D57BD39566F1EF058044281C3275AAB8C44F905DEA89F9D1ACD8FC3C5E9F2DF429637D635359D0A3D91D765C71E5DA37C2BCF29F1EA9AEE40BCF69C70168BC10F1E9576CD541325A8A729566CAD7C0483ACC8E23DDCEBD1114559AAA8C6621F7A7AD11AD19D6312097C99841A84C35772FF6ACF5E1028BD5885C73C78A719FE0D63D52E9F55509B7AEB252865C6720285208786A2439382CD03CA0BFA2FF1A45B734943CA586AAD35DDCFB075538B0850551967EE7D7E1261DEDE7016BAC7E1B447BED75C565A09D3F173B5F9DF4CBD86780F35E9D7D62E54A2FEFFA0FCFC5CBAB99D2F5EF5784EC92C6A9C8DF06FD4491E197B153B084BB9A5F629E4E7923220EA7981AEDC10CCBE387725C16BCD5A4CFFB3566525CB00B5295DEFA64574065D1173DAC40340878BDAED7D71811FF8EB1B55C9E3C8BB8BEB2D011A9D6DBA1522C969314EA2A7FF20000EEFAC8F760CD24975B2CD9D37FFF352B4B13CEC723C68A595E301D02E0FD881D3286582D5472DB230F77C644E02E4FD2118592D323D93CD22E55EDAEC15693758CA10E3F215E6814BC13E2DACC05A226ACAF6DACA3B9EE91B0CD0740A5B50E6E10013407A7AC9A58F2C2D41A8CC0BD39BEB52BB643AA89A1194312A69D6245A1844A03D0EE0BD92C46B5D8EA77927C48D23107C3D498427E8DCEAEAA36E368A58EABA0E06B97532BD8D2B17A03933D6BB6E00C1AA62CFEF7C7834BB0705A50205C4EF8D3270C4A0716A59CAF17D13F6E01699B1ED376095D3F6850ED50053CB56D83A15DF12887CC06E7B45D143CF738881A322557FBAA2381B355638DEC332B690F7A2C91AD96C5102819AC027304301756A1B970378FC0C627135DB8D5F6B0B75316DCF93F0955E37193575DD0C14961D776379DAC58F5FC1150785BBBA92D1009E1B49D7E3362CFA468D539203E53FE2EDF38BA68448A3520CCF623D8427DE666CFB05E0BC25452E528FC4BAE4FCB020F4ED5EF4F2A71B9D225F7B7E6655E60877D7B7F3DCFFD8C4C77A3A3B36073A69EEE8B35F49BFA43AEC19ADE9CC7DFBB1F6A7AAFC69B3210DD8B9D2D54268336896CC79F76B441391662909A9261AE1A5D75C4F9C360AB0C19A94F3930B33ABF6EF6D5AD18ECADDB1B477C019334C76E553210D4C89E4C32DB11EC281F61A34DC4C3FA81C4C11ABA995BD4EBF44373AB98B000C9F53E39A9E09607A88AAC7AE6A1AB1E735E1D0F8F8D34253718687CFE01212B0B818030EC3F1C8F79574580A44C571456C431C52BA9DD336B1A5F8753263FFBBF6005A7AC41B11814D8CCE8CA7C6B68C4F9A56845611FD6D46C35562176A9E14B357EE8DF2B3F76950986449C0AD69B0BFEF0641CFFEE6CA5112F71E1978592018BE903F66F340EDDDF09089FB1DA7C60F76B3D92527D470E11455137D94A80082FC1AB8DFA33F518E348D50068DC6BFA59015590904AE41CAE8E6A05F2A1296D97077A04DABEC3E27E25173C60F955161EA514178875427F4018AE8CE74578E79E80310F069A611AE281EA56517083EE94B5B37A1493E614AE495D28CC5D8E5A6EA4119FF599BC8DAC4167880FB7EC2FF09007E874ACBF9CAF516CBD6E305EA8492B3FEAF23BC6571A5B800489E07BDB1F2C800BAF3E7D35B4EC997B21A3C29960A9FAA177344E6F9B9C59489A67E782B630D9CB44FB0F82922839403A85C7AD53A9F32D163A64DC226EAA21E0994B218DB931E50BC31C0E1B5651CF2098EB00153DC510E086B1FEB74661932A95116E04BF13E9E302A4CD3783C572CF52249F5FDA51AEE054682E7D3E9BE99FA215853668F015F5F788BC6DE4261C7E53A2FB9B46FAAF6C821BC64ECE7AB00F059A65EA3EA9AC7C64971F504F26D97B48817B3DF9DC46B3C106C041D1A136B4731AA2922B97DEB83A3AD798A719BAA1CC2ADDE4A34D5EA63188A0CFBD3407F3930647C3993848154841EEEAEBCDC2149D942FB644A671D50A1B51ED937765C0C2AAB1B35FC6E4E6DE85E82B4D87727BF30085AD56A27A796F53CB4D3609F07BD7645F7B32EC8B72E51592714D78514941E217E6A8A393F91A907BBEBF9804CAF5925756BB3EB09D32E125469D4413DA437C8BB4CFF2F9C23C6ABA4B90395F55E94E0113E372FDFB37E7801F0AF52AACA367BF4BF90C58D093771AF0991244B91BE5C251F9380444AA86C221D06D0BC12BD1C2DB949E7DB4A5DF1EFA0A4BD339B8F1B937F2AF48072CF8F69E47BC2E20286D2524A59F271852286AF9B8BB57C5FED3E3010743E81629BD1C366D9350DC9329BC839F7B8AD5B7E570C85EF644413F0A6974DA2CE7FD7194C30A43780D5146942339CE2B186698B8CFA564998F0DA458E36F2B66CEDA779C9E9957D987676AD23A507730959ECC0016FF3A53167DB27B2F226A2B4B5EB7A409915DD46A882362462CB5BB7C3D2A75998AF280055E9105EF6A91BFDF40FC5FD0E6E97EDF27F96872351DD3E8C28F46AAC52365CF914A32E5C21626BE9E13BF80A1E7E616022639DB2A5ED92A119164A3FE6DFD83DBEFCE4CFEF2250893E21030934A382A288C69BF0FC7E9C92280906A4BA331C652BC4F904B9B54DCF3DB0651E43A6C83FB9843F85F0DBCA8D2E7F492200039906CF62A95D7B1830FDECAC0306B1A98B6F7B399E406A172202E29FA157E168F4B9C6979150F5AC2EF7769E4A729B6D59DD8F944E9A4A118FD06355D19B28ABDF256B4390DCD5C098DE989678AC25659763FC22E05FC4EB5860F4EFF891AF7D33883382B554819C5CBBA093B55E335D550DACD6AFF9DF70A2A92C1BA88F210224F8F1DFF0B420B6C2F673497B86A156F5F1C675D301F55D69E5D275BD43C850F39D321DBC76B0F153EF703DEF0FE7480D5C83EB1535F0FF92A37EB637DC3AB8D7C7965C8517131F5273B10A2B5E64C16C85791D41854E43BD503F0E52180E9C29499C45CE64BD97C0BA486377BFBE1C6EA2A84AE249C8AE40CF3E86989F0379B9D02694DA77F9E73560E0F38AFD05744E0A30FEC0D8DFF8A1CA3A0EC629144E96B590FD5F75D92F40E0FC0A1127486133218B844D932E038CD1B04DF12E1EC6CEC249345EAF4DACF0D38453A533E5193257BB55AA785666C64B91491B0A5DB93688FBE07D66D926759B669E18521210CAD05EF3F8972754DEA64BCA926D661B145AF5B8090D1A4E51D9CBF8818A4EBFC8FF1BD6CF2C76B914B8A7BEE0EB33F37ECA54E2DA3CBC29F1720DBF0A024C969D4B1E36326FB6F63C9195608C68A3D7C87AC394210D0F4CB7D858A88168FCC25B79E29197E2EA3B3D4A862B70A1D7F3251C75F02D476926DD863B778059B83198414E0672AA1F27898C8A6F035D26AA117F838EC83D453A0D5C49AA350B288F1FBCE59D86C8CCC99F14A221AA18A9F300DA266DCF084910890994ABCBD8185D28BAE4CCA4BD68D4D5790FEFBD7A6D56B8C78974F9A8675E6C410F6D5F7F6D254F1C7885F48F0391E1BEEAEC7437553D480FBA79F55DD5B19C596DC2089BCF9980959958F7FB7E6DB0358093379414F67BCE670BDDBC67BC8ACE419C2E48C5B57EC624C5693562B719C7E6B09F3A309D255D0B7A8B8430F7E9544A881EEB694C7282E20EA3E1ADEA50564B935D528C0372397F26B1497DFA3D0F117F7A6797C1626D1AACEC708302CB0C0E406BEF60B7F6578623EA59A005B804C009A38E0A615F1FEDABBCDA5269C9C48E148A143562E1A372C0DB9D8F249FB5A7ABE5928B4BBB17DBD747A57D9438774BAE2550A5B205FEA96912A2FFE3FBEF1D6DF372A31B1084F0715829C141B845551C086DCF8FB9BEFB43B417AF3426BAF6007DC2EFC3B4999D2A658B5A19CC61FCB3E2ED5EB14D1ADEF650C7254F5163A2FC01B987E3000517DCD878B3D9268E912CA3675000B10E53F5B8172477AF6FE3778CB0E5D279309245647970C216E2E608E25F1C4FAED708E98E1D88193FF5DE2D33B178BCD345DAAA3ADEB8B1B6D7C3E9C2468F943A4AF0596B0AA480A159BB882857360DD34CEB848F5CF3481A660F70E49916F9A952B001E60F11A31CEFB39D3F49BF76159FF3E8B3570BBF5D759F5626B1FACEDF4AD03E261A7E095044665CE61C3359BA5A046E44C8E5506E2BD7E5C5C61EC2EC722ACD680BA597A47ED44E937AA64C0E3523F1EA891BF01E2B92D54EE9A3684A122D33ACD2A6D14133A8DC35EBE37F49D59BB4BB5F24940C18E0B4B5F1349AB813E994AC43DD0420A52527147C9A0F4729F8BCFF0941B934253B98628403937D1E2DEA8BD23A2EDE0A7BCF3A2D66FFC7049C8D2D3D52B4F9479F6652462AC2D18DEBBA361721EF71168CC59501174444B5A2E58AF71E8DFC4E9F836156C1C844EE12FCA65ED97F8189FF34B8EED18C26508B5ABD7DC94DBFD37F18A514F66BEA2AB8F02DFBEF4D54850B589898EBBE0E68E9F864D4468C96BAA0BDF1C074AAF51CD47B20784CDD20DCFC3444802DF292D0B21D32A93F2DCF3154860EE0F469CF0E8BCB4BB474C2C0F6E2F97EE8C155EF5B270FAD06AEB3336087B314915E7CC95153698BC2E486441D1484052BBD641183C9F5495CE45B270E5D085F4DF45707C7615CC89197B2646196A2F382EFBB8436E3B0A09CB2384FA6D3D7E436D19DBCAF897D8A2B3B41D17163C52CCCCE010274A70B6B985545072CC776AA5DCD1D7D1F191AB56003FCCA1F90F9488AC0C010A6FBCF7CCC51AFC15BA2F9E678B9B2D2B44DE9B7C841C386126135E1871324C9C7D3648DCB8213473E4D006FBDD976D2854DBC257DC1C21E0199C10AA0FADFBFAEE03693930F970285460EAC6BCCDB873F2AE73A173F17CF6C07C26B3FEDC0E81E8EA4FF7D68CAACE34340EF1990F3BF44E23BF65CAC9F65B50E4AB2ED67F01DE310314B56B351691609FD835399C51AD9B35E4118BF3B26AD5DAA9A0609CE6A24C8D2A1244709F770A655DF9E80C0C7441917C8329446EB8FB371C506EADD1DFBF6646E0790637395A2C1429C60252D485BD99EB641F0FBCA951DF3698F69DA2B8E751BB02BA592AEA7DD21E7B961499C0238B93F6AC1FC73DD562C80D39493800D0A0A594F26D16FE54EE71B5AA5CCD70B5F1ABC79687AA87DD986F10FDE0002EF9D964E80940FFC39C5F2FDFB81C190A83B0AAB7BB176476712EDE00F6F97973B9FC6061EB404C24993B85BD7BDB4582903BE253ECC3C10C0B65232F5F681953B179E19D4246B0799477359E0496BE7925D46065E4AC4B5EACFA466A8DB0A62F1D1AD326063C89539BBD517FC53ED562D98D20D8A7CE4FC1404B3BCEC7D500F4573EF14C99BCD70F290E6F4206E9BF9E4052A8DF39BF57BAC1969CB4D85E43FEFC1907449AAD6475CD2A7B9F962C315ED6DCFE913A2FAE5E1A695C5BCBC0568797F5154AAC68A30E0EBB8D2F73E6975440421D001AE2076AD1C65F3ACA6C05144A65D535C89243D6F099CD26C54760517EDB1CE98AB4F9E0B6E3A06B3765D62E7812C38B23D6A92ADC6CAF95A256FB750DBAFAA6D3E937BCA9314331C3EC2BFB571E0D54D3A98D5D28522326681F2B91E5BCF4ED462CC90B4CC27225742E5C2286AD1FFADD8418B9B3FD71B3CAB178F34703FDB8ABDD8F5C1461F89446ADB1175E35428091CC0A3B5705C3BC66A1916D1424D631E588FCFA838C2BF8BFE2CA2F5F6648E79942E3DA4B064A22AD6A9BB05C15228E1D20D4A4E8D041BEF83790E9707A581DBB7689E032A083381899EEF508E4B2A897FFAB447F821C848EED8CA09616CE2EFD13966C479F17E1A29D5B6F18387D15E7AB024AAD60E6D68869726EC117084D8E0C42A3A96F5B92139A4B5768CDF2E35810BD1AB3BB40DCE3F38853783F6856552BF95A4A835590582BB7206044086C1CA3BD9B8ADFB09C40A838DEE80E1B3756F98073651454C1567EBB9BB8D9FEA16E9CB0F30FA5E7944CCFE2732FB90178A6F439EF2C83D0FD90FA196CBBECA9DE1DA63AB609F53BF11303F3AE2283195AD62587795E7CE13CCB19132890CE25B085F7AE282F8DE315DED51D9E7B4652285ECB3929B18FEE5FE427610B9311F4173A555CC3D534439D074BB8153F99EF5C62288F9CD393B0C257FDF1AFA64BB68F3DCE632BF81FDFCFBFF93A4CF99D8D50805B18EDAFD09D086D586BF8A5D6A2026084C7DBDDE343F74C964ED3011E29C8683300EFBD9E93C68EE571CD156D8FE815579D8E5AEDB483103BED689A4CEB7EA73CB8E19A6994A01838E173EFE68E816CA53CE578B87754CB34961D83A611466478E9325529D6D15C156B2E2E06E1F624139D230DD3A32A90AD2C7097F43119E10A2E788F15795548B5470728DDDB77CFD86A6C3C6669B9A2217BC37B15B8EA558D2B9E99EEB37E105700A324FD17A5A00803F41C5317FC2445C7216FE28DD0F15BEF50566BFED945796D4F3DBB97D53204D5BD64478A75484912749D9407C09D01CCDC391BEC54A4D43C9157D0A871195C731EB746F61A3F82D6F1A9807C2BD3B275553AA6CDAAE509A3A350DA3F119521A3DF789E011E59EE8138C17EDFA2AEA5C15841D25DF2E3A1FBEE40A3CD98C275AE4FCAD2708F31D7354E4059D43FC5625858721409E990F1DAE7D7FF6B3084897B817D88A99C149497599957A667750E1CF446F5D24409E3CD2AE7F13197FA6705BFAE8C1BF36AA626D524EC10CC50F77B359D718734797BA0154CBC3CCCD88030C97386483EFFACEBA41E5061B95BEF6324AC98FD576AA2A8D264D05596B20200496C54C58146883B62C9051E5F52224294C996EA6B44F84EE277D029766D66AEA021467747DB5CE0597E5D91D92903B74DEF2A7100BFF8201F70D009B0963454C25351D8D43AF77A3E70C95BA5FF34747F55049243C06C036984C5C303378D475F841749BCB2DDE91A25C105501EEF479F2B6C68A60EB8F1A308E74EDEEF93E1E34A50CB272AC278ED9263C0DAE162B7C1FD035421A2CDA9774ADAF21B292C252B94398DF63894C88C4B5529FC5AA5A18E788D74EB6126C7FDEBE4D650E2871B25F37DB9EA8AB64FD4806121F4509D4FF190439B7A8690A81275D9C03CF2B51832B32DE2967485BF84E915F7BCA7647E09863CA48B37131815DF9E5F5A88535186C40F177A06B657B4437728EFA50AA22C45E49026053B3C2A3C554F1B2613EBE50F27CEBD3BB03C8CA17B22EE76C4200A0E85A70B6DFF7F511FA2265BB7D858556213C48436D573F120D4222BB1A5C924B2EF1605B4A1ED717EFAF63AE53B070D7C62B2F8CFDFFBD18DECB0C405E7575C6AD8CAEF4789D6164039F963F807C3B978CEFE718A83A68378F9156BF52F6A3F76E411CFFD88448BFB452ECC10CE99AE5F5E303EB099B89765A377868B0B2B3A0D631264AEE47BDA8FF3A92483D27CC269B16390B3ACCE3350DAA649AB53B9C1CFF2872B6C1F9BA67D9D22C6FBE01424A7DC815F968C77BE937563456A273992579C8E6AD585A0B3D38AAE13ED13B81D58599A43E86C4B4AE7825B358C6FB94BAD7F552544790377714DFAC7F17B9B6B3BAF2E5D6E87AE0D0769A39A5580D5347C78067D7D7C375A91B066A61E124E754549CF27779D43109D8E167423F13D05093CD1D31B7E6B76A89C6BA817D852775ACA8B385138C6CC73639FDA3AB6FDC5F84CD46DA221B2D437A51B54D43D98E6D77E31B07FF420AA12FD6FA8892C4220AFE432664F946E738DFF89EEBBFC16CB168CE1721738B4A1174265AEB27FF3808A80D3BFB6CB893D1B6B33DC27239E96108C6D0D20C912BC1EBBE7E245056220BE957E7B9D49EEE6C4D341AD73932D304798F0A0F04F31D8F70DB5E06E3ED2DA627D47E0AF1C2E14E56054A87AC9810B617A52D0DB5145FE4C2BF6D0D4AFB0F9314FE15167A5AD0FBA0C1454FBAB0705FB6BBFE5F7E39824E59DA24CC67B3AAD9491E7A40906487BF895E90F63CFE6D7C0984F1D2747676B82D09DFCCD2A8F6DD158C917DB81FDBE6213FE43780DDE17ADB969B3D64CD6BA6EF1F9ECC7D6F6207280078B10DBEBAD7581A2E8C2F83E4AAE8A26F8D1DF0F8CB45C690615EA304E5CE30D2A96C55696C6B1D82D274E9D5765C3E5D2D7D05EC6A202BFD0211B534B7C9FC684C7A72C2D619E9DEC4175477792BB930EB5888FB37198A6E1DCEEE6651038F5C0A15DEDCE6D1833CDA5CE4EE61CC144E7C5202FE532E0B274F2CE4E90D91F2BAF7808D0656D5A106EE157491277F92A36239D1CA7D26150C118F9ABCEDD5470A2A0069AC1BA97ED1CA9885FDF2B6750157AA5B72DB5E7C1140E1FDF78DC7FA04773F4570F4544281C2E9627E5F59CA9740A38B452C9F3A930956187079B4EE4C91B3E3D9F0F502F8558A092630BBA965FD8900E738FD1498FAC10E6AFDF58F32DC0824B405C0E1D962CB213D4D834D7D26199B9172CCA1A36D7A76DA603FE07CE0EB070AFD90E7A30D937A32D26419A002A32AD9043B1735AD3D0696AEDA5F47046F8A3134B8D45C090C0A54C70AE992A0916A49AE7F3006165FBC71CBA5F0611FA5140FC304CF49DF3081CEB754E9E87E4FB637D7E701D930EE23B6E7A739274EC3AEB90736D91745A92DCDC5FAEF42918E63079E07316C2F9E59D8B79062F1D816C536E8323F501A20A11D6FAA241A5CB4A04F8384206C1D4BA5BD2DC0DF41A69CCD6390270FF0451211B36B489AC95476493D812ADE03FD8EA165053401587F7A18C2F3FBF4960C82B30E9C7C30EA830FE7D052DB5A191C0F8DB73833839F0D7AE822027E19C3A899EDBB02AD49EA87E1A2D55EA6B010BD984FC6C5B12289B41264F9F2F23B8761F262598692F57DE1277F48B3EBD06762F791DAC23F5A5846795B4C4806EE0909163CF27111BE948EE0CB673F0B744707BE8189B059F6D33E52AC33BEC99DB223FD42F64BE1C3E8D505592A78D5F7D3E465A5E34C1FC7D7ADD80752A83CA5CFBDD7AE15AFFE7BC0A4BF3722EEC05E54482A88287D9850672C2DCDE120E0C7AF377659E5A3313D0FEAD9B350A80F0A5A4A480346AF02414FAD52E5108B911B7A4B877215E400B3FCD4E8786E962704A50EC2B2D2D7256777111EA6646AE8A57C84B56C30D704C4B914EBFCA60FC07CEE5DB943630CB07C872596E0E48193D8B6513232AE14EC985E19B27E231B2EDA344957695939677A09ECB8C65C93C63C6B08FE5DA691AD51D463012565EAE07805134DE6FD09BA7B3659089DB2B16DAB68A89406E67D63B3F0BC70C271C7D0295293CF5E174FE0609D593810EFAD6CD648BDF6D3253E64DCD6D2FA70FCDCEAF24B7C96A3E3E4B078E1668E5F6CB9A598FA202F0AE1DAD0AFC54BB46BEE1105C69C535390CD630A2BE448CFD70112A56A74AFEDC4CB48BD579FEE9039DF705869A1623B1596F77D7420B59F32801106F6AD8A16DB40B1ACD82415BBEADE36585C3BB47F37BFA7162C255542E8284D8EF8CFF88DB68A47249DCD14C1D2E8E5C44E258E9BA867902ADCD588A5A382A60A580458C8C59BD5F182742CA1BD6A52F35FAC26893D74C3D74429401712918098CCC493BD226EA8A9F8C7700123924131913453EF8069237ABCC4B851B0A868015162AB8B7B63B3110906B267DCCE5659F4FCA5298C4073BAAF392C5649B429D5E378557D5CA03C9A52B6208936AE2CFF83D7E28A3274398CB3586BEE9694A14396FA1D67BFA90524574B7DCF0E8C7B86C86A69FC0C2263B437016842743E7E1743802C4542DAC8E6A23D03A158BEE47F010F71E5D9A7063E26FE8C40B208160936B5CD4D13ACD22F928352902BF25A8C8D294B493907F6794A4DCC0E7CE621FE45CC6E5F33199D798FC6E833F9EA4EA54FF6A465EACF2EAC6864D3CD0057429D789466CC60CD853B829679FCC639446CB0657C15B869BFDF27AFB572303E17FF826F8C4EE2C747AE330858830F70879FC8FD6F8D7CA2BA986E5D4DA1B613DF88CE09212B99BA77FB3E3AF7AEFD4FACB02B3E3172AD43BA87A4433CE38E45C1DA3ACE463315CF5A87B14CF4745D5282B17B613A033A9FBF52A40D8265B49A49DFFFC6C71377C20F4B3EB43FE7D89D829477619A7E5B2F7CC9FD0299C838419661773087C7BB3573568DB256F94E57423B1AC21C0662B60F526AF49629B7A8F7E833F858E5C7423437ED22E6E704EA66B26E79878EDCE376E8BB682EF83EB4B9600015217C1219224381665C140C78374B80F47511C48B5238937464F3B0A5612D2F1FDCC91B74CD861CE655CBCF22B68F657EB7D8806DDDB03B4F08E52089938121B0F6B3ECDD2D23003C889FD2F9A4F6D3D4358976641511DDF513181B1C86DE10522AC021B6A301249FB9E6DB19DF42C5BA6D53F1FBF9A7A2249C516513522F8702636F688145B52B1FB6172CA96F59B9F845760677D91996B38371DAAC111D6BC59BF28F19B4E00B5E312191087255D008FEE158A8E1619CC0674E12DCAB593EAF6C99C9CBE9C700B498697A725E2F30EA74365F3CD3318AA1D0D7C07DCA4F2F6C3AC8EFF0501F8F65A07363621059517EF1BA27310ED930A1A1B0D4DA322D5FD13EF522D21A3A7D623FC499AB8648C1AA0CE2EF94316B2965A246AD7C8869E9C489AF1FD2DA40E3D688531CF77F083F281E012ECF83C4ADC97B5AE47CC38FDB41C7ECBF402AD42716821AE404A1D224363958B9E71DD4B3E77A16FC80598A3065E8E00F36F2DF940F4E99902A1D62D73470FB4923D3A46EF07E65D02963E1B5308121675F1C1973C656549030DCE1BAE145C7712A4879E2F3E219B72B673243BD71442B699F3A4E366C7B88C1266330282D0D9357FBCEC2F95AE54D87A50C8581597B0C24C2F77763B326A55EE924C4A492307610526A864CCDDF6FFC64321D570589BBC5F9CFBCDD95D0C7AD62DEC853875BA2F3C5E3FC20CFF99FF86539F37EDC56643EF7D70D0025B395061B83A100E1BE1D6096D007DC42082D4E793CCFB79CC5A06242518998D835B32B7E579AA14806AEB8A4F19E554FD72D2899617541C6B86B63AC60BD7B6185A7A86BC7702CCB91069ADA68EB4F117E239BB7A9581A56CAD59A618449EE02E2089CE3A1B97B22AE34BBB421F2194B00B80F1841480577415436FCC20FD60731E6E28138A320C9237FF656A5366890E492A318EFDAB7F22CDF81AE5CE56539034A8790E942E58118A8F141B2FC6E4559A04B9EF8827BB7C11D5A4CDAC22E42660082AEE184078053860369D354552F1CB9D798F3FDF657648A7D5BE4F41E6141FBD80732B6D3AB57C0F60D38848FD33F7E468BF7600E16F25B9552688D3AAE33DA731DFA536059D24AAD21AE940CF31E18A40508DD1623FC89EC11BE4B852EEEFD56C002C1388DCD5C54E0524BB681A25E076CFFF94EA7B5E0A0B7DA1DED8DBE3F9770536FFD43BB48C9E55E33554E5C0411BB823FE16AE3CFE51DFC9177764955DB39B08C627F74A7B9A16DCDCAAB1CC31E37B0D3B90ABA2F1EC00FD2EF6E4FF3A15358C551BACB93EF59361567E0834E72383F4EA2E8F76F000EE38B179F7F0F9A3351C5BFF81B49E8A5119C6CB5CFCF49A6875B3A99CF14E6CBABAC0F4F38FC97CBADE13BB807CEADF726AD565D65334539E879575702D58462BB2A7C7F322A16F3F1C4FE116CEDBA6094EB4712D774B8207189B700C8B84FC7D0DB49B02F7AF17A6270BD75AA54F8A79E4A1A6D588FEDF94C0829EC1496988507C8C5BB87A70DFC3FF6C7F985ED38CF6C23E04FFC8001C2958B5E0920B284A4A3A55023D13D4FB99D392A0F61281E6DE6AD1F907788504F80477B8C21454E4FF16236E42DF95C85E20DEC39B2920ED49AA540BF504E74627B678097B4EC800A37698C32118BFF564BDE9BE0E4B16A3D91A9A83FBE991DD88E7341BA96976F7694323E523B76DFE3C52F28188C8D64DFB1341EAFC98C9A28CE446C4983AC52A1C38F9CC5D8CAAABA4E8BF9B7E45E3521567A46AE5166642E89F8503F892F522A447B2FCB1BCE2EF4EC86E22F48FA99555DC193F080D3F0096A47BE3C2597FE83A27E8132D28EB55AE87B36C93F31A9E371BEF51E405037DBED6CC4916E5A855116586F7C34F33B3EE626DF600644EC881246E32B5716E9580A1733ABCB22346C4414E5FF2C085E2CBFB45BC77168F4164B7CECC874DA5594F6E8D0B7B6B36EDEEDA1342672A4D6925CA2864B93BC7F63994F8449929C3206E086738FADF14B1872973A6093B5916E565DC3B354FC544A44202598AC2326C5EB9F305C448CF68323DE4C5BD28472B340E43DEDCA0DC290CAA47238A7A26713869C6B4237D40EE2743BFCE74E5CADFC183B14075FC8088943F3B2E93FD3A96ACA364B9292413B2B67B43C855A898F877683FFA238C05E6F789ACCCC40C434FFFA494F2710C3DFA213DA7B56D5A4C273603ECE648F3E9D6EF1CBC0EAD4BFBAD01E0651103DD17A534A2CCD00CA53C713F3045B2389B81651E8E2C2B6629D127505EAE2ABD26F2086E9D6BD48CA6FC3BF98F99604F221DC203BCE9D61B756A89BB0B418249889529F7E8F070F35D35E572EFA012DABB16A98D0AC8A99E596A91468A1AAC939629FE780A45D8406B60D04C8E2B31EB7E28294FB2595F4E7071CD906FDFEC3EC3CBB02B03E38AF71EBE9EBCAE3DFC9A37E6B54 remain = 1099511627774 -max = 1099511627775 \ No newline at end of file +max = 1099511627775 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-12_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-12_256.rsp index 7a3f549c8b..678fdccf6a 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-12_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-12_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHAKE_60/12_256 - pk = 000000187C9DBD8C9B8EA4E9F5B0D99E80ACDC712F597F327BFE800419A478530242532C04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 000000180000000000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A7C9DBD8C9B8EA4E9F5B0D99E80ACDC712F597F327BFE800419A478530242532C04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001521B6795E3B31C6F469147CDE5776D1FAF80EE268B570DD87C1895E195F358E50100000000000135050ED1EAD3E799B63D5EDC01FDE9B7E3E8036A429C0AB56C909CC2B6378D6F020000000000010D93E097DE2D5330AA792D234007668B3E7F9E699621D298D2AB7577E8518A0703000000000001F2616B47D5F8376AF6A5FC658A75A52D032F7A1710630905C152957F41FA24010400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE5900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011420B60C54314ED8291B4F251FF32674EE6A3C3609140380F6B20865B7AE643401000000000001DA6EC89DAF2B01E86C06ABE8043C9A6EA0562A18C49B4A9497D347FAF8EB910002000000000001A0A42481338E08706BAC35F7B5F5D93432D40144F47A0F6790DF4B68525ED740030000000000014A9507DA8B4941DFD3D5E9A02EA050B97F9887A65D93FD8723FDC30C7E2AA4E00400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164A3FE6DFD83DBEFCE4CFEF2250893E21030934A382A288C69BF0FC7E9C92280906A4BA331C652BC4F904B9B54DCF3DB0651E43A6C83FB9843F85F0DBCA8D2E7F492200039906CF62A95D7B1830FDECAC0306B1A98B6F7B399E406A172202E29FA157E168F4B9C6979150F5AC2EF7769E4A729B6D59DD8F944E9A4A118FD06355D19B28ABDF256B4390DCD5C098DE989678AC25659763FC22E05FC4EB5860F400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018BB8E296C7509BC115ABB151E123D4E0343D51087A3A7321FD6406381792A7DA01000000000001166966BACD855719FD325B6CB7EEE8DEC0ABA7479BEEC9A71F451BD9EC1886B002000000000001E480EE1888B362F2F00B536DC0FB57F3AA94097DD543F05D299341633DEFE5FB03000000000001522E3D23E82223C8085779A58B7ECF45EB835F4B8FF5294923C95EEC4FCA5034040000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096F5B92139A4B5768CDF2E35810BD1AB3BB40DCE3F38853783F6856552BF95A4A835590582BB7206044086C1CA3BD9B8ADFB09C40A838DEE80E1B3756F98073651454C1567EBB9BB8D9FEA16E9CB0F30FA5E7944CCFE2732FB90178A6F439EF2C83D0FD90FA196CBBECA9DE1DA63AB609F53BF11303F3AE2283195AD62587795E7CE13CCB19132890CE25B085F7AE282F8DE315DED51D9E7B4652285ECB3929B0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D10E76AEEA90CDFF9F15085B0834F5C0339E4C86D2CB52C234F6B18B472E8A020100000000000195C0CD14484D08075EDA691EE42CD999A552CA1A62318D9765CADAB553C1C5B90200000000000157A8A577120F2AD134FBF0E0E061E38A768CF935F4D2AA9A541C7A3D033A991503000000000001A467DDA3824B40F0D0D861A12328735CB8C23D1726982BE71F4CF68EEB4925500400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B07C872596E0E48193D8B6513232AE14EC985E19B27E231B2EDA344957695939677A09ECB8C65C93C63C6B08FE5DA691AD51D463012565EAE07805134DE6FD09BA7B3659089DB2B16DAB68A89406E67D63B3F0BC70C271C7D0295293CF5E174FE0609D593810EFAD6CD648BDF6D3253E64DCD6D2FA70FCDCEAF24B7C96A3E3E4B078E1668E5F6CB9A598FA202F0AE1DAD0AFC54BB46BEE1105C69C535390CD63000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151D5FD68390EB99D8038558DDDF270C7B6F86FB6880610C1958EC697B28F07030100000000000110E17383D0E375BD799216DC0666186C133435744D4C0B5160341DE623FB326A02000000000001446011ADFF0A4CDC66D4AD0938159A880A250A728A209F32F3AFA46A2FE4644303000000000001656C05D7A6E564380A829747834E40FABF67FCA7B2388E9EA19CB553E670F39D0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F1CBC0EAD4BFBAD01E0651103DD17A534A2CCD00CA53C713F3045B2389B81651E8E2C2B6629D127505EAE2ABD26F2086E9D6BD48CA6FC3BF98F99604F221DC203BCE9D61B756A89BB0B418249889529F7E8F070F35D35E572EFA012DABB16A98D0AC8A99E596A91468A1AAC939629FE780A45D8406B60D04C8E2B31EB7E28294FB2595F4E7071CD906FDFEC3EC3CBB02B03E38AF71EBE9EBCAE3DFC9A37E6B540000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001FC2D9E83F622B942A7AB522F9BBA979A17180C4905EC5D9373BA8CFB20522714010000000000016319A9C8C78226547F3DCA6A70375F911BE4AE9028FDCCA6D161C5E3698EF41C02000000000001B15AA0B323C0B86CC6F8D84E17A54A6198649F962EADC06CE71C2D0FCE0F3F57030000000000016849136962E7C523775EF2B7BFA1967E4C45FD1B5FA9927D5068CB7045F945F80400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B76671FE88C84A4357C76C316723D855FCC4372ADE20F8746B501EB76E62E66AE390961FD58752D4914C7CA53CD0B83E168C40777F8F136502A84B6C1A338D450ACFE885E77790E4EA399EA859A3F37A5FCB8AD3679063566F14B36FABB97B125F4BAB4B60EE9B26EAB4BA86E1C81E61C1A4103D9BB2D17389A93D792C203B005A361C41D2C620CDA46919CD9F7D30E547F62CFCF3BAFC540F5E6D9CC212792A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001C9A1D016CBD15EAD633BACDD80FA9B396D41EB60B5C6C42A9376572A15B7630801000000000001340AE4E9FBEFBB05FAE40AC69DD5D9882AEC64ACEB5B791C23B5E38F7E0D8C86020000000000017BF4F1D53369BD8AE978EE67ACE5844E4677C930973856D35464FFB7DD2E380A030000000000010A5A6E217E8ABD673B1F169D13255F2B1EF225A6B17B4E8FDB3638EEE425A0FC04000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002FE6945E6FAB674CFDEE3C8446481D1144C9AD9F8CA0DC87D99E2FE038A09F0E9741814E09511540CEAE2C0E950551E10B4BED309E2F6E7CE10500BD8B00C5BE0B5D88B01A1AF25ADD068421C0F98CF345A597427D043CB53ED18DB764F4288B2B88AD917C4F0788488D1C56B7579C7695983135EF479D902A4360389A206CCD9652672552F9726782AAE9A57D0C64034E7F124FF75B1B55AF309F0E9B4597E20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001407FB5EC75AC3694AE740341B13D2FFBC2F6AE7343A54E37F6C6F2EEAB258CAB010000000000016C508B22C241B8C08D163FE5B1977B860137F0FA390970C779F27757D5462FA8020000000000012AF02BB715D65D2C0C4F7658BA084A5F34ABFE8EC98BB4A4C7729B0B1D5727F50300000000000163E339A7757812D58B835953C2F8542B9ECA45C566C6D40776D1E0F54E4BF3750400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D896E231EE5DE2FF695736AA9B93B48C13D6D0F9E4EBB68A1088B311D3E1696610E7DBA6023AD3BB4122BDC83FA28938AA6023D1BA84752D897BAC75911F9928A4585F3C071FD858EC3721BE2A9F5FFCD260A7A5413BA2F7BE17E59830A7DE2299D83F779D0C780EFCA74D6D71015D7F21F54DF0A5231A5577BC161BFEB7F6B2A41B5B9A3661FCCA56ABDCFE63F3B49CCEF00938CC038FD084477C91123FA1490000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001FF52E922221EAEF117F25F4BA35F0DF3BFD2E83DC3CE0F32221B397B0F58D3D301000000000001456A0108B1CB197506370C82469217CD46DA5260518EBE060F5041541526F0B20200000000000139283287215239886CF223FC451D7DA8F28DD9DF4A17E46E24B0A3CEF86ADB3003000000000001C1BA8932F5114BBF3321498FBAFE23E699D71BE06B2EA0CC423F79688CB3DCE60400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000DF8DCC3B3A8B6659B70F64725133A9FD36DE92C29A485C582BB80B5C6609CC4C7D274BB7FAAF35EC4D80F5362F198D5B837132D84273B57B21103639CA52F910FDBD585155A2BD052051BC9E8E43C7AA006A41FE7864BBFBA510253161545DC3E660490763A929FD7A5FB32773FF52FDEA9FE7D35C141D13ABFEFA7A164D484F75B78484DACBE33271095DB0A74F25E78B1C0514641F50D62A173D20DF1B38600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001F29DF8D7B37FF45EFF2C758310D7A14228AF285986BD41E283E3197DB9A7F530010000000000016BF475A4431CFA7C1CF0BAEB757C97E64B03D109D598E620FF8641E5CD50710B02000000000001A870C6026E859248B7866BC1A623CDEC1A9E807C402550E33676E949C2B6DC8803000000000001D19E407B03C9F6EEA492ADDCB9DDE699227C8DC630DBD5134D93EC762844274F0400000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB939E6518A5122E37D4C257B0A0FD60CE0BA3BD55C9CBF369DD315A3C0609933D25DA403DF7E69FEB7EEE64DC3C13DC83217C2834B42876862CD48E99E69564B336506B85FDB493CF8FA87A7FE48DFE6778DDE8E8DD066FAA745C121480B5BF9D5F301B358D18FCCCBD24069E71836981F168FC49E6A4F27B00F6259B183B62CEAE0BF4AC0F53FCEBEB9052C0B48EB0666F361C5DA674B20B06AE2EA8783C2DD7EA74D98AC98C55748A368DF5B433C39538365EAE8DAE5E032A2008768FEB01F65D001AAC437781F742F536EFE2B3AE59EA12A6DC7F2712BA2D9D1C253D29B419A765985ACDB42BCCE5D64F6AF8368A5D122BB16B525A80C8BC5355A53917CC82262254378CFFDF1C7D6355F114E4FC013A5E4DD9AB373A0EFDC470854E20330BC00960ECBE882098D6D0D429A7AD19D3E5D4B78AC5E568C722A21877DA617190CB43123FB04333FAE5846953E33407080D04DF1417E740E7E7A14B0E3CA7D5B693F9615E1F7D417B9004F28D5002325B851C31F5EB31E1DAA80E6CFF22F11221E5180BB050888B6564A381E54401AF9409FE12A818B69BA34E1916092A0EBA24457EF994A1B0028649C9803045EC93CF416373F6A568856B771C3BB076AC265045ACE8E9BE3C3074D8806BEAA3B8B21F7E37F50B16221E14FE5503C615A13738CCDE39E2395E292119959CF686532CC3C9F9129E62ECFB43A091B06FD48ABE8C2CBE2D9691C8907881991CAB9D0D9CC7B2699F2261E5D799D26A7C8A4AEC40789B34CF5FE7BC8D24D6F0BBA7A5870E37F4D9B2605BB56ED9BAEB780CC74097DD8AA8741A97E22EC7B7434F81DE9D83CB9816A33C5A79D718C76A3442FE50C68FE1CE7AF728F2177F88E5168D4668518897AB050B57FF42AAC731E484B440D0D7B254383C74BE41C2AAEC02A8D8C7020355C4A1FAFAF4BBF56C74D78949D087259FE8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B179B32F9F94BBD8371B973B19E60C3CE2206A2061C7BCF159BC3A50163924774BB13C708A573472DA73B4C78DB30FEF310EA3643BC75D9155762D5B87809E2A727AC0428B746801D693074ED5245F29B8FF9FB782F2E57BDD89DD700EDBF12E8311946CAD9BCC98E3B1D581E678BEB1D0A6EFE15CF4052A1AECD328B2C4A8D5DDEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA36145D1653D108813E42654CB5350FFDB33BD2FDF4E416C6C0A61784E2327F42B2DA2AF040822C291D63645B0AC2377D0DE3FDBD99FF9CD9AAAE2B978C4DBEA95E330E90EAB0C4C34E88855C7C62C40B231AA1A9EB409D18CAA1C612A98F1B7BC25B18E3A89CAF96AA4BDF12F865EE7DB20273D7CA11970219BE997DD0EDE7A8ADFECFF1D90984694EF152346402207BD7D9166DC1B09F3C3520D109824442B8AB08869B0A4850BE3227E746998925CECCB422C4C05047D890E291B4E5478967A42BEEE34BA2765D86D183C71FB6A3CD86EAF457756FC000FAFDB24AF3C968E547A5223821BABF91B31B3F970D9F7C1FBFD16CC63D14243DB22CDBC266BFA4DE4B15D23B17D34C674649A695E80F84F6FEBAC0255BB155BD8B8D46FF7AFC532117E26985D99B0E23345F9A0247D834697804C6644501CA7D2726DA563C7F02371B5CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438DC67DF57A5B11025EDDC8915C57C8C72F6D6E71978496E206201184593506E39582DD2C803CE9204D2AC833C35BC683E0BD3CAD30BBCBF584AD38DAD30C9A400DE22F0CD6199FA6C622941E79F8C5C500389E9FBDEB8E1C926443B6FB0313DA9AABB163F5319C0164C1E58864827E38C18B7ECF6FB44274CCCB84B10F1A1BD76C8740F479777BDD7C557DBEFA9415B7FD50CA659E304EF4FA22680980D0FCEFC75E36231F740F38E9B4AC55BD8307F8AD9FE45B046B7BFF0F1B9FD5EEB82D474DC311A8418BB27CFE324426CD3311D65513B0A4D58515B94B8EE5ACC6815D6D1246527188E7B6C579CE42B28E1F273887FAFAA96D44FE6830E96081ED562FF4A08416DE4213A89CD666E2814FA290A5B1FA5AD6DB86B9E4DA85486E11BB36382C13607F50EDC83909F47A7D089CFEAF4680A6F2F10A2D9D9A679AE82D2DB387C5B7BCA11161E49E01C28D0FB7FEFE1C9A4BEDE994DEA4087F3B74906EA8E49153ABA49BE0F35C0572E9CE0C68B2267884C4BC4AD32BF28CE64DC7C825BDB2D8561C69161E075F48A40220159BFF1C4158187D4DE23C85979304DD4DBB98BAA57DBE6B7C55C271B134D61906F6ADBA4639BCAD3C1A70DA04A9409A4A35FEF1BC103D4F17BAFEC37C3F108B31327E0FB227E0E2C5B5410726ECC93B56D4D153572C2DB4EB4757F5B2232C475EB9802FEFB53EAC7BE6A090AAE98027AE13D2B338442FE6EF2DCF141C4D1AF00C7B3E973467FADDF6F1950ACF2BE908FED354EDFB147D6AC4B0740F87DE06E768293CC83AC995760FE0015CAC682036CCABA9C86B9B06924369E35688F7255F5D5422AB808D023B150D62D9A7DE4F7A5D28689EB038E9EF9D3366C3D777AB6D1C33878327018CC51EEDE65BB5FEEFDB1442B9006C76B10B6CE9EE1B6E43306DBB0D9030E3A191DA24634A80063F6A5269E77543525E11BCF02DF82E5921E3225EC97FC5F9174E0225E8C5D08B4C093EA28A19D03E908426578661E107E5E2C5371D79C31F11468112A6050703BB8FD9ACDEEF8D0BC31E82FB4F7DD0DFE8AE0216582E6C86FCBC1E7B3FFDD921F220702D827F145D79D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CE8D216DC6F19C3AC0A1017837C31D76ACDBD48F018A1CB14E98848B66A59F09AE557964888EBFCAD45C491A2A3C44B7085FCA7C983EA4AA22F62B99109F6E425CDFF5D87105EDC065810CA3E055F62FB80F5CAFEC57F7CB47A95B14A215714FB345FC73E57C1574E38657755CE991FCEEDC5ED84824E0E4AFD43205E126A3402910DCE16C59C8840FC7FC5ED9FE6379F9A388601D57B366FCF44FBD2D0C15A3D8A4A28D71ADE5965C137996748EFC7FB68ED165D2480FE34EF58A3169D03D0395D94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB08391412A812DBBE4FF09E10661B7DD604481AE6EB2F89A1FC04E393B3353F7547AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6222D7DC2F78B2E3FC4C8CEAE02E3FC9D7972CA803061F534D39E4F02809C7A18A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F9536829157F62BB003C2E45042DBEBA9622508F9AACA5FE89F665A5F35BA7C26D93A84F9DC744354C73885BC59EFB657317594D34B561FC2A789C919EE08D5D68185BFB2A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E1866ED93157270FB47C81CC3076E5B381E6B03127E7AE78C54F5F35B2474F18A2461297462FFAE651BDBF3D438E30420A3BA5686483DA2EACD874CC44102C09319C10FFE87AB2099A185DFD0FDDB6393B2F61490D65F93CE565C6575C877246044FD52ED475831AFE194BB163D0FE5A023BBC435497C3C16C8C7A85FF92426B59E588978E29EC0DAD032330035B797471B74BE366FA75D79D35228004D3231654D5F301D6597B83258DBE9284121A2BB21EF66F40C17FF135201D18092FA6A72B511A456786ECE1FCFC986A28C744DD4DEBCB552C638043B0602343CC796834B13660A86C5E3CCAAA1845C5165074AEFBA7C52190845A95DC59B1E8D6B052D253EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D1B478E24D9EDAC7EC8816FA54DFDAB0F181E9E1A8A6CD77A9EC29B3E35544898EAA311411BA22E8BA6418CF252675917A88572E0CE98CE03457996BA4FD86D07C4FA2D3487400E484F4CE0A83CF490C49588DB83ED1EE2A93B78101144586427FF43F434D3A40268920A4FA3C64C0F5F4600A8E52E01CD8210965C4B212DCC942C68D589D21FEF433904C26239698EA85C32423EF7AE1ADC90744996C956FD5D0683674010173EE4A110DA2642C8E1C4BF7B5DD3DE268A3AD0A261A30AFB6AD7D54210702C635C3E707CB1F17053D475A026EF57852DEC1FDA4252FDA2E69BA95C866BD432139CA8A4E367960F85B2FBC75420737CA4843B89F053192BB086BDC0D739B2753DBE42E1D45877097F3B97FCA6F43AC15DF883C3B42D9F472F910DE579301FF7F57D9857890651B64B6C1E8A7E2227ACAC7154D97252EACF8BC5FF430E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD637170756688D9AD3002B3148ACF0009CB1C0802EB04197FBD2FCE168B5FACDD052DD46F9F0B0A34295557CF741102E7592C24FA56DEDA63ECB7A2149E406C0943E5E554767D166EBC95FAF0E9B20C1E530633CF8BD7AB2A66CB105E108C1793B0D87ABBBBA9A4679A05C94BE6A698F4758B8BD38C51371C8043FC79E749D7E41C04DC6D815B0D32A779D0AC6E80C1D56B03C8EF30F6F6CB73A089B149F46BD4671D7C13B41A5B1BCAD94C0552C12CF23352200198CD876615EDDA7257E3CC94B732D75AF6D67A67929458E2639BA4A2967D05F76C4EAED429AC246CAB410B0FC8806B84EBFE1159C88D6E71EDDCC3B956F33739AD9FF6C43168B54FD592D845A54307AD16E42AAD4621D33A037D47D1002DE1AE0BCF2ADD9B01895EB0E63742FCBB5CFDA14EC9C63D94E3387E0FC22FB1B93D9065DF33D03AFA7D156BA719EB9DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF1DF5023719932492A5EE2B7A3B40B7C7F6814D179AEEFA584D317D536645921799727CED4C3D658D5A425D2D3EB1359C975FBE1A2FB2D11F37098B7234A19628624F07698EC3658799436DB5CCE6AC18702D4F27548F61BABC4807826E95D23889575EE119A88256D4326D4BBB48D0F589C6CB22E7F95D49F6607BE258753A6120CEFBC2E6C502138AEA689B4EDA13FDC39CC0759F392860168C2BA881FF70632D05E797A4F52453418035DFE9D072F0593E8029FFC25D75FC7DE13309B0AE4509D8A315C31F0FD0F480B598ADDB0D5A8F945FE6C28C2421DDB4A0DEB478478A49D5E628799ADC5E489FBDBC9DD38686EA7943969A5AC97497B2C380CAD367A8DF3DADD2E31F759AFA47A422D2A5F7C44CCB028AEC63EAA0727231A8BB4FAC096D19BA50AEC9522A00DDBEB86ED6DEB298AB433CDB7B4F15EA4AE08EB01782B70CD59C57D485848B16B9C55BCCECC876AA99071A9A7599868A9BB42F178BF3DD0FBB7EB52A796801D67E250148584C46F3E96898AA264BCC3826317B5BF7DFF55B6F3C3F3929FB552D79FFC1D014C52965F50B446DFC1CFB3302D8C7367A6F64C93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B787B24028E369C59743659E28980F3776146D88956F5E02B3E3116B8292C2E578C8708D4B518B95E8FCB7C7D5C3B16EF976B20FD0E53DCD6D92301061F2588F693A84052F8C776D033ED7A5EC71E928DD7CC7EED8DFC585AA94D8C9CF92D9694377C0268A53536DB64565FD9F5652B0A3634B381121BDA48C2D1FD9E189991D092178D79AEE8333BB0EC988417AD6CD9DD0DCBF6EFDB0E4E8D1B38E2A3DD01B3EAAD55E1CCB1291C87E2A835E86D2E0C0C3642166D2E9BC98CF354E28B6CD3F121606F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174BE4D5805F128D4A9B00266CB6CC792C45CA4E506C8B2504D13AC93044BF3FB332A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B275680E933FB83760E66AB8BBCD67108A95111001B9F8E85B6C96B4BBF952517D6330EB1C6AB68317C91468E90237214C46A5F496EE46E2E8069D65797581C01BA0B2DD1DFEE0F95C0AD7E426F877D0CD294CB0F3ECD1C65659D20594153630E46E4A32CA7D3B408B33227123C6449C4644192BAE44916FE60256703EAB9B2821973C8A37F2FC6B3B18FFE0E4C8036583B7E63E60A5EA8FE89401C8633BDC355FDDAD733A74922E73333FF9B2F9EAE2ABF957105197D92E7CAA56F91767E282E0910608FFA0E651B882398F8187E5203F8B56F788A4DE4130D211BAEDBE44B1DE0D729B926D5FBC98A1FA9EF01E415BE3795F085E28E1B32F86B0EC72DB22414EACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E947CA8092F4480FEC3CE1D8A6D8C4CBE3F7EB35919888B729C1CADAA559A42E1BBDA600C713EBB3487FAF3CCCC40CAFDEAE9B9C6EF40D5041B83973133A03156CE65E33173CC6EC41F0061D31797BF2D58C95B5B4E218AA783E09AAD39682072C6EAE7C52E3491E8B0345D3F6DD019D7DA6D9AE08FE40461B81D414B8D5BBE0672D892793121DDB345A2E5B1F8F3EECFFFEE5E425834717D59506DAC94BB9F31F00AC84767700A6FFBB6D93D4A9FC6F02C67F2710269A4162C284E0D9BF486ACFDB55A33CE915B41F167D533B268F96CE0C70A54377A5A76B1C8E992BD4908F6C9AE1B8A1129A6A94F2C1FA3EACE58297AB6E83568F0857FEBA399FAECFAC9FA94217BAD28BE66B04EF4EF7862DBFC7F9D86A69D63D84665C826910849A959626B2F95B16FBFAB29A97876BC2F43A43F841F6161648AA9D1689D67A4BEE2C859702320B726B0219DCC859A330C6C337AF2EFB0B9C8C689D2A7B92DC615BEF81F9488AC5E678E63D3E9C4CD4D2138F500D7967745773C58A8704107771E6AC93AA2307D387AF3CCF853E572E74624A7E40305FF4F57266A6BFBEEC78BC8CC981479D5A80F351588B5E378EC89F193C02A92E5BAB45E1C12BE0DBCAA00E85E73FF666690C4133023ACCD88989AD44530D63D54B090E115F6A25111B4F006B0EDBC73FFCA5B037240E88F9F4FDFF79F6874B6D6865B3B93037E272D66F1BB1EA9AD7952CE8F8F353C2910FBFC6F73626986970C6B1FA3F7D010A7DF2AD27ED28F727F9B6E10E08E9F23278C2C6ACA482528DFDD42021B690D777444DED9C912B2CD003DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D5023540D6CD04777ECAF4F4D58C64C158042656BCA7DFBBA61D7551154DC1535618FB3576C6A634E79E80BC56D4A77A32480711DCF387CC963BBC7A339C907928DBA6545BFEA6878A58236DC95D439F8F3061C099AEF80CB7128E0C1D3AC5841B65C0A738A16BA2EF4649CB510F512A819CD03BE1174182022DDBA30AE32DB5AB9ED29B2FCAF259886A4E479D5B5C118DFFA5529CF83978DBDC1B233C410279CC031E0EFD98F95DF6A32C1FB854F7DA54F12E0D0078F9287622542E551863DCB0B534DCA8EDE06545D0860957FF3A0C13495A47A669355FFF55DAC93C3357E5FC17274ACFCF9905705D6F32C7C6E6FCAE6086384B4939C70128CC73540E47ADC633EF01CD9E59A14EDC10AB0A9313ADC2123A4F3F3B4207CC9564D39F7CE86184505C432B568E4CCAEAA1BB93EFE4C696CA690F4B4EAC21A83E1860C5F26C6ACEE315F139E8C7543B2075D3FBF446058A1F0E0DC7893D9C78FB25914ACECE4664F58E03209D0EE1FCA892A9002B32FE67B0CD27E60F35706FC2BCE8A0F77E89FDD67DCAF4073DE5B72BFB56A87525875B0E27042175EAC158AB2D5A7B85C041FC13F81A9E78911686B33488DB258E31630B4D779F6F40E079F5094D31D70E74F2220ACCE407CB3491B80DCA95CF6126E9D2E955683F0B6BBA28885065E50309BD5E3429C626D547A87ED33769F9BFBB514F8792EB90F90C956F0148B9928189EE06BB40CE18932DB44AD96E226B6BB6A313DDC8CE4FB50C6C548BFA794FDD1EE7EAEA2F119CAA2E0DC7664B0136EE7F50B88FA4F4B1F0A665F36C56AAECC77D637637ABD7EE25BFC8B638430370B0F92FADBFE5C4F166A0B1FFDFDABA98EB3E5D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3C1578D7F6DFBFF09D46817D7C61EFDDFEC6AEB1A21EBD5AF1A0F399A2096C8E30821DCFD15298AB26911D40A97E78421AC35B6E8B47C483E1538E1C110540E6B23095AFAF8CCC9883C1BA2810AFDBC488849BF8E2BD2B63AA036BCE1BF9E6FE84C7C830C65CB9870A441512C55557F371276F3CA97910118271DC35F5A46454B02318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3FBF9F7DDEBC0995B90104C717FA2977F9559887204B56298813EAEFCE587F9D2DF49378B38F71833410D667351B1949CF406F18B0727666AA94DE7EA90B093CEEABA95EEE4D2DB043CFD3504F59CF36374C48E804535A76BB8BF67DFB39E03CE613D53D7515BBC8DF04062A185B7825FD3260B1B377B5D3CF470603B1900FC978329FE4F050A62A0440FA26E9B3D2CDA32E7F9FCFE6446B29FEC3639F068E56D446765B606D7B4FDA46826E8BB9E3FE9ADD93EBF3848B70C759922B63ADAFC8E71CA051A07FCDA3126BC8B4EAE41DB2031017A6794C6784FD8B93672BE6206ECC5F1396078719C45CEB31BDE4A3D503A56CD1BA60A875E2A5AC7CF340A79F261480A2A36EE4FE88106DD0976B8FD47010119D6D21982AF0E8E58AEF1BA68D4BF979DE633E719AAFC7A6C8AC6D127BDABFC3660711DAA2962D639D46747BC03BB269789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411923F9FC45FE90EEA617A4971AB81153088F58B488C507F5C230586CF967833C9A0DEA1CAD7FC139A9710382C46136E4F4007BBD729ACF06FBFEDFF5144533FBFE8186E4905539B32F01DF3F0FA65E08B09F4F16719DAE9A987DAC3A28B2B9E001FAAAD0F03810E525D26529CBA1829D42796B65515D55BCD2315DDDB342591BE8E217286002741AD99A1565D106690A5D6277539266747D8632686C5C9061D5119998BAF8B6C09E61D13B2D91426AB98DDECE3EBC2CCA03A8B6591E2A1712FE71F847F486D6E177932521D9196CF0F637314E2329A86F733D95CAA0C2F7F08FA45A993F52B44077712B70116CA4A7DB6587E24BFEB70AFBF3A6F1A33F469D98278A6603810F6664B9BDF27388FA8C69CDD4127B39AD97A6E2432E3C2B6E0087EEBCCC54DA43837F112E61409D225BF5E5222DC107D698C0E571EE8D532C99C6CA353C02F2BC7233F1636D14FAE126DD4433CCBB5DA1C5BD079804FC920E7A7906C9579B18D7B78824CB39614E28A2091D1194C26DFBE86462EE24FA1FE24ACA85F912404458AE8DDCC5B03A0E0402BB689ECE763D0825A8D566713A013923627115705098D63351D22772A01D57BD39566F1EF058044281C3275AAB8C44F905DEA89F9D1ACD8FC3C5E9F2DF429637D635359D0A3D91D765C71E5DA37C2BCF29F1EA9AEE40BCF69C70168BC10F1E9576CD541325A8A729566CAD7C0483ACC8E23DDCEBD1114559AAA8C6621F7A7AD11AD19D6312097C99841A84C35772FF6ACF5E1028BD5885C73C78A719FE0D63D52E9F55509B7AEB252865C6720285208786A2439382CD03CA0BFA2FF1A45B734943CA586AAD35DDCFB075538B0850551967EE7D7E1261DEDE7016BAC7E1B447BED75C565A09D3F173B5F9DF4CBD86780F35E9D7D62E54A2FEFFA0FCFC5CBAB99D2F5EF5784EC92C6A9C8DF06FD4491E197B153B084BB9A5F629E4E7923220EA7981AEDC10CCBE387725C16BCD5A4CFFB3566525CB00B5295DEFA64574065D1173DAC40340878BDAED7D71811FF8EB1B55C9E3C8BB8BEB2D011A9D6DBA1522C969314EA2A7FF20000EEFAC8F760CD24975B2CD9D37FFF352B4B13CEC723C68A595E301D02E0FD881D3286582D5472DB230F77C644E02E4FD2118592D323D93CD22E55EDAEC15693758CA10E3F215E6814BC13E2DACC05A226ACAF6DACA3B9EE91B0CD0740A5B50E6E10013407A7AC9A58F2C2D41A8CC0BD39BEB52BB643AA89A1194312A69D6245A1844A03D0EE0BD92C46B5D8EA77927C48D23107C3D498427E8DCEAEAA36E368A58EABA0E06B97532BD8D2B17A03933D6BB6E00C1AA62CFEF7C7834BB0705A50205C4EF8D3270C4A0716A59CAF17D13F6E01699B1ED376095D3F6850ED50053CB56D83A15DF12887CC06E7B45D143CF738881A322557FBAA2381B355638DEC332B690F7A2C91AD96C5102819AC027304301756A1B970378FC0C627135DB8D5F6B0B75316DCF93F0955E37193575DD0C14961D776379DAC58F5FC1150785BBBA92D1009E1B49D7E3362CFA468D539203E53FE2EDF38BA68448A3520CCF623D8427DE666CFB05E0BC25452E528FC4BAE4FCB020F4ED5EF4F2A71B9D225F7B7E6655E60877D7B7F3DCFFD8C4C77A3A3B36073A69EEE8B35F49BFA43AEC19ADE9CC7DFBB1F6A7AAFC69B3210DD8B9D2D54268336896CC79F76B441391662909A9261AE1A5D75C4F9C360AB0C19A94F3930B33ABF6EF6D5AD18ECADDB1B477C019334C76E553210D4C89E4C32DB11EC281F61A34DC4C3FA81C4C11ABA995BD4EBF44373AB98B000C9F53E39A9E09607A88AAC7AE6A1AB1E735E1D0F8F8D34253718687CFE01212B0B818030EC3F1C8F79574580A44C571456C431C52BA9DD336B1A5F8753263FFBBF6005A7AC41B11814D8CCE8CA7C6B68C4F9A56845611FD6D46C35562176A9E14B357EE8DF2B3F76950986449C0AD69B0BFEF0641CFFEE6CA5112F71E1978592018BE903F66F340EDDDF09089FB1DA7C60F76B3D92527D470E11455137D94A80082FC1AB8DFA33F518E348D50068DC6BFA59015590904AE41CAE8E6A05F2A1296D97077A04DABEC3E27E25173C60F955161EA514178875427F4018AE8CE74578E79E80310F069A611AE281EA56517083EE94B5B37A1493E614AE495D28CC5D8E5A6EA4119FF599BC8DAC4167880FB7EC2FF09007E874ACBF9CAF516CBD6E305EA8492B3FEAF23BC6571A5B800489E07BDB1F2C800BAF3E7D35B4EC997B21A3C29960A9FAA177344E6F9B9C59489A67E782B630D9CB44FB0F82922839403A85C7AD53A9F32D163A64DC226EAA21E0994B218DB931E50BC31C0E1B5651CF2098EB00153DC510E086B1FEB74661932A95116E04BF13E9E302A4CD3783C572CF52249F5FDA51AEE054682E7D3E9BE99FA215853668F015F5F788BC6DE4261C7E53A2FB9B46FAAF6C821BC64ECE7AB00F059A65EA3EA9AC7C64971F504F26D97B48817B3DF9DC46B3C106C041D1A136B4731AA2922B97DEB83A3AD798A719BAA1CC2ADDE4A34D5EA63188A0CFBD3407F3930647C3993848154841EEEAEBCDC2149D942FB644A671D50A1B51ED937765C0C2AAB1B35FC6E4E6DE85E82B4D87727BF30085AD56A27A796F53CB4D3609F07BD7645F7B32EC8B72E51592714D78514941E217E6A8A393F91A907BBEBF9804CAF5925756BB3EB09D32E125469D4413DA437C8BB4CFF2F9C23C6ABA4B90395F55E94E0113E372FDFB37E7801F0AF52AACA367BF4BF90C58D093771AF0991244B91BE5C251F9380444AA86C221D06D0BC12BD1C2DB949E7DB4A5DF1EFA0A4BD339B8F1B937F2AF48072CF8F69E47BC2E20286D2524A59F271852286AF9B8BB57C5FED3E3010743E81629BD1C366D9350DC9329BC839F7B8AD5B7E570C85EF644413F0A6974DA2CE7FD7194C30A43780D5146942339CE2B186698B8CFA564998F0DA458E36F2B66CEDA779C9E9957D987676AD23A507730959ECC0016FF3A53167DB27B2F226A2B4B5EB7A409915DD46A882362462CB5BB7C3D2A75998AF280055E9105EF6A91BFDF40FC5FD0E6E97EDF27F96872351DD3E8C28F46AAC52365CF914A32E5C21626BE9E13BF80A1E7E616022639DB2A5ED92A119EFF891AF7D33883382B554819C5CBBA093B55E335D550DACD6AFF9DF70A2A92C1BA88F210224F8F1DFF0B420B6C2F673497B86A156F5F1C675D301F55D69E5D275BD43C850F39D321DBC76B0F153EF703DEF0FE7480D5C83EB1535F0FF92A37EB637DC3AB8D7C7965C8517131F5273B10A2B5E64C16C85791D41854E43BD503F0E52180E9C29499C45CE64BD97C0BA486377BFBE1C6EA2A84AE249C8AE40CF3E86989F0379B9D02694DA77F9E73560E0F38AFD05744E0A30FEC0D8DFF8A1CA3A0EC629144E96B590FD5F75D92F40E0FC0A1127486133218B844D932E038CD1B04DF12E1EC6CEC249345EAF4DACF0D38453A533E5193257BB55AA785666C64B91491B0A5DB93688FBE07D66D926759B669E18521210CAD05EF3F8972754DEA64BCA926D661B145AF5B8090D1A4E51D9CBF8818A4EBFC8FF1BD6CF2C76B914B8A7BEE0EB33F37ECA54E2DA3CBC29F1720DBF0A024C969D4B1E36326FB6F63C9195608C68A3D7C87AC394210D0F4CB7D858A88168FCC25B79E29197E2EA3B3D4A862B70A1D7F3251C75F02D476926DD863B778059B83198414E0672AA1F27898C8A6F035D26AA117F838EC83D453A0D5C49AA350B288F1FBCE59D86C8CCC99F14A221AA18A9F300DA266DCF084910890994ABCBD8185D28BAE4CCA4BD68D4D5790FEFBD7A6D56B8C78974F9A8675E6C410F6D5F7F6D254F1C7885F48F0391E1BEEAEC7437553D480FBA79F55DD5B19C596DC2089BCF9980959958F7FB7E6DB0358093379414F67BCE670BDDBC67BC8ACE419C2E48C5B57EC624C5693562B719C7E6B09F3A309D255D0B7A8B8430F7E9544A881EEB694C7282E20EA3E1ADEA50564B935D528C0372397F26B1497DFA3D0F117F7A6797C1626D1AACEC708302CB0C0E406BEF60B7F6578623EA59A005B804C009A38E0A615F1FEDABBCDA5269C9C48E148A143562E1A372C0DB9D8F249FB5A7ABE5928B4BBB17DBD747A57D9438774BAE2550A5B205FEA96912A2FFE3FBEF1D6DF372A31B1084F0715829C141B845551C086DCF8FB9BEFB43B417AF3426BAF6007DC2EFC3B4999D2A658B5A19CC61FCB3E2ED5EB14D1ADEF650C7254F5163A2FC01B987E3000517DCD878B3D9268E912CA3675000B10E53F5B8172477AF6FE3778CB0E5D279309245647970C216E2E608E25F1C4FAED708E98E1D88193FF5DE2D33B178BCD345DAAA3ADEB8B1B6D7C3E9C2468F943A4AF0596B0AA480A159BB882857360DD34CEB848F5CF3481A660F70E49916F9A952B001E60F11A31CEFB39D3F49BF76159FF3E8B3570BBF5D759F5626B1FACEDF4AD03E261A7E095044665CE61C3359BA5A046E44C8E5506E2BD7E5C5C61EC2EC722ACD680BA597A47ED44E937AA64C0E3523F1EA891BF01E2B92D54EE9A3684A122D33ACD2A6D14133A8DC35EBE37F49D59BB4BB5F24940C18E0B4B5F1349AB813E994AC43DD0420A52527147C9A0F4729F8BCFF0941B934253B98628403937D1E2DEA8BD23A2EDE0A7BCF3A2D66FFC7049C8D2D3D52B4F9479F6652462AC2D18DEBBA361721EF71168CC59501174444B5A2E58AF71E8DFC4E9F836156C1C844EE12FCA65ED97F8189FF34B8EED18C26508B5ABD7DC94DBFD37F18A514F66BEA2AB8F02DFBEF4D54850B589898EBBE0E68E9F864D4468C96BAA0BDF1C074AAF51CD47B20784CDD20DCFC3444802DF292D0B21D32A93F2DCF3154860EE0F469CF0E8BCB4BB474C2C0F6E2F97EE8C155EF5B270FAD06AEB3336087B314915E7CC95153698BC2E486441D1484052BBD641183C9F5495CE45B270E5D085F4DF45707C7615CC89197B2646196A2F382EFBB8436E3B0A09CB2384FA6D3D7E436D19DBCAF897D8A2B3B41D17163C52CCCCE010274A70B6B985545072CC776AA5DCD1D7D1F191AB56003FCCA1F90F9488AC0C010A6FBCF7CCC51AFC15BA2F9E678B9B2D2B44DE9B7C841C386126135E1871324C9C7D3648DCB8213473E4D006FBDD976D2854DBC257DC1C21E0199C10AA0FADFBFAEE03693930F970285460EAC6BCCDB873F2AE73A173F17CF6C07C26B3FEDC0E81E8EA4FF7D68CAACE34340EF1990F3BF44E23BF65CAC9F65B50E4AB2ED67F01DE310314B56B351691609FD835399C51AD9B35E4118BF3B26AD5DAA9A0609CE6A24C8D2A1244709F770A655DF9E80C0C7441917C8329446EB8FB371C506EADD1DFBF6646E0790637395A2C1429C60252D485BD99EB641F0FBCA951DF3698F69DA2B8E751BB02BA592AEA7DD21E7B961499C0238B93F6AC1FC73DD562C80D39493800D0A0A594F26D16FE54EE71B5AA5CCD70B5F1ABC79687AA87DD986F10FDE0002EF9D964E80940FFC39C5F2FDFB81C190A83B0AAB7BB176476712EDE00F6F97973B9FC6061EB404C24993B85BD7BDB4582903BE253ECC3C10C0B65232F5F681953B179E19D4246B0799477359E0496BE7925D46065E4AC4B5EACFA466A8DB0A62F1D1AD326063C89539BBD517FC53ED562D98D20D8A7CE4FC1404B3BCEC7D500F4573EF14C99BCD70F290E6F4206E9BF9E4052A8DF39BF57BAC1969CB4D85E43FEFC1907449AAD6475CD2A7B9F962C315ED6DCFE913A2FAE5E1A695C5BCBC0568797F5154AAC68A30E0EBB8D2F73E6975440421D001AE2076AD1C65F3ACA6C05144A65D535C89243D6F099CD26C54760517EDB1CE98AB4F9E0B6E3A06B3765D62E7812C38B23D6A92ADC6CAF95A256FB750DBAFAA6D3E937BCA9314331C3EC2BFB571E0D54D3A98D5D28522326681F2B91E5BCF4ED462CC90B4CC27225742E5C2286AD1FFADD8418B9B3FD71B3CAB178F34703FDB8ABDD8F5C1461F89446ADB1175E35428091CC0A3B5705C3BC66A1916D1424D631E588FCFA838C2BF8BFE2CA2F5F6648E79942E3DA4B064A22AD6A9BB05C15228E1D20D4A4E8D041BEF83790E9707A581DBB7689E032A083381899EEF508E4B2A897FFAB447F821C848EED8CA09616CE2EFD13966C479F17E1A29D5B6F18387D15E7AB024AAD60E6D68869726EC117084D8E0C42A3A18FEE5FE427610B9311F4173A555CC3D534439D074BB8153F99EF5C62288F9CD393B0C257FDF1AFA64BB68F3DCE632BF81FDFCFBFF93A4CF99D8D50805B18EDAFD09D086D586BF8A5D6A2026084C7DBDDE343F74C964ED3011E29C8683300EFBD9E93C68EE571CD156D8FE815579D8E5AEDB483103BED689A4CEB7EA73CB8E19A6994A01838E173EFE68E816CA53CE578B87754CB34961D83A611466478E9325529D6D15C156B2E2E06E1F624139D230DD3A32A90AD2C7097F43119E10A2E788F15795548B5470728DDDB77CFD86A6C3C6669B9A2217BC37B15B8EA558D2B9E99EEB37E105700A324FD17A5A00803F41C5317FC2445C7216FE28DD0F15BEF50566BFED945796D4F3DBB97D53204D5BD64478A75484912749D9407C09D01CCDC391BEC54A4D43C9157D0A871195C731EB746F61A3F82D6F1A9807C2BD3B275553AA6CDAAE509A3A350DA3F119521A3DF789E011E59EE8138C17EDFA2AEA5C15841D25DF2E3A1FBEE40A3CD98C275AE4FCAD2708F31D7354E4059D43FC5625858721409E990F1DAE7D7FF6B3084897B817D88A99C149497599957A667750E1CF446F5D24409E3CD2AE7F13197FA6705BFAE8C1BF36AA626D524EC10CC50F77B359D718734797BA0154CBC3CCCD88030C97386483EFFACEBA41E5061B95BEF6324AC98FD576AA2A8D264D05596B20200496C54C58146883B62C9051E5F52224294C996EA6B44F84EE277D029766D66AEA021467747DB5CE0597E5D91D92903B74DEF2A7100BFF8201F70D009B0963454C25351D8D43AF77A3E70C95BA5FF34747F55049243C06C036984C5C303378D475F841749BCB2DDE91A25C105501EEF479F2B6C68A60EB8F1A308E74EDEEF93E1E34A50CB272AC278ED9263C0DAE162B7C1FD035421A2CDA9774ADAF21B292C252B94398DF63894C88C4B5529FC5AA5A18E788D74EB6126C7FDEBE4D650E2871B25F37DB9EA8AB64FD4806121F4509D4FF190439B7A8690A81275D9C03CF2B51832B32DE2967485BF84E915F7BCA7647E09863CA48B37131815DF9E5F5A88535186C40F177A06B657B4437728EFA50AA22C45E49026053B3C2A3C554F1B2613EBE50F27CEBD3BB03C8CA17B22EE76C4200A0E85A70B6DFF7F511FA2265BB7D858556213C48436D573F120D4222BB1A5C924B2EF1605B4A1ED717EFAF63AE53B070D7C62B2F8CFDFFBD18DECB0C405E7575C6AD8CAEF4789D6164039F963F807C3B978CEFE718A83A68378F9156BF52F6A3F76E411CFFD88448BFB452ECC10CE99AE5F5E303EB099B89765A377868B0B2B3A0D631264AEE47BDA8FF3A92483D27CC269B16390B3ACCE3350DAA649AB53B9C1CFF2872B6C1F9BA67D9D22C6FBE01424A7DC815F968C77BE937563456A273992579C8E6AD585A0B3D38AAE13ED13B81D58599A43E86C4B4AE7825B358C6FB94BAD7F552544790377714DFAC7F17B9B6B3BAF2E5D6E87AE0D0769A39A5580D5347C78067D7D7C375A91B066A61E124E754549CF27779D43109D8E167423F13D05093CD1D31B7E6B76A89C6BA817D852775ACA8B385138C6CC73639FDA3AB6FDC5F84CD46DA221B2D437A51B54D43D98E6D77E31B07FF420AA12FD6FA8892C4220AFE432664F946E738DFF89EEBBFC16CB168CE1721738B4A1174265AEB27FF3808A80D3BFB6CB893D1B6B33DC27239E96108C6D0D20C912BC1EBBE7E245056220BE957E7B9D49EEE6C4D341AD73932D304798F0A0F04F31D8F70DB5E06E3ED2DA627D47E0AF1C2E14E56054A87AC9810B617A52D0DB5145FE4C2BF6D0D4AFB0F9314FE15167A5AD0FBA0C1454FBAB0705FB6BBFE5F7E39824E59DA24CC67B3AAD9491E7A40906487BF895E90F63CFE6D7C0984F1D2747676B82D09DFCCD2A8F6DD158C917DB81FDBE6213FE43780DDE17ADB969B3D64CD6BA6EF1F9ECC7D6F6207280078B10DBEBAD7581A2E8C2F83E4AAE8A26F8D1DF0F8CB45C690615EA304E5CE30D2A96C55696C6B1D82D274E9D5765C3E5D2D7D05EC6A202BFD0211B534B7C9FC684C7A72C2D619E9DEC4175477792BB930EB5888FB37198A6E1DCEEE6651038F5C0A15DEDCE6D1833CDA5CE4EE61CC144E7C5202FE532E0B274F2CE4E90D91F2BAF7808D0656D5A106EE157491277F92A36239D1CA7D26150C118F9ABCEDD5470A2A0069AC1BA97ED1CA9885FDF2B6750157AA5B72DB5E7C1140E1FDF78DC7FA04773F4570F4544281C2E9627E5F59CA9740A38B452C9F3A930956187079B4EE4C91B3E3D9F0F502F8558A092630BBA965FD8900E738FD1498FAC10E6AFDF58F32DC0824B405C0E1D962CB213D4D834D7D26199B9172CCA1A36D7A76DA603FE07CE0EB070AFD90E7A30D937A32D26419A002A32AD9043B1735AD3D0696AEDA5F47046F8A3134B8D45C090C0A54C70AE992A0916A49AE7F3006165FBC71CBA5F0611FA5140FC304CF49DF3081CEB754E9E87E4FB637D7E701D930EE23B6E7A739274EC3AEB90736D91745A92DCDC5FAEF42918E63079E07316C2F9E59D8B79062F1D816C536E8323F501A20A11D6FAA241A5CB4A04F8384206C1D4BA5BD2DC0DF41A69CCD6390270FF0451211B36B489AC95476493D812ADE03FD8EA165053401587F7A18C2F3FBF4960C82B30E9C7C30EA830FE7D052DB5A191C0F8DB73833839F0D7AE822027E19C3A899EDBB02AD49EA87E1A2D55EA6B010BD984FC6C5B12289B41264F9F2F23B8761F262598692F57DE1277F48B3EBD06762F791DAC23F5A5846795B4C4806EE0909163CF27111BE948EE0CB673F0B744707BE8189B059F6D33E52AC33BEC99DB223FD42F64BE1C3E8D505592A78D5F7D3E465A5E34C1FC7D7ADD80752A83CA5CFBDD7AE15AFFE7BC0A4BF3722EEC05E54482A88287D9850672C2DCDE120E0C7AF377659E5A3313D0FEAD9B350A80F0A5A4A480346AF02414FAD52E5108B911B7A4B877215E400B3FCD4E8786E962704A50EC2B2D2D7256777111EA6646AE8A57C84B56C30D704C4B914EBFCA60FC07CEE5DB943630C0A2BE448CFD70112A56A74AFEDC4CB48BD579FEE9039DF705869A1623B1596F77D7420B59F32801106F6AD8A16DB40B1ACD82415BBEADE36585C3BB47F37BFA7162C255542E8284D8EF8CFF88DB68A47249DCD14C1D2E8E5C44E258E9BA867902ADCD588A5A382A60A580458C8C59BD5F182742CA1BD6A52F35FAC26893D74C3D74429401712918098CCC493BD226EA8A9F8C7700123924131913453EF8069237ABCC4B851B0A868015162AB8B7B63B3110906B267DCCE5659F4FCA5298C4073BAAF392C5649B429D5E378557D5CA03C9A52B6208936AE2CFF83D7E28A3274398CB3586BEE9694A14396FA1D67BFA90524574B7DCF0E8C7B86C86A69FC0C2263B437016842743E7E1743802C4542DAC8E6A23D03A158BEE47F010F71E5D9A7063E26FE8C40B208160936B5CD4D13ACD22F928352902BF25A8C8D294B493907F6794A4DCC0E7CE621FE45CC6E5F33199D798FC6E833F9EA4EA54FF6A465EACF2EAC6864D3CD0057429D789466CC60CD853B829679FCC639446CB0657C15B869BFDF27AFB572303E17FF826F8C4EE2C747AE330858830F70879FC8FD6F8D7CA2BA986E5D4DA1B613DF88CE09212B99BA77FB3E3AF7AEFD4FACB02B3E3172AD43BA87A4433CE38E45C1DA3ACE463315CF5A87B14CF4745D5282B17B613A033A9FBF52A40D8265B49A49DFFFC6C71377C20F4B3EB43FE7D89D829477619A7E5B2F7CC9FD0299C838419661773087C7BB3573568DB256F94E57423B1AC21C0662B60F526AF49629B7A8F7E833F858E5C7423437ED22E6E704EA66B26E79878EDCE376E8BB682EF83EB4B9600015217C1219224381665C140C78374B80F47511C48B5238937464F3B0A5612D2F1FDCC91B74CD861CE655CBCF22B68F657EB7D8806DDDB03B4F08E52089938121B0F6B3ECDD2D23003C889FD2F9A4F6D3D4358976641511DDF513181B1C86DE10522AC021B6A301249FB9E6DB19DF42C5BA6D53F1FBF9A7A2249C516513522F8702636F688145B52B1FB6172CA96F59B9F845760677D91996B38371DAAC111D6BC59BF28F19B4E00B5E312191087255D008FEE158A8E1619CC0674E12DCAB593EAF6C99C9CBE9C700B498697A725E2F30EA74365F3CD3318AA1D0D7C07DCA4F2F6C3AC8EFF0501F8F65A07363621059517EF1BA27310ED930A1A1B0D4DA322D5FD13EF522D21A3A7D623FC499AB8648C1AA0CE2EF94316B2965A246AD7C8869E9C489AF1FD2DA40E3D688531CF77F083F281E012ECF83C4ADC97B5AE47CC38FDB41C7ECBF402AD42716821AE404A1D224363958B9E71DD4B3E77A16FC80598A3065E8E00F36F2DF940F4E99902A1D62D73470FB4923D3A46EF07E65D02963E1B5308121675F1C1973C656549030DCE1BAE145C7712A4879E2F3E219B72B673243BD71442B699F3A4E366C7B88C1266330282D0D9357FBCEC2F95AE54D87A50C8581597B0C24C2F77763B326A55EE924C4A492307610526A864CCDDF6FFC64321D570589BBC5F9CFBCDD95D0C7AD62DEC853875BA2F3C5E3FC20CFF99FF86539F37EDC56643EF7D70D0025B395061B83A100E1BE1D6096D007DC42082D4E793CCFB79CC5A06242518998D835B32B7E579AA14806AEB8A4F19E554FD72D2899617541C6B86B63AC60BD7B6185A7A86BC7702CCB91069ADA68EB4F117E239BB7A9581A56CAD59A618449EE02E2089CE3A1B97B22AE34BBB421F2194B00B80F1841480577415436FCC20FD60731E6E28138A320C9237FF656A5366890E492A318EFDAB7F22CDF81AE5CE56539034A8790E942E58118A8F141B2FC6E4559A04B9EF8827BB7C11D5A4CDAC22E42660082AEE184078053860369D354552F1CB9D798F3FDF657648A7D5BE4F41E6141FBD80732B6D3AB57C0F60D38848FD33F7E468BF7600E16F25B9552688D3AAE33DA731DFA536059D24AAD21AE940CF31E18A40508DD1623FC89EC11BE4B852EEEFD56C002C1388DCD5C54E0524BB681A25E076CFFF94EA7B5E0A0B7DA1DED8DBE3F9770536FFD43BB48C9E55E33554E5C0411BB823FE16AE3CFE51DFC9177764955DB39B08C627F74A7B9A16DCDCAAB1CC31E37B0D3B90ABA2F1EC00FD2EF6E4FF3A15358C551BACB93EF59361567E0834E72383F4EA2E8F76F000EE38B179F7F0F9A3351C5BFF81B49E8A5119C6CB5CFCF49A6875B3A99CF14E6CBABAC0F4F38FC97CBADE13BB807CEADF726AD565D65334539E879575702D58462BB2A7C7F322A16F3F1C4FE116CEDBA6094EB4712D774B8207189B700C8B84FC7D0DB49B02F7AF17A6270BD75AA54F8A79E4A1A6D588FEDF94C0829EC1496988507C8C5BB87A70DFC3FF6C7F985ED38CF6C23E04FFC8001C2958B5E0920B284A4A3A55023D13D4FB99D392A0F61281E6DE6AD1F907788504F80477B8C21454E4FF16236E42DF95C85E20DEC39B2920ED49AA540BF504E74627B678097B4EC800A37698C32118BFF564BDE9BE0E4B16A3D91A9A83FBE991DD88E7341BA96976F7694323E523B76DFE3C52F28188C8D64DFB1341EAFC98C9A28CE446C4983AC52A1C38F9CC5D8CAAABA4E8BF9B7E45E3521567A46AE5166642E89F8503F892F522A447B2FCB1BCE2EF4EC86E22F48FA99555DC193F080D3F0096A47BE3C2597FE83A27E8132D28EB55AE87B36C93F31A9E371BEF51E405037DBED6CC4916E5A855116586F7C34F33B3EE626DF600644EC881246E32B5716E9580A1733ABCB22346C4414E5FF2C085E2CBFB45BC77168F4164B7CECC874DA5594F6E8D0B7B6B36EDEEDA1342672A4D6925CA2864B93BC7F63994F8449929C3206E086738FADF14B1872973A6093B5916E565DC3B354FC544A44202598AC2326C5EB9F305C448CF68323DE4C5BD28472B340E43DEDCA0DC290CAA47238A7A26713869C6B4237D40EE2743BFCE74E5CADFC183B14075FC8088943F3B2E93FD3A96ACA364B9292413B2B67B43C855A898F877683FFA238C05E6F789ACCCC40C434FFFA494F2710C3DFA213DA7B56D5A4C273603ECE648F3E9D6E5DDC034C1B684A22B4C43569169D30694DA2D259C846541CD1FC1D4F3553DDDEB5650C0207248DED91C549B76BE830383E8E158E188D78CD90E7B03AB56FEAB895A3B82C1709F9FDE140EF89B847CF556D8D40BA06511E6B003080C2A9FA8E9B43888C41965DA5B6B2225206AA998AD1BB76E38DAA65F1759EBE6F4E301AB3B59D217FCD6C08C626143FE4B176E51D1B66839600593F01E40F7DEF55A9405B5F3E816E59039E3528A724CF0116508D784866E2FC9864778D5BD5F25DBF3C8023DB6AE937B028A471165990FED36BD793D165DA1A4A836FCC7B9039CE4375344659432BEB0820FFE1CE1DDF984FDAD61284FB7BF551CFFA91FDD3237950DBB9523C478C56AC1D0B5E7DC0BD88548A1946CB98BE05BAC55BFB535391558FA57EFAD67AAA9456D0F9AF82567AE1FBF375F69ED9B30324350C6FB4FAE7FEA4E7BF7012F515076835FA348D9ED6207D9A21A471AE1D5E036801694BCBF5268776EFBC9020F5101055D97EE9EB04C5CBFB4D9132855E2B0DB7C4F4C26B97A7B8DB1C2433BC12085E0E624896179924685837CF20258DD9D5F698BF4D1E5203F6CFFAACE82379CA26B15603786CE45AC18C296B05919A834CA0EBA4855F63CEE3BCA8FA2AD24C07D3B7B9F73ECFECABD9306C647F575D7ACC30ECD72329D51B7AAAFB919C0511DA596C23A520D9705BB6C5A4969346C30AF6D53D5A9032E04D1F960B87E0BE110FC1468A4E657BD55A832476E82A839B9B44199B12D51D3642F50774A9490BA404470C54A9249E772BCBB344597CCC73FA0919C4C67971C5195449D812F7A6979279C23B020C6801DCE5472B66B4457F56B7B0CE5C9AADB0955180917A72E93B10F4EDE8691ACA70109399FE9ECAEE4FDE5B687836315E7F16FABDD3FDBC2004D9ED41008D0AC77CE46DB9E402C14C08DE7C0AF9EBC927D40DA2D7C7DF9CDFB5DDAE39743E9A15C53A7999B3B35FD329FE1002975F668A2307221020F884388C0649E8A6EA76027BC254C948426CA44628071076E4E5C77C7F155AB517C5026032052792533A29E6FE7CE81A20C68786F9315C73A430429E2F2BDA55C4E3C09FA73081E19166F7F0359FA6B078F1B4EB95103698F9DF7610E30B3E801AF5BEC6D262A2B8F1D1EB0D00FA8B041F6AB95888643EE9B00F3E925455A0ADB35267FFA9E8354BC69AC46E67106979EE5B75705D80550D7173CC407A4201127FCCA7A162F00796F46DEB7CBB36311A900248FEA298EFF33A3D645E28FD183B230841F4D848A1FB51A7319D5C1474A05694C06741CD15B251FF33E95F18DC944DA035532E1F27C654C302FE8BFC7D8CB5541008B01AE4D5E7C2A09E4E5D5C5B314B67DE4A03BEF268203ACF15A4F9A148E4072710AD9C94F78A55784558C32F3A2E513E84E9B1299FBE18E607FF547B1619AAD1D63A1C761DEC8A262CBF89714EFFA189ECAFA723C81D00ADC10B09B4F678A6710BB3C64569F731E7F1BA28371905460C7E1C877F398422C48D8232DD5204089DEC49108CBA8DD493418DB492BBA225FE73C1CAA7D91D6638A2662F114A40CAC9D1D6AA16E67E0DD281EFAC4D883A25ADE30D9CD44FB2E2D24054CAB5C527301CA96B020EB0ECBDC803B9C1FF07BC50CF6921CBBBC757A2EBA28D307F9B67C752443A9859A35E14B25EF675243ACCC36641991D00E03234079C0B53E8AC99033B52967861C85D548D25DF927EC74C8AAFA5F78884B5443D8F43591451494BC12F7CA33BC42C629EF0AC93F11B942F4C8250C4A4411A6B14774EE772BC485E2C676746083A0DE3EC7D0894281E09686D13A7E628A4EEC1DEA1F847698086CCEB661AA10F54755E8E7553502F5F0431D91DD4D66B963B213D615A0DCECF5CA6195EC9610B92C3FBE750E3912180D33E3F04B29842F61CD1454CB4D0302F2BE905BE49F82F470380492429A349CE86B0EAA2E305326985321D35B1AAED5FD3324D12EE14CB3FA5BB739696228F645A1E9A9063DFCE147C2065BE5E2E7741B20B29A037974174FD42F0796CA07764153278AF8707320DD6A820EF2A72EB981A82EACE9FF55179554DFFB3F8E1796973E86BAB1C22848968823EF74DA3977108CBA1FD67EBA4170539D24F12087F5954E6FC086D915A2037E7BFCE97A394F987EA1D6FB7DAE67765939991E7F2163C33DD20950E0F00A4EF163CA7A903C0AAE22A6516C172D54A73D4EB181DEC2B1BD62671562D60192F32844EC777DB3EB698A8575787EE699402A80F6E2AD283A6EF387C23A4102463C14E2EBC5A0FACCDCBF0E359263792DAE6DCF0E2EC202ADFFA1480357A3B722DBCFBFEB8D341FB67CE96AE936A36D42113F298E3125289FD8617DC69536B2E52BC81E903A7E72CDF15A0FE289C51C35F5A04237B797D1E3E71E09FEEFEEEBA7F14A9BEE50D4ABA48BB2F39B0E6702AADC8A93BBBF9496A15C7F35AF67415973BB58626E9315042019E1D35F768D377035870264A1806AE7A142ED4FC9A3EB4A9F54185E990889BA19EA36961EAFD483802AE4AA6E7FB34B1F7A6AE378C229FE154FCC476AAB6C23C524877DA7BD994F8859B7B9DE9F841EA055A56469962133E231EFE161886085944D70F07819D4896F6E63F5A20F4EDA06DD45EBCAFEF5D5B384E7F0B2DD10809D9B84885385C12C5345DBE856A4E2513277E576581BFBC6D73F085314E0AF1D2A3364532D4EBEF4F8F960201DC635731765B4FEFB8D13C18626D5D4A955B1FAF6E5D65B87CEFA18B021B72187365C45D6FAB5B2A4AE7060C5479124B5F5CD2E6D6496E52BDECB9900686BC6DBC0848C8E71FC9D7740405ED290C5AAA70A3126A4040C5966DFFFA6CA4D20BDE82441C973D7E639F774C806964B00221ADFD7C60836F032E794DC6B814B9E36EAAF0AC330407ACA11305731003502A578C9DD2556400086DE1A137176E752AD2A0BA318FC09DC51977725ADEC2F5CC4D71BB2AAA373DA9EB4A01F5E7DA252F75FE7B94A3F80E9EAD1863D1A478E5E6D63702D7730843AD460B0522D28F9EE1F5E6AC01DBE3CDF91F291202C4FEDA136CA6899184C53A94B2A2B2F027760875ADAD89484F21305226C8AB81BAF359B9A9399C4E71E343043B41FB814656E62A49F75D72F8B70EDD2B3AFE68C0449920ACE28BC7B4117CAD1B78A0ABC4069B742CB4781B10664BE256B345925FC0E56EC16437374426D7330716AE3F4FAAD02FD5B5F7C01CE23E9304914C8305B39309B9A7AC172E0C8FA63812A11F4A4EB5338CBFC2287AA1490D8166BD1866CE08654BDE8069D65EDCED448117EEE3B3C69549CFEE04B802B06567FB33D41BA1FE380CAD9B3D3F732A6D065F84B401C78DA3684BAF9A559A548807ECD23CD0B75EB36AA7350E23756FBC96BDF49334FBF1ABE26E165804C5627A08B11AB1DE840350BBF7FE153011BB1BE7489EB5A211FC23BA240F5ED74AA2C3E84443939F4728AD938391C6C1CC808BF9EE734E81711868D986A1616E3CD56F1A61E1B339A057688C74A3FFA6BFF6EF62022D21CD6D7729746463A520065B66CCDBDD296771F9B5C002491191EAA0A72609EEDAB634DD69D328665D6109E9DE6284018DBD25F77234C556A474968445D85011E09E31A17FEE95798508E7762221BAEC3D6A4956DF1262A3B13B967154E369B26A70C16838260C63979DC56A02BB1E3953DEE601E69F5467F7CE20C1DC799902C391D27635BADFCD73242DB995F7B6CBC331BE00FF871DF5DB0F2A497B9B06DEE8C77ABAB0B27F2AA4FE1383668A8C3DBBDB9FC21F053171ED76E797F08043204E2FDFF63760C15373A120A95F9989194AD1D5126B4C224F0722AEB2327AFC908A6635BE840BE589401F1E97858FBF94B2295930A490117755D298A5D3E417ABBE3EAAFC8585E76C08CF7B563B2DED16B40538FA4267CDD3B3455783035CBF9258B5503F4F072D7FBF60DCACA6DA5AE3482A3CBAB760F774720BA86DCDB03E38B75F27D6DE9C06BE33B8B68983DDCF453802BEF21332B1F221BF653F58331116E31F8939F51D8FC63531DD0BADB161C8ADAB525E6DFA1F8C84C6A2AA557330DF4DAC68DFDB1D29344869792FC6E4AFA247A3DF68EC505CC8770F7B4805F2A8AF534629BC61C92A1B1C02D55656D7A19115C48616F6C813248C20901FBEF34EC0DE8C429174040458C3B431A62D2C57CE4BA13CA80063DE7BD6668384FF7CB02629C967538617C4F58E4CE1B2E26F09DC7F51E9C3548D9A99016438D9F98E2C7FE468BB5E4CDE479EC24936BE7CF353E185385BC82E7ED9A11C3193C00B923587E98DCD268AC6035FCDF802B733497FF41CEDE795BE3434A5BEB065297A701A24EAA026A4A95B5DA980020C77714A463521794DE232AE1A538FFFEBDAB46C8A6A660A338F932184DBFFC9ECE13B8A8D5808FF2ABB614C39444AE701828BDDDB7B91446894E323C9270763AB3DF7D0A4028EA99EB3823D64625AFF2E01E381ADCB40F1B7B833296CA35F17EFF716232FCA154ADC289A1C9ED14AC0E527E8243BC3540357EB5ADBA8800921611B48A81EC2482CAC88FD4693256F4755700FA47DE0807D29C71264F848D907F9C5FFBFE2581503A591C0ED2711EC0EEB80AD335F0E6435DB9AD543E6A1F881C52F867F51E5280CAAE4BF63BB222DD7AFFC0B1C5C63DCFB19E3F17AB415BADAF3A8396F15C20AD2B5A6C8603CA70742FED3128D6F9C52F3A8CC7B8473643FE4C54FE696885AEC9C1A02CBA04C5C81A4844E927DDF668ABE9A083B84FCFC15D2C747BEC2526CA293E8363F1B495CDA2573DE1BE95D2F5882C89CCF61998EEA4CF5002C3674807C9800D652AAE2A0210DD9C206B5D351C5320DAA89A79D025A365396BBAB9EF785BD4485B5D59E9A10559F3C6F7D541119DEFA26CEEBF7ADF3A0CCB0F1EF2ED7367F2EC87B335994041923C1924798925EF572912EB5C3A344B0F9724632BE4011EBAB92F9423514B19DCABA93A4A7C8F51C0EBEFBD86E50DC6820DD61C166A52DCEC9BEB5230ED209E9BC839F6F16C7F0BDCAD1BB429C8FB4403AE3A72304F178FACFEA00DA6ABA89ADFF21CAD65BD1ACDFF2F8F5AE0D89C25FBA430BC54F8B4C79A159E22750395CBF2A8296C49A74D1AAF4AF55E6A52445044C948F43E9E49CB730267A2AC636AFA84F96F935E8BC021A68CA506272C4332EA472F5A8DEBD98A002CC8E4332B542194C34BE4F493572C563AB7C44E93BCE4AE67DFFD6FED96C3F3CE2470AFB2DD4A0FF01AD6FD485649B1F262CF8C86E51D41686A9E71CDA534E02ABA6C832E92E3B664F5205509B774211D8634843245D3553D8912EAB493A8825DE21810ED60C61C3C51E702207308509BA05E78E6DFA755EB4660944FBDC0DC8AC53DAD237DB0C9531FEC555425F4B1198A2C97F75C588E490ED7806FE0EEC48450D1EFFF90512343BCF48BAF528E30F3AC1A3BF72EBC51D872CB8990435B35189DEC662F45F327CB14DFA069624F20DA2346B2C556C9AD4F692A739829F4B967054AC1222F351E7B81454AA5D594304361BA49810FD0C6DC469BC9137AFFF98D0AE0CC13BACA774394A1575CF01339CEB8085DC985DCEA36BADDE80E50FB8BE1F6165A5B6976391A6468815FC70C6A5976109930414FCBCB070F469446F0B71DA220F64D800695A0CCFAAE22E876BB0B283C3DBCE83638D571102E894F9DA43C9B4C359063DDA0B86FC9C7D45DA126C7F06E2C9ED770B17E57E860B03C64AC7E9FDD8ED8CE95E2DBC2F51122FA2B6730151B144CB6C82E3FBA42C55A5405AC1E023840771F8EED666662AF35431A463BB569839A4871AA21C4817A0144A79720F530F32A682743B9C01AEDB95FED48C38C9793F59C2098E60779293D0F8E20284C2267F03C085303AE010171256C4787EE88FEAB7B31E269142887D2CCC30B8737772DED1A9F671556BFE43A7C381D764B6318A82DD7FFFD190222B5A33F79232EFB1E767E6764A9FEFAA5165B7645FD10D7E30C735EBB49038D582E2DCA81BC47EFE21514B20795DDFE04F114C7AFB4F91881B8C03FD368F3AC30437269B521FFDB8DE0D978CA78D28C716086F58B2767A2323D46172274BAB8DB92814987D9AE26BC0140361E4528877C2C66668F2F7A127F63F5A43C2964894036C46F90A673040FB198DC50D9866BB956364FDE3B9BB6F2E9274D4A6E05AB919609FA3DA339C75A542083E1D6CFC6AE7D40C1EBE4D9AD9358AD16D392E78C086A682FC2CA00E386764073A121157F98A15C7FADFB9525D581A7DE84DF9B0293BC1B7961BEA4A894FC598CD76D6BE49CA389D3C6D06A4E79CB682BFD8D2246D1BBDE5E9754AD3B3F5F6A8DDAB708CAFF40909EA4DF53753D1DDE1C8C959F939DE10DE4CB937C21111973B890AEC27B06C8DADFCEADA3A211FAADE3411FD5F376CD1752B91019C3D9AB949209A344D24C5F4432B6354AE4B2631811990F49E16DF01DB78577132348B7D5A4157E60D7DF14798C8B606A6240AE45D6F1448314AB98AFD0D703266671192FDBCCA33B67A469D1F600F51C4A75BAADA71838D74272B41DBEF720DF137D57F208C195144527958F7EF69D6AE9631E899DF15B8EB560E372A5618FE7319296204A68C97DE9BCAB00296957F7A1955C8EEF4484EF2617E73E5783F8A3DD61BCB40A2F2C560CD6C8EFA96A9C58B73E0D654A5C016E6C776BA3D9D13D78CD7C5B640BEAEDAC87B16D12DE8BF4BBDF77F04A917D70046C285D6CDD3AF7284C2DDB5AA9016DA50207D2C28F52CC0B924D2515271BD986DCE5659D337FD9F2D939E192E310BF0D3A00CE794F0DB51D912630E4F35A04D94E7D9A2DB86FECFE8D799AAD2059D7410D1F2FA0DDBFAA343946A16CBE0D334C8DF591C890B3EB764E29AFB3077EE99525EF898C7B3D460CDB6B8B6F42D1A62813AA0F5179B95AA5291E36345059CE4066F9A2E8AA9411A70FA0D9E51BE77C21A5D7150411086CA188254437C9F5857927E6551D4D551A930D2FF7C8FBC0E5D9C03F584AECB8EB5565279F63AC74A1E9DB16EA8A0F4B6D0845372BB842A2B08A96F1D9A16BEA070CA72101CABEE6A2B17D5E33FE91C134D0DC7CF8A2F019937101D7C02EE727A56587E440AF7D82D036D5A124C1268BD6E32D73F896A9EEAE3B67517889E2EE99BDF8960A857B4D494BAFFD01E098B1C7F95B4A8A205644212A171EC485DD2CAE014962F15B1557ECFA9205DAEC5C5DB83D9B5642C817CBD6CA12E5B56650990FE46842C425FFE5C0C18D4669CEF27800A7A7FD3F34944B63BBE4EB0A41FBD6D0FCA12CFA457C72B122EE5CFD43429E9FBE78A38FDFEDF58724519E0550EEAB0481485453FB22FCA1C0A4FB3993B48166CB0B7F88A1609FBD833A866728747DF88B798DCB7BAFF64458567EF3419C9A659EC81B8329920496E82FAC7634BB7936AA6A467FD8971C061908A0F63F52E847E9D7667FF8C7995F457C4E0DEA5E9E8ECB60E8EE3BBE3CF55321A6E2E33C6FFE922AB56E6C494445451A1A0A9F144A0FA330AFDB58D3BD0A1D0166D6CA7AF21B86F0CE184F0BE6F1CF84609AA79E8D59D5BDFD7BC69A997E3D8B51B4C9F95165D9A451DE1342A736053BD21D538F9B1A43C9CA3621526D031344B51D5DEAF78F85BDB8BAB5CF11D6AD7B1F99DD4E90CC6B4B2F524ABB33B50BDE01D046AC09CEEDDE4D32225EAC2FF4D5E6E1B4D391C3A9D20D542214D03DC25462B60E8F5D80EC469FAAB57E4AA15BA50F94AD559DB5FD02FD5E334D5988C82EFA9B94E0A347757B81ADDF735753119350C0F3E8F3657BE5F58D4EB1E51583560B0775CDADE003C320FA6650D69674B3224318E8F51A17B4F3C9A5F9B3D9C1C3F6AC472D56EB9CCFA6FF592E8397BB30F558F12E290EA0333A6A0ED58A2EB1BA457FFE88888B610C9015A7DB11850D49011898A40E01C98A129DA9BDA8C64827879842D3966619A0388ABD88CA787005B7B69FE56066A0AAB8BD9D28ACE6AADC728E3EB30E16E4ED6C0F93670891CCCF18CE0CC7822E9CEB6D9E6B2B4F0F2DCA5382887A81F7CE2AEB122F0B7429C0E0D5BB32E53DAC5094481A2385D9F65B2FD2922F84D03AEDC4CA79C4F81F0A73386FFA7E5FE5B41D1571C426D88B18861FFC16311D61DF54F123A65DDCC2A6A5380F396C5B532A657BB0A97CCCE2F7D8C46096D0883CB16EAA8C57087678D9AE57D502E9C693DD899435DFC44F274B5F7F67A09F9C62AE0C08DC225B65983E3FBBC014000B51E3AC1B6290F135DE1FD32C6B6C049314DD7546E10A1EFA5A5A715D197B27408FC04AD61ED93A1FA08A764D2932060EF61ACDBEBCA8D6A16BB146FF0F6720BE6716292D2351B3F396B25015701B1827A8805204678ADF18AC38DDE4E2B27C6B1514BD197248FA9E88655E7DD20EDF4C9060653CE3C49D3B722514C421D0DAAB0CE802C7DE6A85C247B9DAF3EE936FE2823E13632FA91B9217B749DECECC7B4CC5A30168E0661CC142B8C62D5D056FEFA683EA4B06C74AAFA0170685D3F60E68CB0CE4F343B5F2900FA928557312A390F6744D47DB83D2B1917EB736B68383A90A14011A3C5EF48C7779E5BB6413824DFFB0B584420FCA86F7B798C33F790535EE0090E7CF6A0BBC0FDCA5D8A157748B4FE5B1CC64D9F1FEC367AC4D967712B7193F05058A35D7D286686AB611F1C4807B8F6B95BC021BCACD7EE59156710476C0BC628C387C1ED619BFF0FB68593502CAEC6996845C28489039AAD9BF5F0BD92776804ADBCE3BCBFE5F9F4FAA49DB29E53F6D047427A874AAE9B37A2FF7E753B7C712BAB4B128D88420CB0B8AB746491FBD4EBB70CE6AB653DCBE5A175E92D94DDACFB6F13094DC4205EAC3F85AC3EDED83C86DDEE0A9EF785DD42BEFD4299B5F044EF271571E5DB7D5349E47F14CEB297866621578F976DDD07F01698F8312117532CA2F68F57420F77CB85A8E0F1408ADAFB96D6BA04A0E6269B9F5D9121959617885F4F75E052D09DCC32C91F56A3E86832F6764038B61CF1DF5E6D588CB1028FACC7F99AE4082E5A604A5BAAA180845045993EACC930B64AEE680A9ADAFFE21A271721A3771EE60B12B85987CF25265D0ACF2C6FB55E762E877ED8E44266941C47F410A5698102D7E263F8530FB0EE9A26E0E5603A189CCEEAF7141CAA1467A523948869C47F4E2905E7B48A468FE615643E66BBDC55356E395381FC0C747ADF495233356FAEA046F2C18F2DCA0A7CE744C110D0E0B2DD861BB5080570DB0A2674C5F177E902E171C6A96BADB979A5DB94CA8F73BD8AE70B43C3F8E2B618097D2C796F7F92DC56092A6B0D863A04E2F4645C4817E42AFA9CDFBACF1597341DA1BCDF29F38B37B8BB135A937EC8D16BFDF3B5E1CB4C335FCCDF7F71522E7BF2004EEF77F9B73B5B69216C4EFA4DBDC170132F2E0B897A8D5DF9866CA80F54342B024ADF78B550DEAD9E1642483205723024A15DC37AAC36EA593E152A6F7F8AD2A985AABBE3F1171E738FAF2594370A0C330CCE5D06E23EB942EBCB8F68FA465FB98F8FF1604A4AC4A286629AD3AD552032A49FA27774734B8C8F0DB2DD6A28C2D4DCF2E07BF1969AC4A9F218939EC685DAD80D848A8F6E803DF90A4BD133EE88F1013942FB74E19333B4AE530EE5E7752EDB8603D0D9D962A9CDB3D2188A610CE5C6D71D6A508446BE79DAF26B866DB6EEF1ACF5A995C9EFA9B33256A9582DBB4773BBAC9DEEAC03175BC18D283E76A8815EDF736F4C3217E810807BECE4442A002B71F87F6BDED77E5780FADC3AADB2FC146788D4E7F6EFCAF95213CF7F954C210754A3E79164E2373306C87F9814A07F155BE50F9EC2968F5E9D1A620240DAD2FCBD7521D8A875F8C50E6F86DEFB1BBC6ED7E8A9E434BAD73AC655B507A7F306A1554E73683BC5626D9EBA5C68CA9017AF81F74DB79CB2C594ECE50A73C8AA927554A30444D147DB937D5664D480D85FD560225E6DF2CCC33FF2C4EFC13A9E1116A373EB9CE1A064D10DF412A0C989FDCFCE6453AF69131D21DBC2B0D2EA5690DD4C76ACE68101E8C62487E06B303B41538A6FA71F264156E58E3BB29726E527F8C2E0E8285A9600FECE97E8FEC1C23F3FAFC6BD9D87067888B619328E25178198ED8CF2EA8D064A7B4B3B23FCC20734472B21D1E953024A3EF48B6379D632663607D22B81D3733E5E0A91F2A923BCBD91869BC51392625D0AB03676E6F2493327BC2F3E22C372BD1B6F9B33979FBB4F0EAA539E0510348F54C08C8F15AD4164AE7C8AF54F1C350AB9199BCBDDB54F4A346345F8F3D2418CEC1ACAC26E0AA592417D341A561BBD234FD5592E98308464AC5075B12EC1CBBDCF6D755C1B7214DAD0D68B2E031001216D0F0E8C458ED8446C81C6A689E776128C8327153E8908A38DB062520C4674773AFAEEE925B3C147F2573BAF628B90451CD169A7CE7CD110E54FF4AADDF92D0BFA853BFA03DC7C4E56A0A9807F3D17461E018C0CFB45968788D8242B3F6BC497052C272A1D1F9AD87DF0AE450BC9CFD342C10B6D1B644607C7CE3A26E8502C3C511B4958AC2064F9341036687A2F60C1415484D044B9C1B311EC5DFC5CE73D419FA7F2FDA6A69DEE46B8B53304FFB8C6B54C28524C3F85AE319DD339EEA6EC82DB6F0E71A52ED1032A01E00E9197843D5D6CC394CD826938E3791CAB36CD64C1B96B9139B761FA05B7CE05B548AD6AF898EACC9F41EEC6F4913B0493C22354CF3FD33D7CDB1A77823945EEFF0FF14FE286D8C6C94D681870457EA2B17EB50F15F3A4FCC15D3FEE02C1755B1311C8AD40A953FEB72429989F20465C0614826D863F0F2B8B6F79506D1F4696049B87DEE0DD4F9572EC64E7DFA4E2762012D5D7501399407BBD1377A99D38BE5523D286BFE047F15A35470262B8AEF766EC1F1044BE8E8091E28337F2E6AC3CE60230CEBA94D7263F17631E7BD5AC570E4F8E9DB1295C47523F55AC69BCB6E700C96275D622DAAD8FA5EB8AC2D8596C66D9A36921AC8876DD857DF0CCCD9E995B42B9B4A35E2173167FFAD52C3EDF245E1F309A39463EE1AACB6CE436ADEEEADD3F23CB7A046AC04B1975643D26D8947B99BA98C8115AEFBFC68AE16161045F4AFB151FCB9A8B99B48DA52A16DA615960743BFC8D37DB87BC5267432EB1F3B2B7CD6BDCE900D18C7DEBEA76E74FFAE48AFB2B2F0D93BD7550EED69704645586760AB0D7A4E1EFEAD9E32C11FA3D2941403A4928F52608E56DA5841B23F9ECD188588D1E06595C8096BD8BFEC4C8026D733E6958366140C45E074A1FDDBE5E660287157668246664C17701CA69FA30AC21E2C66EB6FC2133ECBFDA9053013002A2985376E8C64E3DF2E5A1ED150A2A77DA3E48749C2FEDA06F1E4F2E13344348FCF64587B3DD571FEDEF9435C00D6B9905EC78C3CF2E2275B1CE57CD54281CD7B2653618793966DCBD52213C1DE648E00866BFF9879685D91367FEE3A0C860C40BEE995D1F83E3DD8A18826B2BB1394A3DC5ACC8D32ABD88AC3883736F1A87F1207ADC1DC24314AFA573CEC977E9CB9A872F42228CD3A3A1F2CDE0F5B48AAB9F8E57AA4DB21CD76CD4F6818DBFA5A6EEA2045FC4A5FC94232700411BBEBF3CFA3A1EA79DBD80B06A1756910DFDA987316433548788243EE97A2CA95E48FE04EC9B94409088D1A174F0C72EB9CD40C68F01185090D53C8314CD4A1E3EA7ADE58B834634D9684A9B7597FFD0F94C63E4ABCE55F0DBDF098BB25E91DC34E12B87FE7990E7F42AE93D3786BBB04EF4557645971CBE15361C9CA0334F7BC24060E7719B302BD30B03DF4F6FE0E4704171622F698F49A12A2F275B54F189D3CCBCC985E3484D6CF116B48838B7285FF2BA096B1D5922F3CE587E8E01E2D52D810E8F4A043E8E52961423CB4D5598DB0956D5571701CFAD3D7D82F6880C5DACC062B38B132B860E67D872C6C13B3A058DFB5EB2514D20349A672D4CBEA53A0992E4DB48DF060ECDEB36AE029F911F2D09C56C26659A3AB6B062FB87DAB85703921BEE6AB6753189ED1E66A6D114E98B09413F8D07C8056F393431A3CEDB33E90B8C599D41D1E62E95F4BFF1B95D16F29DA210E290E623331E35D0C751D82C935CD554F17D936A690435447DA2C31DFF0CA9A5FC732E9A9F2045AE04594F36DAE29EB90ADE939D701491E2F5EF7B3425161EBA828083733742B7D9CD69C6C51E9A574C2130C92C @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 27688 sm = 00000000000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6936812CC6477E4A34C890D220F2C0ADF50811BF03F0A198DD1EFCE9B1BD475ADB107005759C1AD991FBACA5F12BE25CCF5A487CDCB35D2FA0415A48AED18AECF13077F648B8C7435CE755907418C55379857F06E2F7A61A232B67C86AC1352B9C6DFFEB95D5F828ACA606136DCA17F08C38DE5AEBF9CAC54646BF3B7809882E94D6C58C88F8FD5C2C018CB53B7BBDA343D9B0F76F9057BA0C56DE12931A556205430682E22AC918051D97466B12D2FC559413DEFAAFC677C8351565ACC58D4813CDA3DE3DAA746040AF1B2C23D07DE37701C19D709600831D7D504B9EE5726175C867B0E080333CE315D72777219B6350D39E366D591FE3ED9EE9EF63A3291ED55C6DD4C888FD4C8BDEF806EB73B632B3C27697F2410935EBD0B4EB7D4FE85D9C2BDAB9A5E9A5FDF318AAE6D462D982DA995A71471994CC82E5A293A2228BD645083110E6EA40E37B74D165AB9F394E7E8C66143A319C832923A83D13133CC09F74706B5F89A6A5C36351181638BB36F11309C672B7B4D234CD7E4537489406FAAC07D59B03A06086E043466BACB5E4DDAB7AC7F43409219F27561CA6168DD17988266C9B2D49652CB8CDEC30866F81F41B8F6EB6C6F5DDAE07C5E405A42EC217E50AA87CD6E7083FB9309F7536D7CEEB80FE10ED59DE83E6CBCF832280B1CE403B410AF91DED3E66AA5A849B0E9006B97005A133E7BE66BC295473961DF6C5935EA50DC699D5233C7C07E22FA98EACB905820F49CB77A44374C0219D53B7570BDECDC6DB095544CECE9268232729556E6339B9B8A2F22FEEA16F32E6FBA55778D3E7D9E51D6E5B2E8BCAF0DC0AC338EE1AC30758672A27DC09A9BE38957BAAE5F97ECD8B86028FF8FEE10503ECAD7AA2C80431D97F2F60C7E0AF24FE782584921BE921E1C2CC0ECBA29139E304A0BDF7123670D3FF614F1F0E22C7C8E161E91A68117C321B617B039B9E959026ABAA73BDB8BCB6E852AC7E661E2C316BB3BD479B46A3C3D7F58A693491E85A75DC3F8DD5BC0124C3C811236F16D02FC5A46E77215A1A303D5064C11C7DDEE11810F33E05292A78CDD6F8A34709B56414A4CB3247AA9757EF13771EA5BB3CAEE6D93AFA18665B2B6621EDD3C961C151179A97B4CC73FDA4B0851CE702E085953B9D195E13981E55CCDBA1620CB5DA2D599570A30BD9FC3023FD9559D895E07980FC00563233B57946EC04F8FC996E63DFD602DC132C6C621E713C34F333AE17767867E6E866D96C29B3DD48C7DC7C519070C9059B394DE8D15BFECE1FCE1884860BE12411A625BAD6A8CD7A99C157C62AC36B3A2F7D8C162BA7F7F4601025685E59E261826B1D9E9A9AC5B4AA1DD947CDAE896AE82981B2430CF17DF5F99AEC8A7B6D51DA7367CAA8BEA46AAEE4571D657D290FEA3545B757A7FA09AAB8ED0C941B5F91EA0A89DFE54737A37267760AFD2CC84A9F6A9548A58E119830C4A1C28BDAFB0F94E7539D5F73E2043018B8FCEB218AD24D0B5AF139DE4BF0968A70B206EDA0FF3324096BDCB13A3DA1C550639C0606508C1FA5D4D8C57C4450C792469FC166C18EF0134760323FF8BEF4E9E16C1C48BB565F6F3F7774A9CE75488FBA6FF0205FD45334A09906A3774718DDF36BB668C0E6EA958198FD4DBFA834119583E248955DAD739F078DD240FB8B5A3642BF5506B1E2CC30E6E7DC45BFDA37C100EB88E44069492CECC82E9E4EC8C7C2C9F85B00EC8AD191BF0B1D8C6D027A7C176BCE1CA7CBBA0C336D80411D9A61A5E4D093FE138ABA2002AE12DD317205ABE4FA332FDDFB4AAE669A71A0A6A402D3E8DB7E401A3F8FD69EC9C4AD644FC10F73E8D4EAA8D202E38A3609D1034E9A9460341D702019E62520710B50C76A82229A1075E52F918DB230C481D0350A33EA0E6C8A2D8670C1C475BCEFC9106350D0DFCCD2D1E46187432CB18B46F12AE9BABA851D30304EE94F6647F707A3583CDB82837D280DC501FE49B9D27AE13D5796BC047F5482AD8837D9292111D56E88AC70930176D14EE75E771DAF91316664D9F6F84B4509B13FB00DF87ED2BFDEA30928486A9363A6559C08A4ED761F5FC89A488B81BAAFA27919CE38E7D5550819CBD0F02A02420FC3F10D62E2E1436804B7F12E6B451A6AFBD1EF6E49CE8FD350DE872090DE73F0C124AE014920F104EC5BC7EA0FCEBE08F20F05310687E973E17F1B39B9436F1C1BD5CB39C7641828A7CE9326E53AFF9DD828FC436A9C04183ECC25BFC1E19A6B2C5CB182239761D25ABCF71FE3C2D1BB52A35052545FA899B73D5DA8D6340B3C2794D4A24A4FD388C8581C384407EA9429D048B67D56B413B9002434DEFA4F2F025658778DFCF9BF148E70A2A7084AB49FC4849D497AAEC8FA2A8C8DB244001F4348AE47425932E61A64C79846C2BCE8E0D611E1C6993589B529400771332F16F123352198A4D6872CF63F4401ADA24D8BAA8DD8A433AE2F58F188C064465DF6ADF6E57E982A8D5234D0F19650FF52D3F474B9AFB3DDB2C7606402D32BDFD91415832B3C3D22FF68DFF183D81F0811A8EC2C94C40AB226519C8D324F3069F4ADC08211A716C181B1D47ADFB07120B152898366FC0906F835ED4B9FE9A776EC249F3B7A73C8ADD42D2B17B5893635D1C1F7665FC12087A0DB4851503264508C31852B8741903D43BE0EFD469F89F28A87041F739E13504103A1A8324392800C0F640D6A7D75DCE2D69607864529BFC4219BC6D76EEEF5E7B592DBE80AB3D19CC9500A8ACF148F75009E4EEF81EDA55DA30A254D0B3C2EF633F5E04CDB10A20311D2846AB24749D78FAB6EC47F89E4A338CE9B8073DAE5D30A9571B807D43788E72A7A499DA5589B7C5BF91173A9A573A7CB1C938876CA58C9DEE64B7EDCB6BACA85C9E20AFAD6B68054B862DDFCEB991456CDDF24C6BFC89FB8A8757F940DF8DE473602610F33F655872E11109EA6B7E3BC14749E7C7FA2F28480EFC0784B9C5FEEE217946EF2D55F5FD2902B6E01B40AFF393D6177502756D15DB5232BCD58ABDB633EFEA7390FF8BEA443BFB32F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D265894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB939E6518A5122E37D4C257B0A0FD60CE0BA3BD55C9CBF369DD315A3C0609933D25DA403DF7E69FEB7EEE64DC3C13DC83217C2834B42876862CD48E99E69564B336506B85FDB493CF8FA87A7FE48DFE6778DDE8E8DD066FAA745C121480B5BF9D5F301B358D18FCCCBD24069E71836981F168FC49E6A4F27B00F6259B183B62CEAE0BF4AC0F53FCEBEB9052C0B48EB0666F361C5DA674B20B06AE2EA8783C2DD7EA74D98AC98C55748A368DF5B433C39538365EAE8DAE5E032A2008768FEB01F65D001AAC437781F742F536EFE2B3AE59EA12A6DC7F2712BA2D9D1C253D29B419A765985ACDB42BCCE5D64F6AF8368A5D122BB16B525A80C8BC5355A53917CC82262254378CFFDF1C7D6355F114E4FC013A5E4DD9AB373A0EFDC470854E20330BC00960ECBE882098D6D0D429A7AD19D3E5D4B78AC5E568C722A21877DA617190CB43123FB04333FAE5846953E33407080D04DF1417E740E7E7A14B0E3CA7D5B693F9615E1F7D417B9004F28D5002325B851C31F5EB31E1DAA80E6CFF22F11221E5180BB050888B6564A381E54401AF9409FE12A818B69BA34E1916092A0EBA24457EF994A1B0028649C9803045EC93CF416373F6A568856B771C3BB076AC265045ACE8E9BE3C3074D8806BEAA3B8B21F7E37F50B16221E14FE5503C615A13738CCDE39E2395E292119959CF686532CC3C9F9129E62ECFB43A091B06FD48ABE8C2CBE2D9691C8907881991CAB9D0D9CC7B2699F2261E5D799D26A7C8A4AEC40789B34CF5FE7BC8D24D6F0BBA7A5870E37F4D9B2605BB56ED9BAEB780CC74097DD8AA8741A97E22EC7B7434F81DE9D83CB9816A33C5A79D718C76A3442FE50C68FE1CE7AF728F2177F88E5168D4668518897AB050B57FF42AAC731E484B440D0D7B254383C74BE41C2AAEC02A8D8C7020355C4A1FAFAF4BBF56C74D78949D087259FE8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B179B32F9F94BBD8371B973B19E60C3CE2206A2061C7BCF159BC3A50163924774BB13C708A573472DA73B4C78DB30FEF310EA3643BC75D9155762D5B87809E2A727AC0428B746801D693074ED5245F29B8FF9FB782F2E57BDD89DD700EDBF12E8311946CAD9BCC98E3B1D581E678BEB1D0A6EFE15CF4052A1AECD328B2C4A8D5DDEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA36145D1653D108813E42654CB5350FFDB33BD2FDF4E416C6C0A61784E2327F42B2DA2AF040822C291D63645B0AC2377D0DE3FDBD99FF9CD9AAAE2B978C4DBEA95E330E90EAB0C4C34E88855C7C62C40B231AA1A9EB409D18CAA1C612A98F1B7BC25B18E3A89CAF96AA4BDF12F865EE7DB20273D7CA11970219BE997DD0EDE7A8ADFECFF1D90984694EF152346402207BD7D9166DC1B09F3C3520D109824442B8AB08869B0A4850BE3227E746998925CECCB422C4C05047D890E291B4E5478967A42BEEE34BA2765D86D183C71FB6A3CD86EAF457756FC000FAFDB24AF3C968E547A5223821BABF91B31B3F970D9F7C1FBFD16CC63D14243DB22CDBC266BFA4DE4B15D23B17D34C674649A695E80F84F6FEBAC0255BB155BD8B8D46FF7AFC532117E26985D99B0E23345F9A0247D834697804C6644501CA7D2726DA563C7F02371B5CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438DC67DF57A5B11025EDDC8915C57C8C72F6D6E71978496E206201184593506E39582DD2C803CE9204D2AC833C35BC683E0BD3CAD30BBCBF584AD38DAD30C9A400DE22F0CD6199FA6C622941E79F8C5C500389E9FBDEB8E1C926443B6FB0313DA9AABB163F5319C0164C1E58864827E38C18B7ECF6FB44274CCCB84B10F1A1BD76C8740F479777BDD7C557DBEFA9415B7FD50CA659E304EF4FA22680980D0FCEFC75E36231F740F38E9B4AC55BD8307F8AD9FE45B046B7BFF0F1B9FD5EEB82D474DC311A8418BB27CFE324426CD3311D65513B0A4D58515B94B8EE5ACC6815D6D1246527188E7B6C579CE42B28E1F273887FAFAA96D44FE6830E96081ED562FF4A08416DE4213A89CD666E2814FA290A5B1FA5AD6DB86B9E4DA85486E11BB36382C13607F50EDC83909F47A7D089CFEAF4680A6F2F10A2D9D9A679AE82D2DB387C5B7BCA11161E49E01C28D0FB7FEFE1C9A4BEDE994DEA4087F3B74906EA8E49153ABA49BE0F35C0572E9CE0C68B2267884C4BC4AD32BF28CE64DC7C825BDB2D8561C69161E075F48A40220159BFF1C4158187D4DE23C85979304DD4DBB98BAA57DBE6B7C55C271B134D61906F6ADBA4639BCAD3C1A70DA04A9409A4A35FEF1BC103D4F17BAFEC37C3F108B31327E0FB227E0E2C5B5410726ECC93B56D4D153572C2DB4EB4757F5B2232C475EB9802FEFB53EAC7BE6A090AAE98027AE13D2B338442FE6EF2DCF141C4D1AF00C7B3E973467FADDF6F1950ACF2BE908FED354EDFB147D6AC4B0740F87DE06E768293CC83AC995760FE0015CAC682036CCABA9C86B9B06924369E35688F7255F5D5422AB808D023B150D62D9A7DE4F7A5D28689EB038E9EF9D3366C3D777AB6D1C33878327018CC51EEDE65BB5FEEFDB1442B9006C76B10B6CE9EE1B6E43306DBB0D9030E3A191DA24634A80063F6A5269E77543525E11BCF02DF82E5921E3225EC97FC5F9174E0225E8C5D08B4C093EA28A19D03E908426578661E107E5E2C5371D79C31F11468112A6050703BB8FD9ACDEEF8D0BC31E82FB4F7DD0DFE8AE0216582E6C86FCBC1E7B3FFDD921F220702D827F145D79D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CE8D216DC6F19C3AC0A1017837C31D76ACDBD48F018A1CB14E98848B66A59F09AE22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB96557964888EBFCAD45C491A2A3C44B7085FCA7C983EA4AA22F62B99109F6E425CDFF5D87105EDC065810CA3E055F62FB80F5CAFEC57F7CB47A95B14A215714FB345FC73E57C1574E38657755CE991FCEEDC5ED84824E0E4AFD43205E126A3402910DCE16C59C8840FC7FC5ED9FE6379F9A388601D57B366FCF44FBD2D0C15A3D8A4A28D71ADE5965C137996748EFC7FB68ED165D2480FE34EF58A3169D03D0395D94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB08391412A812DBBE4FF09E10661B7DD604481AE6EB2F89A1FC04E393B3353F7547AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6222D7DC2F78B2E3FC4C8CEAE02E3FC9D7972CA803061F534D39E4F02809C7A18A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F9536829157F62BB003C2E45042DBEBA9622508F9AACA5FE89F665A5F35BA7C26D93A84F9DC744354C73885BC59EFB657317594D34B561FC2A789C919EE08D5D68185BFB2A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E1866ED93157270FB47C81CC3076E5B381E6B03127E7AE78C54F5F35B2474F18A2461297462FFAE651BDBF3D438E30420A3BA5686483DA2EACD874CC44102C09319C10FFE87AB2099A185DFD0FDDB6393B2F61490D65F93CE565C6575C877246044FD52ED475831AFE194BB163D0FE5A023BBC435497C3C16C8C7A85FF92426B59E588978E29EC0DAD032330035B797471B74BE366FA75D79D35228004D3231654D5F301D6597B83258DBE9284121A2BB21EF66F40C17FF135201D18092FA6A72B511A456786ECE1FCFC986A28C744DD4DEBCB552C638043B0602343CC796834B13660A86C5E3CCAAA1845C5165074AEFBA7C52190845A95DC59B1E8D6B052D253EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D1B478E24D9EDAC7EC8816FA54DFDAB0F181E9E1A8A6CD77A9EC29B3E35544898EAA311411BA22E8BA6418CF252675917A88572E0CE98CE03457996BA4FD86D07C4FA2D3487400E484F4CE0A83CF490C49588DB83ED1EE2A93B78101144586427FF43F434D3A40268920A4FA3C64C0F5F4600A8E52E01CD8210965C4B212DCC942C68D589D21FEF433904C26239698EA85C32423EF7AE1ADC90744996C956FD5D0683674010173EE4A110DA2642C8E1C4BF7B5DD3DE268A3AD0A261A30AFB6AD7D54210702C635C3E707CB1F17053D475A026EF57852DEC1FDA4252FDA2E69BA95C866BD432139CA8A4E367960F85B2FBC75420737CA4843B89F053192BB086BDC0D739B2753DBE42E1D45877097F3B97FCA6F43AC15DF883C3B42D9F472F910DE579301FF7F57D9857890651B64B6C1E8A7E2227ACAC7154D97252EACF8BC5FF430E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD637170756688D9AD3002B3148ACF0009CB1C0802EB04197FBD2FCE168B5FACDD052DD46F9F0B0A34295557CF741102E7592C24FA56DEDA63ECB7A2149E406C0943E5E554767D166EBC95FAF0E9B20C1E530633CF8BD7AB2A66CB105E108C1793B0D87ABBBBA9A4679A05C94BE6A698F4758B8BD38C51371C8043FC79E749D7E41C04DC6D815B0D32A779D0AC6E80C1D56B03C8EF30F6F6CB73A089B149F46BD4671D7C13B41A5B1BCAD94C0552C12CF23352200198CD876615EDDA7257E3CC94B732D75AF6D67A67929458E2639BA4A2967D05F76C4EAED429AC246CAB410B0FC8806B84EBFE1159C88D6E71EDDCC3B956F33739AD9FF6C43168B54FD592D845A54307AD16E42AAD4621D33A037D47D1002DE1AE0BCF2ADD9B01895EB0E63742FCBB5CFDA14EC9C63D94E3387E0FC22FB1B93D9065DF33D03AFA7D156BA719EB9DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF1DF5023719932492A5EE2B7A3B40B7C7F6814D179AEEFA584D317D536645921799727CED4C3D658D5A425D2D3EB1359C975FBE1A2FB2D11F37098B7234A19628624F07698EC3658799436DB5CCE6AC18702D4F27548F61BABC4807826E95D23889575EE119A88256D4326D4BBB48D0F589C6CB22E7F95D49F6607BE258753A6120CEFBC2E6C502138AEA689B4EDA13FDC39CC0759F392860168C2BA881FF70632D05E797A4F52453418035DFE9D072F0593E8029FFC25D75FC7DE13309B0AE4509D8A315C31F0FD0F480B598ADDB0D5A8F945FE6C28C2421DDB4A0DEB478478A49D5E628799ADC5E489FBDBC9DD38686EA7943969A5AC97497B2C380CAD367A8DF3DADD2E31F759AFA47A422D2A5F7C44CCB028AEC63EAA0727231A8BB4FAC096D19BA50AEC9522A00DDBEB86ED6DEB298AB433CDB7B4F15EA4AE08EB01782B70CD59C57D485848B16B9C55BCCECC876AA99071A9A7599868A9BB42F178BF3DD0FBB7EB52A796801D67E250148584C46F3E96898AA264BCC3826317B5BF7DFF55B6F3C3F3929FB552D79FFC1D014C52965F50B446DFC1CFB3302D8C7367A6F64C93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B787B24028E369C59743659E28980F3776146D88956F5E02B3E3116B8292C2E578C8708D4B518B95E8FCB7C7D5C3B16EF976B20FD0E53DCD6D92301061F2588F693A84052F8C776D033ED7A5EC71E928DD7CC7EED8DFC585AA94D8C9CF92D9694377C0268A53536DB64565FD9F5652B0A3634B381121BDA48C2D1FD9E189991D092178D79AEE8333BB0EC988417AD6CD9DD0DCBF6EFDB0E4E8D1B38E2A3DD01B3EAAD55E1CCB1291C87E2A835E86D2E0C0C3642166D2E9BC98CF354E28B6CD3F121606F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174BE4D5805F128D4A9B00266CB6CC792C45CA4E506C8B2504D13AC93044BF3FB3357F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B82A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B275680E933FB83760E66AB8BBCD67108A95111001B9F8E85B6C96B4BBF952517D6330EB1C6AB68317C91468E90237214C46A5F496EE46E2E8069D65797581C01BA0B2DD1DFEE0F95C0AD7E426F877D0CD294CB0F3ECD1C65659D20594153630E46E4A32CA7D3B408B33227123C6449C4644192BAE44916FE60256703EAB9B2821973C8A37F2FC6B3B18FFE0E4C8036583B7E63E60A5EA8FE89401C8633BDC355FDDAD733A74922E73333FF9B2F9EAE2ABF957105197D92E7CAA56F91767E282E0910608FFA0E651B882398F8187E5203F8B56F788A4DE4130D211BAEDBE44B1DE0D729B926D5FBC98A1FA9EF01E415BE3795F085E28E1B32F86B0EC72DB22414EACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E947CA8092F4480FEC3CE1D8A6D8C4CBE3F7EB35919888B729C1CADAA559A42E1BBDA600C713EBB3487FAF3CCCC40CAFDEAE9B9C6EF40D5041B83973133A03156CE65E33173CC6EC41F0061D31797BF2D58C95B5B4E218AA783E09AAD39682072C6EAE7C52E3491E8B0345D3F6DD019D7DA6D9AE08FE40461B81D414B8D5BBE0672D892793121DDB345A2E5B1F8F3EECFFFEE5E425834717D59506DAC94BB9F31F00AC84767700A6FFBB6D93D4A9FC6F02C67F2710269A4162C284E0D9BF486ACFDB55A33CE915B41F167D533B268F96CE0C70A54377A5A76B1C8E992BD4908F6C9AE1B8A1129A6A94F2C1FA3EACE58297AB6E83568F0857FEBA399FAECFAC9FA94217BAD28BE66B04EF4EF7862DBFC7F9D86A69D63D84665C826910849A959626B2F95B16FBFAB29A97876BC2F43A43F841F6161648AA9D1689D67A4BEE2C859702320B726B0219DCC859A330C6C337AF2EFB0B9C8C689D2A7B92DC615BEF81F9488AC5E678E63D3E9C4CD4D2138F500D7967745773C58A8704107771E6AC93AA2307D387AF3CCF853E572E74624A7E40305FF4F57266A6BFBEEC78BC8CC981479D5A80F351588B5E378EC89F193C02A92E5BAB45E1C12BE0DBCAA00E85E73FF666690C4133023ACCD88989AD44530D63D54B090E115F6A25111B4F006B0EDBC73FFCA5B037240E88F9F4FDFF79F6874B6D6865B3B93037E272D66F1BB1EA9AD7952CE8F8F353C2910FBFC6F73626986970C6B1FA3F7D010A7DF2AD27ED28F727F9B6E10E08E9F23278C2C6ACA482528DFDD42021B690D777444DED9C912B2CD003DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D5023540D6CD04777ECAF4F4D58C64C158042656BCA7DFBBA61D7551154DC1535618FB3576C6A634E79E80BC56D4A77A32480711DCF387CC963BBC7A339C907928DBA6545BFEA6878A58236DC95D439F8F3061C099AEF80CB7128E0C1D3AC5841B65C0A738A16BA2EF4649CB510F512A819CD03BE1174182022DDBA30AE32DB5AB9ED29B2FCAF259886A4E479D5B5C118DFFA5529CF83978DBDC1B233C410279CC031E0EFD98F95DF6A32C1FB854F7DA54F12E0D0078F9287622542E551863DCB0B534DCA8EDE06545D0860957FF3A0C13495A47A669355FFF55DAC93C3357E5FC17274ACFCF9905705D6F32C7C6E6FCAE6086384B4939C70128CC73540E47ADC633EF01CD9E59A14EDC10AB0A9313ADC2123A4F3F3B4207CC9564D39F7CE86184505C432B568E4CCAEAA1BB93EFE4C696CA690F4B4EAC21A83E1860C5F26C6ACEE315F139E8C7543B2075D3FBF446058A1F0E0DC7893D9C78FB25914ACECE4664F58E03209D0EE1FCA892A9002B32FE67B0CD27E60F35706FC2BCE8A0F77E89FDD67DCAF4073DE5B72BFB56A87525875B0E27042175EAC158AB2D5A7B85C041FC13F81A9E78911686B33488DB258E31630B4D779F6F40E079F5094D31D70E74F2220ACCE407CB3491B80DCA95CF6126E9D2E955683F0B6BBA28885065E50309BD5E3429C626D547A87ED33769F9BFBB514F8792EB90F90C956F0148B9928189EE06BB40CE18932DB44AD96E226B6BB6A313DDC8CE4FB50C6C548BFA794FDD1EE7EAEA2F119CAA2E0DC7664B0136EE7F50B88FA4F4B1F0A665F36C56AAECC77D637637ABD7EE25BFC8B638430370B0F92FADBFE5C4F166A0B1FFDFDABA98EB3E5D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3C1578D7F6DFBFF09D46817D7C61EFDDFEC6AEB1A21EBD5AF1A0F399A2096C8E30821DCFD15298AB26911D40A97E78421AC35B6E8B47C483E1538E1C110540E6B23095AFAF8CCC9883C1BA2810AFDBC488849BF8E2BD2B63AA036BCE1BF9E6FE84C7C830C65CB9870A441512C55557F371276F3CA97910118271DC35F5A46454B02318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3FBF9F7DDEBC0995B90104C717FA2977F9559887204B56298813EAEFCE587F9D2DF49378B38F71833410D667351B1949CF406F18B0727666AA94DE7EA90B093CEEABA95EEE4D2DB043CFD3504F59CF36374C48E804535A76BB8BF67DFB39E03CE613D53D7515BBC8DF04062A185B7825FD3260B1B377B5D3CF470603B1900FC978329FE4F050A62A0440FA26E9B3D2CDA32E7F9FCFE6446B29FEC3639F068E56D446765B606D7B4FDA46826E8BB9E3FE9ADD93EBF3848B70C759922B63ADAFC8E71CA051A07FCDA3126BC8B4EAE41DB2031017A6794C6784FD8B93672BE6206ECC5F1396078719C45CEB31BDE4A3D503A56CD1BA60A875E2A5AC7CF340A79F261480A2A36EE4FE88106DD0976B8FD47010119D6D21982AF0E8E58AEF1BA68D4BF979DE633E719AAFC7A6C8AC6D127BDABFC3660711DAA2962D639D46747BC03BB269789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411923F9FC45FE90EEA617A4971AB81153088F58B488C507F5C230586CF967833C9A0DEA1CAD7FC139A9710382C46136E4F4007BBD729ACF06FBFEDFF5144533FBFED92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE598186E4905539B32F01DF3F0FA65E08B09F4F16719DAE9A987DAC3A28B2B9E001FAAAD0F03810E525D26529CBA1829D42796B65515D55BCD2315DDDB342591BE8E217286002741AD99A1565D106690A5D6277539266747D8632686C5C9061D5119998BAF8B6C09E61D13B2D91426AB98DDECE3EBC2CCA03A8B6591E2A1712FE71F847F486D6E177932521D9196CF0F637314E2329A86F733D95CAA0C2F7F08FA45A993F52B44077712B70116CA4A7DB6587E24BFEB70AFBF3A6F1A33F469D98278A6603810F6664B9BDF27388FA8C69CDD4127B39AD97A6E2432E3C2B6E0087EEBCCC54DA43837F112E61409D225BF5E5222DC107D698C0E571EE8D532C99C6CA353C02F2BC7233F1636D14FAE126DD4433CCBB5DA1C5BD079804FC920E7A7906C9579B18D7B78824CB39614E28A2091D1194C26DFBE86462EE24FA1FE24ACA85F912404458AE8DDCC5B03A0E0402BB689ECE763D0825A8D566713A013923627115705098D63351D22772A01D57BD39566F1EF058044281C3275AAB8C44F905DEA89F9D1ACD8FC3C5E9F2DF429637D635359D0A3D91D765C71E5DA37C2BCF29F1EA9AEE40BCF69C70168BC10F1E9576CD541325A8A729566CAD7C0483ACC8E23DDCEBD1114559AAA8C6621F7A7AD11AD19D6312097C99841A84C35772FF6ACF5E1028BD5885C73C78A719FE0D63D52E9F55509B7AEB252865C6720285208786A2439382CD03CA0BFA2FF1A45B734943CA586AAD35DDCFB075538B0850551967EE7D7E1261DEDE7016BAC7E1B447BED75C565A09D3F173B5F9DF4CBD86780F35E9D7D62E54A2FEFFA0FCFC5CBAB99D2F5EF5784EC92C6A9C8DF06FD4491E197B153B084BB9A5F629E4E7923220EA7981AEDC10CCBE387725C16BCD5A4CFFB3566525CB00B5295DEFA64574065D1173DAC40340878BDAED7D71811FF8EB1B55C9E3C8BB8BEB2D011A9D6DBA1522C969314EA2A7FF20000EEFAC8F760CD24975B2CD9D37FFF352B4B13CEC723C68A595E301D02E0FD881D3286582D5472DB230F77C644E02E4FD2118592D323D93CD22E55EDAEC15693758CA10E3F215E6814BC13E2DACC05A226ACAF6DACA3B9EE91B0CD0740A5B50E6E10013407A7AC9A58F2C2D41A8CC0BD39BEB52BB643AA89A1194312A69D6245A1844A03D0EE0BD92C46B5D8EA77927C48D23107C3D498427E8DCEAEAA36E368A58EABA0E06B97532BD8D2B17A03933D6BB6E00C1AA62CFEF7C7834BB0705A50205C4EF8D3270C4A0716A59CAF17D13F6E01699B1ED376095D3F6850ED50053CB56D83A15DF12887CC06E7B45D143CF738881A322557FBAA2381B355638DEC332B690F7A2C91AD96C5102819AC027304301756A1B970378FC0C627135DB8D5F6B0B75316DCF93F0955E37193575DD0C14961D776379DAC58F5FC1150785BBBA92D1009E1B49D7E3362CFA468D539203E53FE2EDF38BA68448A3520CCF623D8427DE666CFB05E0BC25452E528FC4BAE4FCB020F4ED5EF4F2A71B9D225F7B7E6655E60877D7B7F3DCFFD8C4C77A3A3B36073A69EEE8B35F49BFA43AEC19ADE9CC7DFBB1F6A7AAFC69B3210DD8B9D2D54268336896CC79F76B441391662909A9261AE1A5D75C4F9C360AB0C19A94F3930B33ABF6EF6D5AD18ECADDB1B477C019334C76E553210D4C89E4C32DB11EC281F61A34DC4C3FA81C4C11ABA995BD4EBF44373AB98B000C9F53E39A9E09607A88AAC7AE6A1AB1E735E1D0F8F8D34253718687CFE01212B0B818030EC3F1C8F79574580A44C571456C431C52BA9DD336B1A5F8753263FFBBF6005A7AC41B11814D8CCE8CA7C6B68C4F9A56845611FD6D46C35562176A9E14B357EE8DF2B3F76950986449C0AD69B0BFEF0641CFFEE6CA5112F71E1978592018BE903F66F340EDDDF09089FB1DA7C60F76B3D92527D470E11455137D94A80082FC1AB8DFA33F518E348D50068DC6BFA59015590904AE41CAE8E6A05F2A1296D97077A04DABEC3E27E25173C60F955161EA514178875427F4018AE8CE74578E79E80310F069A611AE281EA56517083EE94B5B37A1493E614AE495D28CC5D8E5A6EA4119FF599BC8DAC4167880FB7EC2FF09007E874ACBF9CAF516CBD6E305EA8492B3FEAF23BC6571A5B800489E07BDB1F2C800BAF3E7D35B4EC997B21A3C29960A9FAA177344E6F9B9C59489A67E782B630D9CB44FB0F82922839403A85C7AD53A9F32D163A64DC226EAA21E0994B218DB931E50BC31C0E1B5651CF2098EB00153DC510E086B1FEB74661932A95116E04BF13E9E302A4CD3783C572CF52249F5FDA51AEE054682E7D3E9BE99FA215853668F015F5F788BC6DE4261C7E53A2FB9B46FAAF6C821BC64ECE7AB00F059A65EA3EA9AC7C64971F504F26D97B48817B3DF9DC46B3C106C041D1A136B4731AA2922B97DEB83A3AD798A719BAA1CC2ADDE4A34D5EA63188A0CFBD3407F3930647C3993848154841EEEAEBCDC2149D942FB644A671D50A1B51ED937765C0C2AAB1B35FC6E4E6DE85E82B4D87727BF30085AD56A27A796F53CB4D3609F07BD7645F7B32EC8B72E51592714D78514941E217E6A8A393F91A907BBEBF9804CAF5925756BB3EB09D32E125469D4413DA437C8BB4CFF2F9C23C6ABA4B90395F55E94E0113E372FDFB37E7801F0AF52AACA367BF4BF90C58D093771AF0991244B91BE5C251F9380444AA86C221D06D0BC12BD1C2DB949E7DB4A5DF1EFA0A4BD339B8F1B937F2AF48072CF8F69E47BC2E20286D2524A59F271852286AF9B8BB57C5FED3E3010743E81629BD1C366D9350DC9329BC839F7B8AD5B7E570C85EF644413F0A6974DA2CE7FD7194C30A43780D5146942339CE2B186698B8CFA564998F0DA458E36F2B66CEDA779C9E9957D987676AD23A507730959ECC0016FF3A53167DB27B2F226A2B4B5EB7A409915DD46A882362462CB5BB7C3D2A75998AF280055E9105EF6A91BFDF40FC5FD0E6E97EDF27F96872351DD3E8C28F46AAC52365CF914A32E5C21626BE9E13BF80A1E7E616022639DB2A5ED92A119164A3FE6DFD83DBEFCE4CFEF2250893E21030934A382A288C69BF0FC7E9C92280906A4BA331C652BC4F904B9B54DCF3DB0651E43A6C83FB9843F85F0DBCA8D2E7F492200039906CF62A95D7B1830FDECAC0306B1A98B6F7B399E406A172202E29FA157E168F4B9C6979150F5AC2EF7769E4A729B6D59DD8F944E9A4A118FD06355D19B28ABDF256B4390DCD5C098DE989678AC25659763FC22E05FC4EB5860F4EFF891AF7D33883382B554819C5CBBA093B55E335D550DACD6AFF9DF70A2A92C1BA88F210224F8F1DFF0B420B6C2F673497B86A156F5F1C675D301F55D69E5D275BD43C850F39D321DBC76B0F153EF703DEF0FE7480D5C83EB1535F0FF92A37EB637DC3AB8D7C7965C8517131F5273B10A2B5E64C16C85791D41854E43BD503F0E52180E9C29499C45CE64BD97C0BA486377BFBE1C6EA2A84AE249C8AE40CF3E86989F0379B9D02694DA77F9E73560E0F38AFD05744E0A30FEC0D8DFF8A1CA3A0EC629144E96B590FD5F75D92F40E0FC0A1127486133218B844D932E038CD1B04DF12E1EC6CEC249345EAF4DACF0D38453A533E5193257BB55AA785666C64B91491B0A5DB93688FBE07D66D926759B669E18521210CAD05EF3F8972754DEA64BCA926D661B145AF5B8090D1A4E51D9CBF8818A4EBFC8FF1BD6CF2C76B914B8A7BEE0EB33F37ECA54E2DA3CBC29F1720DBF0A024C969D4B1E36326FB6F63C9195608C68A3D7C87AC394210D0F4CB7D858A88168FCC25B79E29197E2EA3B3D4A862B70A1D7F3251C75F02D476926DD863B778059B83198414E0672AA1F27898C8A6F035D26AA117F838EC83D453A0D5C49AA350B288F1FBCE59D86C8CCC99F14A221AA18A9F300DA266DCF084910890994ABCBD8185D28BAE4CCA4BD68D4D5790FEFBD7A6D56B8C78974F9A8675E6C410F6D5F7F6D254F1C7885F48F0391E1BEEAEC7437553D480FBA79F55DD5B19C596DC2089BCF9980959958F7FB7E6DB0358093379414F67BCE670BDDBC67BC8ACE419C2E48C5B57EC624C5693562B719C7E6B09F3A309D255D0B7A8B8430F7E9544A881EEB694C7282E20EA3E1ADEA50564B935D528C0372397F26B1497DFA3D0F117F7A6797C1626D1AACEC708302CB0C0E406BEF60B7F6578623EA59A005B804C009A38E0A615F1FEDABBCDA5269C9C48E148A143562E1A372C0DB9D8F249FB5A7ABE5928B4BBB17DBD747A57D9438774BAE2550A5B205FEA96912A2FFE3FBEF1D6DF372A31B1084F0715829C141B845551C086DCF8FB9BEFB43B417AF3426BAF6007DC2EFC3B4999D2A658B5A19CC61FCB3E2ED5EB14D1ADEF650C7254F5163A2FC01B987E3000517DCD878B3D9268E912CA3675000B10E53F5B8172477AF6FE3778CB0E5D279309245647970C216E2E608E25F1C4FAED708E98E1D88193FF5DE2D33B178BCD345DAAA3ADEB8B1B6D7C3E9C2468F943A4AF0596B0AA480A159BB882857360DD34CEB848F5CF3481A660F70E49916F9A952B001E60F11A31CEFB39D3F49BF76159FF3E8B3570BBF5D759F5626B1FACEDF4AD03E261A7E095044665CE61C3359BA5A046E44C8E5506E2BD7E5C5C61EC2EC722ACD680BA597A47ED44E937AA64C0E3523F1EA891BF01E2B92D54EE9A3684A122D33ACD2A6D14133A8DC35EBE37F49D59BB4BB5F24940C18E0B4B5F1349AB813E994AC43DD0420A52527147C9A0F4729F8BCFF0941B934253B98628403937D1E2DEA8BD23A2EDE0A7BCF3A2D66FFC7049C8D2D3D52B4F9479F6652462AC2D18DEBBA361721EF71168CC59501174444B5A2E58AF71E8DFC4E9F836156C1C844EE12FCA65ED97F8189FF34B8EED18C26508B5ABD7DC94DBFD37F18A514F66BEA2AB8F02DFBEF4D54850B589898EBBE0E68E9F864D4468C96BAA0BDF1C074AAF51CD47B20784CDD20DCFC3444802DF292D0B21D32A93F2DCF3154860EE0F469CF0E8BCB4BB474C2C0F6E2F97EE8C155EF5B270FAD06AEB3336087B314915E7CC95153698BC2E486441D1484052BBD641183C9F5495CE45B270E5D085F4DF45707C7615CC89197B2646196A2F382EFBB8436E3B0A09CB2384FA6D3D7E436D19DBCAF897D8A2B3B41D17163C52CCCCE010274A70B6B985545072CC776AA5DCD1D7D1F191AB56003FCCA1F90F9488AC0C010A6FBCF7CCC51AFC15BA2F9E678B9B2D2B44DE9B7C841C386126135E1871324C9C7D3648DCB8213473E4D006FBDD976D2854DBC257DC1C21E0199C10AA0FADFBFAEE03693930F970285460EAC6BCCDB873F2AE73A173F17CF6C07C26B3FEDC0E81E8EA4FF7D68CAACE34340EF1990F3BF44E23BF65CAC9F65B50E4AB2ED67F01DE310314B56B351691609FD835399C51AD9B35E4118BF3B26AD5DAA9A0609CE6A24C8D2A1244709F770A655DF9E80C0C7441917C8329446EB8FB371C506EADD1DFBF6646E0790637395A2C1429C60252D485BD99EB641F0FBCA951DF3698F69DA2B8E751BB02BA592AEA7DD21E7B961499C0238B93F6AC1FC73DD562C80D39493800D0A0A594F26D16FE54EE71B5AA5CCD70B5F1ABC79687AA87DD986F10FDE0002EF9D964E80940FFC39C5F2FDFB81C190A83B0AAB7BB176476712EDE00F6F97973B9FC6061EB404C24993B85BD7BDB4582903BE253ECC3C10C0B65232F5F681953B179E19D4246B0799477359E0496BE7925D46065E4AC4B5EACFA466A8DB0A62F1D1AD326063C89539BBD517FC53ED562D98D20D8A7CE4FC1404B3BCEC7D500F4573EF14C99BCD70F290E6F4206E9BF9E4052A8DF39BF57BAC1969CB4D85E43FEFC1907449AAD6475CD2A7B9F962C315ED6DCFE913A2FAE5E1A695C5BCBC0568797F5154AAC68A30E0EBB8D2F73E6975440421D001AE2076AD1C65F3ACA6C05144A65D535C89243D6F099CD26C54760517EDB1CE98AB4F9E0B6E3A06B3765D62E7812C38B23D6A92ADC6CAF95A256FB750DBAFAA6D3E937BCA9314331C3EC2BFB571E0D54D3A98D5D28522326681F2B91E5BCF4ED462CC90B4CC27225742E5C2286AD1FFADD8418B9B3FD71B3CAB178F34703FDB8ABDD8F5C1461F89446ADB1175E35428091CC0A3B5705C3BC66A1916D1424D631E588FCFA838C2BF8BFE2CA2F5F6648E79942E3DA4B064A22AD6A9BB05C15228E1D20D4A4E8D041BEF83790E9707A581DBB7689E032A083381899EEF508E4B2A897FFAB447F821C848EED8CA09616CE2EFD13966C479F17E1A29D5B6F18387D15E7AB024AAD60E6D68869726EC117084D8E0C42A3A96F5B92139A4B5768CDF2E35810BD1AB3BB40DCE3F38853783F6856552BF95A4A835590582BB7206044086C1CA3BD9B8ADFB09C40A838DEE80E1B3756F98073651454C1567EBB9BB8D9FEA16E9CB0F30FA5E7944CCFE2732FB90178A6F439EF2C83D0FD90FA196CBBECA9DE1DA63AB609F53BF11303F3AE2283195AD62587795E7CE13CCB19132890CE25B085F7AE282F8DE315DED51D9E7B4652285ECB3929B18FEE5FE427610B9311F4173A555CC3D534439D074BB8153F99EF5C62288F9CD393B0C257FDF1AFA64BB68F3DCE632BF81FDFCFBFF93A4CF99D8D50805B18EDAFD09D086D586BF8A5D6A2026084C7DBDDE343F74C964ED3011E29C8683300EFBD9E93C68EE571CD156D8FE815579D8E5AEDB483103BED689A4CEB7EA73CB8E19A6994A01838E173EFE68E816CA53CE578B87754CB34961D83A611466478E9325529D6D15C156B2E2E06E1F624139D230DD3A32A90AD2C7097F43119E10A2E788F15795548B5470728DDDB77CFD86A6C3C6669B9A2217BC37B15B8EA558D2B9E99EEB37E105700A324FD17A5A00803F41C5317FC2445C7216FE28DD0F15BEF50566BFED945796D4F3DBB97D53204D5BD64478A75484912749D9407C09D01CCDC391BEC54A4D43C9157D0A871195C731EB746F61A3F82D6F1A9807C2BD3B275553AA6CDAAE509A3A350DA3F119521A3DF789E011E59EE8138C17EDFA2AEA5C15841D25DF2E3A1FBEE40A3CD98C275AE4FCAD2708F31D7354E4059D43FC5625858721409E990F1DAE7D7FF6B3084897B817D88A99C149497599957A667750E1CF446F5D24409E3CD2AE7F13197FA6705BFAE8C1BF36AA626D524EC10CC50F77B359D718734797BA0154CBC3CCCD88030C97386483EFFACEBA41E5061B95BEF6324AC98FD576AA2A8D264D05596B20200496C54C58146883B62C9051E5F52224294C996EA6B44F84EE277D029766D66AEA021467747DB5CE0597E5D91D92903B74DEF2A7100BFF8201F70D009B0963454C25351D8D43AF77A3E70C95BA5FF34747F55049243C06C036984C5C303378D475F841749BCB2DDE91A25C105501EEF479F2B6C68A60EB8F1A308E74EDEEF93E1E34A50CB272AC278ED9263C0DAE162B7C1FD035421A2CDA9774ADAF21B292C252B94398DF63894C88C4B5529FC5AA5A18E788D74EB6126C7FDEBE4D650E2871B25F37DB9EA8AB64FD4806121F4509D4FF190439B7A8690A81275D9C03CF2B51832B32DE2967485BF84E915F7BCA7647E09863CA48B37131815DF9E5F5A88535186C40F177A06B657B4437728EFA50AA22C45E49026053B3C2A3C554F1B2613EBE50F27CEBD3BB03C8CA17B22EE76C4200A0E85A70B6DFF7F511FA2265BB7D858556213C48436D573F120D4222BB1A5C924B2EF1605B4A1ED717EFAF63AE53B070D7C62B2F8CFDFFBD18DECB0C405E7575C6AD8CAEF4789D6164039F963F807C3B978CEFE718A83A68378F9156BF52F6A3F76E411CFFD88448BFB452ECC10CE99AE5F5E303EB099B89765A377868B0B2B3A0D631264AEE47BDA8FF3A92483D27CC269B16390B3ACCE3350DAA649AB53B9C1CFF2872B6C1F9BA67D9D22C6FBE01424A7DC815F968C77BE937563456A273992579C8E6AD585A0B3D38AAE13ED13B81D58599A43E86C4B4AE7825B358C6FB94BAD7F552544790377714DFAC7F17B9B6B3BAF2E5D6E87AE0D0769A39A5580D5347C78067D7D7C375A91B066A61E124E754549CF27779D43109D8E167423F13D05093CD1D31B7E6B76A89C6BA817D852775ACA8B385138C6CC73639FDA3AB6FDC5F84CD46DA221B2D437A51B54D43D98E6D77E31B07FF420AA12FD6FA8892C4220AFE432664F946E738DFF89EEBBFC16CB168CE1721738B4A1174265AEB27FF3808A80D3BFB6CB893D1B6B33DC27239E96108C6D0D20C912BC1EBBE7E245056220BE957E7B9D49EEE6C4D341AD73932D304798F0A0F04F31D8F70DB5E06E3ED2DA627D47E0AF1C2E14E56054A87AC9810B617A52D0DB5145FE4C2BF6D0D4AFB0F9314FE15167A5AD0FBA0C1454FBAB0705FB6BBFE5F7E39824E59DA24CC67B3AAD9491E7A40906487BF895E90F63CFE6D7C0984F1D2747676B82D09DFCCD2A8F6DD158C917DB81FDBE6213FE43780DDE17ADB969B3D64CD6BA6EF1F9ECC7D6F6207280078B10DBEBAD7581A2E8C2F83E4AAE8A26F8D1DF0F8CB45C690615EA304E5CE30D2A96C55696C6B1D82D274E9D5765C3E5D2D7D05EC6A202BFD0211B534B7C9FC684C7A72C2D619E9DEC4175477792BB930EB5888FB37198A6E1DCEEE6651038F5C0A15DEDCE6D1833CDA5CE4EE61CC144E7C5202FE532E0B274F2CE4E90D91F2BAF7808D0656D5A106EE157491277F92A36239D1CA7D26150C118F9ABCEDD5470A2A0069AC1BA97ED1CA9885FDF2B6750157AA5B72DB5E7C1140E1FDF78DC7FA04773F4570F4544281C2E9627E5F59CA9740A38B452C9F3A930956187079B4EE4C91B3E3D9F0F502F8558A092630BBA965FD8900E738FD1498FAC10E6AFDF58F32DC0824B405C0E1D962CB213D4D834D7D26199B9172CCA1A36D7A76DA603FE07CE0EB070AFD90E7A30D937A32D26419A002A32AD9043B1735AD3D0696AEDA5F47046F8A3134B8D45C090C0A54C70AE992A0916A49AE7F3006165FBC71CBA5F0611FA5140FC304CF49DF3081CEB754E9E87E4FB637D7E701D930EE23B6E7A739274EC3AEB90736D91745A92DCDC5FAEF42918E63079E07316C2F9E59D8B79062F1D816C536E8323F501A20A11D6FAA241A5CB4A04F8384206C1D4BA5BD2DC0DF41A69CCD6390270FF0451211B36B489AC95476493D812ADE03FD8EA165053401587F7A18C2F3FBF4960C82B30E9C7C30EA830FE7D052DB5A191C0F8DB73833839F0D7AE822027E19C3A899EDBB02AD49EA87E1A2D55EA6B010BD984FC6C5B12289B41264F9F2F23B8761F262598692F57DE1277F48B3EBD06762F791DAC23F5A5846795B4C4806EE0909163CF27111BE948EE0CB673F0B744707BE8189B059F6D33E52AC33BEC99DB223FD42F64BE1C3E8D505592A78D5F7D3E465A5E34C1FC7D7ADD80752A83CA5CFBDD7AE15AFFE7BC0A4BF3722EEC05E54482A88287D9850672C2DCDE120E0C7AF377659E5A3313D0FEAD9B350A80F0A5A4A480346AF02414FAD52E5108B911B7A4B877215E400B3FCD4E8786E962704A50EC2B2D2D7256777111EA6646AE8A57C84B56C30D704C4B914EBFCA60FC07CEE5DB943630CB07C872596E0E48193D8B6513232AE14EC985E19B27E231B2EDA344957695939677A09ECB8C65C93C63C6B08FE5DA691AD51D463012565EAE07805134DE6FD09BA7B3659089DB2B16DAB68A89406E67D63B3F0BC70C271C7D0295293CF5E174FE0609D593810EFAD6CD648BDF6D3253E64DCD6D2FA70FCDCEAF24B7C96A3E3E4B078E1668E5F6CB9A598FA202F0AE1DAD0AFC54BB46BEE1105C69C535390CD630A2BE448CFD70112A56A74AFEDC4CB48BD579FEE9039DF705869A1623B1596F77D7420B59F32801106F6AD8A16DB40B1ACD82415BBEADE36585C3BB47F37BFA7162C255542E8284D8EF8CFF88DB68A47249DCD14C1D2E8E5C44E258E9BA867902ADCD588A5A382A60A580458C8C59BD5F182742CA1BD6A52F35FAC26893D74C3D74429401712918098CCC493BD226EA8A9F8C7700123924131913453EF8069237ABCC4B851B0A868015162AB8B7B63B3110906B267DCCE5659F4FCA5298C4073BAAF392C5649B429D5E378557D5CA03C9A52B6208936AE2CFF83D7E28A3274398CB3586BEE9694A14396FA1D67BFA90524574B7DCF0E8C7B86C86A69FC0C2263B437016842743E7E1743802C4542DAC8E6A23D03A158BEE47F010F71E5D9A7063E26FE8C40B208160936B5CD4D13ACD22F928352902BF25A8C8D294B493907F6794A4DCC0E7CE621FE45CC6E5F33199D798FC6E833F9EA4EA54FF6A465EACF2EAC6864D3CD0057429D789466CC60CD853B829679FCC639446CB0657C15B869BFDF27AFB572303E17FF826F8C4EE2C747AE330858830F70879FC8FD6F8D7CA2BA986E5D4DA1B613DF88CE09212B99BA77FB3E3AF7AEFD4FACB02B3E3172AD43BA87A4433CE38E45C1DA3ACE463315CF5A87B14CF4745D5282B17B613A033A9FBF52A40D8265B49A49DFFFC6C71377C20F4B3EB43FE7D89D829477619A7E5B2F7CC9FD0299C838419661773087C7BB3573568DB256F94E57423B1AC21C0662B60F526AF49629B7A8F7E833F858E5C7423437ED22E6E704EA66B26E79878EDCE376E8BB682EF83EB4B9600015217C1219224381665C140C78374B80F47511C48B5238937464F3B0A5612D2F1FDCC91B74CD861CE655CBCF22B68F657EB7D8806DDDB03B4F08E52089938121B0F6B3ECDD2D23003C889FD2F9A4F6D3D4358976641511DDF513181B1C86DE10522AC021B6A301249FB9E6DB19DF42C5BA6D53F1FBF9A7A2249C516513522F8702636F688145B52B1FB6172CA96F59B9F845760677D91996B38371DAAC111D6BC59BF28F19B4E00B5E312191087255D008FEE158A8E1619CC0674E12DCAB593EAF6C99C9CBE9C700B498697A725E2F30EA74365F3CD3318AA1D0D7C07DCA4F2F6C3AC8EFF0501F8F65A07363621059517EF1BA27310ED930A1A1B0D4DA322D5FD13EF522D21A3A7D623FC499AB8648C1AA0CE2EF94316B2965A246AD7C8869E9C489AF1FD2DA40E3D688531CF77F083F281E012ECF83C4ADC97B5AE47CC38FDB41C7ECBF402AD42716821AE404A1D224363958B9E71DD4B3E77A16FC80598A3065E8E00F36F2DF940F4E99902A1D62D73470FB4923D3A46EF07E65D02963E1B5308121675F1C1973C656549030DCE1BAE145C7712A4879E2F3E219B72B673243BD71442B699F3A4E366C7B88C1266330282D0D9357FBCEC2F95AE54D87A50C8581597B0C24C2F77763B326A55EE924C4A492307610526A864CCDDF6FFC64321D570589BBC5F9CFBCDD95D0C7AD62DEC853875BA2F3C5E3FC20CFF99FF86539F37EDC56643EF7D70D0025B395061B83A100E1BE1D6096D007DC42082D4E793CCFB79CC5A06242518998D835B32B7E579AA14806AEB8A4F19E554FD72D2899617541C6B86B63AC60BD7B6185A7A86BC7702CCB91069ADA68EB4F117E239BB7A9581A56CAD59A618449EE02E2089CE3A1B97B22AE34BBB421F2194B00B80F1841480577415436FCC20FD60731E6E28138A320C9237FF656A5366890E492A318EFDAB7F22CDF81AE5CE56539034A8790E942E58118A8F141B2FC6E4559A04B9EF8827BB7C11D5A4CDAC22E42660082AEE184078053860369D354552F1CB9D798F3FDF657648A7D5BE4F41E6141FBD80732B6D3AB57C0F60D38848FD33F7E468BF7600E16F25B9552688D3AAE33DA731DFA536059D24AAD21AE940CF31E18A40508DD1623FC89EC11BE4B852EEEFD56C002C1388DCD5C54E0524BB681A25E076CFFF94EA7B5E0A0B7DA1DED8DBE3F9770536FFD43BB48C9E55E33554E5C0411BB823FE16AE3CFE51DFC9177764955DB39B08C627F74A7B9A16DCDCAAB1CC31E37B0D3B90ABA2F1EC00FD2EF6E4FF3A15358C551BACB93EF59361567E0834E72383F4EA2E8F76F000EE38B179F7F0F9A3351C5BFF81B49E8A5119C6CB5CFCF49A6875B3A99CF14E6CBABAC0F4F38FC97CBADE13BB807CEADF726AD565D65334539E879575702D58462BB2A7C7F322A16F3F1C4FE116CEDBA6094EB4712D774B8207189B700C8B84FC7D0DB49B02F7AF17A6270BD75AA54F8A79E4A1A6D588FEDF94C0829EC1496988507C8C5BB87A70DFC3FF6C7F985ED38CF6C23E04FFC8001C2958B5E0920B284A4A3A55023D13D4FB99D392A0F61281E6DE6AD1F907788504F80477B8C21454E4FF16236E42DF95C85E20DEC39B2920ED49AA540BF504E74627B678097B4EC800A37698C32118BFF564BDE9BE0E4B16A3D91A9A83FBE991DD88E7341BA96976F7694323E523B76DFE3C52F28188C8D64DFB1341EAFC98C9A28CE446C4983AC52A1C38F9CC5D8CAAABA4E8BF9B7E45E3521567A46AE5166642E89F8503F892F522A447B2FCB1BCE2EF4EC86E22F48FA99555DC193F080D3F0096A47BE3C2597FE83A27E8132D28EB55AE87B36C93F31A9E371BEF51E405037DBED6CC4916E5A855116586F7C34F33B3EE626DF600644EC881246E32B5716E9580A1733ABCB22346C4414E5FF2C085E2CBFB45BC77168F4164B7CECC874DA5594F6E8D0B7B6B36EDEEDA1342672A4D6925CA2864B93BC7F63994F8449929C3206E086738FADF14B1872973A6093B5916E565DC3B354FC544A44202598AC2326C5EB9F305C448CF68323DE4C5BD28472B340E43DEDCA0DC290CAA47238A7A26713869C6B4237D40EE2743BFCE74E5CADFC183B14075FC8088943F3B2E93FD3A96ACA364B9292413B2B67B43C855A898F877683FFA238C05E6F789ACCCC40C434FFFA494F2710C3DFA213DA7B56D5A4C273603ECE648F3E9D6EF1CBC0EAD4BFBAD01E0651103DD17A534A2CCD00CA53C713F3045B2389B81651E8E2C2B6629D127505EAE2ABD26F2086E9D6BD48CA6FC3BF98F99604F221DC203BCE9D61B756A89BB0B418249889529F7E8F070F35D35E572EFA012DABB16A98D0AC8A99E596A91468A1AAC939629FE780A45D8406B60D04C8E2B31EB7E28294FB2595F4E7071CD906FDFEC3EC3CBB02B03E38AF71EBE9EBCAE3DFC9A37E6B545DDC034C1B684A22B4C43569169D30694DA2D259C846541CD1FC1D4F3553DDDEB5650C0207248DED91C549B76BE830383E8E158E188D78CD90E7B03AB56FEAB895A3B82C1709F9FDE140EF89B847CF556D8D40BA06511E6B003080C2A9FA8E9B43888C41965DA5B6B2225206AA998AD1BB76E38DAA65F1759EBE6F4E301AB3B59D217FCD6C08C626143FE4B176E51D1B66839600593F01E40F7DEF55A9405B5F3E816E59039E3528A724CF0116508D784866E2FC9864778D5BD5F25DBF3C8023DB6AE937B028A471165990FED36BD793D165DA1A4A836FCC7B9039CE4375344659432BEB0820FFE1CE1DDF984FDAD61284FB7BF551CFFA91FDD3237950DBB9523C478C56AC1D0B5E7DC0BD88548A1946CB98BE05BAC55BFB535391558FA57EFAD67AAA9456D0F9AF82567AE1FBF375F69ED9B30324350C6FB4FAE7FEA4E7BF7012F515076835FA348D9ED6207D9A21A471AE1D5E036801694BCBF5268776EFBC9020F5101055D97EE9EB04C5CBFB4D9132855E2B0DB7C4F4C26B97A7B8DB1C2433BC12085E0E624896179924685837CF20258DD9D5F698BF4D1E5203F6CFFAACE82379CA26B15603786CE45AC18C296B05919A834CA0EBA4855F63CEE3BCA8FA2AD24C07D3B7B9F73ECFECABD9306C647F575D7ACC30ECD72329D51B7AAAFB919C0511DA596C23A520D9705BB6C5A4969346C30AF6D53D5A9032E04D1F960B87E0BE110FC1468A4E657BD55A832476E82A839B9B44199B12D51D3642F50774A9490BA404470C54A9249E772BCBB344597CCC73FA0919C4C67971C5195449D812F7A6979279C23B020C6801DCE5472B66B4457F56B7B0CE5C9AADB0955180917A72E93B10F4EDE8691ACA70109399FE9ECAEE4FDE5B687836315E7F16FABDD3FDBC2004D9ED41008D0AC77CE46DB9E402C14C08DE7C0AF9EBC927D40DA2D7C7DF9CDFB5DDAE39743E9A15C53A7999B3B35FD329FE1002975F668A2307221020F884388C0649E8A6EA76027BC254C948426CA44628071076E4E5C77C7F155AB517C5026032052792533A29E6FE7CE81A20C68786F9315C73A430429E2F2BDA55C4E3C09FA73081E19166F7F0359FA6B078F1B4EB95103698F9DF7610E30B3E801AF5BEC6D262A2B8F1D1EB0D00FA8B041F6AB95888643EE9B00F3E925455A0ADB35267FFA9E8354BC69AC46E67106979EE5B75705D80550D7173CC407A4201127FCCA7A162F00796F46DEB7CBB36311A900248FEA298EFF33A3D645E28FD183B230841F4D848A1FB51A7319D5C1474A05694C06741CD15B251FF33E95F18DC944DA035532E1F27C654C302FE8BFC7D8CB5541008B01AE4D5E7C2A09E4E5D5C5B314B67DE4A03BEF268203ACF15A4F9A148E4072710AD9C94F78A55784558C32F3A2E513E84E9B1299FBE18E607FF547B1619AAD1D63A1C761DEC8A262CBF89714EFFA189ECAFA723C81D00ADC10B09B4F678A6710BB3C64569F731E7F1BA28371905460C7E1C877F398422C48D8232DD5204089DEC49108CBA8DD493418DB492BBA225FE73C1CAA7D91D6638A2662F114A40CAC9D1D6AA16E67E0DD281EFAC4D883A25ADE30D9CD44FB2E2D24054CAB5C527301CA96B020EB0ECBDC803B9C1FF07BC50CF6921CBBBC757A2EBA28D307F9B67C752443A9859A35E14B25EF675243ACCC36641991D00E03234079C0B53E8AC99033B52967861C85D548D25DF927EC74C8AAFA5F78884B5443D8F43591451494BC12F7CA33BC42C629EF0AC93F11B942F4C8250C4A4411A6B14774EE772BC485E2C676746083A0DE3EC7D0894281E09686D13A7E628A4EEC1DEA1F847698086CCEB661AA10F54755E8E7553502F5F0431D91DD4D66B963B213D615A0DCECF5CA6195EC9610B92C3FBE750E3912180D33E3F04B29842F61CD1454CB4D0302F2BE905BE49F82F470380492429A349CE86B0EAA2E305326985321D35B1AAED5FD3324D12EE14CB3FA5BB739696228F645A1E9A9063DFCE147C2065BE5E2E7741B20B29A037974174FD42F0796CA07764153278AF8707320DD6A820EF2A72EB981A82EACE9FF55179554DFFB3F8E1796973E86BAB1C22848968823EF74DA3977108CBA1FD67EBA4170539D24F12087F5954E6FC086D915A2037E7BFCE97A394F987EA1D6FB7DAE67765939991E7F2163C33DD20950E0F00A4EF163CA7A903C0AAE22A6516C172D54A73D4EB181DEC2B1BD62671562D60192F32844EC777DB3EB698A8575787EE699402A80F6E2AD283A6EF387C23A4102463C14E2EBC5A0FACCDCBF0E359263792DAE6DCF0E2EC202ADFFA1480357A3B722DBCFBFEB8D341FB67CE96AE936A36D42113F298E3125289FD8617DC69536B2E52BC81E903A7E72CDF15A0FE289C51C35F5A04237B797D1E3E71E09FEEFEEEBA7F14A9BEE50D4ABA48BB2F39B0E6702AADC8A93BBBF9496A15C7F35AF67415973BB58626E9315042019E1D35F768D377035870264A1806AE7A142ED4FC9A3EB4A9F54185E990889BA19EA36961EAFD483802AE4AA6E7FB34B1F7A6AE378C229FE154FCC476AAB6C23C524877DA7BD994F8859B7B9DE9F841EA055A56469962133E231EFE161886085944D70F07819D4896F6E63F5A20F4EDA06DD45EBCAFEF5D5B384E7F0B2DD10809D9B84885385C12C5345DBE856A4E2513277E576581BFBC6D73F085314E0AF1D2A3364532D4EBEF4F8F960201DC635731765B4FEFB8D13C18626D5D4A955B1FAF6E5D65B87CEFA18B021B72187365C45D6FAB5B2A4AE7060C5479124B5F5CD2E6D6496E52BDECB9900686BC6DBC0848C8E71FC9D7740405ED290C5AAA70A3126A4040C5966DFFFA6CA4D20BDE82441C973D7E639F774C806964B00221ADFD7C60836F032E794DC6B814B9E36EAAF0AC330407ACA11305731003502A578C9DD2556400086DE1A137176E752AD2A0BA318FC09DC51977725ADEC2F5CC4D71BB2AAA373DA9EB4A01F5E7DA252F75FE7B94A3F80E9EAD1863D1A478E5E6D63702D7730843AD460B0522D28F9EE1F5E6AC01DBE3B76671FE88C84A4357C76C316723D855FCC4372ADE20F8746B501EB76E62E66AE390961FD58752D4914C7CA53CD0B83E168C40777F8F136502A84B6C1A338D450ACFE885E77790E4EA399EA859A3F37A5FCB8AD3679063566F14B36FABB97B125F4BAB4B60EE9B26EAB4BA86E1C81E61C1A4103D9BB2D17389A93D792C203B005A361C41D2C620CDA46919CD9F7D30E547F62CFCF3BAFC540F5E6D9CC212792ACDF91F291202C4FEDA136CA6899184C53A94B2A2B2F027760875ADAD89484F21305226C8AB81BAF359B9A9399C4E71E343043B41FB814656E62A49F75D72F8B70EDD2B3AFE68C0449920ACE28BC7B4117CAD1B78A0ABC4069B742CB4781B10664BE256B345925FC0E56EC16437374426D7330716AE3F4FAAD02FD5B5F7C01CE23E9304914C8305B39309B9A7AC172E0C8FA63812A11F4A4EB5338CBFC2287AA1490D8166BD1866CE08654BDE8069D65EDCED448117EEE3B3C69549CFEE04B802B06567FB33D41BA1FE380CAD9B3D3F732A6D065F84B401C78DA3684BAF9A559A548807ECD23CD0B75EB36AA7350E23756FBC96BDF49334FBF1ABE26E165804C5627A08B11AB1DE840350BBF7FE153011BB1BE7489EB5A211FC23BA240F5ED74AA2C3E84443939F4728AD938391C6C1CC808BF9EE734E81711868D986A1616E3CD56F1A61E1B339A057688C74A3FFA6BFF6EF62022D21CD6D7729746463A520065B66CCDBDD296771F9B5C002491191EAA0A72609EEDAB634DD69D328665D6109E9DE6284018DBD25F77234C556A474968445D85011E09E31A17FEE95798508E7762221BAEC3D6A4956DF1262A3B13B967154E369B26A70C16838260C63979DC56A02BB1E3953DEE601E69F5467F7CE20C1DC799902C391D27635BADFCD73242DB995F7B6CBC331BE00FF871DF5DB0F2A497B9B06DEE8C77ABAB0B27F2AA4FE1383668A8C3DBBDB9FC21F053171ED76E797F08043204E2FDFF63760C15373A120A95F9989194AD1D5126B4C224F0722AEB2327AFC908A6635BE840BE589401F1E97858FBF94B2295930A490117755D298A5D3E417ABBE3EAAFC8585E76C08CF7B563B2DED16B40538FA4267CDD3B3455783035CBF9258B5503F4F072D7FBF60DCACA6DA5AE3482A3CBAB760F774720BA86DCDB03E38B75F27D6DE9C06BE33B8B68983DDCF453802BEF21332B1F221BF653F58331116E31F8939F51D8FC63531DD0BADB161C8ADAB525E6DFA1F8C84C6A2AA557330DF4DAC68DFDB1D29344869792FC6E4AFA247A3DF68EC505CC8770F7B4805F2A8AF534629BC61C92A1B1C02D55656D7A19115C48616F6C813248C20901FBEF34EC0DE8C429174040458C3B431A62D2C57CE4BA13CA80063DE7BD6668384FF7CB02629C967538617C4F58E4CE1B2E26F09DC7F51E9C3548D9A99016438D9F98E2C7FE468BB5E4CDE479EC24936BE7CF353E185385BC82E7ED9A11C3193C00B923587E98DCD268AC6035FCDF802B733497FF41CEDE795BE3434A5BEB065297A701A24EAA026A4A95B5DA980020C77714A463521794DE232AE1A538FFFEBDAB46C8A6A660A338F932184DBFFC9ECE13B8A8D5808FF2ABB614C39444AE701828BDDDB7B91446894E323C9270763AB3DF7D0A4028EA99EB3823D64625AFF2E01E381ADCB40F1B7B833296CA35F17EFF716232FCA154ADC289A1C9ED14AC0E527E8243BC3540357EB5ADBA8800921611B48A81EC2482CAC88FD4693256F4755700FA47DE0807D29C71264F848D907F9C5FFBFE2581503A591C0ED2711EC0EEB80AD335F0E6435DB9AD543E6A1F881C52F867F51E5280CAAE4BF63BB222DD7AFFC0B1C5C63DCFB19E3F17AB415BADAF3A8396F15C20AD2B5A6C8603CA70742FED3128D6F9C52F3A8CC7B8473643FE4C54FE696885AEC9C1A02CBA04C5C81A4844E927DDF668ABE9A083B84FCFC15D2C747BEC2526CA293E8363F1B495CDA2573DE1BE95D2F5882C89CCF61998EEA4CF5002C3674807C9800D652AAE2A0210DD9C206B5D351C5320DAA89A79D025A365396BBAB9EF785BD4485B5D59E9A10559F3C6F7D541119DEFA26CEEBF7ADF3A0CCB0F1EF2ED7367F2EC87B335994041923C1924798925EF572912EB5C3A344B0F9724632BE4011EBAB92F9423514B19DCABA93A4A7C8F51C0EBEFBD86E50DC6820DD61C166A52DCEC9BEB5230ED209E9BC839F6F16C7F0BDCAD1BB429C8FB4403AE3A72304F178FACFEA00DA6ABA89ADFF21CAD65BD1ACDFF2F8F5AE0D89C25FBA430BC54F8B4C79A159E22750395CBF2A8296C49A74D1AAF4AF55E6A52445044C948F43E9E49CB730267A2AC636AFA84F96F935E8BC021A68CA506272C4332EA472F5A8DEBD98A002CC8E4332B542194C34BE4F493572C563AB7C44E93BCE4AE67DFFD6FED96C3F3CE2470AFB2DD4A0FF01AD6FD485649B1F262CF8C86E51D41686A9E71CDA534E02ABA6C832E92E3B664F5205509B774211D8634843245D3553D8912EAB493A8825DE21810ED60C61C3C51E702207308509BA05E78E6DFA755EB4660944FBDC0DC8AC53DAD237DB0C9531FEC555425F4B1198A2C97F75C588E490ED7806FE0EEC48450D1EFFF90512343BCF48BAF528E30F3AC1A3BF72EBC51D872CB8990435B35189DEC662F45F327CB14DFA069624F20DA2346B2C556C9AD4F692A739829F4B967054AC1222F351E7B81454AA5D594304361BA49810FD0C6DC469BC9137AFFF98D0AE0CC13BACA774394A1575CF01339CEB8085DC985DCEA36BADDE80E50FB8BE1F6165A5B6976391A6468815FC70C6A5976109930414FCBCB070F469446F0B71DA220F64D800695A0CCFAAE22E876BB0B283C3DBCE83638D571102E894F9DA43C9B4C359063DDA0B86FC9C7D45DA126C7F06E2C9ED770B17E57E860B03C64AC7E9FDD8ED8CE95E2DBC2F51122FA2B6730151B144CB6C82E3FBA42C55A5405AC1E023840771F8EED666662AF35431A463BB569839A4871AA21C4817A0144A79720F530F32A682743B9C01AEDB95FED48C38C9793F59C2098E60779293D0F8E20284C2267F03C085303AE010171256C4787EE88FEAB7B31E269142887D2CCC30B8737772DED1A9F671556BFE43A7C381D764B6318A82DD7FFFD190222B5A33F79232EFB1E767E6764A9FEFAA5165B7645FD10D7E30C735EBB49038D582E2DCA81BC47EFE21514B20795DDFE04F114C7AFB4F91881B8C03FD368F3AC30437269B521FFDB8DE0D978CA78D28C716086F58B2767A2323D46172272FE6945E6FAB674CFDEE3C8446481D1144C9AD9F8CA0DC87D99E2FE038A09F0E9741814E09511540CEAE2C0E950551E10B4BED309E2F6E7CE10500BD8B00C5BE0B5D88B01A1AF25ADD068421C0F98CF345A597427D043CB53ED18DB764F4288B2B88AD917C4F0788488D1C56B7579C7695983135EF479D902A4360389A206CCD9652672552F9726782AAE9A57D0C64034E7F124FF75B1B55AF309F0E9B4597E24BAB8DB92814987D9AE26BC0140361E4528877C2C66668F2F7A127F63F5A43C2964894036C46F90A673040FB198DC50D9866BB956364FDE3B9BB6F2E9274D4A6E05AB919609FA3DA339C75A542083E1D6CFC6AE7D40C1EBE4D9AD9358AD16D392E78C086A682FC2CA00E386764073A121157F98A15C7FADFB9525D581A7DE84DF9B0293BC1B7961BEA4A894FC598CD76D6BE49CA389D3C6D06A4E79CB682BFD8D2246D1BBDE5E9754AD3B3F5F6A8DDAB708CAFF40909EA4DF53753D1DDE1C8C959F939DE10DE4CB937C21111973B890AEC27B06C8DADFCEADA3A211FAADE3411FD5F376CD1752B91019C3D9AB949209A344D24C5F4432B6354AE4B2631811990F49E16DF01DB78577132348B7D5A4157E60D7DF14798C8B606A6240AE45D6F1448314AB98AFD0D703266671192FDBCCA33B67A469D1F600F51C4A75BAADA71838D74272B41DBEF720DF137D57F208C195144527958F7EF69D6AE9631E899DF15B8EB560E372A5618FE7319296204A68C97DE9BCAB00296957F7A1955C8EEF4484EF2617E73E5783F8A3DD61BCB40A2F2C560CD6C8EFA96A9C58B73E0D654A5C016E6C776BA3D9D13D78CD7C5B640BEAEDAC87B16D12DE8BF4BBDF77F04A917D70046C285D6CDD3AF7284C2DDB5AA9016DA50207D2C28F52CC0B924D2515271BD986DCE5659D337FD9F2D939E192E310BF0D3A00CE794F0DB51D912630E4F35A04D94E7D9A2DB86FECFE8D799AAD2059D7410D1F2FA0DDBFAA343946A16CBE0D334C8DF591C890B3EB764E29AFB3077EE99525EF898C7B3D460CDB6B8B6F42D1A62813AA0F5179B95AA5291E36345059CE4066F9A2E8AA9411A70FA0D9E51BE77C21A5D7150411086CA188254437C9F5857927E6551D4D551A930D2FF7C8FBC0E5D9C03F584AECB8EB5565279F63AC74A1E9DB16EA8A0F4B6D0845372BB842A2B08A96F1D9A16BEA070CA72101CABEE6A2B17D5E33FE91C134D0DC7CF8A2F019937101D7C02EE727A56587E440AF7D82D036D5A124C1268BD6E32D73F896A9EEAE3B67517889E2EE99BDF8960A857B4D494BAFFD01E098B1C7F95B4A8A205644212A171EC485DD2CAE014962F15B1557ECFA9205DAEC5C5DB83D9B5642C817CBD6CA12E5B56650990FE46842C425FFE5C0C18D4669CEF27800A7A7FD3F34944B63BBE4EB0A41FBD6D0FCA12CFA457C72B122EE5CFD43429E9FBE78A38FDFEDF58724519E0550EEAB0481485453FB22FCA1C0A4FB3993B48166CB0B7F88A1609FBD833A866728747DF88B798DCB7BAFF64458567EF3419C9A659EC81B8329920496E82FAC7634BB7936AA6A467FD8971C061908A0F63F52E847E9D7667FF8C7995F457C4E0DEA5E9E8ECB60E8EE3BBE3CF55321A6E2E33C6FFE922AB56E6C494445451A1A0A9F144A0FA330AFDB58D3BD0A1D0166D6CA7AF21B86F0CE184F0BE6F1CF84609AA79E8D59D5BDFD7BC69A997E3D8B51B4C9F95165D9A451DE1342A736053BD21D538F9B1A43C9CA3621526D031344B51D5DEAF78F85BDB8BAB5CF11D6AD7B1F99DD4E90CC6B4B2F524ABB33B50BDE01D046AC09CEEDDE4D32225EAC2FF4D5E6E1B4D391C3A9D20D542214D03DC25462B60E8F5D80EC469FAAB57E4AA15BA50F94AD559DB5FD02FD5E334D5988C82EFA9B94E0A347757B81ADDF735753119350C0F3E8F3657BE5F58D4EB1E51583560B0775CDADE003C320FA6650D69674B3224318E8F51A17B4F3C9A5F9B3D9C1C3F6AC472D56EB9CCFA6FF592E8397BB30F558F12E290EA0333A6A0ED58A2EB1BA457FFE88888B610C9015A7DB11850D49011898A40E01C98A129DA9BDA8C64827879842D3966619A0388ABD88CA787005B7B69FE56066A0AAB8BD9D28ACE6AADC728E3EB30E16E4ED6C0F93670891CCCF18CE0CC7822E9CEB6D9E6B2B4F0F2DCA5382887A81F7CE2AEB122F0B7429C0E0D5BB32E53DAC5094481A2385D9F65B2FD2922F84D03AEDC4CA79C4F81F0A73386FFA7E5FE5B41D1571C426D88B18861FFC16311D61DF54F123A65DDCC2A6A5380F396C5B532A657BB0A97CCCE2F7D8C46096D0883CB16EAA8C57087678D9AE57D502E9C693DD899435DFC44F274B5F7F67A09F9C62AE0C08DC225B65983E3FBBC014000B51E3AC1B6290F135DE1FD32C6B6C049314DD7546E10A1EFA5A5A715D197B27408FC04AD61ED93A1FA08A764D2932060EF61ACDBEBCA8D6A16BB146FF0F6720BE6716292D2351B3F396B25015701B1827A8805204678ADF18AC38DDE4E2B27C6B1514BD197248FA9E88655E7DD20EDF4C9060653CE3C49D3B722514C421D0DAAB0CE802C7DE6A85C247B9DAF3EE936FE2823E13632FA91B9217B749DECECC7B4CC5A30168E0661CC142B8C62D5D056FEFA683EA4B06C74AAFA0170685D3F60E68CB0CE4F343B5F2900FA928557312A390F6744D47DB83D2B1917EB736B68383A90A14011A3C5EF48C7779E5BB6413824DFFB0B584420FCA86F7B798C33F790535EE0090E7CF6A0BBC0FDCA5D8A157748B4FE5B1CC64D9F1FEC367AC4D967712B7193F05058A35D7D286686AB611F1C4807B8F6B95BC021BCACD7EE59156710476C0BC628C387C1ED619BFF0FB68593502CAEC6996845C28489039AAD9BF5F0BD92776804ADBCE3BCBFE5F9F4FAA49DB29E53F6D047427A874AAE9B37A2FF7E753B7C712BAB4B128D88420CB0B8AB746491FBD4EBB70CE6AB653DCBE5A175E92D94DDACFB6F13094DC4205EAC3F85AC3EDED83C86DDEE0A9EF785DD42BEFD4299B5F044EF271571E5DB7D5349E47F14CEB297866621578F976DDD07F01698F8312117532CA2F68F57420F77CB85A8E0F1408ADAFB96D6BA04A0E6269B9F5D9121959617885F4F75E052D09DCC32C91F56A3E86832F6764038B61CF1DF5E6D588CB1028FACC7F99AE4082E5A604A5BAAA180845045993EACC930B64AEE680A9ADAFFE21A271721A3771EE60B12B85987CF25265D0ACF2C6FB55E762E877ED8E44266941C47F410A5698102D7E263F8530FB0EE9A26E0E5603A189CD896E231EE5DE2FF695736AA9B93B48C13D6D0F9E4EBB68A1088B311D3E1696610E7DBA6023AD3BB4122BDC83FA28938AA6023D1BA84752D897BAC75911F9928A4585F3C071FD858EC3721BE2A9F5FFCD260A7A5413BA2F7BE17E59830A7DE2299D83F779D0C780EFCA74D6D71015D7F21F54DF0A5231A5577BC161BFEB7F6B2A41B5B9A3661FCCA56ABDCFE63F3B49CCEF00938CC038FD084477C91123FA149CEEAF7141CAA1467A523948869C47F4E2905E7B48A468FE615643E66BBDC55356E395381FC0C747ADF495233356FAEA046F2C18F2DCA0A7CE744C110D0E0B2DD861BB5080570DB0A2674C5F177E902E171C6A96BADB979A5DB94CA8F73BD8AE70B43C3F8E2B618097D2C796F7F92DC56092A6B0D863A04E2F4645C4817E42AFA9CDFBACF1597341DA1BCDF29F38B37B8BB135A937EC8D16BFDF3B5E1CB4C335FCCDF7F71522E7BF2004EEF77F9B73B5B69216C4EFA4DBDC170132F2E0B897A8D5DF9866CA80F54342B024ADF78B550DEAD9E1642483205723024A15DC37AAC36EA593E152A6F7F8AD2A985AABBE3F1171E738FAF2594370A0C330CCE5D06E23EB942EBCB8F68FA465FB98F8FF1604A4AC4A286629AD3AD552032A49FA27774734B8C8F0DB2DD6A28C2D4DCF2E07BF1969AC4A9F218939EC685DAD80D848A8F6E803DF90A4BD133EE88F1013942FB74E19333B4AE530EE5E7752EDB8603D0D9D962A9CDB3D2188A610CE5C6D71D6A508446BE79DAF26B866DB6EEF1ACF5A995C9EFA9B33256A9582DBB4773BBAC9DEEAC03175BC18D283E76A8815EDF736F4C3217E810807BECE4442A002B71F87F6BDED77E5780FADC3AADB2FC146788D4E7F6EFCAF95213CF7F954C210754A3E79164E2373306C87F9814A07F155BE50F9EC2968F5E9D1A620240DAD2FCBD7521D8A875F8C50E6F86DEFB1BBC6ED7E8A9E434BAD73AC655B507A7F306A1554E73683BC5626D9EBA5C68CA9017AF81F74DB79CB2C594ECE50A73C8AA927554A30444D147DB937D5664D480D85FD560225E6DF2CCC33FF2C4EFC13A9E1116A373EB9CE1A064D10DF412A0C989FDCFCE6453AF69131D21DBC2B0D2EA5690DD4C76ACE68101E8C62487E06B303B41538A6FA71F264156E58E3BB29726E527F8C2E0E8285A9600FECE97E8FEC1C23F3FAFC6BD9D87067888B619328E25178198ED8CF2EA8D064A7B4B3B23FCC20734472B21D1E953024A3EF48B6379D632663607D22B81D3733E5E0A91F2A923BCBD91869BC51392625D0AB03676E6F2493327BC2F3E22C372BD1B6F9B33979FBB4F0EAA539E0510348F54C08C8F15AD4164AE7C8AF54F1C350AB9199BCBDDB54F4A346345F8F3D2418CEC1ACAC26E0AA592417D341A561BBD234FD5592E98308464AC5075B12EC1CBBDCF6D755C1B7214DAD0D68B2E031001216D0F0E8C458ED8446C81C6A689E776128C8327153E8908A38DB062520C4674773AFAEEE925B3C147F2573BAF628B90451CD169A7CE7CD110E54FF4AADDF92D0BFA853BFA03DC7C4E56A0A9807F3D17461E018C0CFB45968788D8242B3F6BC497052C272A1D1F9AD87DF0AE450BC9CFD342C10B6D1B644607C7CE3A26E8502C3C511B4958AC2064F9341036687A2F60C1415484D044B9C1B311EC5DFC5CE73D419FA7F2FDA6A69DEE46B8B53304FFB8C6B54C28524C3F85AE319DD339EEA6EC82DB6F0E71A52ED1032A01E00E9197843D5D6CC394CD826938E3791CAB36CD64C1B96B9139B761FA05B7CE05B548AD6AF898EACC9F41EEC6F4913B0493C22354CF3FD33D7CDB1A77823945EEFF0FF14FE286D8C6C94D681870457EA2B17EB50F15F3A4FCC15D3FEE02C1755B1311C8AD40A953FEB72429989F20465C0614826D863F0F2B8B6F79506D1F4696049B87DEE0DD4F9572EC64E7DFA4E2762012D5D7501399407BBD1377A99D38BE5523D286BFE047F15A35470262B8AEF766EC1F1044BE8E8091E28337F2E6AC3CE60230CEBA94D7263F17631E7BD5AC570E4F8E9DB1295C47523F55AC69BCB6E700C96275D622DAAD8FA5EB8AC2D8596C66D9A36921AC8876DD857DF0CCCD9E995B42B9B4A35E2173167FFAD52C3EDF245E1F309A39463EE1AACB6CE436ADEEEADD3F23CB7A046AC04B1975643D26D8947B99BA98C8115AEFBFC68AE16161045F4AFB151FCB9A8B99B48DA52A16DA615960743BFC8D37DB87BC5267432EB1F3B2B7CD6BDCE900D18C7DEBEA76E74FFAE48AFB2B2F0D93BD7550EED69704645586760AB0D7A4E1EFEAD9E32C11FA3D2941403A4928F52608E56DA5841B23F9ECD188588D1E06595C8096BD8BFEC4C8026D733E6958366140C45E074A1FDDBE5E660287157668246664C17701CA69FA30AC21E2C66EB6FC2133ECBFDA9053013002A2985376E8C64E3DF2E5A1ED150A2A77DA3E48749C2FEDA06F1E4F2E13344348FCF64587B3DD571FEDEF9435C00D6B9905EC78C3CF2E2275B1CE57CD54281CD7B2653618793966DCBD52213C1DE648E00866BFF9879685D91367FEE3A0C860C40BEE995D1F83E3DD8A18826B2BB1394A3DC5ACC8D32ABD88AC3883736F1A87F1207ADC1DC24314AFA573CEC977E9CB9A872F42228CD3A3A1F2CDE0F5B48AAB9F8E57AA4DB21CD76CD4F6818DBFA5A6EEA2045FC4A5FC94232700411BBEBF3CFA3A1EA79DBD80B06A1756910DFDA987316433548788243EE97A2CA95E48FE04EC9B94409088D1A174F0C72EB9CD40C68F01185090D53C8314CD4A1E3EA7ADE58B834634D9684A9B7597FFD0F94C63E4ABCE55F0DBDF098BB25E91DC34E12B87FE7990E7F42AE93D3786BBB04EF4557645971CBE15361C9CA0334F7BC24060E7719B302BD30B03DF4F6FE0E4704171622F698F49A12A2F275B54F189D3CCBCC985E3484D6CF116B48838B7285FF2BA096B1D5922F3CE587E8E01E2D52D810E8F4A043E8E52961423CB4D5598DB0956D5571701CFAD3D7D82F6880C5DACC062B38B132B860E67D872C6C13B3A058DFB5EB2514D20349A672D4CBEA53A0992E4DB48DF060ECDEB36AE029F911F2D09C56C26659A3AB6B062FB87DAB85703921BEE6AB6753189ED1E66A6D114E98B09413F8D07C8056F393431A3CEDB33E90B8C599D41D1E62E95F4BFF1B95D16F29DA210E290E623331E35D0C751D82C935CD554F17D936A690435447DA2C31DFF0CA9A5FC732E9A9F2045AE04594F36DAE29EB90ADE939D701491E2F5EF7B3425161EBA828083733742B7D9CD69C6C51E9A574C2130C92CDF8DCC3B3A8B6659B70F64725133A9FD36DE92C29A485C582BB80B5C6609CC4C7D274BB7FAAF35EC4D80F5362F198D5B837132D84273B57B21103639CA52F910FDBD585155A2BD052051BC9E8E43C7AA006A41FE7864BBFBA510253161545DC3E660490763A929FD7A5FB32773FF52FDEA9FE7D35C141D13ABFEFA7A164D484F75B78484DACBE33271095DB0A74F25E78B1C0514641F50D62A173D20DF1B3860 remain = 1152921504606846974 -max = 1152921504606846975 \ No newline at end of file +max = 1152921504606846975 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-3_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-3_256.rsp index ab3935d58d..e407b94de5 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-3_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-3_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHAKE_60/3_256 - pk = 00000016BBA15DFC230A90773653F36EDD994F661301535E235D0034A34B25B25C58531B04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 000000160000000000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94ABBA15DFC230A90773653F36EDD994F661301535E235D0034A34B25B25C58531B04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C7D176B37A7DC26214FBBF555DDEF8D970B6AA840AFCEE7B674EE05845118A6FB277ABEB1A792B61CA4D24646DBBFD623564F93B74C1277C1AE4CB326411850F0371D6A848ED0BBFB8B0BC3254398F513E630D075CDD277E0AE10D8D13EBDD0CC60AB0FFC61631C5D17989AD9DDF25BADAF0BB87FD0E32975EB673434812D58CC00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D9330900000000000121C29A3D4E6C5DAA979424FCA26B0EBE6D3FEA8F078FA9A98B0F55503C2541CE0A0000000000015EB6FB8267689B81BC8E2C8950E5F59F4B43194AB167C4A60EC9BCDA7572E5980B000000000001F02838F27F104405AA4D9E111D3A0B1849F6725926BA5B3A6412DEF900E7259A0C000000000001BA1EE79A04487C5639BA096A60E3E17F7A0E9C0238FA049EA7AFF52FAF5890980D000000000001B63504B794C356EB44A98DE32960830E6B275526432F232A7729ADA72571E8D90E0000000000014DA82230B909123D34E30FE0722BDD93EB6D56243518275547CBA7C473744E6F0F0000000000017AD15652FFFF1B8B9E752AD4A07EA737B8D79DE25D7F194E19ACF003E62C48F610000000000001D6819E585CEA52B14299092F01E66E9A6E7AFC9613A69B89ADE061890A230145110000000000017FB1A159FFBC19461AD72D4E385722A08E9A942BDBC3CF8352CAECD938737D89120000000000017B2C7FC20B3305327D2F0FC3C4854B0053D00E56EE4E005E43CBE807A619BEA8130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A86CB037675575D46C48D89A7B644810666979BFDDE595E1A2362B9961A71D9F75A4A72ABF56BBE2C07844E774123A5DEED0116677B286BB3F8BCAF92D501A5FF375487D2694B089FAF47D8632DA9E213A9C914689D9FD8B0DA5320F6A89787E198248FA523B9B2E910FE55F6127ABFE1FF1EDFBAFF132A06AB9FF0F2E368AEFC6AFAAE9F61068AEEFCAF427D37CD93FC0B0D226CDCF6A7C1F007BE2E59568970AB644D475E62D7B8E7E5F7BBCEA4D007BDDAAFCF6B84E09BCBC5553F516E2E5DFFFEB66C9F5EF34559251705C736FF66A96AD2CA2C40A368602DF65045808D87B7E24CE23C67906BF64C90CF0E0F8621537D08A09290E431737F9C493DBADF98C9E250E094C6F0F7E850F5EF65E71967F69159ADD14974C1AF501C74F01D1C36AEBE604A32DC02B676BBD7CE4BC3967FA8899F3B1F654E7F3E425ADB5ACF59B6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000018F224E19E61C8A7076585BF7780AD32D73D04D66A52F0B4CB6D35D9496906BFB05000000000001C0F7248E24BEA5635FD0F3F3411F1A20316CD29E2BDE6DCCBDEF8AFD463CADB306000000000001BFE2E0B4F4BD9B2B955C3CE73D4D0E703C44BE5168224D99756D865D86689E1607000000000001EB5D1F16948BBDEB3335E0F93C3DAC5C3FF7DCB33B16BB28D3826194192729F80800000000000194BC268989E8C957203F60EFD29089692A7FA0980912BCCB1FF3D6921B9805610900000000000182B44F3F72EC96002984E059C46042E3085A35BBBA6A0CA79700D29DB34DF2FA0A000000000001174A1DED5F222EB3573B2A6CC27870F2FAB30A64FFB9601B5B8167314CD3C4AC0B000000000001CEC1E018C94D354F99802059603298AAB121FB0D1CE89A6C90B945D90A6233560C00000000000184D0355AC86A5E83CCA4300AD4EF13DCF7D6185ADD1B29F22FF24B446B6A184C0D000000000001EF0BF8DB8426844A322EACD3C79500078561868864057744206E70294F1B4FBF0E000000000001EA649E4FFD3B7A864E5C9177F8B14D91BE4CFDB050B6EBC86571996AFC1AF62C0F000000000001F80F14346EB4A8387798C08955A0CAF061B367B1F969D28F833140663D9A4B24100000000000010990AE38170C318A1CB81B1C8C6D980077F153C1C0403EC9645459C3C222225011000000000001DDF5AD2829966C243C523B4B91800973741F27929353122DFD2F0F9DE717F31D12000000000001254C2BE70DF73E405F76FFAA6BF442F41018C0C2D3823AC64CC175A601ECE527130000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B832C73668D17AF4C29F2A72A1E8DC0D74C9F2446DE7A42F50A5DCA2F12EE84A91F75004E452A4E5FC799176A42B4D0A0A0CDAD9B44CC246872114650941B08315BA68E4B39A713B08A66F1715FE9300E5AAC533E37AE289B74341BC1DC7C75725C9838412E48A4CE312DEBC345B16A3A1F6388F350997448653448F6C7C91B7BE24118C3A0F4E431E88766E5A6C6113C8A2D1D2646B5EA5821C90CBE2CCB6CCA072F8AC327FD013B98A44146A45192D07A49B3FE150DB78658E659EB8546072823C7AFABE43959B08C3E239FAD4B3F0E87E872FF749B1DB73E5E9337731596C9DCE65AC0A8965DCD720A4B978015DE82E08B56B7C9D2D895861C15B766F9AB3C97E87206A7B951DA427DECC0653B7008BEE0B34E5B8A9D486832469079EECE91552F6208FDCFFD2E81B9E968F16C7A6E718FD43A6699A0E4D2F4692F3F56C2E31C33C937720276C8362A6839A6A055BDB5737525429AF0ACC1C8345BE9A2E9F269938969EE47C53A6E06BF3D9896DD79382F4210266C3BBB9F17386003F120AE41CF9F513B70D94E5A0DF54A0D52D5632495C7D6C843BBA812723C1BA75A6CD8B8FDA61F39B5EE34DABF596608877296A59158883CA4FB0402E22AEF63B5E1658DA5CD6F3BD2AD8D2846B76F86A831EF9F8E2F2EC334ADF81B976512F8FE7D2B9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001521B6795E3B31C6F469147CDE5776D1FAF80EE268B570DD87C1895E195F358E50100000000000135050ED1EAD3E799B63D5EDC01FDE9B7E3E8036A429C0AB56C909CC2B6378D6F020000000000010D93E097DE2D5330AA792D234007668B3E7F9E699621D298D2AB7577E8518A0703000000000001F2616B47D5F8376AF6A5FC658A75A52D032F7A1710630905C152957F41FA240104000000000001806EBD8412403D61AFCBD000376F11695F17BD253F82340C13342F750D09B2D205000000000001207581737977FDD59550FE1E0E62692061E1E37C554529C52E427434D2BC50AD060000000000012C3C45D74BE1C78902947B902756864EFD771DAF34009F91281FBAD0636A74EE070000000000014DC0E1A0DD7194009DC2FC5355C4D62179DA0010E19737654D7DC0E4C9761DFD0800000000000112F03C455D30919DCE22D2F8A0D4B5491A8188A32F17059A6AF994ADE911EF7509000000000001D61AF779A884D53CC99CB056977E564D49F3190CB260462D33ED4C7F0C47AEA80A00000000000174597C0DE43986083F16D33DB5D530E1771AB7CD8D0FBD09BD72854FED1D42C70B0000000000013CBB61C52DC21D115B9BBB0BA69F63D69C35C4047DE852373D70E445D4EB8F710C00000000000149B8C0E29BD2C1508E64FCE039EA36B491D678210DA046FDA6F7216B6276B64E0D0000000000016452B2D12F811FCC1544588490B05FEE831CC4B55263A2425F4AFDB7C804F5710E000000000001862BEC10334F6E0D0E998675C7F4E33F5DA105D68125FB2A8CAA0864D82B1AFF0F000000000001892D8275D3DF4A2354CA013048D86DCCD42EC388A2C20763E351DDA579550C131000000000000124BE91AFEB60D60AB3FAC980149680E6292FD0D89B416DB25C3F354084EDCC911100000000000135E8282E4B19327B8509A8F740D4C94CECB06BB8857844D40E6B38A061E75FB412000000000001B78706158F9720D3B08696410F42566DA7B34846E1D8A586FC003234F885B75A1300000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000665137D5D47667E1CA8F1B70A9029441013DB1E00D4FB39DE01E275ADE1AF6E6483B18C34D78AD814C71F370A0AF1E681C1041FFFACF9685BABB03923BDB41701F927F3316ED4DA8420A373F5471BE4A7215CFE5683EF16855C748D8FBD21DD9A6C36EBDA9BC5497F5C0C93DDBD40A717DCE151B87E8D5CCEFE5E8A0A66B3F92739B24915DA4B87BC7E555AE0554A8FC1D2514A7979DCC78E92D79C6908005648F90E5E4AB32CBDE27EF1BDE91C49C5184A3CE134D7AD33A1AC03F4A09CC245DAB6033C99636D9F6E9A723429F5EDFE118C045EDA721EB21387225EE2764A00D99625EB4FDDDAE398DBB4D8CD926310601CB34D38B7BA4BF60C66925B2E66B838C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A3692F3176BEC212C8CDDA63B223901AFF8E3CA0612978B7D97E8F2E1C000B0D2FB992BE80BE6906A967BE9949853BED6333CB070A1384B5A26ADF28D3BC5ED2236C6699909AC8EF3CE18997A672EFA2087DC9C0C38BB416613F206E136D3135C4E39F98C7C1F50DBBD69337069248EC64C3E5C6EE0EB7618396BFBC2BA26667426721DC84D3A53129AF465CAB586A54924BD35CA4BB250865AE0EFE67BDF060D8F947141B55502BD264BE2F24B40DA59C45FA59620F207E10FE94013B6A9F94182CFDA5694E19B1ADA22B18F183D7DF0A51AE2876A5D6B79D911B0B8A0D3EA283DDE8F0FC0DA1D77498ADC4DE901F89F11DE2753E8EF674622BF03110CB519AE4F6CD0ADC41A43D1929CBE5047D9B09FE60D9075C85CEAE9C825EA53585D180FB610BBA83BBA2E590AC5257DF858E7F11B8298C848F2F79D78C37F00474AEF9B5E9AEDBA4C81ABA062F24531171F8137F7FCF50FE09A38F60404B03CD1BAA934D6DB5CFCB1DC552BF873C6AA9B5FE76FAE92D4C3674E20DCA7BBF430C865F6E5FB5D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF710D288F760D8E6A64D9E2E53F680C21D30AC1439A4A90469D0C6271AB6EFBB90A4F4DBFF7D5F3875C6507DB321D81C3510D7E7F48B297881DB6FA0AFCE41645FC93A37FF04FCBA7FC19B9089BEABCF9BDF44E2C4614A73FEC80C1234162B41BDF1313F6E13AE2C48A6C4CABEF5EDE59AD461384DEFAF1935E23F5CAB3829A81E2DFFBBCF2FFB141D975EABF78FB4BD484F75E08318C08B2104A468E670786397EEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA360AB78FD9219EA890695CE44CC785A3A4DD39CB8F3C82FA5C6A3167055CF3309EB06EB90826159619E65C5E29D46D35E61C961AEC002F87B44A2B7D5C0E2111D17268FC3B147434264112A2E95AADA6ED860C50359372609ADB174741CC3AAAAD1FB50A42A560BB18D12C228F10D2776DED26752930890259A5C0F64C7D30C49383F92F1EAC6B1E8D6BA05423368AD3A8BD145D397389720E80F6EE11965E467D4D5864E164E51437277F698BEDA846AEB66DA3DEF39CA3288D30C001D3B0BCA113AFE8AD333A08D801A9E4C52DF0DDD4C63D8DF7EA938014336BDCDFA10E960DDDB4B5471263D096A49E3C83A188C46AD4EA8D2AEAAD3B1BA78CF6F116D0818BD2F38DB39D74D340546233ABC52278B381B7DEDC3A3B5DAADC8A4E7519AC9F3572A35C016CC7A8E0FABC029801012DD7454D7475E5D8B492A119AC583F4043D25CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438D81219D292421651600D48C2BD291766ABA14ADDC9186764DD212446D27C3738D2F606A9654BB310288F37CF0ECD5D38590E4D887D9D5C523527007F6501ACBE7CF36803727022D98CB15BCC0A88A509DF3B9A84E99B41843283FF2E10FBDA3C14CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D446D278BBC90D6A56B71D6DA6FCA49F332776F402F58D180482B2EBA5132D8ED67144DA06AAF952EF5B9BEBBF0CC8101E93F3BE05E58EB75D55B3CE72B9C8A07725C61C24C34DEB9A7349E51256EECB7DB61510D8BF55798B060EEDF9F9551AA615F1661F544B0779B2974A54BE8BBA388D6D7FB8E2C0956DCB23F834025CAE4BF26B798CBD5938A517C4C3B8FD3B8FE920558256C391433854481944BE487AFBD226853E385D942014B393488D554FBC143B44F7E9F348FB79920D4AB758CAEC55ED8CD388DCE4B4381D5C3A9FF36ACF9948993CF2B2E03030646852CB4193585AC6C56947193F96292D813FCF3671D46B9DF2D99D43E0AB4F1994B81235A50D5D977FA3560CA3D46CF60945C8D3E1103B6B1D13CCFAE43741BE65EAFFB9DCAB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832D381248D668B0A5ADC623F2529B02CCE42442E86382E03BA3FAF21F86FDE1C633C9A17426EF1F4923824A1E394BBAF5058C00950968357FEA01AFA8303DAA21BAE4617293B3B19A50C88C8F7D8A677A3314640452734E7FE4BA483C8AF87356E6822D943C23705352F458ED80B8375DA6F1F0DD7688CBC6101727F2AE7FE500C98A185F29DC71EE3506F8425B8D7EA94BE228679F42ACED5C9162D6A0E9AF148E5903C0ACC117C2BAAF1EC4A73A0BF73CDC646D1559EB1FA607044B5C7CA60FBDD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C6F2AE696330DD7C816130134AC101764D6B4FAFA1E71A404CEBA3406E1996391AC35A28F18E05DA188AA8FB52712696C986C25F70A31DA73957B238FAE89EE0BE4F77ED34ADFF62BB5C0838F9B645F6851BCA9241ACBCD3038BC40F40F076D1CCD8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CEC2A8424E383ACE82322B3629ADA77D454B677A60A2932B49F844A9389E73FCCB04A4A962E7382E5125E529A0E244ACA7F30287FD74C8938A6CFD5FF3857622A676F9528968A73DCB3458A2ACACFED4EE0F6C6B3EFA7207E8F13B15A8F7DF45A3024EA2D0C6179540EF44A8DD43F70222075D9A11B4C32BB0822113EABC09D37D0925C5D27FF4B27EF82812B5609734A615CDB54529EB30EF57F70B1F177F56776E9AF34A592C707753819140669172E2BA4657977CFA700911BD68BDCA9392759431A2E164C7F420B10982E4AE55E77E15C2499B4F0685AA0FFF4C5830F1CF18E0C22B855FAAEFAA6FAC5D79BB0E504D666EBE0D8F8BE770CAA37FD9A4C254357AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6861E7E10F9C70FFC41ACFDF5DF7C525935C838DFF06C5468E647D8F85F945009A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F953682934476EDB8FE887C37129998A21E92F020460D3AF85356DAA577666F5DC0BCC59CCB9D20278F8B155728F4234D7F11EA25B128E7283D09BCB5F54A03163FCEE112A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E10F0D0BD64F607F4E22EC40D80D95808240F1E89E3F856E32304B1B30486468E5A416E66F1A2A85269A95FB827C5AAB7C55061CD2F8FD8B1B467C274A878E290B66B89AC0D71ECF1800F4DB2701176854E40F42D44AEA68CFA350E5FC1EAB4DA784E1DC80443371C10A5CB7E68EC999451FD9017D85C1413F7E13F521B8F62A2BD56DA107015044432ADDA5485CAC00CE0F17A54A9577EC30221D873FE86D21AB50B0422EA1955082CDDAFC53B4A608CE7BD87264C3B1E44D4DA3EA036C17A0C2CCE310F020942DB86B6974C0A2BC2CEBA92880041135754702C769DFA1F62499203A406C768EC14796AD5DBC55FFC30BAD441FC03BF7EAFAC09D8787C4B5F2A8EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D15998001DA4935E216F14DEB2F74D9EB3BC833378A789B550B985FE0A09EE8D8ABF84E861978642C8AF755604D8C0A0821DC1A47E813464E374F09680E752871421599B4BBD0AD2C7ABCA4223B5223616BF5FF927A2BE4997EC8D7E2C75E6C4761AD4C6F40E96BA127BFB08BC1212F7E4FBCBD839B558C5984116355EF45744AD99D74D29C3880C7C7D839C34061BE1CC4CA1FFF12AE81E5A4DFDC1A2D90039E964261BA2D0266E5193CF81859B3C8D464D8B0A7AEB3C822783C4BF41C71A04D4ADA9EC6FA901CCEDAAF06EAA15D89FA7541347EBD19D6D75DEB384B32C275685DA7B596BF37CF982D238B813055E3B929EB119B2A54E6ADB3B8D315A997B721F589100BDFCC72415407617C203AADBDE0A26C50CFB5DF1BBFCB7D484C2103D54BAE53F5401E80CEEC135F9717D3A82E7F919CD1710B254C91BC2688C8DC1D114B3B1BF9EE40897C9692586285A1553057D54A5AA1D794911CF6F4493E7C4A56B39E8C88BB5E4FEC69BA1F9A3FE964D40DD0AE57A8EF70D2C7ED2C954BE542DA5B856C01988E33CE1160823EA49E5E4D6AD4EFD2BD6EB0A5DA925C0159C4EE9714B7B154E1D715C8FEB898A1DA31D5A8ABAB9CDBAB991459E62BE9F0E0A69791265ACD8F7AEDAF736FB944D3CEA82A1B3F23ED9AC0025760D260009668580A7FE2EFDA06FBD6C189BF2DC49AF474F0198F7A896DFA96C21479389CD1B85C660AB4409EFB415FFD9571BBCCFDA01333286A5A934E32D7C6D7EF3A20DD86ED5391AE3F0AE016E52696CB81A00C5186FDF5B3169C51128537427E443FAB85BB58EE6D9F0B43F56996ECCFF99689272C1CA1E12AA1197E29A23D0AB616D1DA9DDA0BB85E150F12E5F7A773411120EEEF802E49440D774E85754826DA02D1309E1050550F24550D49609811B6662B4E1FAA554A4B0DA3B6D79762A0AED8EFF1E0A78FCE68DBD11046CD8555D83FC03E04D766C89732A1F14D56BBE8724BDEDC4D3BC5712FAC4A5141DB75ADDFA2313FD11CFB56C0847DED068A7134B38B66338B3DDE3EEA0C1A11B95F4AD251AFA121C53B39AECB4F804F003D4B202EEF58BBEB16E8ECC1A373ED33FE945991DAC70B8C1DBB499B8F43EDE0EF546FB88837D8042E03AB9E5ADB3F6B9D7B1B95C9FD7233772FDE5DB57B2C533127B0A566BE3C386339DD406F37450F0E477859629CE2B957F3415CC4E2CDB795EB766193DB9CC1E5D3455ED18876287061E39313146C9975417905C247964637492577D9D6F33F4CB1E79426A67B00522DB7DC0D3942F9848287C6F1ECC38A0C93D0E666CAD000AB73B23019D08FC342C9941B31E8BABB65862DAC87CF204EEFC17B6D204F607F60F62A60CD3A02B6E121E1CE591185608500C11AAAEB039497472C12F766386647573387AFEBEB8DD850B853D7C548CC8ACF1E3CEA95E9F2710A6CEEEBBF4A3C6B5A69785106B54205049A9D3C611AE5B4C793058B64536750007BDD97662E2D4C0466738B53D22288F3116F88C5BD5670FA08278385F22510070BB44827D0268FA12DFF0AEF482A87AE152C9A588C6DBB41E4B0B325FF957E45A7F6E7234A8DD609AFC3E2D553CC25C9324591794E60FDE66E2F268FCAA01768FECD57AC90DDCCC988A37AE97A46F7ED29F3D2D34A83AA3CBF17F7C34651BC1278DA9646B228247E0BE29AEA13601305C9F130DD40BAB49A9D9DEC13337A24AA2181E57014F6DAB71CA701C1DBB33A28DEBB815B034952CC68E38E566CBD1B23C1AB6DF52384591A92F8C039F240D39B2F363E8621EBECEBADA3DA938E783A72AB8B5D0D287157649EA39E6D7DCC178F2F979A1931CA6692B746A851CBE2FB336307160CFA574F4EC5319F339F2C79B060A8D875507227D8010A9D74F4E2CE9C92F14466121252B8706F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174CC1FEA72203D681B212B1890DDB2D48CA6197C5B9ABDC377723EF0884703BE27 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 8392 sm = 00000000000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6E5E19338E14E4588FDAD9A348A2B69BB3DB947C41E74B1C49E267A77A94FE9B2438442FE81428E5791B24619D5C18E17066E74EBB881E828DE7442F7EC0F03CCBCEFD889D3361070C554580F55CDC11D8572F0E0F241E24FF7A7AC9E3BFD197FD962E4E6007A684AF87B096B9034966949F56D02660E2B7279214CEB93E6207366A0D5672F44DBB9632CE082C47A1191092030F878A87D3007016131038259D35C2EBF786119150D628A09E9E1C58F8508716FA31DCE1C2CCF7854910D291C83498AC8202BBB4017F727A5E938725AB65B75087A25A952B3F2A54A07C27A654FCEB150A192915844DBD22D5956CF2334FB69351F62036F9C7BF591274153FCF4DCFFA47AB17563DEFAC3A51C0C7E96367FD2A5BDB6420DB2F8E1FA8A1E04E02BD2F72D66DE7B1926B078E7789AF0FF371935A7E432EDF91FF02B2F55E3D348544E86EFC3CBB41204EAD55A3B933F6F3CAA2C4BE36D24A290DB58852434D7C45EBBA724670050F31569813630709AB6A4E35D66684AB154CF647FD64DA3B2E5530B4ECA5ABD9666549F8079173D267642D94F9660C76FF6D5378E015B792B13BB6A3AA55210070C4A413B056C20B2C53135921000948C58FA834135A5C0B3B2849A586CB2FF84925B00E791AD53B58AC6E577BF03A33D008112242388D1464B4616413EFF6A8317C1BA5D42DB01AE12DF2DF062E71777C618CBE7B220A76E5CBF2C0CCE36561758781EB57877CDA69BA5118EBF885452A682B2F650FB9C650884F655867F45720C67D422D5D284328E5439C2BE923E7F9C5307F30E5091A88A02B818B7E31A574796497C2AD22C79CDFF65DE6D4E12F165710A69D1474BC7FB5E4DF07EFD4A4BBDD190878F81047F477A4FF9B89DBA8ACA2B5058528061CC13CC41C207AE1E556CD36E764A42276078F723FA45F7DDE9B045FA1B2B87D528A0C4CB0B5D16C7813F05F9578CECC287D621864B54E54836F3315642DAF8E0F3A61CF1AB866C0EC37A66D86CED0DCAA7DAD8A4E71E08A856A7E8809F918430DD06389BF995302B29441CCE5279FC490F0C8016647BF4125C4E75F168CEC378A488F66EDAF3A6A71C48FA89786E1A76FE326B90AF058B1627040851A517242451CFC34CC73FDA4B0851CE702E085953B9D195E13981E55CCDBA1620CB5DA2D599570A28E55818BC0221E11D899EA733D34DF501FA99A2446DA2F93074804B56E3A7C859E35F94A4492867F7A94B9CBA5348F7071C5732563F8C1C008AD8C1767EC2D20F68C863733E6CA47A29B5851D58F687B256965482434A3643877BD2C0EEC4FF5F8CC13A89E775AB6123C3A1D8301FBA857F30B65D1961FCCDF1C0A1E541092064590954449C3DA834F44EF0A3DA76A90F5FE8EFBFEDBC1BAAE5256E6A1599B45EF51D9A6F477F108EFC9DCC7F139617993D5362ED390A73955749EF1FF0825D5728E4A8CA6264070A7F1F09CD093CAD71FE3263B0E60C73F5F8641AFAF0767651D6534AE73B220CA73A13917887367D055D38A65273890D1FB7A3AD50A7BEC3E7B693C41F717FEC260DC06486D04822DCD3BA1CEB89F12DFFE3534B51B107E7B565F6F3F7774A9CE75488FBA6FF0205FD45334A09906A3774718DDF36BB668C3739D139D5E629140BE6778F0C912343373F637A516E029047FCCECD7C99A5966B1E2CC30E6E7DC45BFDA37C100EB88E44069492CECC82E9E4EC8C7C2C9F85B06F2846EB553C0C49BBD6342D26380F215F7E213C61335DE8F2FE877D38BC2BF84DBDCE94CF1B52C96E524E7179C8ACBBCFCAB586CE6CDAC4FD71787904D4D19A3C95963CC8A0B0F4073965CD5FEBC875F971ECD647F269A6365491CFB0E6F090CEDD43D7F85EB9C9B771CB8EEA797E79F369BCE45087374A20BDC6FEB45871AF23ED0DEA058A8286493883F63B6E25C9BED28B91EC3E6DA1574ECB713557BD2FDC3BCE635C4C98CD3ABDA6B585B5B449422C4CA053D1BD0F83D42696307351BF6C2BC2E38B5392D75F260AB7393D4EC5143E08DE25ABA6FA90C13F1C3CB010C4509B13FB00DF87ED2BFDEA30928486A9363A6559C08A4ED761F5FC89A488B81BD6EB146BA166B7B203A84170E9548C89FD3F34D1B8A288200E2D803B6E5B0A46A45A8CE5E4DA1B56AF04BE0A2D9C1329842C497877D9A5E8FEEA8BD056653836DC0C5363795788CEFC6210B502DB88C434099C46316476FB3FB07E701E29075A820C8D25218B7AB81957686E1BB2C02A72AD3B067589E7E454232E6D4AED6D53228C7A86656CF2453006F1E5F826B247F52F4E7571D886BCEF76579C5A1079EB84454856FC5CBB7A94FE1E8BD05D1597E645C90A90D55196BE811AD44683DC922867C4C6EA4699B17DEA5264D74F30E6C28321576BE93430D75ECBD4D8A99DA5DA96673D115C6382653416DFFD0674E93337AD105F1C5ACDEDF7520B819C2C6669480FCD587D115B1D7951C75225493628CB4963EEF967CF17C509540AD2B7655DD0CA93368A62B937DB491F571A2CBFF957ACC7EDC2201410DB78EFDD783B77B822CD2D5C228338C8F636B590C8B4A083F22185374FB311A8C28990CB91D89E58448E57618F066065AD0653A7135CE175D55D84E19D45932534D0045CE8827E6C485A679499AC15C89843802B844E9E5A280057C9A5DCE4D75B14DCB8CF4475FB01A405403F4ADDD2097729FDE708EB369DB19FAFC35528A11EFF706445E69FF3D16410BA04D24CB605E507D60D552FAA2EC3B70B4AED58517804EC52A746859329225E1BCB7F680B66729BEAAB9C5AC5A2120C8D427E349F364F595BC1D728DAEA01CE9C99BAC79F55E0CCB1C03AF2EF2C56D45E06D33F9D3ABBC6CB4BE097379B461E10794BF16A80B825E59B4645E849AD89E8F7D867355ACE237317FFECE24D982E067547936FBB57F2C25218A230EFB1A665F3D948CDEAA9F8659900F10C43437C01BF081D2664641DB6FD5B0CBE2004A96DD26D999937817B3A8DFF74E2CB3E61134E6B4CF5811150F4276945BA08D0779468902DB915F36620A54536F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD38CE6D0281ABBF9C140B2614526F684254F54E121E3B0291C3926AFDD98DFD10D8959C450F726A8334D3B3C5FF6D5AEE8D27458A4D78040B7F5555AB46E6662EB1D0908805D2B7EAA686FCB7069283CDD505069A7AD1B5BE804548C41A4E273F58EE1E8BA7E951B2F766E1F11C03881B4CDB9A520BC04EDF8E8A9BCE919575914CA22623741D57FF97B036BC9B09C7D5162D983DD5B4D519A869CFFF53F37FD8F550B1F006A3856ECA2DA3804EBC5AB1CD68D64FD4D11747C17C6D3206CCA24C7D176B37A7DC26214FBBF555DDEF8D970B6AA840AFCEE7B674EE05845118A6FB277ABEB1A792B61CA4D24646DBBFD623564F93B74C1277C1AE4CB326411850F0371D6A848ED0BBFB8B0BC3254398F513E630D075CDD277E0AE10D8D13EBDD0CC60AB0FFC61631C5D17989AD9DDF25BADAF0BB87FD0E32975EB673434812D58CC665137D5D47667E1CA8F1B70A9029441013DB1E00D4FB39DE01E275ADE1AF6E6483B18C34D78AD814C71F370A0AF1E681C1041FFFACF9685BABB03923BDB41701F927F3316ED4DA8420A373F5471BE4A7215CFE5683EF16855C748D8FBD21DD9A6C36EBDA9BC5497F5C0C93DDBD40A717DCE151B87E8D5CCEFE5E8A0A66B3F92739B24915DA4B87BC7E555AE0554A8FC1D2514A7979DCC78E92D79C6908005648F90E5E4AB32CBDE27EF1BDE91C49C5184A3CE134D7AD33A1AC03F4A09CC245DAB6033C99636D9F6E9A723429F5EDFE118C045EDA721EB21387225EE2764A00D99625EB4FDDDAE398DBB4D8CD926310601CB34D38B7BA4BF60C66925B2E66B838C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A3692F3176BEC212C8CDDA63B223901AFF8E3CA0612978B7D97E8F2E1C000B0D2FB992BE80BE6906A967BE9949853BED6333CB070A1384B5A26ADF28D3BC5ED2236C6699909AC8EF3CE18997A672EFA2087DC9C0C38BB416613F206E136D3135C4E39F98C7C1F50DBBD69337069248EC64C3E5C6EE0EB7618396BFBC2BA26667426721DC84D3A53129AF465CAB586A54924BD35CA4BB250865AE0EFE67BDF060D8F947141B55502BD264BE2F24B40DA59C45FA59620F207E10FE94013B6A9F94182CFDA5694E19B1ADA22B18F183D7DF0A51AE2876A5D6B79D911B0B8A0D3EA283DDE8F0FC0DA1D77498ADC4DE901F89F11DE2753E8EF674622BF03110CB519AE4F6CD0ADC41A43D1929CBE5047D9B09FE60D9075C85CEAE9C825EA53585D180FB610BBA83BBA2E590AC5257DF858E7F11B8298C848F2F79D78C37F00474AEF9B5E9AEDBA4C81ABA062F24531171F8137F7FCF50FE09A38F60404B03CD1BAA934D6DB5CFCB1DC552BF873C6AA9B5FE76FAE92D4C3674E20DCA7BBF430C865F6E5FB5D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF710D288F760D8E6A64D9E2E53F680C21D30AC1439A4A90469D0C6271AB6EFBB90A4F4DBFF7D5F3875C6507DB321D81C3510D7E7F48B297881DB6FA0AFCE41645FC93A37FF04FCBA7FC19B9089BEABCF9BDF44E2C4614A73FEC80C1234162B41BDF1313F6E13AE2C48A6C4CABEF5EDE59AD461384DEFAF1935E23F5CAB3829A81E2DFFBBCF2FFB141D975EABF78FB4BD484F75E08318C08B2104A468E670786397EEE2BFA57821FD31C38432802C83B7CFEEA3D1AFE176E194B3FF5244CD558CA360AB78FD9219EA890695CE44CC785A3A4DD39CB8F3C82FA5C6A3167055CF3309EB06EB90826159619E65C5E29D46D35E61C961AEC002F87B44A2B7D5C0E2111D17268FC3B147434264112A2E95AADA6ED860C50359372609ADB174741CC3AAAAD1FB50A42A560BB18D12C228F10D2776DED26752930890259A5C0F64C7D30C49383F92F1EAC6B1E8D6BA05423368AD3A8BD145D397389720E80F6EE11965E467D4D5864E164E51437277F698BEDA846AEB66DA3DEF39CA3288D30C001D3B0BCA113AFE8AD333A08D801A9E4C52DF0DDD4C63D8DF7EA938014336BDCDFA10E960DDDB4B5471263D096A49E3C83A188C46AD4EA8D2AEAAD3B1BA78CF6F116D0818BD2F38DB39D74D340546233ABC52278B381B7DEDC3A3B5DAADC8A4E7519AC9F3572A35C016CC7A8E0FABC029801012DD7454D7475E5D8B492A119AC583F4043D25CF1BEDAE7C67F093939FE19265580FF8F199789747FAC252B22338C1F9A81546D474ED8AE3B15450C248728134A1BBC11594148305C1DF6DE9F009DB66C438D81219D292421651600D48C2BD291766ABA14ADDC9186764DD212446D27C3738D2F606A9654BB310288F37CF0ECD5D38590E4D887D9D5C523527007F6501ACBE7CF36803727022D98CB15BCC0A88A509DF3B9A84E99B41843283FF2E10FBDA3C14CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D446D278BBC90D6A56B71D6DA6FCA49F332776F402F58D180482B2EBA5132D8ED67144DA06AAF952EF5B9BEBBF0CC8101E93F3BE05E58EB75D55B3CE72B9C8A07725C61C24C34DEB9A7349E51256EECB7DB61510D8BF55798B060EEDF9F9551AA615F1661F544B0779B2974A54BE8BBA388D6D7FB8E2C0956DCB23F834025CAE4BF26B798CBD5938A517C4C3B8FD3B8FE920558256C391433854481944BE487AFBD226853E385D942014B393488D554FBC143B44F7E9F348FB79920D4AB758CAEC55ED8CD388DCE4B4381D5C3A9FF36ACF9948993CF2B2E03030646852CB4193585AC6C56947193F96292D813FCF3671D46B9DF2D99D43E0AB4F1994B81235A50D5D977FA3560CA3D46CF60945C8D3E1103B6B1D13CCFAE43741BE65EAFFB9DCAB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832D381248D668B0A5ADC623F2529B02CCE42442E86382E03BA3FAF21F86FDE1C633C9A17426EF1F4923824A1E394BBAF5058C00950968357FEA01AFA8303DAA21BAE4617293B3B19A50C88C8F7D8A677A3314640452734E7FE4BA483C8AF87356E6822D943C23705352F458ED80B8375DA6F1F0DD7688CBC6101727F2AE7FE500C98A185F29DC71EE3506F8425B8D7EA94BE228679F42ACED5C9162D6A0E9AF148E5903C0ACC117C2BAAF1EC4A73A0BF73CDC646D1559EB1FA607044B5C7CA60FBDD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C6F2AE696330DD7C816130134AC101764D6B4FAFA1E71A404CEBA3406E1996391AC35A28F18E05DA188AA8FB52712696C986C25F70A31DA73957B238FAE89EE0BE4F77ED34ADFF62BB5C0838F9B645F6851BCA9241ACBCD3038BC40F40F076D1CCD8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C0402AA349ADCC157D3B0E6852516FE480EB2B0D7C38D55BD6B1100D38E5CE79CEC2A8424E383ACE82322B3629ADA77D454B677A60A2932B49F844A9389E73FCCB22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A86CB037675575D46C48D89A7B644810666979BFDDE595E1A2362B9961A71D9F75A4A72ABF56BBE2C07844E774123A5DEED0116677B286BB3F8BCAF92D501A5FF375487D2694B089FAF47D8632DA9E213A9C914689D9FD8B0DA5320F6A89787E198248FA523B9B2E910FE55F6127ABFE1FF1EDFBAFF132A06AB9FF0F2E368AEFC6AFAAE9F61068AEEFCAF427D37CD93FC0B0D226CDCF6A7C1F007BE2E59568970AB644D475E62D7B8E7E5F7BBCEA4D007BDDAAFCF6B84E09BCBC5553F516E2E5DFFFEB66C9F5EF34559251705C736FF66A96AD2CA2C40A368602DF65045808D87B7E24CE23C67906BF64C90CF0E0F8621537D08A09290E431737F9C493DBADF98C9E250E094C6F0F7E850F5EF65E71967F69159ADD14974C1AF501C74F01D1C36AEBE604A32DC02B676BBD7CE4BC3967FA8899F3B1F654E7F3E425ADB5ACF59B604A4A962E7382E5125E529A0E244ACA7F30287FD74C8938A6CFD5FF3857622A676F9528968A73DCB3458A2ACACFED4EE0F6C6B3EFA7207E8F13B15A8F7DF45A3024EA2D0C6179540EF44A8DD43F70222075D9A11B4C32BB0822113EABC09D37D0925C5D27FF4B27EF82812B5609734A615CDB54529EB30EF57F70B1F177F56776E9AF34A592C707753819140669172E2BA4657977CFA700911BD68BDCA9392759431A2E164C7F420B10982E4AE55E77E15C2499B4F0685AA0FFF4C5830F1CF18E0C22B855FAAEFAA6FAC5D79BB0E504D666EBE0D8F8BE770CAA37FD9A4C254357AC146D900D2576B782745048927DDF67AD0A8F93E272EDB721A989D57A2B4F6861E7E10F9C70FFC41ACFDF5DF7C525935C838DFF06C5468E647D8F85F945009A54BA1D966192D8C01FFD4C877E6E6DF3A7A6A7497FE6F192558BA81F953682934476EDB8FE887C37129998A21E92F020460D3AF85356DAA577666F5DC0BCC59CCB9D20278F8B155728F4234D7F11EA25B128E7283D09BCB5F54A03163FCEE112A2E68B183DC833EDDEA8F8D251F710D28C7C1429419DB82DE68BD7CA6EB23E10F0D0BD64F607F4E22EC40D80D95808240F1E89E3F856E32304B1B30486468E5A416E66F1A2A85269A95FB827C5AAB7C55061CD2F8FD8B1B467C274A878E290B66B89AC0D71ECF1800F4DB2701176854E40F42D44AEA68CFA350E5FC1EAB4DA784E1DC80443371C10A5CB7E68EC999451FD9017D85C1413F7E13F521B8F62A2BD56DA107015044432ADDA5485CAC00CE0F17A54A9577EC30221D873FE86D21AB50B0422EA1955082CDDAFC53B4A608CE7BD87264C3B1E44D4DA3EA036C17A0C2CCE310F020942DB86B6974C0A2BC2CEBA92880041135754702C769DFA1F62499203A406C768EC14796AD5DBC55FFC30BAD441FC03BF7EAFAC09D8787C4B5F2A8EB249CA378B495C00888BB2147B61336B38F2F31F82F7DDEBBEB5F6CFA7674D15998001DA4935E216F14DEB2F74D9EB3BC833378A789B550B985FE0A09EE8D8ABF84E861978642C8AF755604D8C0A0821DC1A47E813464E374F09680E752871421599B4BBD0AD2C7ABCA4223B5223616BF5FF927A2BE4997EC8D7E2C75E6C4761AD4C6F40E96BA127BFB08BC1212F7E4FBCBD839B558C5984116355EF45744AD99D74D29C3880C7C7D839C34061BE1CC4CA1FFF12AE81E5A4DFDC1A2D90039E964261BA2D0266E5193CF81859B3C8D464D8B0A7AEB3C822783C4BF41C71A04D4ADA9EC6FA901CCEDAAF06EAA15D89FA7541347EBD19D6D75DEB384B32C275685DA7B596BF37CF982D238B813055E3B929EB119B2A54E6ADB3B8D315A997B721F589100BDFCC72415407617C203AADBDE0A26C50CFB5DF1BBFCB7D484C2103D54BAE53F5401E80CEEC135F9717D3A82E7F919CD1710B254C91BC2688C8DC1D114B3B1BF9EE40897C9692586285A1553057D54A5AA1D794911CF6F4493E7C4A56B39E8C88BB5E4FEC69BA1F9A3FE964D40DD0AE57A8EF70D2C7ED2C954BE542DA5B856C01988E33CE1160823EA49E5E4D6AD4EFD2BD6EB0A5DA925C0159C4EE9714B7B154E1D715C8FEB898A1DA31D5A8ABAB9CDBAB991459E62BE9F0E0A69791265ACD8F7AEDAF736FB944D3CEA82A1B3F23ED9AC0025760D260009668580A7FE2EFDA06FBD6C189BF2DC49AF474F0198F7A896DFA96C21479389CD1B85C660AB4409EFB415FFD9571BBCCFDA01333286A5A934E32D7C6D7EF3A20DD86ED5391AE3F0AE016E52696CB81A00C5186FDF5B3169C51128537427E443FAB85BB58EE6D9F0B43F56996ECCFF99689272C1CA1E12AA1197E29A23D0AB616D1DA9DDA0BB85E150F12E5F7A773411120EEEF802E49440D774E85754826DA02D1309E1050550F24550D49609811B6662B4E1FAA554A4B0DA3B6D79762A0AED8EFF1E0A78FCE68DBD11046CD8555D83FC03E04D766C89732A1F14D56BBE8724BDEDC4D3BC5712FAC4A5141DB75ADDFA2313FD11CFB56C0847DED068A7134B38B66338B3DDE3EEA0C1A11B95F4AD251AFA121C53B39AECB4F804F003D4B202EEF58BBEB16E8ECC1A373ED33FE945991DAC70B8C1DBB499B8F43EDE0EF546FB88837D8042E03AB9E5ADB3F6B9D7B1B95C9FD7233772FDE5DB57B2C533127B0A566BE3C386339DD406F37450F0E477859629CE2B957F3415CC4E2CDB795EB766193DB9CC1E5D3455ED18876287061E39313146C9975417905C247964637492577D9D6F33F4CB1E79426A67B00522DB7DC0D3942F9848287C6F1ECC38A0C93D0E666CAD000AB73B23019D08FC342C9941B31E8BABB65862DAC87CF204EEFC17B6D204F607F60F62A60CD3A02B6E121E1CE591185608500C11AAAEB039497472C12F766386647573387AFEBEB8DD850B853D7C548CC8ACF1E3CEA95E9F2710A6CEEEBBF4A3C6B5A69785106B54205049A9D3C611AE5B4C793058B64536750007BDD97662E2D4C0466738B53D22288F3116F88C5BD5670FA08278385F22510070BB44827D0268FA12DFF0AEF482A87AE152C9A588C6DBB41E4B0B325FF957E45A7F6E7234A8DD609AFC3E2D553CC25C9324591794E60FDE66E2F268FCAA01768FECD57AC90DDCCC988A37AE97A46F7ED29F3D2D34A83AA3CBF17F7C34651BC1278DA9646B228247E0BE29AEA13601305C9F130DD40BAB49A9D9DEC13337A24AA2181E57014F6DAB71CA701C1DBB33A28DEBB815B034952CC68E38E566CBD1B23C1AB6DF52384591A92F8C039F240D39B2F363E8621EBECEBADA3DA938E783A72AB8B5D0D287157649EA39E6D7DCC178F2F979A1931CA6692B746A851CBE2FB336307160CFA574F4EC5319F339F2C79B060A8D875507227D8010A9D74F4E2CE9C92F14466121252B8706F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C0F90F4CB1FC9902522B7D47779E2B1B8D5FFDBD472931E145AAF583A359F8174CC1FEA72203D681B212B1890DDB2D48CA6197C5B9ABDC377723EF0884703BE2757F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B832C73668D17AF4C29F2A72A1E8DC0D74C9F2446DE7A42F50A5DCA2F12EE84A91F75004E452A4E5FC799176A42B4D0A0A0CDAD9B44CC246872114650941B08315BA68E4B39A713B08A66F1715FE9300E5AAC533E37AE289B74341BC1DC7C75725C9838412E48A4CE312DEBC345B16A3A1F6388F350997448653448F6C7C91B7BE24118C3A0F4E431E88766E5A6C6113C8A2D1D2646B5EA5821C90CBE2CCB6CCA072F8AC327FD013B98A44146A45192D07A49B3FE150DB78658E659EB8546072823C7AFABE43959B08C3E239FAD4B3F0E87E872FF749B1DB73E5E9337731596C9DCE65AC0A8965DCD720A4B978015DE82E08B56B7C9D2D895861C15B766F9AB3C97E87206A7B951DA427DECC0653B7008BEE0B34E5B8A9D486832469079EECE91552F6208FDCFFD2E81B9E968F16C7A6E718FD43A6699A0E4D2F4692F3F56C2E31C33C937720276C8362A6839A6A055BDB5737525429AF0ACC1C8345BE9A2E9F269938969EE47C53A6E06BF3D9896DD79382F4210266C3BBB9F17386003F120AE41CF9F513B70D94E5A0DF54A0D52D5632495C7D6C843BBA812723C1BA75A6CD8B8FDA61F39B5EE34DABF596608877296A59158883CA4FB0402E22AEF63B5E1658DA5CD6F3BD2AD8D2846B76F86A831EF9F8E2F2EC334ADF81B976512F8FE7D2B9 remain = 1152921504606846974 -max = 1152921504606846975 \ No newline at end of file +max = 1152921504606846975 diff --git a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-6_256.rsp b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-6_256.rsp index bf11e7de76..9c54ac3b00 100644 --- a/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-6_256.rsp +++ b/tests/KATs/sig_stfl/xmss/XMSSMT-SHAKE_60-6_256.rsp @@ -1,5 +1,3 @@ -# XMSSMT-SHAKE_60/6_256 - pk = 000000171657949C495B0A1FD294C1E4123901C1A43FE62FEBC70C30CB6088378ADDBAAA04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F94 sk = 000000170000000000000000061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA19810F5392D076276EF41277C3AB6E94A1657949C495B0A1FD294C1E4123901C1A43FE62FEBC70C30CB6088378ADDBAAA04562AD35E8ECAFAAFDA16981CDAA147606BEEA62801342AF13C8B5535F72F9400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000156F2B5178982D4946D6E968EEB01CA7D844869EB44220E8E71236F901784903C0100000000000192737A531F302A803624A0B888C55121F214DBAF6B300FE76DF64981558B49F4020000000000010AE3F3AFEC85031EB6E0FB2226818250BF20BA339D900B44D93E7C600F942280030000000000010F958C5BD8719E20C29B923A33D53A728C56602A181BFF1FA76DA4B45CB58D4D04000000000001D20B316C66BB61F992D5716DF5A5C4177FB654E362C661C16F1EE608CA6C2BDB05000000000001374E41D58A8E33A48F5FA6B7432DB7603E07767B3995B2C17C7FB16140C685800600000000000190FFE7DAD512868DAD7367C9A99404DA4A67CA8B5818F161F32970780EC146C40700000000000172C32293501F9EAB280F18B54FC472C9EEA0CBBAB14E5CFAEE3ACA59E955DA1B080000000000017297F325C0632D162BC9EC5DA3DB47673FD35A5EA4B618185A72DF8F11E7D933090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001DEAF54E0E1E211C80D56AACEC8C88A07A1462DF08B61D0ED60E7FDC8228AA00B01000000000001F42645121DCBCF871281B35BF017B4E1E16537ED183763A4F1F32EE524EC768D02000000000001113CCBBBA4734E57BAA78619199D764EE18AE83C9F18E4292A480AE29B4BC0710300000000000140E2BAC01C528A669AA060531E2E0496117E8C3493E5FC894784546EC2580A67040000000000018F224E19E61C8A7076585BF7780AD32D73D04D66A52F0B4CB6D35D9496906BFB05000000000001C0F7248E24BEA5635FD0F3F3411F1A20316CD29E2BDE6DCCBDEF8AFD463CADB306000000000001BFE2E0B4F4BD9B2B955C3CE73D4D0E703C44BE5168224D99756D865D86689E1607000000000001EB5D1F16948BBDEB3335E0F93C3DAC5C3FF7DCB33B16BB28D3826194192729F80800000000000194BC268989E8C957203F60EFD29089692A7FA0980912BCCB1FF3D6921B980561090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000057F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B832C73668D17AF4C29F2A72A1E8DC0D74C9F2446DE7A42F50A5DCA2F12EE84A91F75004E452A4E5FC799176A42B4D0A0A0CDAD9B44CC246872114650941B08315BA68E4B39A713B08A66F1715FE9300E5AAC533E37AE289B74341BC1DC7C75725C9838412E48A4CE312DEBC345B16A3A1F6388F350997448653448F6C7C91B7BE24118C3A0F4E431E88766E5A6C6113C8A2D1D2646B5EA5821C90CBE2CCB6CCA00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001521B6795E3B31C6F469147CDE5776D1FAF80EE268B570DD87C1895E195F358E50100000000000135050ED1EAD3E799B63D5EDC01FDE9B7E3E8036A429C0AB56C909CC2B6378D6F020000000000010D93E097DE2D5330AA792D234007668B3E7F9E699621D298D2AB7577E8518A0703000000000001F2616B47D5F8376AF6A5FC658A75A52D032F7A1710630905C152957F41FA240104000000000001806EBD8412403D61AFCBD000376F11695F17BD253F82340C13342F750D09B2D205000000000001207581737977FDD59550FE1E0E62692061E1E37C554529C52E427434D2BC50AD060000000000012C3C45D74BE1C78902947B902756864EFD771DAF34009F91281FBAD0636A74EE070000000000014DC0E1A0DD7194009DC2FC5355C4D62179DA0010E19737654D7DC0E4C9761DFD0800000000000112F03C455D30919DCE22D2F8A0D4B5491A8188A32F17059A6AF994ADE911EF750900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE59F8968E30E844A031BC745FED8550EE78B1266A91694B967E66785403F9FDE097DBFF047A171318C43FB2472127512463FA79877B475C7F810D28AE0BA7C5966102673F9F55653D9E546E378D2BB17CD35FAD2F50C5372DF7871B1F1DE78A72FC84F2AD1BACFB45712FB13E3773B3565B021D30A31602528EF16FE6D83795A1A8620E06BE25AAB07A8F3F1EE979687840B7C863D0D8A547A5F7197FB72024DA7F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011420B60C54314ED8291B4F251FF32674EE6A3C3609140380F6B20865B7AE643401000000000001DA6EC89DAF2B01E86C06ABE8043C9A6EA0562A18C49B4A9497D347FAF8EB910002000000000001A0A42481338E08706BAC35F7B5F5D93432D40144F47A0F6790DF4B68525ED740030000000000014A9507DA8B4941DFD3D5E9A02EA050B97F9887A65D93FD8723FDC30C7E2AA4E004000000000001BDEA75F9BF80695B677BD7E643AAB0D6DEE791B64A29E66D796C51176B9F718C050000000000014F174AE6AE0AD2D1C856FD802C756287A8496B907E56C4BE48E85864F71DE7160600000000000131702A4AC2D7BD2722AD083379A254918CF9EE0656A5DAD6B07C11A74BBEC85207000000000001C2F54B401EC9CFC51F249ED76CF09A24665D8603D3747E67778075CC7817C4D708000000000001A1D56697DB12706AEF7EF31B1584DFB73FC269AEDE8C438FE9B6FE17C7A659860900000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164A3FE6DFD83DBEFCE4CFEF2250893E21030934A382A288C69BF0FC7E9C92280906A4BA331C652BC4F904B9B54DCF3DB0651E43A6C83FB9843F85F0DBCA8D2E7F492200039906CF62A95D7B1830FDECAC0306B1A98B6F7B399E406A172202E29FA157E168F4B9C6979150F5AC2EF7769E4A729B6D59DD8F944E9A4A118FD06355D19B28ABDF256B4390DCD5C098DE989678AC25659763FC22E05FC4EB5860F4532E1EFCBAA0ACFCB91F30D21D2C90F8DBB5B419D8771AF1FA14AED614FA2B5DAB9F6F85016293B0716170A972790FEA6B0967F1FF1848CD29934182A9DDEA9BB49DE7B0A8EE13DA1F0A46E2376820EE34C1CA84E4524F21B5AA5FF74310EA831A3D3D08BCE359B830828E376B3C3999A9AC6168ABC74DDA8FFF0B35D6CD022BEC9BF0527A743822DFB79CBC96A90B6CF80B4E244E8F4386B653AF3D322BCF1E00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018BB8E296C7509BC115ABB151E123D4E0343D51087A3A7321FD6406381792A7DA01000000000001166966BACD855719FD325B6CB7EEE8DEC0ABA7479BEEC9A71F451BD9EC1886B002000000000001E480EE1888B362F2F00B536DC0FB57F3AA94097DD543F05D299341633DEFE5FB03000000000001522E3D23E82223C8085779A58B7ECF45EB835F4B8FF5294923C95EEC4FCA50340400000000000175597A079FE64BFEAEDAB8F7995E5E9F7C88741A0DD3F273361C01971985AC6305000000000001DF8A269F13EC6CFE6713B0E94D2C3B25A880F3BF1B34A76946666837A1A3FABF060000000000011EC3BD5D59B96FC03D21CF2A93978E5397521400E05C4BB2F66B8C53C5322DCB07000000000001462C4051C5F8F1C53FB2A73D731FA41C1CD97C3BE99C1ADE2751A405C95B683F08000000000001428C6A22C98B1969BB9E66F698DDADF342C585C26289E42FEA210E34A4C279A4090000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096F5B92139A4B5768CDF2E35810BD1AB3BB40DCE3F38853783F6856552BF95A4A835590582BB7206044086C1CA3BD9B8ADFB09C40A838DEE80E1B3756F98073651454C1567EBB9BB8D9FEA16E9CB0F30FA5E7944CCFE2732FB90178A6F439EF2C83D0FD90FA196CBBECA9DE1DA63AB609F53BF11303F3AE2283195AD62587795E7CE13CCB19132890CE25B085F7AE282F8DE315DED51D9E7B4652285ECB3929B9D6F51E82EA4BB5AAB4110925E014691A62121C27B5D929D24069ECDD6148B64213FCD94FB9EB6CA08C3D942DCB7FADCE9FB3917E40A455701CA8028A1456EDECC5EE3A3A27DE819CC28084BA0BA992CBA7D3DEDB39B4FBF247D2845FF9D4B455F5D29E81C17C5FFDEFFF7CA2153F968A130EED46293DACE1777C0173B089DD2DC63CA91C994E506ECC920E8A96608FB6E4F970A59145E77CBB83D1A5C22F9170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D10E76AEEA90CDFF9F15085B0834F5C0339E4C86D2CB52C234F6B18B472E8A020100000000000195C0CD14484D08075EDA691EE42CD999A552CA1A62318D9765CADAB553C1C5B90200000000000157A8A577120F2AD134FBF0E0E061E38A768CF935F4D2AA9A541C7A3D033A991503000000000001A467DDA3824B40F0D0D861A12328735CB8C23D1726982BE71F4CF68EEB492550040000000000016C6BC09F7073D85882AF0A9B60C224629A2B9BA3C0F3CBCBAD527E4DA7B9C003050000000000018ACD5F94CF14BD16B576FB1BA005CBD50AC4B03D5E54BAE131D723BC35FCD1AA06000000000001366FD19DE6022FE26A5E139A7E119C7045423D56D1C83861F263D7127DE85E9007000000000001BCCB39DEACD797170E9D863E6DD42F7C8C9B5B10CBB9130E84561B98073B1A57080000000000017937AF716807E93101BC400344D3698048E787D2FC6DD01EC7629B28F9D3F51609000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB931516966BA24D9585F1C0B04D660E629B3A2A3F31AEB6AC3EE8DF4DB67DABB5C332B61CC10887A0A207201703DFC4C27B774468F2CD9C6EFC711426E248C33EF946923D4C1AFA7B608F9F080410AE8F9F08CB38D5C0F6664EA0F630D34DFC55462334F617F3E4AE640E6C2D27597D4967E08EDC91704B9E3EE49EC4F0506994C3DD1027F8BE7FC46589CC21F9BEAF4F4130BC7D8325FD638235372E12CBB84FC424BAFF7D301855839698FE2E38B63BE461E681B43A02F99E466319E808084BDEFF59DC9DA0BC5F523A21D4525D81501A83F357BAB3633C061D403C7ADD90CBF38C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A36918612009A7CF4A981971AB37B767BC120AA994494DA75CABF22D1FE63F1464E981A0FF2BA93D3AAF2CEEADAFCB80FB7D012A588D4E409051A44F7287EB74B23A7F9A4302D2E7EA81F9FFD74D72807123DC3529B24DA2AF50619784A32B75985FE5AF8191B1CCF65322E266C37555CC3A971BF53E46DFDBC336CE5DAB6A84AC0F17F219C1DB9BD42A4F9662C74AF602347DE8A4EF176A34EAA287C9615F90FC02ABB78D80A6327768932976729CC4BC564E870C58EE9889C877CE31BA913EA7E454C0868D80335CC063C57D0BC1FB3C5E09B3A20F8166F8BDC41B01A8EEB62127C5BF88686BB8D0350F7BE6B56E0CE6E66B0998140C6F839A1AB13D68EF718809E2973CBB24BF5D927E83DD6C16C292D94B6EFE4A1BC9E050E8D6992BFD1C6F906C0A7B81474293A86ED095FD785C5BBA70F51BA7D49E9A5FFCE8193DD10914F642178026F159AE536FC1FABC7B78A3C2DF55D0C8E1EF23883C6FDBC053B447825E75F945D8157A967B58B0574C6E0615387CE1652DC027B72C45A8E9A4287219D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF71E8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B1A8277D00D5F8C835AB2820DFCFC4C8AFB2CB247B6DACFCDFB3765002D7D6EBA358848E7C7C63DA066252A81CC95E38A556ACD239ACB010A8169696B347EE86AE99CC7386155ECC56277B39192742ED8C959F142209943A017FBCE130FBDC3A491E7F650C98DAA0497D6C9CCABFD02921ABE4CFF254FB1521C702FB19F3DBBA1B691F7E44003C618C1B0C1B68A840B9763D43295E0CB779A59EEF7ED63AA1020069B2EF88BBCAB1D03693FE34C4C497F7936878D4DAB7B75BFF0FD8A0509D9A3B0CF209C9B7D09732CA0914617778AD289AC2110692D502C8DC75316530280FC926A62D46620A91EB4C89377C47ACC72884CAE39545022290B0D0EFA74045E4FFE5B7950E421091808852738371BAF20E81ADEE43642303C0F979B8EDAF4B47ADFB135B60A3E4F0BD2340A03D9F774ED36135C7C7241A89B2E9C71979E6BAA1E4D272BEA996623E399F2DA2AAAF6D0CE10191BA0853C08743DF8F9C98575E4F398BC3F19CFCBDB00B6C71E6B2B86A0E3BB72811DA873A3A318F6F334B64992648C9DA43BE0DB9CBA43FB1191DB64EA575DB1FA7F5E345ED532AEFC9F878894723ACC25CFEA3765FD8B4445453AB184E6C5A33FE8C136C8B401ED890A840BCC8C13CE2560D86119D74B6258D4381A4813572B6AEE5DB91BFA38F1E36EFF3DE17E255F8302A3A8161AD44F095659EEBB8E99100B7A19BCB8842ED58C474D1FFC28FD87A032D583050C09C64D4AE5F937743FC5E4705D9EADC758DF2CE55F240A40267311278E9198452030917F0ADB64226D6D413BCCB02C9A5C830AE5F2DBF73BCD8161132CCF43553B8FBA8E5283C953AEE50DDCE4EB59D29E4A2E5DA0530B922286F3588848CAFE9182175706266C466D65F41C3C18B000789C74952E3E2FEE44CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D58C6E04B24FDA2C3239210393254B41DA390EE357C7C175EA1DFD32FE5AADE666337542E508FAD05AA818E37539322BE1320FB587B83E86AA18434C47CA39E9850984F7339BD164FD46557BE86FB71B18CCAB5C34449AA65150D6F47A8117453D706F30DEDEB127BBA56F23193113CCBEB626F61BC4EA2D5053B489414A7F9731010D4333E72690C936D00367C343DA301A455B4CA7DCFC4215B0EE5185F1DFEAD2F09542D42C8CC1BA6ACFA452C6237454C5D115C0F5E04479131F9F1ACCA098EF0ACDFEF6FA39E4AEE14B0823E911EF2DAE145E261AE05A117E5A52E9DEDAC73742F90B4EAA8AA944F14679B0F72AADF6B56B31F3A2AA0AFA243C3DCCF6FFD2799FFA1F9861A5C04B0A8F68CC1BC8C90703AB05FBE50C15F06B04570370DEBB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832121C0C078E6BA4A80F1A20BD16BA90FCD04D43A0927C164582A796C12545CBD0BE45745F9E0090A47F31AB9B11E1496EED876912B13A841C06B6A5E812B11EC912A83D6B8663FBA403442AB4C70D3CCB76BE6686CD55D831E8DCCD05594F47FD58A835E3132D95EF4B4E8EBC275280999BF68305531A7F9F5EF2E8ED77C42227D0ED07B337CEB70317037ADA07819791A04BBF73646CC89806912EB3E2BABA0C80C7EB7BBAB7CE68583B609A5152A39457D51EE0A3CB4E897EB6363CB767057ADD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C63F474F26E2917A9A1B025C28BAC7D53E4E150E981E0D5BA4129911F99588369CD97444E871D47141AA795560B9576AF7870E3F62BC6F010869F6CA393E48A0BF5BE7ED218D65D942EC0F815F2258A47F7A509B6BB999C17B28D46B7D3CA59061D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C09FB9C3782471D5185D98077B9CD560F0F2D8109B8F2DFA711892BAF0A4A828E506417EECDAD332975E49F3E9019CE173E2ED3985D7C241AB4F7AE082E8EF49FD6E7D8241F8BAB4D68DE3288296539D0DDF68497D7634A964B76E82AF13767129B7FE5BF4C85685F9C1649B8A52FCBAA9B2AF0C0C2BE1904DEB98ADA34507734E7937BE5E686F6DDD4E57D5EEF9FDC2164D60CD06AB5C9D11B840625837703C3CEB44B6542B684CFC5EB9B3297D946E7F698FD75C5A824EEA9328EDBA65225623ECF3B1F560C0D9DD03CA404DDEB74F901FA06FF4D2B0972C31F94450036B01DDD94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB0AC0CF31A27014816177F79DBE703195F44C47205EC4A5CBE62146B5246AFD86660BB52A30FCC16AC9D773E97F581C7518D007FE0489C09FDFA334F49313FAC2B579C7AF47F9946A85247DC902ACD5E0B22949F45945DDD51DF6AB0FBC225603D7377F93D29F2DF9500194E614F93DEFECBCA3AFB03D22F8FD7661D9D41D62D3F34476EDB8FE887C37129998A21E92F020460D3AF85356DAA577666F5DC0BCC5986DAAF87F5A9E602BA73B7392923FDC5B81A6BAE67BDABA7F7D2E9410D160455BE2CC6A833BA1B0F8FE54852A576BCECECF9BDAEF1C9B426B3DBCA32353CEF2D782F9FF8C8DB114C65E259BD077E800BBF0AF92AE1083501FBCB6D736C848AFA2C836F2E20EAC0336B58D10000EE1E6FE4AF2C87B2DB73F0F695508E653A3755D0CF17516575A25E8960FFDB7B1A00FBED460A8BC7EDC370A52E214885B7DD496596F52B1697C11D5127906C27EEA91E5D3E948E752D54EDC1A8284B9330F1BAF79C2B31C41136602FB4D1A7418EE586E7386677F90D185CF9D61FD7178055651AAB6AFAF6B955469C05B619297155F922B97B7FD28FDA0C0FF3BF34081177EC83DC0433EFB8A1417D60691D76E15384DADDFE66566032B722D99F959653F5C68D4FACDEB4DB5F9CA52CAB9D78109D66D75ECA67FE82A790ADABA4C8F8EDC5663FE77361E78A43189D2B89D1F26535B1E860C9F18E7A3BC6892A68C68AF96C1F4730192CE3BF69D4E7048912FFAA309913C054E041306B4B0079D606F9EF3E08020379FC3A11CE22436F7C8BE6C5F5EE2C1C1778320456C18A68F306AD1B55954389F635A502169454E7C432BADF0A68F529903CA29C2B836DFF01B67CB745A77A9E7813A52B92C810B51BC3E71D7AAA9A9F31EE4542965AA0F6F9907D1595A31E720D4A7098FB2D72F01F8B83BF3A93D05157307E2B595F0609BF2C8B94EF6A5D60E53F20C1559A9476CD2391127B12D77357269359C424A769021D139860DCA4136B718B65880234089C1138705945AB76C815ECB06C01C73C60312FE6DE218F09C1607F528CEDD2898E077008FF6E47C4FB6B2C103BA92C399A24CC38B373B3D7F00D63E6A42412F710C62528106482F703ABC7CD198A24723A6BE730E6DC971D468EA20D76800F938E651FAFD425643ECCDE70BB4DC1D6FE4E9B3D3624C330E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD6847C7DCD156F805A9A513F17CFB60F16925F4C587744E4AD35C7127757AAD37B73E5277D6614F0C315BB9E3BE48F654AD2D343B3967FCCF5387EE8297F2F74214B7B154E1D715C8FEB898A1DA31D5A8ABAB9CDBAB991459E62BE9F0E0A69791265ACD8F7AEDAF736FB944D3CEA82A1B3F23ED9AC0025760D260009668580A7FED8B073D52EB9D1847445D2064669D9E03116C2D999F3274876F37552E2D8A04E4409EFB415FFD9571BBCCFDA01333286A5A934E32D7C6D7EF3A20DD86ED5391AF91188FC2BBA388067FA443275DF1C06B23BEBEB418CCF1A7CA0E4BAD57780AD7D5528BD18362F273F0D97C081E502F32EFE1508B343268F1D2EB3F12914313283E40F4EC9F02AA17AA8A310FF50DF2712F49896FE31BA07A188488E45EB59D6BD6B858D527BBC0892580637EE631FDE8EAC14EDEB1E73EC75C8C241294EA628DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF47606C4D632B57BF57812D2B2CB85C631F239710C05C7743C2F4515F6C64CBBC8109E7FFA421A5A637256FFE7F44413BBDE5787EB92060591282ED69794E9D64356A585D5E293E705EFC493596D08F3E68CA984532F71A20D81C4BE0CA989A19C2FC268CACE37F8F2D5B481F2A4F387043A4715FE805C6FE2D4AB89DEBE10CAFD406F37450F0E477859629CE2B957F3415CC4E2CDB795EB766193DB9CC1E5D34B022FF9C01B7ABAB66A08EA5A0983E6E85954C92A6D3B2AB9D45BA49B21D45A3468B53440BB45283D3251613D162A9CE508A5766740BC16F13842C2F89F2396E3363A1934E3AF2E7221957FDBC5F2BAA72B6E62BAEB9E6D33B248A5102714178A60CD3A02B6E121E1CE591185608500C11AAAEB039497472C12F766386647573D2974687D3B63D655D412B1DC0D3084791DC9CF5BC4A42D6D3787A187D4765E5C65894BA159FCFEE27FB3B36A54A9FA312C81EA09C6762770B9649872A738FA0111D745A1F9A0BC53FA819D6E7220FB07293058C8EE51270F86D956780BB52984745B68DA948F7F936345F770F38661F35198D5BED466C3E1C7A23DD56D543CFC93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B7871339ACAC858B546C9139F4B917CDA356F04B779BBF803351C1B452BD9EDD0E2DA226A5F930C3C97F43D4633BF11B8BCEBF646B8608685E36F0ECDE7C7FB5F977E4D61038C745DE151D832D47C979224CADCFDB0C82650055F1519B94680A840FA14B55B2190C71AC1F7A7AEED989BE8C8AC61149A0C809449B677AC353867D0185EB15322792A3A7E328FEE3DF2230E4B70551FD7F9BD57BBEAF02E40124C58F019EEB66602B9EA10094839EFA9070F5C2DA3AAB6CDE6EB58246A59AFFA0352106F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C013843CFEF1EDA266283A5CE4A6ACD7597519FBD097E9E460D9B071D34EDC61672D14E6D9D4F9A033B5B473A1B13476C3C447E884455A5D168DA793F9E2F09612A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B2BD0A2D4978F82258687586F9E6EE6AA21877D8A2C7AE37332573C420DB9C8754CC20EB937A8B94056D96EF571162B0106AEBFC344B5F28D52B8CD02F6168F45B321639DDDFBB333C5B872E80370F408EFFB5CC7394767F8CEC0CDCD7C9189E1B24FD29C7FBA4B14F30B8F5996155855C08A749B6AAED58C55271223A53D1E8714549EEA65B9A9245D9F5AD2EEBAE82637B9E3C78A24B5262873759CAE9AF9054C3230F88509E71CAE2238AA2DA1C25F0DCBFDE9BCC7B234BF1EA6697DD4E8B020B099CD92492855F1B528BA0B359BDEC1E77245432B7B1B2A5A7B969947A2FCFEAB2E94762E2F3F524E88E6FEFC4DBECED7EA550E6BCEDFF229E69D9C7C7803FACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E9847ED6D3A7874015F0AE87EE37FB6C478F7330A07D4C59E314847065E2F1F5F7F6DAE557F85B03FE6BB31B28A40263B64218FAD4572BC5FF2FD4E3F8F9A8894795658466BFB5DAFFCD99A69D532713CE072D81A42045933CDD30DD257F6C9848577D9F8B09B5D7BF71CF202AC4CF296E05C6A7ADF77D8FC670B88DAD02DE5A80D4168F7F72A7252B0E421F9734012AC8A8188677647D35ED6199EB300A6B71111D7CC77F04AF5E559A0D34CE1E1490576716A861E79902678C1241CB6F614176147ED88C82A99CCF2BBF62AE65572300CD4FB12DED4B6B0901D5F6BD02F036BF66B095215AAA76BAA4A07E2C0CAD2B2D76BEB56956C26ACDC11FDEFE9D42C6A698C09F0ECAC502F2F7E00233329DCA9595A191DF6C87B728E8F9B59105B9074992A62F2DFB38852C7F4BA5BF782395E906AF48136AB2DEAB4BBE7F0F79867696DDAA4176F14C9DC7A301B0DACA30332F73CA3356A62A4832A12DCCC3D696505F59E73148ED6401A34F6986428CB1CF18FD61DF1455A042455FBD97A76A404E65CD0BF41E26465281A0BA11EAA39CB48B99F2354BF5407629727B52DBA14B29C65083AE8B8891AECA5500BD15DE9E66E7D5C0104891C17A108B79D8D96D35F12170E2C930F8F16068AE3CA8511016203A1A4726CFEC7B6AAC959B67F3FF1E4AAEAD667487299703D38472B5085FC55B9BB775574AAA118BC81076CD53A4AA7E927482B1D617C09C6C24DEB07DD41C2C42B6A0BE168493CA5A40266AF5B992B9B2C65CFA82A2EFC515948A5FC521A7F49DC4BBAD296BB6FD4AA6FE1B7A7726229C03DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D973867CC37DAFE8FC39332DFD321B1ACA45587EB6D4727F5AFEC4178CDD8AF03FA0629DA84844B5131CC2AA07E2FBB8F80D3320AF5C1734031AEB68DB8B6C7358F775E8538C260FE6A79DDAE2BC7D40222B2942A2D8ADD3F295A135B5FBBA319FA3636F56D1BC8CBFA175EA61C1F53980664282E56291B4ECE5B5FF33C2141F04A3FF83EFC062CF6C635497FD03D6E56E405C43C4A31DDE872C4E277AA190D1D8350A298F16BE75BE305891F9D1084146199960A881C34318CFCF1366E82A487CEE95D5EC9F9756FFFC9DF3A1058E367160B321753C937D587130F9AAC766C19F033CCB2D886AB532683F50D360D10DF559AA16DA2C0E3203337B46EA1FCC1407675C5057052EDEFFF36BB2A6331522DC5CBC871C52CC35E95DF677771084A6E3E10A56111E6B9F7DAEB1FAA11B9CE5EA450A7D75F2B7266193CEA51A9532D8A32A2D4C275ECE75C3A59C3F02E3F9F40968642D6387F752C801A761F121A3EEF4F6B0AB83B7E815E5BB9D67EF85BF9DBF72E5E6DAEF4A6F7519130BD4F826A82D23332BC291A3D320CBFBE4BF1A143B78FAF7C1BF61F30801BCF715A05F2F7429F0D1A3B9F90D191754FE3D761A77CEA46082D3D2CA5BF26EF05257DBC8B72D156920EBCB1E064FBEC3CA43AF31CB2A53B246BA02E3F8AD4E07DE794CC1D8E3814DE61807A116F768CFFB159D16CB7214EAF1F52452B768380F4E16E2BCC10E82A027148477F2C717844DBB1677D6F2559AACA58E4759D40C7D62610399D6EDBC6DD4DA7904D2C53E4D9E07928FE181D503C5D45D6DE07E767025D9B0386F8C123C38CAEF00BE2223E8B1F46370B1D20FF0DBF78CB6A016D0F72F07820238885D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3A1E6EADFE7066FC6A5781AF310597B333977E34D01483A860E7D986357107DADB4F5D040550E524D9D1AA456CAED45FB5F6475160AB01C8AEC46EEA735384E4FBF205BB117F68C03F6D301E5C469033B05360DA23CF49DA36E050D627B2067B30983B2B426DCE0B78C0500BD15B3D2572537DC9B5F0BC0E1A12F533F58B2E21102318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3F5C33BF53D2A951EA7BE7FE2D487362EEC1DCB93920B266C5AD39FFA0FC6D4B335B1355A6D8AD3CFE51E9F69C8961A82831BD27F727C9030A816E817783DF89B519D6EC14C9CD88B73FD6152250E229BC6CD8C952777CC5D670051B18F5AFC99860FF7387C5880564703541C2883BC93C5C0EEFA57AF9E9D9D04EAB3BA87782807C37D299789C60C63CC2E86B5610ECA54D3949E17070B1978781F705E32042AFF28FA979979A511C5D14ADD08AFF7DDAE858415D7B0CBA138BF6D1C72C99A9564FE6CB5C9ED554B98D21CB796FC053CAFB4B3E8214F44643C99D9C92EA847A1B6DF3BC21FBF810F9D04B26771BC6DBAD0BDE30265D402E62EEE8ADC84CE8AF0FECBE8F68D13501515B8C28F68AD45D9D1A454904DE944A90C7500049FB74979AE952EBDCBA09DE543283CCA44D3F00EABF99DD714B8FDE3755D30105AC8CBC4569789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411935E2773E3B03C5E4959D9A2F7D55B05B8574768DF40B5EBF76FCAA69F463E0FAFC9F02B01C7B89C1AFB661B43AED07A9D54A6669DCD9022A4EA628CA69577EB10D3E331C300BBA084A239D762A49141F81E46C97BCB157E81FFD88A34862C07F224E2ABEEEDB7E701AEF0A2FBC73A73CCF9B88E0606784D0BF4E99D41EA993B5401881439CBF17699A62F3D426EBD3681942C7F6F7B40835A7C996B400565E8BC9E636698FE0B197B96767C304CC366E2279F19A9E76B8B549DB73200EA7B3F788CCA15EC4A56D86CFBA4058C3C514F3154854CA6939229C3FAD386BF62626211CDAA71529B5410E08604348A4FA025A71894B946DF27454F27BC01996F23C8677C11780437BBE7131493B77D15C667AB0012BAD1CED0DE088C3D83795C30A3E34C878413680940B88C4693DD69B53E014174D8DB87EA6138C8CA99800F4F93981189912022DDCA5B6D5AA4DD2E04C394191204492E8CD5BD3B1599292F066E4E9D5917ADC3CF954851323255BB47D6FB2B0B6E93D9C2E39E23F7F02915149F9234FB2F13E6BDE58B24DD23CAD19056B0F92E3C1449421FEB5A740C7BDD04C76D8C2AA84F1BD9CCB562B9AC66C54ACC986BCCC869025339B9EE0CD9B8C0D7025B3662F8BDAFF77D6C77324F336C1A5276F7734EB3399FEC4A5902AA5971A933EEA9AEE40BCF69C70168BC10F1E9576CD541325A8A729566CAD7C0483ACC8E23D17DB2E495CA46032D9EAB61DFB6703C7C06BA4FD0513B55B05512CECC642CBB9D75AE94922FA66546C306BB281A106EB0D25D4156DD04911DB499F9A77B8F8487EB0287D9D564EDA31C37DD33E57A8D5A33C3088F4269E28E87145AC781DC38A75D575DDDEF448BAA06A60E54E4F6EBF94B095C14E36CDFD29B45BE3455F1930F39F77150E595CF127D1FB7E8226CA954C355D7098E783D32A41E702A611115154F3DB1A8484E4C6A81D13632998E75BC4B868F7E6178F035BF1BEA7510E3A823DBF976A0741138D1D5C9B2B434076228B7C3DAEB0576CD1194E82E62A8F902F9C84A1040262E83913A179EC88A1973DA20CD50D9676DBA1B8C036B97AF2C2005F1F556D1C462DAAF0E1E720B728AE3A7187F576F6B19177F83CB2953F058E0573D795A69B4C72365CE904C9690FAD0ACBC12108D950BE728E935FB7FE0779C54C8C0CDED49F111DE5777AA6131EE9084796DDEE52FDD7567A66ACFC8BAFFE19F46D0BC02258E9CD605176480A7E11B2B7283334B1398342061098099C06B1DB47A027B6577055A67649E98A0AE2E890FAE3186EBDBC6962257DCADBD50352BF17A03933D6BB6E00C1AA62CFEF7C7834BB0705A50205C4EF8D3270C4A0716A593858D31D1B989FA57C694A39CF877024ADFBC5FA2386FD36B07BE137723172C0E08CDDD0185E2510CAA4E4845ECA6C9750F4501FEA182D7748CE3BC2C902DF532BFAA83B530C214A5C649102309116DEFCCD338D8AB9CBEC500C26095E4BE1521964AD4694546C8D1F3774776C0595E0ADD0203F0FE1489B43ABF5FFA96C25138D539203E53FE2EDF38BA68448A3520CCF623D8427DE666CFB05E0BC25452E526C7FFB8D1DC496F047277FB03444CB5ED7342FFA18EEE7B1730925FDB23A34CEE84A5DB13C4AC46BE0B0FBF36759DA3E7B8C3289628F7E8254BDE347A1267A888D7FB18D021FC09668E7DDCC0FE714DFCBCD73AEE1395991E44B423F05043F6094F3930B33ABF6EF6D5AD18ECADDB1B477C019334C76E553210D4C89E4C32DB105FFEA84396B80DCE49EC772FC586D65A0C6FA012888B314FCA5FE7D56304AEC2B6EBCA87240731E19F8A237E3080A5B4FB92BC823AEA37AE3886609B5E4335559AB13257E92D2EE60938B3FA1A8B15958F8340A6062A0045C098A08D6A78F0C8806789322017F576BE2590AF4AFE35C2C1DD17A4EFBCE7F65B7FCED0A56A91C2D5724455D0A7A4BE1A543451792BE01E9A9614C6026623E730A21A5AA1B22EA38E983F1CB3C6AFCEE94FD813CE143F84FA32A70A97CEB20BA50BEA097D13CAB9F0E7032D052D9D9903A39F07E56690711D67081510427FE7D665D64BDD70EFD0215C6EF994CF6FD7444DBFB51DF33FD88A9B2D54BADC321512B7B57AE2AEF89959050169E710CC7D38B011611B655BA781A5B3391868F48AE12EA4F0D539BADFF7D81270E6847C387DD76569E539687B1FFF23F0226CE24125D85D229804869826671E44CD3B5942738E53432EB5267B1DFD7C80DA709A3E6ED28B83E10721F4D08519A3474C951803C0172025BE77A6CD8F5F9B9E09ED8CEB187F381D57F893F96E78A10C1AE29A306BE20246579F74C2AEDA46D2FB03A5A08C152BD736C93C7450149AFF1C0505E34E48C193F046647C61565FA6BC99044E7FCD0488716774CC0371D9ABC47CC69C415AF45B35FD240661DA201D3906863E1E0236A8A0307E854DBF000462D7217090E77A43FCA84061F881F71DC197BCE1D6B518FFC25A3E4926F64229AFFA4098F5198DCD8BBD2F99F95453723D6BD04DC5F2C732970D2AE4A9165E3AC8C8A767F0BA93BCE6F76F1E4A96D167E9EDFBA17A78E7EB3015E158630058EFDA8FFFD9D1B074C8ABE07300265DBCF6CFD550047FECFDFE05721DB0EC4FC21D4C675B7387B6D524DF052BAB92912B6DFF155F00462AF058203F94021F6388249475132A803A31E55E366AD3935EA2D7BF1FB0DD9AAB9D494ECCB3B7D0B7663374228438E11FFA2918324BAEFE443FB17B1A1950B0989D5B3379A13D82AAC83687BCCA2358DE7DA30541EB84E75DEA2D27409E7C02131C1FEFC1E02CA55584FFFA7CD7E8B6E2E2B7B685BB96710B6BD0B672334E8902CF6D49F47CA682E4343EB5DD588B7E61FD37D1972BACBC77C27CF06218B51E82E000185CB9BD13F89E6C3AF38596F181FC8A31B68C8C21DC711EC8BABA1CD7E812B4D6C939B449251718439129B95119BC9BE22C5E237B0B083582093D9DFF114C0F632A0C0016FF3A53167DB27B2F226A2B4B5EB7A409915DD46A882362462CB5BB7C3D2FA7DFAE5EF6969F34FF7E1B0958C4297CECDF374312B3231354D04E61AB4B668921E65D7ED31AB5AA46E5DE9EA4F5243CBBDDF261FCE1BCD26DE90FB46AF94530DA62C28D019C7BB1B7D245E3B773871F0871B12ADB9306D31135B241A8E49D6EC6743C95469C24DAB5CE75E670357F3D22481C2E01E30215A0538DB0448CB9340D58FC633C9CA5141CFD79109D30F5943DD8A69F47F49C25E89EF486180AE64497FF2197EE4D518994942F6FA35BAB9D747CB356907B409CB427788C3D7708D77B706D9F90FAC25E492EB60F2DFAD94821D05D8F5721D46560CDC2E43963F70B64C7EC230170F2221693D7FC10B0F27CC4B154EDA86B74CF82CB44EB097E3703FE0B938346856014A50A106F64B236B17DBFEBF2B455FBB9C999CC1F9E7CC7D4DF12E1EC6CEC249345EAF4DACF0D38453A533E5193257BB55AA785666C64B91491B0A5DB93688FBE07D66D926759B669E18521210CAD05EF3F8972754DEA64BC0846516FEB472ACFF5EE2D7E29F7633E32E1A91E5DD713A56AABD6ED1EB967F371FE4D1A7EDF2432FC050A47F34300DC4B69F8553FA4A23509A45977E62736EC9653A51FA687A30FC0787CBD6824BCE36088AACAE7F55D877F773255A13B3A006CE4D2B2ACED5C03764B81B9DE5D9E0EBF9230164C5F75F05C4353F64A182FA15948C9BD8D89E5C6364B84ABFBEE413D0EC4D3B553A46B63FF0699542A2A7ED568B6E8A9C2C772B4F7F7FA17726174968E216636B4FC547AE59D73DD40F320D6B3329C868728B97CC704859F851149108B705C39AF3DD97EFAEBD39ACCFAAC8EE1FAAEABB32E689063B11483C47510DA0DA16B02EE4E397B146B6F777B1F2C393379414F67BCE670BDDBC67BC8ACE419C2E48C5B57EC624C5693562B719C7E696E1C83076E0EDE8540DE3D7AA00AC5A50E481F7BAA41C43A1C2EF09100EBFFE5EED9FCC095945F525F66ACD9A814582D6609DE9FDC132974B98454B501DEAB673C6D33AD29686E1D43912840DF6398F2468C0788D1D3B597004E6BDB7A89B57DCD4249EB51489F4DDA36B0A3B90C4EA616135B089C4D4B8DA02E695EB8657B2E12FB5554D2D833353A3FBF3FEA441A755FC4F0A49C243C3682A20B04AAB0EC430C9BFA134C383E4B6FD45DFB613E362B171F0C2B2473B38E92A21C72C100505B3E2ED5EB14D1ADEF650C7254F5163A2FC01B987E3000517DCD878B3D9268E912CA3675000B10E53F5B8172477AF6FE3778CB0E5D279309245647970C216E2E626D2148795132C2479B65FEEFD8B38395AE4A34ACD06B005F311974D6197A0FB415D7FA5E64502FC8C878B14462F0C6458E04BE6DA9308697467937AE52099382FCDC35FD7D2734B1150C214107CA53F6EAC9D584AFF8FBC6C2AF2B711F45BCC5626B1FACEDF4AD03E261A7E095044665CE61C3359BA5A046E44C8E5506E2BD7D4F6F08B57C7303472AD0369BD7B5199525024D34A0143DE46F8F3316F4A8B93DC5AE6B02A0F362EC7F9EEEF5303E3C0E13246E0F214FC2843F6116A7986920BAFDBC483B7D8F84ACCA690C6FBAF794BAEB0B687249A360CFE9E1C0A2817F2D93A166ACD35C00A1BDC4B1AC6BAEE6588B0958D5C2A0D63E6DADD81AE2ED7B8ACAA19040E7E30E454D629944FD10E1AC8ADC8C0CBCDD9868B973299A4DC927C49E944C7C00705669F96557477EE62F0E6140D613B110B9FBECAF70983B17EC4A470FFA4BFB8AEDB435FC607B957898278FC2D33E66F68E1F630D4A06B6413ED8C2B7BCD931DD4271D12B29336E47FBB378D48A956DDB447ED3A2B93E3C3A5559DB3B18505CFD0AE9377C5F87964A89B20952F5804125EACFF6CD0C256CB30288ED1BA4324F9F7850AB4A14F5107A91C3DFF05B82D1C4E3BBE38B7C6380AD2D1C41621187066598C2A314A84E55E8260D78D6220923EDF59C8CB7BB6E5B6AEB96BD7E436D19DBCAF897D8A2B3B41D17163C52CCCCE010274A70B6B985545072CC765A499A3E4FA7388E44F9A1F9F0D45694EAF817A3A7D068D3FF6F054145C716DD7CE747D3889E49DB2121A81EB40E2E2D08750F1CCF791EC924ED46F3C5C741E57C9CA75D7EF3C821A3A2EDACA966CDA766A3CE6EC0DEA096870022496856890CAEE492ACBDB949FE0BD8CE0C3E72468318B0322F894C64EED64AFDE22A7A1C2B22B348830444DD5B99050B4D3976A70DED872E92593215ECA63D2EF78B901B89230D2C18BFB4D50EBC5949A090DA9D27C7B9B3ADA9C787913ECD0D8E578DB0D646965DDF5C5DD3395906A9C02E7F33194DA5A6583C198A7D41CE382A6BA5B8F9E52701B31E1987E7AFE0109391E187223DBEC2E516F103BE65BF0FF2141194836BC3DA9C1031A5D51676AE1914885D9CE838DB07F72B047AC46EBB3E1FC79AE2BA473FAC3EAD512D9F1D3AC2536093EA580F0384B36F8B798C8313207EA12A1E244F0B2AE1B64664D23C8C2D7CD5EFC95C18F4EB7B196F368F29D39578DD3F53E050D351AE6D93A40AD4915927D82925BAEB09E8A877AB1C6B704775C0EE210025CEDD475823479761DB3C8CFBDD9739754C743307E5B9E81036C748B79AB78D0C56DABCB9893147A5BF4E3655329E433A0521B08DE2BDE442CBE9A2721EAA94B4F9C0DFAEC4D500FCC073568B0421444AB51CE94C9489818D4C598C1E219AB50C7F7D914FD59BC96542C72BB3636746A9C08A4A416E7E581255FEF48340CF1D9D6C5E9832B004C0F646FECA43FBF0E016BBCCDE92C1CC9AF6C92BB735640733DC1C031BD10D554E51BE3DBE3306D64CFA148779EDCAD8AEB21F5FDF085FB1DA0BE2DDEDCD1B094810903D80BE04D1FBFA7E59E17069DDBB49EEC76320B74F31C4428BDE620DE149EE74DD9BF22FE0047FF71486E339072F2B603B8055D7BA43FD71B3CAB178F34703FDB8ABDD8F5C1461F89446ADB1175E35428091CC0A3B58DD435FB4D9B5D62FDB9FA0A34224FAED03B10B5FE70EA67AE1A3005D3DC4AFBB064A22AD6A9BB05C15228E1D20D4A4E8D041BEF83790E9707A581DBB7689E032A083381899EEF508E4B2A897FFAB447F821C848EED8CA09616CE2EFD13966C494E919BD76A7C971A7731B13C4601F7B659429C2F7F7592F4B17894BC1391235 @@ -11,4 +9,4 @@ msg = B338DD755D5618C464AB331F14DE3DD4A358BBA00D28FB35236741E902F7B248CE smlen = 14824 sm = 00000000000000003017CF6CDBA4AF7D6CA495B9872967AFAB62AB87100AA92CFBD66591BEE188E6CE81C6363BA48FE2B0D71D79936241991202D5104DF670AF8FD02AB7A23DE82E836BC369F2D8F1CF51071C04B6F9E53D566244F07B484199D4371F1B44303CCE8AC6CBDDD4679835304CA9F74433A62DF5524FC44D637BBAB3520CE625826DAA944B9F2B22F2D9419B5B5DB6301DDEA449F184552E9EF0F4B80893CE0D38184D844AC73D3DF74710D87286288BFC59EFDA5B93828D6EE2785EEE07487B1B36165852D62225D7554249CC1FE71B8CA3B01240808B769DC4154DB886DB5C1EF5B55644534E0F86ADE3417BE364CACDF76C0C906F64BD58A7B363C52870995A9DDE573341348D3D99C6759EE3444AC8A7C1801E45A8981573519B8C4AE4954C0AD861B94240759D2668D905F569E62A80D2FE7A221D6637D43DD890EE5DDA19C64B97C8C184673F470042729CFC1417C7D363B9EFD028AF65E4A1C95F2E6286AE6217745BD9E9B7B1FDC64E5A30640EF813AE0A4B46D5EE89A7A674E2D96BCE130D78727144332A7276950BC3A0548E270CBD4FC31004AF248BEA3BF61558946A2DDAED185C777160E9B20E4A823B470CBD2D890348594F4502BB34E2CD86B1E5C393B0896752FCAE3699AF03C2E8C8725BE6073251317D1EEFB497336A32C511CAE0FF66E62A9501705B04495C7B1052E59C094A12D534DA283FFA112C6C4F0F84481FFACD6E480671C8705E234CB846BE6A2323B69DE001457284D03FB6709B9A09BA06825E1A32451CA92D7B58785E22C755B2083EEEEBEB7071E62A3AC45C099B5A7F8E341A8CBF33A1D8338EE6696C485C3447024EAC99D174BADC9F88763968223ED5CE3170858485437C132229DB3823CF7D727E8DDC6B6BF00983947D021F22B71F638350358266320296B2E22A7495A708E30B7835A169D303A94A318A3D8AC4BADAAF808051A63BF66C7426CDFAD57168794CF4B50D8FBE4439B6416CC20ED1097E1670E2B93FA14EB1BA35D7B2C047E6BE110205B80B6F169695CDD44B935E0ACFE1323451349968E0E7B71DFAC15FC53E1FEB7E987BBCE964CF61EC44881F2AC9A8E607CB63D640D64C4433EE80CBFDFBCB0B822F192A053C5120DEA4E6B4D0E8F6B2040D9CCF85DA7C9522BD571EFF09D5B1561225886FFCD6B78810F452317BE7048D2C1679145C0E4F36E34D3A45169F8127BE584FEC80129C3DE3F2D9487FC2287870964D9F328563E36677622B3E074A980DAB585FF96FD09B7A843E4B2BA51E42D964AF28BDFA113E2853EE1051EF044C34EE020DBC7172C159B394DE8D15BFECE1FCE1884860BE12411A625BAD6A8CD7A99C157C62AC36B3DBF8805CDDF0CAB4272FFA12C062DF8602E4E53CCCA89F5A821904F2CF333CC9C4D5288AAB31781CB01B5D4A9AA378AB2DDE7F865F0933515DBA6527FA1C44C381B553342B5840124030F6004BF0D0C29A67C7601C0FEA9192B1434C362D81C65728E4A8CA6264070A7F1F09CD093CAD71FE3263B0E60C73F5F8641AFAF07676799DCF127420486671BA5E757D09573B0C09130A7C90B6D8CCDF578765B4FB0BA839339BB9AB60CB5B1F922D6C430FDF84A3A8A81B7FC0282C404FAD61A9AEC079B54A100E0E44DB333BCEC50007F239B57FAF01D826F08313BEB59A591A4BA0C6D26F71CA01814F9DB4CF438E89C2E99E26EB47DEF45EA8A595A177DA49A888B84DB5B399E45FEB575E3A4131D0DD98AE8482529815DC0CF2717E7B9EBC26524503881BFAD12C8887BD0D9C2019ED15FC5DABFEFFFBC6117388688BCD4ABFEC0610C27800BA6EF3954933656348BDE0A3D47C80581305B672BCCA2A235F654F01A3F8FD69EC9C4AD644FC10F73E8D4EAA8D202E38A3609D1034E9A9460341D78347A384EFBE009EE5ACD512C88DC34BB54340BC9B1C0CCA389E8BDE6AF14B3DB250101F04D29BDC7D2094146125ADA6A3063A0098EC13C0BE830901807F99B5155C4BB0727EF06F5BA2D821170E457D290444C80475A6DEAA1E9EB7B334F93253913A2A372B5CEC76D57348A81842EC2A2BA6D8D23C976F3CB9F3D349A8448C5FDAC524981F6F2094DC9F5FDE8F50B7F07061ECA5CF27E01B529BE1948522206C8051F01577D24C318FEBC2762DEE56090A69FA567D0C5C78126420F1A05ADA51A6AFBD1EF6E49CE8FD350DE872090DE73F0C124AE014920F104EC5BC7EA0FCEBE08F20F05310687E973E17F1B39B9436F1C1BD5CB39C7641828A7CE9326E53A330165405C68139B17268176ECDB8152C820EFE4B2A27F111680129D3CDD01F47DE9C9D7E9E73AB798649D6E629B2BA94CEAA58172565F34A2DC536D64EB4C81041F74F76D99E4FF70A47B904C80118090DA4220AC717C36C588FD89EFC4730049FA8AAD5AF60BDAFAC1B2FCCA3ECB67A59F97E752BDC33C5CFF2E1ED929D6F4214ED25F04D7E07E38C51FF1B1B3BCF0D8D38B31CD3B8A69210C1C3E5A92FB8FF9E494DD38DDE356F73A78AFA9F052468928384DE9E28DBC174230EEF55BEFCAB87909D9D5B21508BBD0D5D3876F754FE9285CA3208CA501606F0EB6B7FA672FA34C4701D464A9F05DCD14482A95871046B385D87F0CE6BE103A45B7E8F10E458448E57618F066065AD0653A7135CE175D55D84E19D45932534D0045CE8827EA5B7096A5B0960BC218F36C8BE436AF40B6FC2A6B7D8884F55DB87AB811FF571FB01A405403F4ADDD2097729FDE708EB369DB19FAFC35528A11EFF706445E69F463A8321FB76FDF380A71B9412AC6DFE1FB190D60A05F8E5FA34E90E9F735BB155DA30A254D0B3C2EF633F5E04CDB10A20311D2846AB24749D78FAB6EC47F89EDAEA01CE9C99BAC79F55E0CCB1C03AF2EF2C56D45E06D33F9D3ABBC6CB4BE09793A386048112071548CF0A71C9991DBB3A11D93483E3716D9A8BAAF62BC5BB58E24D982E067547936FBB57F2C25218A230EFB1A665F3D948CDEAA9F8659900F10C43437C01BF081D2664641DB6FD5B0CBE2004A96DD26D999937817B3A8DFF7404AC0D7D1CDB6AB21EDBB8D7AFA8D1DA69E5878F2D83BF8B926E29C2EFEB16A4F0E70EDE870D540FE22DCF51857EC30BD19ADB90CC68E6E51F3AB68DE8785CF510E7F3A5A039709DF63B801DC3323251351376715F8095ACF170629954B96795175B24E1C258AAB6CC89CED08AD7F756DEEE47A8D0D840E9B431461563DB4EED9560FC38258423E965E31E14D6074C9346404A6ADEF162D1C91432E5F83F97BE838879301613ED7190B2364158338F84A912C522F3D9E643BB90D65727628D26C8694BB2E1F35A45A4C4DC4F6974F9B8371DEDB8D4567370FB91A3AB7744D87321D2A37E808A0AF39B13AEC4593BC12BDB3FFFB32E69644B7CAB6860EA783BCDCFF142775F8C724B9F3E28C6686F9EE8422B03DBE8FE038717EE84BA5A8636DBC22FC29FBF6D07DF598B4641D4EEEE179160AC230A6A201F4127333E15975099212DA36524881CE7A2BFDEB0A69944804A6406D160D57942E851CD23F2445BCD5894006DCB4491D4429B0EE86143ED4F2C9C8BB26721581678D4C21F93B7CB931516966BA24D9585F1C0B04D660E629B3A2A3F31AEB6AC3EE8DF4DB67DABB5C332B61CC10887A0A207201703DFC4C27B774468F2CD9C6EFC711426E248C33EF946923D4C1AFA7B608F9F080410AE8F9F08CB38D5C0F6664EA0F630D34DFC55462334F617F3E4AE640E6C2D27597D4967E08EDC91704B9E3EE49EC4F0506994C3DD1027F8BE7FC46589CC21F9BEAF4F4130BC7D8325FD638235372E12CBB84FC424BAFF7D301855839698FE2E38B63BE461E681B43A02F99E466319E808084BDEFF59DC9DA0BC5F523A21D4525D81501A83F357BAB3633C061D403C7ADD90CBF38C0FD6063BFD585AF9EB65E63542A64CF0294521F768291991A27EC05F90A36918612009A7CF4A981971AB37B767BC120AA994494DA75CABF22D1FE63F1464E981A0FF2BA93D3AAF2CEEADAFCB80FB7D012A588D4E409051A44F7287EB74B23A7F9A4302D2E7EA81F9FFD74D72807123DC3529B24DA2AF50619784A32B75985FE5AF8191B1CCF65322E266C37555CC3A971BF53E46DFDBC336CE5DAB6A84AC0F17F219C1DB9BD42A4F9662C74AF602347DE8A4EF176A34EAA287C9615F90FC02ABB78D80A6327768932976729CC4BC564E870C58EE9889C877CE31BA913EA7E454C0868D80335CC063C57D0BC1FB3C5E09B3A20F8166F8BDC41B01A8EEB62127C5BF88686BB8D0350F7BE6B56E0CE6E66B0998140C6F839A1AB13D68EF718809E2973CBB24BF5D927E83DD6C16C292D94B6EFE4A1BC9E050E8D6992BFD1C6F906C0A7B81474293A86ED095FD785C5BBA70F51BA7D49E9A5FFCE8193DD10914F642178026F159AE536FC1FABC7B78A3C2DF55D0C8E1EF23883C6FDBC053B447825E75F945D8157A967B58B0574C6E0615387CE1652DC027B72C45A8E9A4287219D85A91D9705220F5AD851B47FEC4C2F700C035D20BB3D317EDB29AF8ACD0EF71E8F5F8FE70F49B939C97A521454B0944E1BF53CBAFFAF3380AD8D273EA8117B1A8277D00D5F8C835AB2820DFCFC4C8AFB2CB247B6DACFCDFB3765002D7D6EBA358848E7C7C63DA066252A81CC95E38A556ACD239ACB010A8169696B347EE86AE99CC7386155ECC56277B39192742ED8C959F142209943A017FBCE130FBDC3A491E7F650C98DAA0497D6C9CCABFD02921ABE4CFF254FB1521C702FB19F3DBBA1B691F7E44003C618C1B0C1B68A840B9763D43295E0CB779A59EEF7ED63AA1020069B2EF88BBCAB1D03693FE34C4C497F7936878D4DAB7B75BFF0FD8A0509D9A3B0CF209C9B7D09732CA0914617778AD289AC2110692D502C8DC75316530280FC926A62D46620A91EB4C89377C47ACC72884CAE39545022290B0D0EFA74045E4FFE5B7950E421091808852738371BAF20E81ADEE43642303C0F979B8EDAF4B47ADFB135B60A3E4F0BD2340A03D9F774ED36135C7C7241A89B2E9C71979E6BAA1E4D272BEA996623E399F2DA2AAAF6D0CE10191BA0853C08743DF8F9C98575E4F398BC3F19CFCBDB00B6C71E6B2B86A0E3BB72811DA873A3A318F6F334B64992648C9DA43BE0DB9CBA43FB1191DB64EA575DB1FA7F5E345ED532AEFC9F878894723ACC25CFEA3765FD8B4445453AB184E6C5A33FE8C136C8B401ED890A840BCC8C13CE2560D86119D74B6258D4381A4813572B6AEE5DB91BFA38F1E36EFF3DE17E255F8302A3A8161AD44F095659EEBB8E99100B7A19BCB8842ED58C474D1FFC28FD87A032D583050C09C64D4AE5F937743FC5E4705D9EADC758DF2CE55F240A40267311278E9198452030917F0ADB64226D6D413BCCB02C9A5C830AE5F2DBF73BCD8161132CCF43553B8FBA8E5283C953AEE50DDCE4EB59D29E4A2E5DA0530B922286F3588848CAFE9182175706266C466D65F41C3C18B000789C74952E3E2FEE44CCD9DA324807959D7DBC2E486A467DC1B72392EFC9F6FCA352D6F93756A048D58C6E04B24FDA2C3239210393254B41DA390EE357C7C175EA1DFD32FE5AADE666337542E508FAD05AA818E37539322BE1320FB587B83E86AA18434C47CA39E9850984F7339BD164FD46557BE86FB71B18CCAB5C34449AA65150D6F47A8117453D706F30DEDEB127BBA56F23193113CCBEB626F61BC4EA2D5053B489414A7F9731010D4333E72690C936D00367C343DA301A455B4CA7DCFC4215B0EE5185F1DFEAD2F09542D42C8CC1BA6ACFA452C6237454C5D115C0F5E04479131F9F1ACCA098EF0ACDFEF6FA39E4AEE14B0823E911EF2DAE145E261AE05A117E5A52E9DEDAC73742F90B4EAA8AA944F14679B0F72AADF6B56B31F3A2AA0AFA243C3DCCF6FFD2799FFA1F9861A5C04B0A8F68CC1BC8C90703AB05FBE50C15F06B04570370DEBB7612D8B7B8C25C25AEF86E08DF0B7822772BF58BFDFEA74C75B634A5D436832121C0C078E6BA4A80F1A20BD16BA90FCD04D43A0927C164582A796C12545CBD0BE45745F9E0090A47F31AB9B11E1496EED876912B13A841C06B6A5E812B11EC912A83D6B8663FBA403442AB4C70D3CCB76BE6686CD55D831E8DCCD05594F47FD58A835E3132D95EF4B4E8EBC275280999BF68305531A7F9F5EF2E8ED77C42227D0ED07B337CEB70317037ADA07819791A04BBF73646CC89806912EB3E2BABA0C80C7EB7BBAB7CE68583B609A5152A39457D51EE0A3CB4E897EB6363CB767057ADD8A1BE0814B7733DF1B811D86F8059C38D2C10318E34F24DB29F0949A3686C63F474F26E2917A9A1B025C28BAC7D53E4E150E981E0D5BA4129911F99588369CD97444E871D47141AA795560B9576AF7870E3F62BC6F010869F6CA393E48A0BF5BE7ED218D65D942EC0F815F2258A47F7A509B6BB999C17B28D46B7D3CA59061D8B99F7D2210E12828849EC8CE337D281D2246850C3DC3F9FA763B0EF81885C09FB9C3782471D5185D98077B9CD560F0F2D8109B8F2DFA711892BAF0A4A828E506417EECDAD332975E49F3E9019CE173E2ED3985D7C241AB4F7AE082E8EF49FD22CAFACCEAAF12E4C4CDA200ED92E5AB50E9E5210C963B82E0245F45BFF0E90DA76B2409FB75636B8406CF5437F84EF8CBFD76ADCF101B25F0351A8AD6C3B6ED35BD20E3610A1B543C035C020AA24164657737AEBF745F9C2675ABCAF2E9F3E2376ACB015E5688C01DCAB49E1959BF677F3CD1CED88EAF7207516AF40BA2DE6AEEB6F2E93025E817C6C694E7CF245C9A024506AF8AFD2996B227984ABB85EB960AAD8377CA5D00D65A8D7B474B45CE65D9058146C78362AA6DE23BF202BCE88C7465524F0CC26A5485B4FD693B4021AC902860D7415FC49D59900F2EBE5B8B1A1826953CF77D64CAD20EE88210A5C8D4BD3180ED4BD9A262E54484F422D56F3567A412A71EED26885FF7F21BF3A01BCDDBACB58A73A3186829582E2DA1ABAC45E466E0ACBB575FC803A925AE3D90EF26EE91B41A4DC47A11F0010177C7F63E4A6E7D8241F8BAB4D68DE3288296539D0DDF68497D7634A964B76E82AF13767129B7FE5BF4C85685F9C1649B8A52FCBAA9B2AF0C0C2BE1904DEB98ADA34507734E7937BE5E686F6DDD4E57D5EEF9FDC2164D60CD06AB5C9D11B840625837703C3CEB44B6542B684CFC5EB9B3297D946E7F698FD75C5A824EEA9328EDBA65225623ECF3B1F560C0D9DD03CA404DDEB74F901FA06FF4D2B0972C31F94450036B01DDD94C162CFDE0019DA2B04096357E7392466D2F933D14E381D7CC3085A4CADCB0AC0CF31A27014816177F79DBE703195F44C47205EC4A5CBE62146B5246AFD86660BB52A30FCC16AC9D773E97F581C7518D007FE0489C09FDFA334F49313FAC2B579C7AF47F9946A85247DC902ACD5E0B22949F45945DDD51DF6AB0FBC225603D7377F93D29F2DF9500194E614F93DEFECBCA3AFB03D22F8FD7661D9D41D62D3F34476EDB8FE887C37129998A21E92F020460D3AF85356DAA577666F5DC0BCC5986DAAF87F5A9E602BA73B7392923FDC5B81A6BAE67BDABA7F7D2E9410D160455BE2CC6A833BA1B0F8FE54852A576BCECECF9BDAEF1C9B426B3DBCA32353CEF2D782F9FF8C8DB114C65E259BD077E800BBF0AF92AE1083501FBCB6D736C848AFA2C836F2E20EAC0336B58D10000EE1E6FE4AF2C87B2DB73F0F695508E653A3755D0CF17516575A25E8960FFDB7B1A00FBED460A8BC7EDC370A52E214885B7DD496596F52B1697C11D5127906C27EEA91E5D3E948E752D54EDC1A8284B9330F1BAF79C2B31C41136602FB4D1A7418EE586E7386677F90D185CF9D61FD7178055651AAB6AFAF6B955469C05B619297155F922B97B7FD28FDA0C0FF3BF34081177EC83DC0433EFB8A1417D60691D76E15384DADDFE66566032B722D99F959653F5C68D4FACDEB4DB5F9CA52CAB9D78109D66D75ECA67FE82A790ADABA4C8F8EDC5663FE77361E78A43189D2B89D1F26535B1E860C9F18E7A3BC6892A68C68AF96C1F4730192CE3BF69D4E7048912FFAA309913C054E041306B4B0079D606F9EF3E08020379FC3A11CE22436F7C8BE6C5F5EE2C1C1778320456C18A68F306AD1B55954389F635A502169454E7C432BADF0A68F529903CA29C2B836DFF01B67CB745A77A9E7813A52B92C810B51BC3E71D7AAA9A9F31EE4542965AA0F6F9907D1595A31E720D4A7098FB2D72F01F8B83BF3A93D05157307E2B595F0609BF2C8B94EF6A5D60E53F20C1559A9476CD2391127B12D77357269359C424A769021D139860DCA4136B718B65880234089C1138705945AB76C815ECB06C01C73C60312FE6DE218F09C1607F528CEDD2898E077008FF6E47C4FB6B2C103BA92C399A24CC38B373B3D7F00D63E6A42412F710C62528106482F703ABC7CD198A24723A6BE730E6DC971D468EA20D76800F938E651FAFD425643ECCDE70BB4DC1D6FE4E9B3D3624C330E3713065721BA000D6683DE4263DBBD2FFB0E5AD20E33F6003B0E85356FCD6847C7DCD156F805A9A513F17CFB60F16925F4C587744E4AD35C7127757AAD37B73E5277D6614F0C315BB9E3BE48F654AD2D343B3967FCCF5387EE8297F2F74214B7B154E1D715C8FEB898A1DA31D5A8ABAB9CDBAB991459E62BE9F0E0A69791265ACD8F7AEDAF736FB944D3CEA82A1B3F23ED9AC0025760D260009668580A7FED8B073D52EB9D1847445D2064669D9E03116C2D999F3274876F37552E2D8A04E4409EFB415FFD9571BBCCFDA01333286A5A934E32D7C6D7EF3A20DD86ED5391AF91188FC2BBA388067FA443275DF1C06B23BEBEB418CCF1A7CA0E4BAD57780AD7D5528BD18362F273F0D97C081E502F32EFE1508B343268F1D2EB3F12914313283E40F4EC9F02AA17AA8A310FF50DF2712F49896FE31BA07A188488E45EB59D6BD6B858D527BBC0892580637EE631FDE8EAC14EDEB1E73EC75C8C241294EA628DE7ED2D9FEE1453299D45B2EEF3039D2CC80F131306006DA1BD9D68084F72AFF47606C4D632B57BF57812D2B2CB85C631F239710C05C7743C2F4515F6C64CBBC8109E7FFA421A5A637256FFE7F44413BBDE5787EB92060591282ED69794E9D64356A585D5E293E705EFC493596D08F3E68CA984532F71A20D81C4BE0CA989A19C2FC268CACE37F8F2D5B481F2A4F387043A4715FE805C6FE2D4AB89DEBE10CAFD406F37450F0E477859629CE2B957F3415CC4E2CDB795EB766193DB9CC1E5D34B022FF9C01B7ABAB66A08EA5A0983E6E85954C92A6D3B2AB9D45BA49B21D45A3468B53440BB45283D3251613D162A9CE508A5766740BC16F13842C2F89F2396E3363A1934E3AF2E7221957FDBC5F2BAA72B6E62BAEB9E6D33B248A5102714178A60CD3A02B6E121E1CE591185608500C11AAAEB039497472C12F766386647573D2974687D3B63D655D412B1DC0D3084791DC9CF5BC4A42D6D3787A187D4765E5C65894BA159FCFEE27FB3B36A54A9FA312C81EA09C6762770B9649872A738FA0111D745A1F9A0BC53FA819D6E7220FB07293058C8EE51270F86D956780BB52984745B68DA948F7F936345F770F38661F35198D5BED466C3E1C7A23DD56D543CFC93078FCC7266BB8219611568877CFED4D596D7218D1AB6764E422874981B7871339ACAC858B546C9139F4B917CDA356F04B779BBF803351C1B452BD9EDD0E2DA226A5F930C3C97F43D4633BF11B8BCEBF646B8608685E36F0ECDE7C7FB5F977E4D61038C745DE151D832D47C979224CADCFDB0C82650055F1519B94680A840FA14B55B2190C71AC1F7A7AEED989BE8C8AC61149A0C809449B677AC353867D0185EB15322792A3A7E328FEE3DF2230E4B70551FD7F9BD57BBEAF02E40124C58F019EEB66602B9EA10094839EFA9070F5C2DA3AAB6CDE6EB58246A59AFFA0352106F2360946C26969F0372852E46749AFF6713022F5F8FA138D1D17A01F42B44C013843CFEF1EDA266283A5CE4A6ACD7597519FBD097E9E460D9B071D34EDC61672D14E6D9D4F9A033B5B473A1B13476C3C447E884455A5D168DA793F9E2F096157F1B5CC674FB289CFDDADB63DF46F2753E7B2775A411DEE754770918335AA96CB5D9CD1C95E50A0CB6B42693E728A0BA9D012330F3FD5ED1F8BB85AE97835CD6350671EA5FAE17751E2924E3CA8B377788D44E06EB9CD7366B406F61444068CA52174641AA678DBFA7BC12592E766B5C27CE49C72A8AB86CC68E2FBD6211FFA124FCE56A5AC28B94FB88ACC2A8AF25A40E3A79348167B5509DC5EB24A6CC5B832C73668D17AF4C29F2A72A1E8DC0D74C9F2446DE7A42F50A5DCA2F12EE84A91F75004E452A4E5FC799176A42B4D0A0A0CDAD9B44CC246872114650941B08315BA68E4B39A713B08A66F1715FE9300E5AAC533E37AE289B74341BC1DC7C75725C9838412E48A4CE312DEBC345B16A3A1F6388F350997448653448F6C7C91B7BE24118C3A0F4E431E88766E5A6C6113C8A2D1D2646B5EA5821C90CBE2CCB6CCA02A7306B38F3FD08B3D8A4177B44DD50D8F1ECBE9C5F7730EA926D482C3D845B2BD0A2D4978F82258687586F9E6EE6AA21877D8A2C7AE37332573C420DB9C8754CC20EB937A8B94056D96EF571162B0106AEBFC344B5F28D52B8CD02F6168F45B321639DDDFBB333C5B872E80370F408EFFB5CC7394767F8CEC0CDCD7C9189E1B24FD29C7FBA4B14F30B8F5996155855C08A749B6AAED58C55271223A53D1E8714549EEA65B9A9245D9F5AD2EEBAE82637B9E3C78A24B5262873759CAE9AF9054C3230F88509E71CAE2238AA2DA1C25F0DCBFDE9BCC7B234BF1EA6697DD4E8B020B099CD92492855F1B528BA0B359BDEC1E77245432B7B1B2A5A7B969947A2FCFEAB2E94762E2F3F524E88E6FEFC4DBECED7EA550E6BCEDFF229E69D9C7C7803FACF0284529618EC64E05B0A916DE5463E27597B745C58C05BCBB58C5200FE3E9847ED6D3A7874015F0AE87EE37FB6C478F7330A07D4C59E314847065E2F1F5F7F6DAE557F85B03FE6BB31B28A40263B64218FAD4572BC5FF2FD4E3F8F9A8894795658466BFB5DAFFCD99A69D532713CE072D81A42045933CDD30DD257F6C9848577D9F8B09B5D7BF71CF202AC4CF296E05C6A7ADF77D8FC670B88DAD02DE5A80D4168F7F72A7252B0E421F9734012AC8A8188677647D35ED6199EB300A6B71111D7CC77F04AF5E559A0D34CE1E1490576716A861E79902678C1241CB6F614176147ED88C82A99CCF2BBF62AE65572300CD4FB12DED4B6B0901D5F6BD02F036BF66B095215AAA76BAA4A07E2C0CAD2B2D76BEB56956C26ACDC11FDEFE9D42C6A698C09F0ECAC502F2F7E00233329DCA9595A191DF6C87B728E8F9B59105B9074992A62F2DFB38852C7F4BA5BF782395E906AF48136AB2DEAB4BBE7F0F79867696DDAA4176F14C9DC7A301B0DACA30332F73CA3356A62A4832A12DCCC3D696505F59E73148ED6401A34F6986428CB1CF18FD61DF1455A042455FBD97A76A404E65CD0BF41E26465281A0BA11EAA39CB48B99F2354BF5407629727B52DBA14B29C65083AE8B8891AECA5500BD15DE9E66E7D5C0104891C17A108B79D8D96D35F12170E2C930F8F16068AE3CA8511016203A1A4726CFEC7B6AAC959B67F3FF1E4AAEAD667487299703D38472B5085FC55B9BB775574AAA118BC81076CD53A4AA7E927482B1D617C09C6C24DEB07DD41C2C42B6A0BE168493CA5A40266AF5B992B9B2C65CFA82A2EFC515948A5FC521A7F49DC4BBAD296BB6FD4AA6FE1B7A7726229C03DD1043AE89A5349A1F9192CEA32FF331C51B99029914DED316746351E9B641D973867CC37DAFE8FC39332DFD321B1ACA45587EB6D4727F5AFEC4178CDD8AF03FA0629DA84844B5131CC2AA07E2FBB8F80D3320AF5C1734031AEB68DB8B6C7358F775E8538C260FE6A79DDAE2BC7D40222B2942A2D8ADD3F295A135B5FBBA319FA3636F56D1BC8CBFA175EA61C1F53980664282E56291B4ECE5B5FF33C2141F04A3FF83EFC062CF6C635497FD03D6E56E405C43C4A31DDE872C4E277AA190D1D8350A298F16BE75BE305891F9D1084146199960A881C34318CFCF1366E82A487CEE95D5EC9F9756FFFC9DF3A1058E367160B321753C937D587130F9AAC766C19F033CCB2D886AB532683F50D360D10DF559AA16DA2C0E3203337B46EA1FCC1407675C5057052EDEFFF36BB2A6331522DC5CBC871C52CC35E95DF677771084A6E3E10A56111E6B9F7DAEB1FAA11B9CE5EA450A7D75F2B7266193CEA51A9532D8A32A2D4C275ECE75C3A59C3F02E3F9F40968642D6387F752C801A761F121A3EEF4F6B0AB83B7E815E5BB9D67EF85BF9DBF72E5E6DAEF4A6F7519130BD4F826A82D23332BC291A3D320CBFBE4BF1A143B78FAF7C1BF61F30801BCF715A05F2F7429F0D1A3B9F90D191754FE3D761A77CEA46082D3D2CA5BF26EF05257DBC8B72D156920EBCB1E064FBEC3CA43AF31CB2A53B246BA02E3F8AD4E07DE794CC1D8E3814DE61807A116F768CFFB159D16CB7214EAF1F52452B768380F4E16E2BCC10E82A027148477F2C717844DBB1677D6F2559AACA58E4759D40C7D62610399D6EDBC6DD4DA7904D2C53E4D9E07928FE181D503C5D45D6DE07E767025D9B0386F8C123C38CAEF00BE2223E8B1F46370B1D20FF0DBF78CB6A016D0F72F07820238885D3269D22E4E45462E1FC4283961785820FE1AF085BADDD385B99F1DFB5C16A3A1E6EADFE7066FC6A5781AF310597B333977E34D01483A860E7D986357107DADB4F5D040550E524D9D1AA456CAED45FB5F6475160AB01C8AEC46EEA735384E4FBF205BB117F68C03F6D301E5C469033B05360DA23CF49DA36E050D627B2067B30983B2B426DCE0B78C0500BD15B3D2572537DC9B5F0BC0E1A12F533F58B2E21102318B0AB3341FC2C6D237287114820AE20D45FB96325D2A1D2FDF104108EF3F5C33BF53D2A951EA7BE7FE2D487362EEC1DCB93920B266C5AD39FFA0FC6D4B335B1355A6D8AD3CFE51E9F69C8961A82831BD27F727C9030A816E817783DF89B519D6EC14C9CD88B73FD6152250E229BC6CD8C952777CC5D670051B18F5AFC99860FF7387C5880564703541C2883BC93C5C0EEFA57AF9E9D9D04EAB3BA87782807C37D299789C60C63CC2E86B5610ECA54D3949E17070B1978781F705E32042AFF28FA979979A511C5D14ADD08AFF7DDAE858415D7B0CBA138BF6D1C72C99A9564FE6CB5C9ED554B98D21CB796FC053CAFB4B3E8214F44643C99D9C92EA847A1B6DF3BC21FBF810F9D04B26771BC6DBAD0BDE30265D402E62EEE8ADC84CE8AF0FECBE8F68D13501515B8C28F68AD45D9D1A454904DE944A90C7500049FB74979AE952EBDCBA09DE543283CCA44D3F00EABF99DD714B8FDE3755D30105AC8CBC4569789B900129140D740E82653975625288323BAB5437CE832A600D1F344C411935E2773E3B03C5E4959D9A2F7D55B05B8574768DF40B5EBF76FCAA69F463E0FAFC9F02B01C7B89C1AFB661B43AED07A9D54A6669DCD9022A4EA628CA69577EB1D92A0648FBA768C9539AB22C6A7FFCA85858F1BFF4AD7043CC3CFCB3E69E2D6EA8BD1B2082A8D546E56C4B994E44CD8342621BD2027E5880AEF36EE7DDC8A8900875DE5D77074DEA0AA6AF1C0D403ACCE8E220D2AC30693BA865C46BF7416F2E53CD57DC43DCB9D0FA3300DF706BA4ED6872B2A3E417ECE57E42541D95EBEB238A881DF4445CB68718B3616B3456930494CD31924E7B60BCA6F85CFCEC61AE59F8968E30E844A031BC745FED8550EE78B1266A91694B967E66785403F9FDE097DBFF047A171318C43FB2472127512463FA79877B475C7F810D28AE0BA7C5966102673F9F55653D9E546E378D2BB17CD35FAD2F50C5372DF7871B1F1DE78A72FC84F2AD1BACFB45712FB13E3773B3565B021D30A31602528EF16FE6D83795A1A8620E06BE25AAB07A8F3F1EE979687840B7C863D0D8A547A5F7197FB72024DA7F0D3E331C300BBA084A239D762A49141F81E46C97BCB157E81FFD88A34862C07F224E2ABEEEDB7E701AEF0A2FBC73A73CCF9B88E0606784D0BF4E99D41EA993B5401881439CBF17699A62F3D426EBD3681942C7F6F7B40835A7C996B400565E8BC9E636698FE0B197B96767C304CC366E2279F19A9E76B8B549DB73200EA7B3F788CCA15EC4A56D86CFBA4058C3C514F3154854CA6939229C3FAD386BF62626211CDAA71529B5410E08604348A4FA025A71894B946DF27454F27BC01996F23C8677C11780437BBE7131493B77D15C667AB0012BAD1CED0DE088C3D83795C30A3E34C878413680940B88C4693DD69B53E014174D8DB87EA6138C8CA99800F4F93981189912022DDCA5B6D5AA4DD2E04C394191204492E8CD5BD3B1599292F066E4E9D5917ADC3CF954851323255BB47D6FB2B0B6E93D9C2E39E23F7F02915149F9234FB2F13E6BDE58B24DD23CAD19056B0F92E3C1449421FEB5A740C7BDD04C76D8C2AA84F1BD9CCB562B9AC66C54ACC986BCCC869025339B9EE0CD9B8C0D7025B3662F8BDAFF77D6C77324F336C1A5276F7734EB3399FEC4A5902AA5971A933EEA9AEE40BCF69C70168BC10F1E9576CD541325A8A729566CAD7C0483ACC8E23D17DB2E495CA46032D9EAB61DFB6703C7C06BA4FD0513B55B05512CECC642CBB9D75AE94922FA66546C306BB281A106EB0D25D4156DD04911DB499F9A77B8F8487EB0287D9D564EDA31C37DD33E57A8D5A33C3088F4269E28E87145AC781DC38A75D575DDDEF448BAA06A60E54E4F6EBF94B095C14E36CDFD29B45BE3455F1930F39F77150E595CF127D1FB7E8226CA954C355D7098E783D32A41E702A611115154F3DB1A8484E4C6A81D13632998E75BC4B868F7E6178F035BF1BEA7510E3A823DBF976A0741138D1D5C9B2B434076228B7C3DAEB0576CD1194E82E62A8F902F9C84A1040262E83913A179EC88A1973DA20CD50D9676DBA1B8C036B97AF2C2005F1F556D1C462DAAF0E1E720B728AE3A7187F576F6B19177F83CB2953F058E0573D795A69B4C72365CE904C9690FAD0ACBC12108D950BE728E935FB7FE0779C54C8C0CDED49F111DE5777AA6131EE9084796DDEE52FDD7567A66ACFC8BAFFE19F46D0BC02258E9CD605176480A7E11B2B7283334B1398342061098099C06B1DB47A027B6577055A67649E98A0AE2E890FAE3186EBDBC6962257DCADBD50352BF17A03933D6BB6E00C1AA62CFEF7C7834BB0705A50205C4EF8D3270C4A0716A593858D31D1B989FA57C694A39CF877024ADFBC5FA2386FD36B07BE137723172C0E08CDDD0185E2510CAA4E4845ECA6C9750F4501FEA182D7748CE3BC2C902DF532BFAA83B530C214A5C649102309116DEFCCD338D8AB9CBEC500C26095E4BE1521964AD4694546C8D1F3774776C0595E0ADD0203F0FE1489B43ABF5FFA96C25138D539203E53FE2EDF38BA68448A3520CCF623D8427DE666CFB05E0BC25452E526C7FFB8D1DC496F047277FB03444CB5ED7342FFA18EEE7B1730925FDB23A34CEE84A5DB13C4AC46BE0B0FBF36759DA3E7B8C3289628F7E8254BDE347A1267A888D7FB18D021FC09668E7DDCC0FE714DFCBCD73AEE1395991E44B423F05043F6094F3930B33ABF6EF6D5AD18ECADDB1B477C019334C76E553210D4C89E4C32DB105FFEA84396B80DCE49EC772FC586D65A0C6FA012888B314FCA5FE7D56304AEC2B6EBCA87240731E19F8A237E3080A5B4FB92BC823AEA37AE3886609B5E4335559AB13257E92D2EE60938B3FA1A8B15958F8340A6062A0045C098A08D6A78F0C8806789322017F576BE2590AF4AFE35C2C1DD17A4EFBCE7F65B7FCED0A56A91C2D5724455D0A7A4BE1A543451792BE01E9A9614C6026623E730A21A5AA1B22EA38E983F1CB3C6AFCEE94FD813CE143F84FA32A70A97CEB20BA50BEA097D13CAB9F0E7032D052D9D9903A39F07E56690711D67081510427FE7D665D64BDD70EFD0215C6EF994CF6FD7444DBFB51DF33FD88A9B2D54BADC321512B7B57AE2AEF89959050169E710CC7D38B011611B655BA781A5B3391868F48AE12EA4F0D539BADFF7D81270E6847C387DD76569E539687B1FFF23F0226CE24125D85D229804869826671E44CD3B5942738E53432EB5267B1DFD7C80DA709A3E6ED28B83E10721F4D08519A3474C951803C0172025BE77A6CD8F5F9B9E09ED8CEB187F381D57F893F96E78A10C1AE29A306BE20246579F74C2AEDA46D2FB03A5A08C152BD736C93C7450149AFF1C0505E34E48C193F046647C61565FA6BC99044E7FCD0488716774CC0371D9ABC47CC69C415AF45B35FD240661DA201D3906863E1E0236A8A0307E854DBF000462D7217090E77A43FCA84061F881F71DC197BCE1D6B518FFC25A3E4926F64229AFFA4098F5198DCD8BBD2F99F95453723D6BD04DC5F2C732970D2AE4A9165E3AC8C8A767F0BA93BCE6F76F1E4A96D167E9EDFBA17A78E7EB3015E158630058EFDA8FFFD9D1B074C8ABE07300265DBCF6CFD550047FECFDFE05721DB0EC4FC21D4C675B7387B6D524DF052BAB92912B6DFF155F00462AF058203F94021F6388249475132A803A31E55E366AD3935EA2D7BF1FB0DD9AAB9D494ECCB3B7D0B7663374228438E11FFA2918324BAEFE443FB17B1A1950B0989D5B3379A13D82AAC83687BCCA2358DE7DA30541EB84E75DEA2D27409E7C02131C1FEFC1E02CA55584FFFA7CD7E8B6E2E2B7B685BB96710B6BD0B672334E8902CF6D49F47CA682E4343EB5DD588B7E61FD37D1972BACBC77C27CF06218B51E82E000185CB9BD13F89E6C3AF38596F181FC8A31B68C8C21DC711EC8BABA1CD7E812B4D6C939B449251718439129B95119BC9BE22C5E237B0B083582093D9DFF114C0F632A0C0016FF3A53167DB27B2F226A2B4B5EB7A409915DD46A882362462CB5BB7C3D2FA7DFAE5EF6969F34FF7E1B0958C4297CECDF374312B3231354D04E61AB4B668921E65D7ED31AB5AA46E5DE9EA4F5243CBBDDF261FCE1BCD26DE90FB46AF9453164A3FE6DFD83DBEFCE4CFEF2250893E21030934A382A288C69BF0FC7E9C92280906A4BA331C652BC4F904B9B54DCF3DB0651E43A6C83FB9843F85F0DBCA8D2E7F492200039906CF62A95D7B1830FDECAC0306B1A98B6F7B399E406A172202E29FA157E168F4B9C6979150F5AC2EF7769E4A729B6D59DD8F944E9A4A118FD06355D19B28ABDF256B4390DCD5C098DE989678AC25659763FC22E05FC4EB5860F4532E1EFCBAA0ACFCB91F30D21D2C90F8DBB5B419D8771AF1FA14AED614FA2B5DAB9F6F85016293B0716170A972790FEA6B0967F1FF1848CD29934182A9DDEA9BB49DE7B0A8EE13DA1F0A46E2376820EE34C1CA84E4524F21B5AA5FF74310EA831A3D3D08BCE359B830828E376B3C3999A9AC6168ABC74DDA8FFF0B35D6CD022BEC9BF0527A743822DFB79CBC96A90B6CF80B4E244E8F4386B653AF3D322BCF1E0DA62C28D019C7BB1B7D245E3B773871F0871B12ADB9306D31135B241A8E49D6EC6743C95469C24DAB5CE75E670357F3D22481C2E01E30215A0538DB0448CB9340D58FC633C9CA5141CFD79109D30F5943DD8A69F47F49C25E89EF486180AE64497FF2197EE4D518994942F6FA35BAB9D747CB356907B409CB427788C3D7708D77B706D9F90FAC25E492EB60F2DFAD94821D05D8F5721D46560CDC2E43963F70B64C7EC230170F2221693D7FC10B0F27CC4B154EDA86B74CF82CB44EB097E3703FE0B938346856014A50A106F64B236B17DBFEBF2B455FBB9C999CC1F9E7CC7D4DF12E1EC6CEC249345EAF4DACF0D38453A533E5193257BB55AA785666C64B91491B0A5DB93688FBE07D66D926759B669E18521210CAD05EF3F8972754DEA64BC0846516FEB472ACFF5EE2D7E29F7633E32E1A91E5DD713A56AABD6ED1EB967F371FE4D1A7EDF2432FC050A47F34300DC4B69F8553FA4A23509A45977E62736EC9653A51FA687A30FC0787CBD6824BCE36088AACAE7F55D877F773255A13B3A006CE4D2B2ACED5C03764B81B9DE5D9E0EBF9230164C5F75F05C4353F64A182FA15948C9BD8D89E5C6364B84ABFBEE413D0EC4D3B553A46B63FF0699542A2A7ED568B6E8A9C2C772B4F7F7FA17726174968E216636B4FC547AE59D73DD40F320D6B3329C868728B97CC704859F851149108B705C39AF3DD97EFAEBD39ACCFAAC8EE1FAAEABB32E689063B11483C47510DA0DA16B02EE4E397B146B6F777B1F2C393379414F67BCE670BDDBC67BC8ACE419C2E48C5B57EC624C5693562B719C7E696E1C83076E0EDE8540DE3D7AA00AC5A50E481F7BAA41C43A1C2EF09100EBFFE5EED9FCC095945F525F66ACD9A814582D6609DE9FDC132974B98454B501DEAB673C6D33AD29686E1D43912840DF6398F2468C0788D1D3B597004E6BDB7A89B57DCD4249EB51489F4DDA36B0A3B90C4EA616135B089C4D4B8DA02E695EB8657B2E12FB5554D2D833353A3FBF3FEA441A755FC4F0A49C243C3682A20B04AAB0EC430C9BFA134C383E4B6FD45DFB613E362B171F0C2B2473B38E92A21C72C100505B3E2ED5EB14D1ADEF650C7254F5163A2FC01B987E3000517DCD878B3D9268E912CA3675000B10E53F5B8172477AF6FE3778CB0E5D279309245647970C216E2E626D2148795132C2479B65FEEFD8B38395AE4A34ACD06B005F311974D6197A0FB415D7FA5E64502FC8C878B14462F0C6458E04BE6DA9308697467937AE52099382FCDC35FD7D2734B1150C214107CA53F6EAC9D584AFF8FBC6C2AF2B711F45BCC5626B1FACEDF4AD03E261A7E095044665CE61C3359BA5A046E44C8E5506E2BD7D4F6F08B57C7303472AD0369BD7B5199525024D34A0143DE46F8F3316F4A8B93DC5AE6B02A0F362EC7F9EEEF5303E3C0E13246E0F214FC2843F6116A7986920BAFDBC483B7D8F84ACCA690C6FBAF794BAEB0B687249A360CFE9E1C0A2817F2D93A166ACD35C00A1BDC4B1AC6BAEE6588B0958D5C2A0D63E6DADD81AE2ED7B8ACAA19040E7E30E454D629944FD10E1AC8ADC8C0CBCDD9868B973299A4DC927C49E944C7C00705669F96557477EE62F0E6140D613B110B9FBECAF70983B17EC4A470FFA4BFB8AEDB435FC607B957898278FC2D33E66F68E1F630D4A06B6413ED8C2B7BCD931DD4271D12B29336E47FBB378D48A956DDB447ED3A2B93E3C3A5559DB3B18505CFD0AE9377C5F87964A89B20952F5804125EACFF6CD0C256CB30288ED1BA4324F9F7850AB4A14F5107A91C3DFF05B82D1C4E3BBE38B7C6380AD2D1C41621187066598C2A314A84E55E8260D78D6220923EDF59C8CB7BB6E5B6AEB96BD7E436D19DBCAF897D8A2B3B41D17163C52CCCCE010274A70B6B985545072CC765A499A3E4FA7388E44F9A1F9F0D45694EAF817A3A7D068D3FF6F054145C716DD7CE747D3889E49DB2121A81EB40E2E2D08750F1CCF791EC924ED46F3C5C741E57C9CA75D7EF3C821A3A2EDACA966CDA766A3CE6EC0DEA096870022496856890CAEE492ACBDB949FE0BD8CE0C3E72468318B0322F894C64EED64AFDE22A7A1C2B22B348830444DD5B99050B4D3976A70DED872E92593215ECA63D2EF78B901B89230D2C18BFB4D50EBC5949A090DA9D27C7B9B3ADA9C787913ECD0D8E578DB0D646965DDF5C5DD3395906A9C02E7F33194DA5A6583C198A7D41CE382A6BA5B8F9E52701B31E1987E7AFE0109391E187223DBEC2E516F103BE65BF0FF2141194836BC3DA9C1031A5D51676AE1914885D9CE838DB07F72B047AC46EBB3E1FC79AE2BA473FAC3EAD512D9F1D3AC2536093EA580F0384B36F8B798C8313207EA12A1E244F0B2AE1B64664D23C8C2D7CD5EFC95C18F4EB7B196F368F29D39578DD3F53E050D351AE6D93A40AD4915927D82925BAEB09E8A877AB1C6B704775C0EE210025CEDD475823479761DB3C8CFBDD9739754C743307E5B9E81036C748B79AB78D0C56DABCB9893147A5BF4E3655329E433A0521B08DE2BDE442CBE9A2721EAA94B4F9C0DFAEC4D500FCC073568B0421444AB51CE94C9489818D4C598C1E219AB50C7F7D914FD59BC96542C72BB3636746A9C08A4A416E7E581255FEF48340CF1D9D6C5E9832B004C0F646FECA43FBF0E016BBCCDE92C1CC9AF6C92BB735640733DC1C031BD10D554E51BE3DBE3306D64CFA148779EDCAD8AEB21F5FDF085FB1DA0BE2DDEDCD1B094810903D80BE04D1FBFA7E59E17069DDBB49EEC76320B74F31C4428BDE620DE149EE74DD9BF22FE0047FF71486E339072F2B603B8055D7BA43FD71B3CAB178F34703FDB8ABDD8F5C1461F89446ADB1175E35428091CC0A3B58DD435FB4D9B5D62FDB9FA0A34224FAED03B10B5FE70EA67AE1A3005D3DC4AFBB064A22AD6A9BB05C15228E1D20D4A4E8D041BEF83790E9707A581DBB7689E032A083381899EEF508E4B2A897FFAB447F821C848EED8CA09616CE2EFD13966C494E919BD76A7C971A7731B13C4601F7B659429C2F7F7592F4B17894BC139123596F5B92139A4B5768CDF2E35810BD1AB3BB40DCE3F38853783F6856552BF95A4A835590582BB7206044086C1CA3BD9B8ADFB09C40A838DEE80E1B3756F98073651454C1567EBB9BB8D9FEA16E9CB0F30FA5E7944CCFE2732FB90178A6F439EF2C83D0FD90FA196CBBECA9DE1DA63AB609F53BF11303F3AE2283195AD62587795E7CE13CCB19132890CE25B085F7AE282F8DE315DED51D9E7B4652285ECB3929B9D6F51E82EA4BB5AAB4110925E014691A62121C27B5D929D24069ECDD6148B64213FCD94FB9EB6CA08C3D942DCB7FADCE9FB3917E40A455701CA8028A1456EDECC5EE3A3A27DE819CC28084BA0BA992CBA7D3DEDB39B4FBF247D2845FF9D4B455F5D29E81C17C5FFDEFFF7CA2153F968A130EED46293DACE1777C0173B089DD2DC63CA91C994E506ECC920E8A96608FB6E4F970A59145E77CBB83D1A5C22F917 remain = 1152921504606846974 -max = 1152921504606846975 \ No newline at end of file +max = 1152921504606846975 diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index 52245f3dac..76a7307037 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -207,7 +207,6 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { } fh = stdout; - fprintf(fh, "# %s\n\n", sig->method_name); OQS_fprintBstr(fh, "pk = ", public_key, sig->length_public_key); OQS_fprintBstr(fh, "sk = ", secret_key->secret_key_data, sig->length_secret_key); @@ -286,7 +285,7 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_total failed!\n", method_name); goto err; } - fprintf(fh, "max = %llu", sigs_maximum); + fprintf(fh, "max = %llu\n", sigs_maximum); ret = OQS_SUCCESS; goto cleanup; @@ -322,7 +321,7 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { // Echo back max if (FindMarker(fp_rsp, "max = ")) { fscanf(fp_rsp, "%lld", &sigs_maximum); - fprintf(fh, "max = %llu", sigs_maximum); + fprintf(fh, "max = %llu\n", sigs_maximum); } else { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_total failed!\n", method_name); goto err; @@ -441,7 +440,6 @@ static OQS_STATUS test_lms_kat(const char *method_name, const char *katfile) { fprintf(stderr, "ERROR: Verify test vector failed: %s\n", method_name); } else { fh = stdout; - fprintf(fh, "# %s\n\n", sig->method_name); fprint_l_str(fh, "msg = ", msg, msg_len); fprintf(fh, "\n"); fprint_l_str(fh, "sm = ", sm, sig->length_signature); From 194163611c1353b417ac47f4568f74fdd9325cff Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Mon, 11 Mar 2024 15:45:18 -0400 Subject: [PATCH 43/68] Add return check for lock/unlock function (#1727) --- src/sig_stfl/xmss/sig_stfl_xmss_functions.c | 10 +++++++--- src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c index 64d714e600..3b205e8f90 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c @@ -37,7 +37,9 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sign(uint8_t *signature, size_t *signat } /* Lock secret to ensure OTS use */ - OQS_SECRET_KEY_XMSS_acquire_lock(secret_key); + if (OQS_SECRET_KEY_XMSS_acquire_lock(secret_key) != OQS_SUCCESS) { + return OQS_ERROR; + } if (xmss_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { status = OQS_ERROR; @@ -59,8 +61,10 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sign(uint8_t *signature, size_t *signat OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); err: - /* Unlock secret to ensure OTS use */ - OQS_SECRET_KEY_XMSS_release_lock(secret_key); + /* Unlock the key if possible */ + if (OQS_SECRET_KEY_XMSS_release_lock(secret_key) != OQS_SUCCESS) { + return OQS_ERROR; + } return status; } diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c index ec1143f1b8..3f280e024c 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c @@ -38,7 +38,9 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(uint8_t *signature, size_t *sign } /* Lock secret to ensure OTS use */ - OQS_SECRET_KEY_XMSS_acquire_lock(secret_key); + if (OQS_SECRET_KEY_XMSS_acquire_lock(secret_key) != OQS_SUCCESS) { + return OQS_ERROR; + } if (xmssmt_sign(secret_key->secret_key_data, signature, &sig_length, message, message_len)) { status = OQS_ERROR; @@ -60,8 +62,10 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(uint8_t *signature, size_t *sign OQS_MEM_secure_free(sk_key_buf_ptr, sk_key_buf_len); err: - /* Unlock secret to ensure OTS use */ - OQS_SECRET_KEY_XMSS_release_lock(secret_key); + /* Unlock the key if possible */ + if (OQS_SECRET_KEY_XMSS_release_lock(secret_key) != OQS_SUCCESS) { + return OQS_ERROR; + } return status; } From b45415c5ff2b4087c4e3091a6ef7dc3f25eb3940 Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:49:19 -0400 Subject: [PATCH 44/68] Use `abort()` instead of exit to get the trace log. (#1728) --- src/common/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/common.c b/src/common/common.c index 1146f5c45b..904b91519c 100644 --- a/src/common/common.c +++ b/src/common/common.c @@ -275,7 +275,7 @@ void *OQS_MEM_checked_malloc(size_t len) { void *ptr = malloc(len); if (ptr == NULL) { fprintf(stderr, "Memory allocation failed\n"); - exit(EXIT_FAILURE); + abort(); } return ptr; @@ -285,7 +285,7 @@ void *OQS_MEM_checked_aligned_alloc(size_t alignment, size_t size) { void *ptr = OQS_MEM_aligned_alloc(alignment, size); if (ptr == NULL) { fprintf(stderr, "Memory allocation failed\n"); - exit(EXIT_FAILURE); + abort(); } return ptr; From ba63672527eabfe43139adaf9bc37e15e8a3657a Mon Sep 17 00:00:00 2001 From: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> Date: Sat, 30 Mar 2024 12:53:22 -0400 Subject: [PATCH 45/68] Reduce number of `malloc/free` call in `XMSS/external` (#1724) * remove unused file * move malloc from prf and prf_keygen to external, reduce number of malloc/free calls * push malloc/free to top level function * continue to move malloc/free to upper level * clean up * modify TODO to TODO(from upstream) * make astyle happy * clean up * use malloc and NULL check --- src/sig_stfl/sig_stfl.c | 3 - src/sig_stfl/xmss/external/hash.c | 44 ++-- src/sig_stfl/xmss/external/hash.h | 12 +- src/sig_stfl/xmss/external/params.c | 4 +- src/sig_stfl/xmss/external/wots.c | 46 +++- src/sig_stfl/xmss/external/xmss_commons.c | 39 ++- src/sig_stfl/xmss/external/xmss_core.c | 278 -------------------- src/sig_stfl/xmss/external/xmss_core_fast.c | 87 ++++-- src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c | 1 - 9 files changed, 151 insertions(+), 363 deletions(-) delete mode 100644 src/sig_stfl/xmss/external/xmss_core.c diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 69fdbc352c..9299975348 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -912,7 +912,6 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature #endif } - OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { if (sig == NULL || sig->verify == NULL || sig->verify(message, message_len, signature, signature_len, public_key) != 0) { return OQS_ERROR; @@ -921,7 +920,6 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m } } - OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { #ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN (void)sig; @@ -937,7 +935,6 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned #endif //OQS_ALLOW_SFTL_KEY_AND_SIG_GEN } - OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned long long *max, const OQS_SIG_STFL_SECRET_KEY *secret_key) { #ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN (void)sig; diff --git a/src/sig_stfl/xmss/external/hash.c b/src/sig_stfl/xmss/external/hash.c index f9272f01c3..6330c5871a 100644 --- a/src/sig_stfl/xmss/external/hash.c +++ b/src/sig_stfl/xmss/external/hash.c @@ -29,17 +29,15 @@ void addr_to_bytes(unsigned char *bytes, const uint32_t addr[8]) */ int prf(const xmss_params *params, unsigned char *out, const unsigned char in[32], - const unsigned char *key) + const unsigned char *key, + unsigned char *buf) { - unsigned char* buf = malloc(params->padding_len + params->n + 32); - ull_to_bytes(buf, params->padding_len, XMSS_HASH_PADDING_PRF); memcpy(buf + params->padding_len, key, params->n); memcpy(buf + params->padding_len + params->n, in, 32); int ret = core_hash(params, out, buf, params->padding_len + params->n + 32); - OQS_MEM_insecure_free(buf); return ret; } @@ -50,18 +48,15 @@ int prf(const xmss_params *params, */ int prf_keygen(const xmss_params *params, unsigned char *out, const unsigned char *in, - const unsigned char *key) + const unsigned char *key, + unsigned char *buf) { - unsigned char *buf = malloc(params->padding_len + 2*params->n + 32); - ull_to_bytes(buf, params->padding_len, XMSS_HASH_PADDING_PRF_KEYGEN); memcpy(buf + params->padding_len, key, params->n); memcpy(buf + params->padding_len + params->n, in, params->n + 32); int ret = core_hash(params, out, buf, params->padding_len + 2*params->n + 32); - OQS_MEM_insecure_free(buf); - return ret; } @@ -92,12 +87,11 @@ int hash_message(const xmss_params *params, unsigned char *out, */ int thash_h(const xmss_params *params, unsigned char *out, const unsigned char *in, - const unsigned char *pub_seed, uint32_t addr[8]) + const unsigned char *pub_seed, uint32_t addr[8], + unsigned char *buf) { - unsigned char *tmp = malloc(params->padding_len + 3 * params->n + 2 * params->n); - - unsigned char *buf = tmp; - unsigned char *bitmask = tmp + (params->padding_len + 3 * params->n); + unsigned char *bitmask = buf + (params->padding_len + 3 * params->n); + unsigned char *prf_buf = bitmask + 2*params->n; unsigned char addr_as_bytes[32]; unsigned int i; @@ -108,34 +102,32 @@ int thash_h(const xmss_params *params, /* Generate the n-byte key. */ set_key_and_mask(addr, 0); addr_to_bytes(addr_as_bytes, addr); - prf(params, buf + params->padding_len, addr_as_bytes, pub_seed); + prf(params, buf + params->padding_len, addr_as_bytes, pub_seed, prf_buf); /* Generate the 2n-byte mask. */ set_key_and_mask(addr, 1); addr_to_bytes(addr_as_bytes, addr); - prf(params, bitmask, addr_as_bytes, pub_seed); + prf(params, bitmask, addr_as_bytes, pub_seed, prf_buf); set_key_and_mask(addr, 2); addr_to_bytes(addr_as_bytes, addr); - prf(params, bitmask + params->n, addr_as_bytes, pub_seed); + prf(params, bitmask + params->n, addr_as_bytes, pub_seed, prf_buf); for (i = 0; i < 2 * params->n; i++) { buf[params->padding_len + params->n + i] = in[i] ^ bitmask[i]; } int ret = core_hash(params, out, buf, params->padding_len + 3 * params->n); - OQS_MEM_insecure_free(tmp); - return ret; } int thash_f(const xmss_params *params, unsigned char *out, const unsigned char *in, - const unsigned char *pub_seed, uint32_t addr[8]) + const unsigned char *pub_seed, uint32_t addr[8], + unsigned char *buf) { - unsigned char *tmp = malloc(params->padding_len + 2 * params->n + params->n); - unsigned char *buf = tmp; - unsigned char *bitmask = tmp + (params->padding_len + 2 * params->n); + unsigned char *bitmask = buf + (params->padding_len + 2 * params->n); + unsigned char *prf_buf = bitmask + params->n; unsigned char addr_as_bytes[32]; unsigned int i; @@ -146,19 +138,17 @@ int thash_f(const xmss_params *params, /* Generate the n-byte key. */ set_key_and_mask(addr, 0); addr_to_bytes(addr_as_bytes, addr); - prf(params, buf + params->padding_len, addr_as_bytes, pub_seed); + prf(params, buf + params->padding_len, addr_as_bytes, pub_seed, prf_buf); /* Generate the n-byte mask. */ set_key_and_mask(addr, 1); addr_to_bytes(addr_as_bytes, addr); - prf(params, bitmask, addr_as_bytes, pub_seed); + prf(params, bitmask, addr_as_bytes, pub_seed, prf_buf); for (i = 0; i < params->n; i++) { buf[params->padding_len + params->n + i] = in[i] ^ bitmask[i]; } int ret = core_hash(params, out, buf, params->padding_len + 2 * params->n); - OQS_MEM_insecure_free(tmp); - return ret; } diff --git a/src/sig_stfl/xmss/external/hash.h b/src/sig_stfl/xmss/external/hash.h index 708dd6932a..e0b06eba98 100644 --- a/src/sig_stfl/xmss/external/hash.h +++ b/src/sig_stfl/xmss/external/hash.h @@ -12,12 +12,14 @@ void addr_to_bytes(unsigned char *bytes, const uint32_t addr[8]); #define prf XMSS_INNER_NAMESPACE(prf) int prf(const xmss_params *params, unsigned char *out, const unsigned char in[32], - const unsigned char *key); + const unsigned char *key, + unsigned char *buf); #define prf_keygen XMSS_INNER_NAMESPACE(prf_keygen) int prf_keygen(const xmss_params *params, unsigned char *out, const unsigned char *in, - const unsigned char *key); + const unsigned char *key, + unsigned char *buf); #define h_msg XMSS_INNER_NAMESPACE(h_msg) int h_msg(const xmss_params *params, @@ -28,12 +30,14 @@ int h_msg(const xmss_params *params, #define thash_h XMSS_INNER_NAMESPACE(thash_h) int thash_h(const xmss_params *params, unsigned char *out, const unsigned char *in, - const unsigned char *pub_seed, uint32_t addr[8]); + const unsigned char *pub_seed, uint32_t addr[8], + unsigned char *buf); #define thash_f XMSS_INNER_NAMESPACE(thash_f) int thash_f(const xmss_params *params, unsigned char *out, const unsigned char *in, - const unsigned char *pub_seed, uint32_t addr[8]); + const unsigned char *pub_seed, uint32_t addr[8], + unsigned char *buf); #define hash_message XMSS_INNER_NAMESPACE(hash_message) int hash_message(const xmss_params *params, unsigned char *out, diff --git a/src/sig_stfl/xmss/external/params.c b/src/sig_stfl/xmss/external/params.c index a1d49d1340..2a91a964df 100644 --- a/src/sig_stfl/xmss/external/params.c +++ b/src/sig_stfl/xmss/external/params.c @@ -369,7 +369,7 @@ int xmss_parse_oid(xmss_params *params, const uint32_t oid) params->d = 1; params->wots_w = 16; - // TODO figure out sensible and legal values for this based on the above + // TODO (from upstream) figure out sensible and legal values for this based on the above params->bds_k = 0; return xmss_xmssmt_initialize_params(params); @@ -692,7 +692,7 @@ int xmssmt_parse_oid(xmss_params *params, const uint32_t oid) params->wots_w = 16; - // TODO figure out sensible and legal values for this based on the above + // TODO (from upstream) figure out sensible and legal values for this based on the above params->bds_k = 0; return xmss_xmssmt_initialize_params(params); diff --git a/src/sig_stfl/xmss/external/wots.c b/src/sig_stfl/xmss/external/wots.c index 8ef4f026cd..067d48e6e4 100644 --- a/src/sig_stfl/xmss/external/wots.c +++ b/src/sig_stfl/xmss/external/wots.c @@ -14,10 +14,11 @@ */ static void expand_seed(const xmss_params *params, unsigned char *outseeds, const unsigned char *inseed, - const unsigned char *pub_seed, uint32_t addr[8]) + const unsigned char *pub_seed, uint32_t addr[8], + unsigned char *buf) { unsigned int i; - unsigned char *buf = malloc(params->n + 32); + unsigned char *prf_buf = buf + params->n + 32; set_hash_addr(addr, 0); set_key_and_mask(addr, 0); @@ -25,10 +26,8 @@ static void expand_seed(const xmss_params *params, for (i = 0; i < params->wots_len; i++) { set_chain_addr(addr, i); addr_to_bytes(buf + params->n, addr); - prf_keygen(params, outseeds + i*params->n, buf, inseed); + prf_keygen(params, outseeds + i*params->n, buf, inseed, prf_buf); } - - OQS_MEM_insecure_free(buf); } /** @@ -41,7 +40,8 @@ static void expand_seed(const xmss_params *params, static void gen_chain(const xmss_params *params, unsigned char *out, const unsigned char *in, unsigned int start, unsigned int steps, - const unsigned char *pub_seed, uint32_t addr[8]) + const unsigned char *pub_seed, uint32_t addr[8], + unsigned char *thash_buf) { unsigned int i; @@ -51,7 +51,7 @@ static void gen_chain(const xmss_params *params, /* Iterate 'steps' calls to the hash function. */ for (i = start; i < (start+steps) && i < params->wots_w; i++) { set_hash_addr(addr, i); - thash_f(params, out, out, pub_seed, addr); + thash_f(params, out, out, pub_seed, addr, thash_buf); } } @@ -88,6 +88,9 @@ static void wots_checksum(const xmss_params *params, int csum = 0; unsigned int csum_bytes_length = (params->wots_len2 * params->wots_log_w + 7) / 8; unsigned char *csum_bytes = malloc(csum_bytes_length); + if (csum_bytes == NULL) { + return; + } unsigned int i; /* Compute checksum. */ @@ -125,15 +128,21 @@ void wots_pkgen(const xmss_params *params, const unsigned char *pub_seed, uint32_t addr[8]) { unsigned int i; - + unsigned char *buf = malloc(2 * params->padding_len + 4 * params->n + 64); + if (buf == NULL) { + return; + } + /* The WOTS+ private key is derived from the seed. */ - expand_seed(params, pk, seed, pub_seed, addr); + expand_seed(params, pk, seed, pub_seed, addr, buf); for (i = 0; i < params->wots_len; i++) { set_chain_addr(addr, i); gen_chain(params, pk + i*params->n, pk + i*params->n, - 0, params->wots_w - 1, pub_seed, addr); + 0, params->wots_w - 1, pub_seed, addr, buf); } + + OQS_MEM_insecure_free(buf); } /** @@ -146,20 +155,25 @@ void wots_sign(const xmss_params *params, uint32_t addr[8]) { unsigned int *lengths = calloc(params->wots_len, sizeof(unsigned int)); + unsigned char *buf = malloc(2 * params->padding_len + 4 * params->n + 64); unsigned int i; + if (lengths == NULL || buf == NULL) { + return; + } chain_lengths(params, lengths, msg); /* The WOTS+ private key is derived from the seed. */ - expand_seed(params, sig, seed, pub_seed, addr); + expand_seed(params, sig, seed, pub_seed, addr, buf); for (i = 0; i < params->wots_len; i++) { set_chain_addr(addr, i); gen_chain(params, sig + i*params->n, sig + i*params->n, - 0, lengths[i], pub_seed, addr); + 0, lengths[i], pub_seed, addr, buf); } OQS_MEM_insecure_free(lengths); + OQS_MEM_insecure_free(buf); } /** @@ -172,15 +186,21 @@ void wots_pk_from_sig(const xmss_params *params, unsigned char *pk, const unsigned char *pub_seed, uint32_t addr[8]) { unsigned int *lengths = calloc(params->wots_len, sizeof(unsigned int )); + const size_t thash_buf_len = 2 * params->padding_len + 4 * params->n + 32; + unsigned char *thash_buf = malloc(thash_buf_len); unsigned int i; + if (lengths == NULL || thash_buf == NULL) { + return; + } chain_lengths(params, lengths, msg); for (i = 0; i < params->wots_len; i++) { set_chain_addr(addr, i); gen_chain(params, pk + i*params->n, sig + i*params->n, - lengths[i], params->wots_w - 1 - lengths[i], pub_seed, addr); + lengths[i], params->wots_w - 1 - lengths[i], pub_seed, addr, thash_buf); } OQS_MEM_insecure_free(lengths); + OQS_MEM_insecure_free(thash_buf); } diff --git a/src/sig_stfl/xmss/external/xmss_commons.c b/src/sig_stfl/xmss/external/xmss_commons.c index 645faf0112..3d7e469a4d 100644 --- a/src/sig_stfl/xmss/external/xmss_commons.c +++ b/src/sig_stfl/xmss/external/xmss_commons.c @@ -16,7 +16,8 @@ */ static void l_tree(const xmss_params *params, unsigned char *leaf, unsigned char *wots_pk, - const unsigned char *pub_seed, uint32_t addr[8]) + const unsigned char *pub_seed, uint32_t addr[8], + unsigned char *thash_buf) { unsigned int l = params->wots_len; unsigned int parent_nodes; @@ -31,7 +32,7 @@ static void l_tree(const xmss_params *params, set_tree_index(addr, i); /* Hashes the nodes at (i*2)*params->n and (i*2)*params->n + 1 */ thash_h(params, wots_pk + i*params->n, - wots_pk + (i*2)*params->n, pub_seed, addr); + wots_pk + (i*2)*params->n, pub_seed, addr, thash_buf); } /* If the row contained an odd number of nodes, the last node was not hashed. Instead, we pull it up to the next layer. */ @@ -55,10 +56,11 @@ static void l_tree(const xmss_params *params, static void compute_root(const xmss_params *params, unsigned char *root, const unsigned char *leaf, unsigned long leafidx, const unsigned char *auth_path, - const unsigned char *pub_seed, uint32_t addr[8]) + const unsigned char *pub_seed, uint32_t addr[8], + unsigned char *buffer, + unsigned char *thash_buf) { - uint32_t i; - unsigned char *buffer = malloc(2*params->n); + uint32_t i; /* If leafidx is odd (last bit = 1), current path element is a right child and auth_path has to go left. Otherwise it is the other way around. */ @@ -79,11 +81,11 @@ static void compute_root(const xmss_params *params, unsigned char *root, /* Pick the right or left neighbor, depending on parity of the node. */ if (leafidx & 1) { - thash_h(params, buffer + params->n, buffer, pub_seed, addr); + thash_h(params, buffer + params->n, buffer, pub_seed, addr, thash_buf); memcpy(buffer, auth_path, params->n); } else { - thash_h(params, buffer, buffer, pub_seed, addr); + thash_h(params, buffer, buffer, pub_seed, addr, thash_buf); memcpy(buffer + params->n, auth_path, params->n); } auth_path += params->n; @@ -93,9 +95,8 @@ static void compute_root(const xmss_params *params, unsigned char *root, set_tree_height(addr, params->tree_height - 1); leafidx >>= 1; set_tree_index(addr, leafidx); - thash_h(params, root, buffer, pub_seed, addr); + thash_h(params, root, buffer, pub_seed, addr, thash_buf); - OQS_MEM_insecure_free(buffer); } @@ -108,11 +109,15 @@ void gen_leaf_wots(const xmss_params *params, unsigned char *leaf, const unsigned char *sk_seed, const unsigned char *pub_seed, uint32_t ltree_addr[8], uint32_t ots_addr[8]) { - unsigned char *pk = malloc(params->wots_sig_bytes); + unsigned char *pk = malloc(params->wots_sig_bytes + 2 * params->padding_len + 6 * params->n + 32); + if (pk == NULL) { + return; + } + unsigned char *thash_buf = pk + params->wots_sig_bytes; wots_pkgen(params, pk, sk_seed, pub_seed, ots_addr); - l_tree(params, leaf, pk, pub_seed, ltree_addr); + l_tree(params, leaf, pk, pub_seed, ltree_addr, thash_buf); OQS_MEM_insecure_free(pk); } @@ -146,10 +151,16 @@ int xmssmt_core_sign_open(const xmss_params *params, const unsigned char *pub_root = pk; const unsigned char *pub_seed = pk + params->n; - unsigned char *tmp = malloc(params->wots_sig_bytes + params->n + params->n); + unsigned char *tmp = malloc(params->wots_sig_bytes + params->n + params->n + + + 2 *params->n + 2 * params->padding_len + 6 * params->n + 32); + if (tmp == NULL) { + return -1; + } unsigned char *wots_pk = tmp; unsigned char *leaf = tmp + params->wots_sig_bytes; unsigned char *root = leaf + params->n; + unsigned char *compute_root_buf = root + params->n; + unsigned char *thash_buf = compute_root_buf + 2*params->n; unsigned long long prefix_length = params->padding_len + 3*params->n; unsigned long long m_with_prefix_len = mlen + prefix_length; @@ -211,10 +222,10 @@ int xmssmt_core_sign_open(const xmss_params *params, /* Compute the leaf node using the WOTS public key. */ set_ltree_addr(ltree_addr, idx_leaf); - l_tree(params, leaf, wots_pk, pub_seed, ltree_addr); + l_tree(params, leaf, wots_pk, pub_seed, ltree_addr, thash_buf); /* Compute the root node of this subtree. */ - compute_root(params, root, leaf, idx_leaf, sm, pub_seed, node_addr); + compute_root(params, root, leaf, idx_leaf, sm, pub_seed, node_addr, compute_root_buf, thash_buf); sm += params->tree_height*params->n; } diff --git a/src/sig_stfl/xmss/external/xmss_core.c b/src/sig_stfl/xmss/external/xmss_core.c deleted file mode 100644 index 1052d4d7e5..0000000000 --- a/src/sig_stfl/xmss/external/xmss_core.c +++ /dev/null @@ -1,278 +0,0 @@ -// SPDX-License-Identifier: (Apache-2.0 OR MIT) AND CC0-1.0 -#include -#include -#include -#include - -#include "hash.h" -#include "hash_address.h" -#include "params.h" -#include "wots.h" -#include "utils.h" -#include "xmss_commons.h" -#include "xmss_core.h" - -/** - * For a given leaf index, computes the authentication path and the resulting - * root node using Merkle's TreeHash algorithm. - * Expects the layer and tree parts of subtree_addr to be set. - */ -static void treehash(const xmss_params *params, - unsigned char *root, unsigned char *auth_path, - const unsigned char *sk_seed, - const unsigned char *pub_seed, - uint32_t leaf_idx, const uint32_t subtree_addr[8]) -{ - unsigned char stack[(params->tree_height+1)*params->n]; - unsigned int heights[params->tree_height+1]; - unsigned int offset = 0; - - /* The subtree has at most 2^20 leafs, so uint32_t suffices. */ - uint32_t idx; - uint32_t tree_idx; - - /* We need all three types of addresses in parallel. */ - uint32_t ots_addr[8] = {0}; - uint32_t ltree_addr[8] = {0}; - uint32_t node_addr[8] = {0}; - - /* Select the required subtree. */ - copy_subtree_addr(ots_addr, subtree_addr); - copy_subtree_addr(ltree_addr, subtree_addr); - copy_subtree_addr(node_addr, subtree_addr); - - set_type(ots_addr, XMSS_ADDR_TYPE_OTS); - set_type(ltree_addr, XMSS_ADDR_TYPE_LTREE); - set_type(node_addr, XMSS_ADDR_TYPE_HASHTREE); - - for (idx = 0; idx < (uint32_t)(1 << params->tree_height); idx++) { - /* Add the next leaf node to the stack. */ - set_ltree_addr(ltree_addr, idx); - set_ots_addr(ots_addr, idx); - gen_leaf_wots(params, stack + offset*params->n, - sk_seed, pub_seed, ltree_addr, ots_addr); - offset++; - heights[offset - 1] = 0; - - /* If this is a node we need for the auth path.. */ - if ((leaf_idx ^ 0x1) == idx) { - memcpy(auth_path, stack + (offset - 1)*params->n, params->n); - } - - /* While the top-most nodes are of equal height.. */ - while (offset >= 2 && heights[offset - 1] == heights[offset - 2]) { - /* Compute index of the new node, in the next layer. */ - tree_idx = (idx >> (heights[offset - 1] + 1)); - - /* Hash the top-most nodes from the stack together. */ - /* Note that tree height is the 'lower' layer, even though we use - the index of the new node on the 'higher' layer. This follows - from the fact that we address the hash function calls. */ - set_tree_height(node_addr, heights[offset - 1]); - set_tree_index(node_addr, tree_idx); - thash_h(params, stack + (offset-2)*params->n, - stack + (offset-2)*params->n, pub_seed, node_addr); - offset--; - /* Note that the top-most node is now one layer higher. */ - heights[offset - 1]++; - - /* If this is a node we need for the auth path.. */ - if (((leaf_idx >> heights[offset - 1]) ^ 0x1) == tree_idx) { - memcpy(auth_path + heights[offset - 1]*params->n, - stack + (offset - 1)*params->n, params->n); - } - } - } - memcpy(root, stack, params->n); -} - -/** - * Given a set of parameters, this function returns the size of the secret key. - * This is implementation specific, as varying choices in tree traversal will - * result in varying requirements for state storage. - */ -unsigned long long xmss_xmssmt_core_sk_bytes(const xmss_params *params) -{ - return params->index_bytes + 4 * params->n; -} - -/* - * Generates a XMSS key pair for a given parameter set. - * Format sk: [(32bit) index || SK_SEED || SK_PRF || root || PUB_SEED] - * Format pk: [root || PUB_SEED], omitting algorithm OID. - */ -int xmss_core_keypair(const xmss_params *params, - unsigned char *pk, unsigned char *sk) -{ - /* The key generation procedure of XMSS and XMSSMT is exactly the same. - The only important detail is that the right subtree must be selected; - this requires us to correctly set the d=1 parameter for XMSS. */ - return xmssmt_core_keypair(params, pk, sk); -} - -/** - * Signs a message. Returns an array containing the signature followed by the - * message and an updated secret key. - */ -int xmss_core_sign(const xmss_params *params, - unsigned char *sk, - unsigned char *sm, unsigned long long *smlen, - const unsigned char *m, unsigned long long mlen) -{ - /* XMSS signatures are fundamentally an instance of XMSSMT signatures. - For d=1, as is the case with XMSS, some of the calls in the XMSSMT - routine become vacuous (i.e. the loop only iterates once, and address - management can be simplified a bit).*/ - return xmssmt_core_sign(params, sk, sm, smlen, m, mlen); -} - -/* - * Derives a XMSSMT key pair for a given parameter set. - * Seed must be 3*n long. - * Format sk: [(ceil(h/8) bit) index || SK_SEED || SK_PRF || root || PUB_SEED] - * Format pk: [root || PUB_SEED] omitting algorithm OID. - */ -int xmssmt_core_seed_keypair(const xmss_params *params, - unsigned char *pk, unsigned char *sk, - unsigned char *seed) -{ - /* We do not need the auth path in key generation, but it simplifies the - code to have just one treehash routine that computes both root and path - in one function. */ - unsigned char auth_path[params->tree_height * params->n]; - uint32_t top_tree_addr[8] = {0}; - set_layer_addr(top_tree_addr, params->d - 1); - - /* Initialize index to 0. */ - memset(sk, 0, params->index_bytes); - sk += params->index_bytes; - - /* Initialize SK_SEED and SK_PRF. */ - memcpy(sk, seed, 2 * params->n); - - /* Initialize PUB_SEED. */ - memcpy(sk + 3 * params->n, seed + 2 * params->n, params->n); - memcpy(pk + params->n, sk + 3*params->n, params->n); - - /* Compute root node of the top-most subtree. */ - treehash(params, pk, auth_path, sk, pk + params->n, 0, top_tree_addr); - memcpy(sk + 2*params->n, pk, params->n); - - return 0; -} - -/* - * Generates a XMSSMT key pair for a given parameter set. - * Format sk: [(ceil(h/8) bit) index || SK_SEED || SK_PRF || root || PUB_SEED] - * Format pk: [root || PUB_SEED] omitting algorithm OID. - */ -int xmssmt_core_keypair(const xmss_params *params, - unsigned char *pk, unsigned char *sk) -{ - unsigned char seed[3 * params->n]; - - OQS_randombytes(seed, 3 * params->n); - xmssmt_core_seed_keypair(params, pk, sk, seed); - - return 0; -} - -/** - * Signs a message. Returns an array containing the signature followed by the - * message and an updated secret key. - */ -int xmssmt_core_sign(const xmss_params *params, - unsigned char *sk, - unsigned char *sm, unsigned long long *smlen, - const unsigned char *m, unsigned long long mlen) -{ - const unsigned char *sk_seed = sk + params->index_bytes; - const unsigned char *sk_prf = sk + params->index_bytes + params->n; - const unsigned char *pub_root = sk + params->index_bytes + 2*params->n; - const unsigned char *pub_seed = sk + params->index_bytes + 3*params->n; - - unsigned long long prefix_length = params->padding_len + 3*params->n; - unsigned char m_with_prefix[mlen + prefix_length]; - - unsigned char root[params->n]; - unsigned char *mhash = root; - unsigned long long idx; - unsigned char idx_bytes_32[32]; - unsigned int i; - uint32_t idx_leaf; - - uint32_t ots_addr[8] = {0}; - set_type(ots_addr, XMSS_ADDR_TYPE_OTS); - - /* Already put the message in the right place, to make it easier to prepend - * things when computing the hash over the message. */ - memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, prefix_length); - memcpy(m_with_prefix + prefix_length, m, mlen); - *smlen = params->sig_bytes; - - /* Read and use the current index from the secret key. */ - idx = (unsigned long)bytes_to_ull(sk, params->index_bytes); - - /* Check if we can still sign with this sk. - * If not, return -2 - * - * If this is the last possible signature (because the max index value - * is reached), production implementations should delete the secret key - * to prevent accidental further use. - * - * For the case of total tree height of 64 we do not use the last signature - * to be on the safe side (there is no index value left to indicate that the - * key is finished, hence external handling would be necessary) - */ - if (idx >= ((1ULL << params->full_height) - 1)) { - // Delete secret key here. We only do this in memory, production code - // has to make sure that this happens on disk. - memset(sk, 0xFF, params->index_bytes); - memset(sk + params->index_bytes, 0, (params->sk_bytes - params->index_bytes)); - if (idx > ((1ULL << params->full_height) - 1)) - return -2; // We already used all one-time keys - if ((params->full_height == 64) && (idx == UINT64_MAX)) - return -2; // We already used all one-time keys - } - - memcpy(sm, sk, params->index_bytes); - - /************************************************************************* - * THIS IS WHERE PRODUCTION IMPLEMENTATIONS WOULD UPDATE THE SECRET KEY. * - *************************************************************************/ - /* Increment the index in the secret key. */ - ull_to_bytes(sk, params->index_bytes, idx + 1); - - /* Compute the digest randomization value. */ - ull_to_bytes(idx_bytes_32, 32, idx); - prf(params, sm + params->index_bytes, idx_bytes_32, sk_prf); - - /* Compute the message hash. */ - hash_message(params, mhash, sm + params->index_bytes, pub_root, idx, - m_with_prefix, - mlen); - sm += params->index_bytes + params->n; - - set_type(ots_addr, XMSS_ADDR_TYPE_OTS); - - for (i = 0; i < params->d; i++) { - idx_leaf = (idx & ((1 << params->tree_height)-1)); - idx = idx >> params->tree_height; - - set_layer_addr(ots_addr, i); - set_tree_addr(ots_addr, idx); - set_ots_addr(ots_addr, idx_leaf); - - /* Compute a WOTS signature. */ - /* Initially, root = mhash, but on subsequent iterations it is the root - of the subtree below the currently processed subtree. */ - wots_sign(params, sm, root, sk_seed, pub_seed, ots_addr); - sm += params->wots_sig_bytes; - - /* Compute the authentication path for the used WOTS leaf. */ - treehash(params, root, sm, sk_seed, pub_seed, idx_leaf, ots_addr); - sm += params->tree_height*params->n; - } - - return 0; -} diff --git a/src/sig_stfl/xmss/external/xmss_core_fast.c b/src/sig_stfl/xmss/external/xmss_core_fast.c index d539c1f6c2..ed8886501f 100644 --- a/src/sig_stfl/xmss/external/xmss_core_fast.c +++ b/src/sig_stfl/xmss/external/xmss_core_fast.c @@ -88,8 +88,8 @@ static void xmssmt_deserialize_state(const xmss_params *params, /* Skip past the 'regular' sk */ sk += params->index_bytes + 4*params->n; - // TODO These data sizes follow from the (former) test xmss_core_fast.c - // TODO They should be reconsidered / motivated more explicitly + // TODO (from upstream) These data sizes follow from the (former) test xmss_core_fast.c + // TODO (from upstream) They should be reconsidered / motivated more explicitly for (i = 0; i < 2*params->d - 1; i++) { states[i].stack = sk; @@ -162,20 +162,23 @@ static void memswap(void *a, void *b, void *t, unsigned long long len) * it is now necessary to make swaps 'real swaps'. This could be done in the * serialization function as well, but that causes more overhead */ -// TODO this should not be necessary if we keep better track of the states +// TODO (from upstream) this should not be necessary if we keep better track of the states static void deep_state_swap(const xmss_params *params, bds_state *a, bds_state *b) { if (a->stack == NULL || b->stack == NULL) { return; } - // TODO this is extremely ugly and should be refactored - // TODO right now, this ensures that both 'stack' and 'retain' fit + // TODO (from upstream) this is extremely ugly and should be refactored + // TODO (from upstream) right now, this ensures that both 'stack' and 'retain' fit unsigned char *t = malloc( ((params->tree_height + 1) > ((1 << params->bds_k) - params->bds_k - 1) ? (params->tree_height + 1) : ((1 << params->bds_k) - params->bds_k - 1)) * params->n); + if (t == NULL) { + return; + } unsigned int i; memswap(a->stack, b->stack, t, (params->tree_height + 1) * params->n); @@ -240,6 +243,12 @@ static void treehash_init(const xmss_params *params, uint32_t lastnode = index +(1<n, sizeof(unsigned char)); unsigned int *stacklevels = malloc((height + 1)*sizeof(unsigned int)); + unsigned char *thash_buf = malloc(2 * params->padding_len + 6 * params->n + 32); + + if (stack == NULL || stacklevels == NULL || thash_buf == NULL) { + return; + } + unsigned int stackoffset=0; unsigned int nodeh; @@ -274,7 +283,7 @@ static void treehash_init(const xmss_params *params, } set_tree_height(node_addr, stacklevels[stackoffset-1]); set_tree_index(node_addr, (idx >> (stacklevels[stackoffset-1]+1))); - thash_h(params, stack+(stackoffset-2)*params->n, stack+(stackoffset-2)*params->n, pub_seed, node_addr); + thash_h(params, stack+(stackoffset-2)*params->n, stack+(stackoffset-2)*params->n, pub_seed, node_addr, thash_buf); stacklevels[stackoffset-2]++; stackoffset--; } @@ -285,6 +294,7 @@ static void treehash_init(const xmss_params *params, OQS_MEM_insecure_free(stacklevels); OQS_MEM_insecure_free(stack); + OQS_MEM_insecure_free(thash_buf); } static void treehash_update(const xmss_params *params, @@ -309,6 +319,11 @@ static void treehash_update(const xmss_params *params, set_ots_addr(ots_addr, treehash->next_idx); unsigned char *nodebuffer = malloc(2 * params->n); + unsigned char *thash_buf = malloc(2 * params->padding_len + 6 * params->n + 32); + if (nodebuffer == NULL || thash_buf == NULL) { + return; + } + unsigned int nodeheight = 0; gen_leaf_wots(params, nodebuffer, sk_seed, pub_seed, ltree_addr, ots_addr); while (treehash->stackusage > 0 && state->stacklevels[state->stackoffset-1] == nodeheight) { @@ -316,7 +331,7 @@ static void treehash_update(const xmss_params *params, memcpy(nodebuffer, state->stack + (state->stackoffset-1)*params->n, params->n); set_tree_height(node_addr, nodeheight); set_tree_index(node_addr, (treehash->next_idx >> (nodeheight+1))); - thash_h(params, nodebuffer, nodebuffer, pub_seed, node_addr); + thash_h(params, nodebuffer, nodebuffer, pub_seed, node_addr, thash_buf); nodeheight++; treehash->stackusage--; state->stackoffset--; @@ -334,6 +349,7 @@ static void treehash_update(const xmss_params *params, } OQS_MEM_insecure_free(nodebuffer); + OQS_MEM_insecure_free(thash_buf); } /** @@ -393,6 +409,11 @@ static char bds_state_update(const xmss_params *params, uint32_t ltree_addr[8] = {0}; uint32_t node_addr[8] = {0}; uint32_t ots_addr[8] = {0}; + unsigned char *thash_buf = malloc(2 * params->padding_len + 6 * params->n + 32); + if (thash_buf == NULL) + { + return -1; + } unsigned int nodeh; int idx = state->next_leaf; @@ -434,12 +455,14 @@ static char bds_state_update(const xmss_params *params, } set_tree_height(node_addr, state->stacklevels[state->stackoffset-1]); set_tree_index(node_addr, (idx >> (state->stacklevels[state->stackoffset-1]+1))); - thash_h(params, state->stack+(state->stackoffset-2)*params->n, state->stack+(state->stackoffset-2)*params->n, pub_seed, node_addr); + thash_h(params, state->stack+(state->stackoffset-2)*params->n, state->stack+(state->stackoffset-2)*params->n, pub_seed, node_addr, thash_buf); state->stacklevels[state->stackoffset-2]++; state->stackoffset--; } state->next_leaf++; + + OQS_MEM_insecure_free(thash_buf); return 0; } @@ -458,6 +481,10 @@ static void bds_round(const xmss_params *params, unsigned int startidx; unsigned int offset, rowidx; unsigned char *buf = malloc(2 * params->n); + unsigned char *thash_buf = malloc(2 * params->padding_len + 6 * params->n + 32); + if (buf == NULL || thash_buf == NULL) { + return; + } uint32_t ots_addr[8] = {0}; uint32_t ltree_addr[8] = {0}; @@ -495,7 +522,7 @@ static void bds_round(const xmss_params *params, else { set_tree_height(node_addr, (tau-1)); set_tree_index(node_addr, leaf_idx >> tau); - thash_h(params, state->auth + tau * params->n, buf, pub_seed, node_addr); + thash_h(params, state->auth + tau * params->n, buf, pub_seed, node_addr, thash_buf); for (i = 0; i < tau; i++) { if (i < params->tree_height - params->bds_k) { memcpy(state->auth + i * params->n, state->treehash[i].node, params->n); @@ -519,6 +546,7 @@ static void bds_round(const xmss_params *params, } OQS_MEM_insecure_free(buf); + OQS_MEM_insecure_free(thash_buf); } /** @@ -554,9 +582,12 @@ int xmss_core_keypair(const xmss_params *params, { uint32_t addr[8] = {0}; - // TODO refactor BDS state not to need separate treehash instances + // TODO (from upstream) refactor BDS state not to need separate treehash instances bds_state state; treehash_inst *treehash = calloc(params->tree_height - params->bds_k, sizeof(treehash_inst)); + if (treehash == NULL) { + return -1; + } state.treehash = treehash; xmss_deserialize_state(params, &state, sk); @@ -612,11 +643,15 @@ int xmss_core_sign(const xmss_params *params, uint16_t i = 0; - // TODO refactor BDS state not to need separate treehash instances + // TODO (from upstream) refactor BDS state not to need separate treehash instances bds_state state; treehash_inst *treehash = calloc(params->tree_height - params->bds_k, sizeof(treehash_inst)); - state.treehash = treehash; + unsigned char *tmp = malloc(5 * params->n + params->padding_len + params->n + 32); + if (treehash == NULL || tmp == NULL) { + return -1; + } + state.treehash = treehash; /* Load the BDS state from sk. */ xmss_deserialize_state(params, &state, sk); @@ -644,7 +679,6 @@ int xmss_core_sign(const xmss_params *params, goto cleanup; } } - unsigned char *tmp = malloc(5 * params->n); unsigned char *sk_seed = tmp; unsigned char *sk_prf = sk_seed + params->n; @@ -670,6 +704,7 @@ int xmss_core_sign(const xmss_params *params, // Init working params unsigned char *R = pub_seed + params->n; unsigned char *msg_h = R + params->n; + unsigned char *prf_buf = msg_h + params->n; uint32_t ots_addr[8] = {0}; // --------------------------------- @@ -678,12 +713,15 @@ int xmss_core_sign(const xmss_params *params, // Message Hash: // First compute pseudorandom value - prf(params, R, idx_bytes_32, sk_prf); + prf(params, R, idx_bytes_32, sk_prf, prf_buf); /* Already put the message in the right place, to make it easier to prepend * things when computing the hash over the message. */ unsigned long long prefix_length = params->padding_len + 3*params->n; unsigned char *m_with_prefix = malloc((size_t)(mlen + prefix_length)); + if (m_with_prefix == NULL) { + return -1; + } memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, (size_t)prefix_length); memcpy(m_with_prefix + prefix_length, m, (size_t)mlen); @@ -762,9 +800,12 @@ int xmssmt_core_keypair(const xmss_params *params, unsigned int i; unsigned char *wots_sigs; - // TODO refactor BDS state not to need separate treehash instances + // TODO (from upstream) refactor BDS state not to need separate treehash instances bds_state *states = calloc(2*params->d - 1, sizeof(bds_state)); treehash_inst *treehash = calloc((2*params->d - 1) * (params->tree_height - params->bds_k), sizeof(treehash_inst)); + if (states == NULL || treehash == NULL) { + return -1; + } for (i = 0; i < 2*params->d - 1; i++) { states[i].treehash = treehash + i * (params->tree_height - params->bds_k); } @@ -834,14 +875,21 @@ int xmssmt_core_sign(const xmss_params *params, int needswap_upto = -1; unsigned int updates; - unsigned char *tmp = malloc(5 * params->n); - + // TODO (from upstream) refactor BDS state not to need separate treehash instances + bds_state *states = calloc(2*params->d - 1, sizeof(bds_state)); + treehash_inst *treehash = calloc((2*params->d - 1) * (params->tree_height - params->bds_k), sizeof(treehash_inst)); + unsigned char *tmp = malloc(5 * params->n + + params->padding_len + params->n + 32); + if (states == NULL || treehash == NULL || tmp == NULL) { + return -1; + } unsigned char *sk_seed = tmp; unsigned char *sk_prf = sk_seed + params->n; unsigned char *pub_seed = sk_prf + params->n; // Init working params unsigned char *R = pub_seed + params->n; unsigned char *msg_h = R + params->n; + unsigned char *prf_buf = msg_h + params->n; uint32_t addr[8] = {0}; uint32_t ots_addr[8] = {0}; unsigned char idx_bytes_32[32]; @@ -852,9 +900,6 @@ int xmssmt_core_sign(const xmss_params *params, unsigned char *m_with_prefix = NULL; int ret = 0; - // TODO refactor BDS state not to need separate treehash instances - bds_state *states = calloc(2*params->d - 1, sizeof(bds_state)); - treehash_inst *treehash = calloc((2*params->d - 1) * (params->tree_height - params->bds_k), sizeof(treehash_inst)); for (i = 0; i < 2*params->d - 1; i++) { states[i].stack = NULL; states[i].stackoffset = 0; @@ -921,7 +966,7 @@ int xmssmt_core_sign(const xmss_params *params, // Message Hash: // First compute pseudorandom value ull_to_bytes(idx_bytes_32, 32, idx); - prf(params, R, idx_bytes_32, sk_prf); + prf(params, R, idx_bytes_32, sk_prf, prf_buf); /* Already put the message in the right place, to make it easier to prepend * things when computing the hash over the message. */ diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c b/src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c index 7868d68c94..ed25233be1 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_xmssmt.c @@ -14,7 +14,6 @@ #define XMSS_UNUSED_ATT #endif - // macro to en/disable OQS_SIG_STFL-only structs used only in sig&gen case: #ifdef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN #define XMSS_SIGGEN(xmss_v, XMSS_V) \ From 8524a16c4e3a4daa6e067af1f4a1dbb3858093d6 Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Fri, 12 Apr 2024 11:55:57 -0400 Subject: [PATCH 46/68] Post-rebase cleanup --- .CMake/alg_support.cmake | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index bcf6150e7e..75bee17e6a 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -495,7 +495,7 @@ if(OQS_DIST_X86_64_BUILD OR (OQS_USE_AVX2_INSTRUCTIONS)) endif() endif() -##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_ADD_ENABLE_BY_ALG_END +##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_ADD_ENABLE_BY_ALG_CONDITIONAL_END option(OQS_ENABLE_SIG_STFL_XMSS "Enable XMSS algorithm family" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha256_h10 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) @@ -582,26 +582,6 @@ if(OQS_ALLOW_SFTL_KEY_AND_SIG_GEN STREQUAL "ON") message(STATUS "Experimental stateful key and signature generation is enabled. Ensure secret keys are securely stored to prevent multiple simultaneous sign operations.") endif() -if((OQS_MINIMAL_BUILD STREQUAL "ON")) - message(FATAL_ERROR "OQS_MINIMAL_BUILD option ${OQS_MINIMAL_BUILD} no longer supported") -endif() - -if(NOT DEFINED OQS_ALGS_ENABLED OR OQS_ALGS_ENABLED STREQUAL "") - set(OQS_ALGS_ENABLED "All") -endif() - -if(NOT ((OQS_MINIMAL_BUILD STREQUAL "") OR (OQS_MINIMAL_BUILD STREQUAL "OFF"))) - filter_algs("${OQS_MINIMAL_BUILD}") -elseif (${OQS_ALGS_ENABLED} STREQUAL "STD") -##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_LIST_STANDARDIZED_ALGS_START - filter_algs("KEM_kyber_512;KEM_kyber_768;KEM_kyber_1024;SIG_dilithium_2;SIG_dilithium_3;SIG_dilithium_5;SIG_falcon_512;SIG_falcon_1024;SIG_sphincs_sha2_128f_simple;SIG_sphincs_sha2_128s_simple;SIG_sphincs_sha2_192f_simple;SIG_sphincs_sha2_192s_simple;SIG_sphincs_sha2_256f_simple;SIG_sphincs_sha2_256s_simple;SIG_sphincs_shake_128f_simple;SIG_sphincs_shake_128s_simple;SIG_sphincs_shake_192f_simple;SIG_sphincs_shake_192s_simple;SIG_sphincs_shake_256f_simple;SIG_sphincs_shake_256s_simple") -##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_LIST_STANDARDIZED_ALGS_END -elseif(${OQS_ALGS_ENABLED} STREQUAL "NIST_R4") - filter_algs("KEM_classic_mceliece_348864;KEM_classic_mceliece_348864f;KEM_classic_mceliece_460896;KEM_classic_mceliece_460896f;KEM_classic_mceliece_6688128;KEM_classic_mceliece_6688128f;KEM_classic_mceliece_6960119;KEM_classic_mceliece_6960119f;KEM_classic_mceliece_8192128;KEM_classic_mceliece_8192128f;KEM_hqc_128;KEM_hqc_192;KEM_hqc_256;KEM_bike_l1;KEM_bike_l3") -else() - message(STATUS "Alg enablement unchanged") -endif() - # Set XKCP (Keccak) required for Sphincs AVX2 code even if OpenSSL3 SHA3 is used: if (${OQS_ENABLE_SIG_SPHINCS} OR NOT ${OQS_USE_SHA3_OPENSSL}) set(OQS_ENABLE_SHA3_xkcp_low ON) @@ -614,4 +594,4 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin") else() set(OQS_ENABLE_SHA3_xkcp_low_avx2 OFF) endif() -endif() \ No newline at end of file +endif() From 5da49e33c6dd35780dc65dd5b1a4200191436405 Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Fri, 12 Apr 2024 12:05:51 -0400 Subject: [PATCH 47/68] Satisfy astyle --- src/common/sha2/sha2.c | 2 +- src/common/sha2/sha2_impl.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/sha2/sha2.c b/src/common/sha2/sha2.c index e0d3902e3b..b34e61273e 100644 --- a/src/common/sha2/sha2.c +++ b/src/common/sha2/sha2.c @@ -23,7 +23,7 @@ void OQS_SHA2_sha256_inc_blocks(OQS_SHA2_sha256_ctx *state, const uint8_t *in, s } void OQS_SHA2_sha256_inc(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t len) { - callbacks->SHA2_sha256_inc(state, in, len); + callbacks->SHA2_sha256_inc(state, in, len); } void OQS_SHA2_sha256_inc_finalize(uint8_t *out, OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inlen) { diff --git a/src/common/sha2/sha2_impl.c b/src/common/sha2/sha2_impl.c index 1d6d4fb323..33805989e8 100644 --- a/src/common/sha2/sha2_impl.c +++ b/src/common/sha2/sha2_impl.c @@ -112,7 +112,7 @@ struct OQS_SHA2_callbacks sha2_default_callbacks = { SHA2_sha256, SHA2_sha256_inc_init, SHA2_sha256_inc_ctx_clone, - SHA2_sha256_inc, + SHA2_sha256_inc, SHA2_sha256_inc_blocks, SHA2_sha256_inc_finalize, SHA2_sha256_inc_ctx_release, From a535114d514dc5871a8f4d7ce9515954b9befc3a Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Mon, 15 Apr 2024 09:28:23 -0400 Subject: [PATCH 48/68] Fix macOS build error: lld -> llu --- tests/kat_sig_stfl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index 76a7307037..158c953fa5 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -311,7 +311,7 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { // Echo back remain if (FindMarker(fp_rsp, "remain = ")) { - fscanf(fp_rsp, "%lld", &sigs_remain); + fscanf(fp_rsp, "%llu", &sigs_remain); fprintf(fh, "remain = %llu\n", sigs_remain); } else { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_remaining failed!\n", method_name); @@ -320,7 +320,7 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { // Echo back max if (FindMarker(fp_rsp, "max = ")) { - fscanf(fp_rsp, "%lld", &sigs_maximum); + fscanf(fp_rsp, "%llu", &sigs_maximum); fprintf(fh, "max = %llu\n", sigs_maximum); } else { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_total failed!\n", method_name); From 71ee535eca8398f170a489ad45556464816782de Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Mon, 15 Apr 2024 09:37:34 -0400 Subject: [PATCH 49/68] Bring EVP_DigestUpdate calls in line with main --- src/common/sha2/sha2_ossl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/sha2/sha2_ossl.c b/src/common/sha2/sha2_ossl.c index 064fb61ad8..3aff58fab6 100644 --- a/src/common/sha2/sha2_ossl.c +++ b/src/common/sha2/sha2_ossl.c @@ -59,7 +59,7 @@ static void SHA2_sha256_inc_init(OQS_SHA2_sha256_ctx *state) { } static void SHA2_sha256_inc(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t len) { - OQS_OPENSSL_GUARD(EVP_DigestUpdate((EVP_MD_CTX *) state->ctx, in, len)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestUpdate)((EVP_MD_CTX *) state->ctx, in, len)); } static void SHA2_sha256_inc_blocks(OQS_SHA2_sha256_ctx *state, const uint8_t *in, size_t inblocks) { From 154d8e4b1c07c5fa4f0c12303a9c2a38aa3a36b3 Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Mon, 15 Apr 2024 09:38:32 -0400 Subject: [PATCH 50/68] Fix test program linkage for cross-compiling --- tests/CMakeLists.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c59657f646..eb297a8047 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -105,6 +105,14 @@ endif() add_executable(kat_sig_stfl kat_sig_stfl.c test_helpers.c) target_link_libraries(kat_sig_stfl PRIVATE ${TEST_DEPS}) +if(CMAKE_SYSTEM_NAME STREQUAL "Windows" AND BUILD_SHARED_LIBS) + # workaround for Windows .dll + if(CMAKE_CROSSCOMPILING) + target_link_options(kat_sig_stfl PRIVATE -Wl,--allow-multiple-definition) + else() + target_link_options(kat_sig_stfl PRIVATE "/FORCE:MULTIPLE") + endif() +endif() add_executable(test_sig test_sig.c) target_link_libraries(test_sig PRIVATE ${TEST_DEPS}) From b2cdab6b79acaa60080328be1db02a0c55c52811 Mon Sep 17 00:00:00 2001 From: Duc Tri Nguyen Date: Tue, 16 Apr 2024 14:58:10 -0400 Subject: [PATCH 51/68] Fix typo from STFL to SFTL Signed-off-by: Duc Tri Nguyen --- .CMake/alg_support.cmake | 4 ++-- src/oqsconfig.h.cmake | 2 +- src/sig_stfl/sig_stfl.c | 12 ++++++------ src/sig_stfl/sig_stfl.h | 4 ++-- src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c | 2 +- tests/example_sig_stfl.c | 2 +- tests/kat_sig_stfl.c | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index 75bee17e6a..c2c74230cc 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -564,7 +564,7 @@ cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h15_w8 "" ON "OQS_E cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h20_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) option(OQS_ENABLE_SIG_STFL_KEY_SIG_GEN "Enable stateful key and signature generation for research and experimentation" OFF) -cmake_dependent_option(OQS_ALLOW_SFTL_KEY_AND_SIG_GEN "" ON "OQS_ENABLE_SIG_STFL_KEY_SIG_GEN" OFF) +cmake_dependent_option(OQS_ALLOW_STFL_KEY_AND_SIG_GEN "" ON "OQS_ENABLE_SIG_STFL_KEY_SIG_GEN" OFF) if (${OQS_ENABLE_SIG_STFL_KEY_SIG_GEN} AND ${OQS_ENABLE_SIG_STFL_XMSS}) set(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN ON) @@ -578,7 +578,7 @@ else() set(OQS_ALLOW_LMS_KEY_AND_SIG_GEN OFF) endif() -if(OQS_ALLOW_SFTL_KEY_AND_SIG_GEN STREQUAL "ON") +if(OQS_ALLOW_STFL_KEY_AND_SIG_GEN STREQUAL "ON") message(STATUS "Experimental stateful key and signature generation is enabled. Ensure secret keys are securely stored to prevent multiple simultaneous sign operations.") endif() diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index ac13bf093c..f2dd085519 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -238,6 +238,6 @@ #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 1 #cmakedefine OQS_ENABLE_SIG_STFL_KEY_SIG_GEN 1 -#cmakedefine OQS_ALLOW_SFTL_KEY_AND_SIG_GEN 1 +#cmakedefine OQS_ALLOW_STFL_KEY_AND_SIG_GEN 1 #cmakedefine OQS_ALLOW_XMSS_KEY_AND_SIG_GEN 1 #cmakedefine OQS_ALLOW_LMS_KEY_AND_SIG_GEN 1 \ No newline at end of file diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 9299975348..d0047108c8 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -878,7 +878,7 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { } OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { -#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +#ifndef OQS_ALLOW_STFL_KEY_AND_SIG_GEN (void)sig; (void)public_key; (void)secret_key; @@ -895,7 +895,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { -#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +#ifndef OQS_ALLOW_STFL_KEY_AND_SIG_GEN (void)sig; (void)signature; (void)signature_len; @@ -921,7 +921,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *m } OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { -#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +#ifndef OQS_ALLOW_STFL_KEY_AND_SIG_GEN (void)sig; (void)remain; (void)secret_key; @@ -932,11 +932,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned } else { return OQS_SUCCESS; } -#endif //OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +#endif //OQS_ALLOW_STFL_KEY_AND_SIG_GEN } OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned long long *max, const OQS_SIG_STFL_SECRET_KEY *secret_key) { -#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +#ifndef OQS_ALLOW_STFL_KEY_AND_SIG_GEN (void)sig; (void)max; (void)secret_key; @@ -947,7 +947,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned lon } else { return OQS_SUCCESS; } -#endif //OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +#endif //OQS_ALLOW_STFL_KEY_AND_SIG_GEN } OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig) { diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index b0cb69b843..615c18738f 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -178,7 +178,7 @@ OQS_API int OQS_SIG_STFL_alg_count(void); */ OQS_API int OQS_SIG_STFL_alg_is_enabled(const char *method_name); -#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +#ifndef OQS_ALLOW_STFL_KEY_AND_SIG_GEN #define OQS_SIG_STFL OQS_SIG #else /** @@ -284,7 +284,7 @@ typedef struct OQS_SIG_STFL { OQS_STATUS (*sigs_total)(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key); } OQS_SIG_STFL; -#endif //OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +#endif //OQS_ALLOW_STFL_KEY_AND_SIG_GEN /** * @brief OQS_SIG_STFL_SECRET_KEY object for stateful signature schemes diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c index 3f280e024c..0a0664291a 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c @@ -15,7 +15,7 @@ #endif /* -------------- XMSSMT -------------- */ -#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +#ifndef OQS_ALLOW_STFL_KEY_AND_SIG_GEN OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(XMSS_UNUSED_ATT uint8_t *signature, XMSS_UNUSED_ATT size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { return OQS_ERROR; diff --git a/tests/example_sig_stfl.c b/tests/example_sig_stfl.c index cdcd9f6472..a2b3ba21c1 100644 --- a/tests/example_sig_stfl.c +++ b/tests/example_sig_stfl.c @@ -121,7 +121,7 @@ static OQS_STATUS stfl_example(char *method_name) { } int main(void) { -#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +#ifndef OQS_ALLOW_STFL_KEY_AND_SIG_GEN OQS_init(); printf("Stateful signature algorithms key and signature generation is not enabled.\n"); if (stfl_example((char *)"XMSS-SHA2_10_256") == OQS_ERROR && stfl_example((char *)"LMS_SHA256_H10_W4") == OQS_ERROR) { diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index 158c953fa5..5c99f5d5bd 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -242,7 +242,7 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { OQS_fprintBstr(fh, "msg = ", msg, msg_len); -#ifdef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +#ifdef OQS_ALLOW_STFL_KEY_AND_SIG_GEN rc = OQS_SIG_STFL_sign(sig, signature, &signature_len, msg, msg_len, secret_key); if (rc != OQS_SUCCESS) { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sign failed!\n", method_name); From e92aab307f41b492c684438c4fdd8caae7b7a820 Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Thu, 18 Apr 2024 13:02:13 -0400 Subject: [PATCH 52/68] Stateful sigs: Rename keygen / sign option, add more tests, fix memory errors (#1755) * Add "EXPERIMENTAL" to keygen / sign enable switch * Add CI tests for macos * Zero-initialize aux_data * Fix test program arg parsing * Fix typo * Valgrind testing for stateful sigs * Satisfy astyle * Use calloc instead of malloc / memset --- .CMake/alg_support.cmake | 8 ++++---- .github/workflows/android.yml | 2 +- .github/workflows/apple.yml | 2 +- .github/workflows/unix.yml | 19 ++++++++++--------- .github/workflows/windows.yml | 4 ++-- CONFIGURE.md | 6 +++--- src/oqsconfig.h.cmake | 4 ++-- src/sig_stfl/lms/sig_stfl_lms_functions.c | 2 +- tests/test_leaks.py | 16 ++++++++++++++++ tests/test_sig_stfl.c | 7 ++++++- 10 files changed, 46 insertions(+), 24 deletions(-) diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index c2c74230cc..3810585a9c 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -563,16 +563,16 @@ cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h10_w8 "" ON "OQS_E cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h15_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h20_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) -option(OQS_ENABLE_SIG_STFL_KEY_SIG_GEN "Enable stateful key and signature generation for research and experimentation" OFF) -cmake_dependent_option(OQS_ALLOW_STFL_KEY_AND_SIG_GEN "" ON "OQS_ENABLE_SIG_STFL_KEY_SIG_GEN" OFF) +option(OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN "Enable stateful key and signature generation for research and experimentation" OFF) +cmake_dependent_option(OQS_ALLOW_STFL_KEY_AND_SIG_GEN "" ON "OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN" OFF) -if (${OQS_ENABLE_SIG_STFL_KEY_SIG_GEN} AND ${OQS_ENABLE_SIG_STFL_XMSS}) +if (${OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN} AND ${OQS_ENABLE_SIG_STFL_XMSS}) set(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN ON) else() set(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN OFF) endif() -if (${OQS_ENABLE_SIG_STFL_KEY_SIG_GEN} AND ${OQS_ENABLE_SIG_STFL_LMS}) +if (${OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN} AND ${OQS_ENABLE_SIG_STFL_LMS}) set(OQS_ALLOW_LMS_KEY_AND_SIG_GEN ON) else() set(OQS_ALLOW_LMS_KEY_AND_SIG_GEN OFF) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 26b4d13186..d54b6ebcde 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -16,4 +16,4 @@ jobs: - name: Checkout code uses: actions/checkout@v3 - name: Build project - run: ./scripts/build-android.sh $ANDROID_NDK_HOME -a ${{ matrix.abi }} -f "-DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }}" + run: ./scripts/build-android.sh $ANDROID_NDK_HOME -a ${{ matrix.abi }} -f "-DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }}" diff --git a/.github/workflows/apple.yml b/.github/workflows/apple.yml index bb9a2f47b6..69021d60a9 100644 --- a/.github/workflows/apple.yml +++ b/.github/workflows/apple.yml @@ -17,6 +17,6 @@ jobs: - name: Generate project run: | cmake -B build --toolchain .CMake/apple.cmake -DOQS_USE_OPENSSL=OFF -DPLATFORM=${{ matrix.platform }} \ - -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . + -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . - name: Build project run: cmake --build build diff --git a/.github/workflows/unix.yml b/.github/workflows/unix.yml index 3e534319c7..fa459f9aed 100644 --- a/.github/workflows/unix.yml +++ b/.github/workflows/unix.yml @@ -74,19 +74,19 @@ jobs: include: - name: alpine container: openquantumsafe/ci-alpine-amd64:latest - CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: alpine-no-stfl-key-sig-gen container: openquantumsafe/ci-alpine-amd64:latest - CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: alpine-openssl-all container: openquantumsafe/ci-alpine-amd64:latest - CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_USE_AES_OPENSSL=ON -DOQS_USE_SHA2_OPENSSL=ON -DOQS_USE_SHA3_OPENSSL=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_USE_AES_OPENSSL=ON -DOQS_USE_SHA2_OPENSSL=ON -DOQS_USE_SHA3_OPENSSL=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: alpine-noopenssl container: openquantumsafe/ci-alpine-amd64:latest - CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=OFF -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=OFF -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: focal-nistr4-openssl container: openquantumsafe/ci-ubuntu-focal-x86_64:latest @@ -102,11 +102,11 @@ jobs: PYTEST_ARGS: --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py - name: address-sanitizer container: openquantumsafe/ci-ubuntu-focal-x86_64:latest - CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_distbuild.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py --numprocesses=auto --maxprocesses=10 - name: address-sanitizer-no-stfl-key-sig-gen container: openquantumsafe/ci-ubuntu-focal-x86_64:latest - CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_distbuild.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py --numprocesses=auto --maxprocesses=10 container: image: ${{ matrix.container }} @@ -145,11 +145,11 @@ jobs: include: - name: armhf ARCH: armhf - CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: armhf-no-stfl-key-sig-gen ARCH: armhf - CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py # no longer supporting armel # - name: armel @@ -215,6 +215,7 @@ jobs: - macos-13 - macos-14 CMAKE_ARGS: + - -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON - -DCMAKE_C_COMPILER=gcc-13 - -DOQS_USE_OPENSSL=OFF - -DBUILD_SHARED_LIBS=ON -DOQS_DIST_BUILD=OFF @@ -280,4 +281,4 @@ jobs: working-directory: build - name: Run tests timeout-minutes: 60 - run: mkdir -p tmp && python3 -m pytest --verbose --ignore=tests/test_code_conventions.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py \ No newline at end of file + run: mkdir -p tmp && python3 -m pytest --verbose --ignore=tests/test_code_conventions.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index de0d5e82db..3c3e483337 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Generate Project - run: cmake -B build --toolchain .CMake/toolchain_windows_arm64.cmake -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . + run: cmake -B build --toolchain .CMake/toolchain_windows_arm64.cmake -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . - name: Build Project run: cmake --build build @@ -26,7 +26,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Generate Project - run: cmake -B build --toolchain ${{ matrix.toolchain }} -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . + run: cmake -B build --toolchain ${{ matrix.toolchain }} -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . - name: Build Project run: cmake --build build - name: Test dependencies diff --git a/CONFIGURE.md b/CONFIGURE.md index 89bd01e042..a537f94be5 100644 --- a/CONFIGURE.md +++ b/CONFIGURE.md @@ -125,10 +125,10 @@ Only has an effect if the system supports `dlopen` and ELF binary format, such a XMSS and LMS are the two supported Hash-Based Signatures schemes. `OQS_ENABLE_SIG_STFL_XMSS` and `OQS_ENABLE_SIG_STFL_LMS` control these algorithms, which are disabled by default. -A thrid variable, `OQS_ENABLE_SIG_STFL_KEY_SIG_GEN`, also controls the ability to generate keys and signatures. This is also disabled by default. +A third variable, `OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN`, also controls the ability to generate keys and signatures. This is also disabled by default. Each of these variables can be set to `ON` or `OFF`. When all three are `ON`, stateful signatures are fully functional and can generate key pairs, sign data, and verify signatures. -If `OQS_ENABLE_SIG_STFL_KEY_SIG_GEN` is `OFF` signature verification is the only functional operation. +If `OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN` is `OFF` signature verification is the only functional operation. Standards bodies, such as NIST, recommend that key and signature generation only by done in hardware in order to best enforce the one-time use of secret keys. Keys stored in a file system are extremely susceptible to simultaneous use. @@ -137,7 +137,7 @@ When enabled in this library a warning message will be generated by the config p By default, - `OQS_ENABLE_SIG_STFL_XMSS` is `OFF` - `OQS_ENABLE_SIG_STFL_LMS` is `OFF` -- `OQS_ENABLE_SIG_STFL_KEY_SIG_GEN` is `OFF`. +- `OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN` is `OFF`. **Default**: `OFF`. diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index f2dd085519..414b759cfa 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -237,7 +237,7 @@ #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 1 -#cmakedefine OQS_ENABLE_SIG_STFL_KEY_SIG_GEN 1 +#cmakedefine OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN 1 #cmakedefine OQS_ALLOW_STFL_KEY_AND_SIG_GEN 1 #cmakedefine OQS_ALLOW_XMSS_KEY_AND_SIG_GEN 1 -#cmakedefine OQS_ALLOW_LMS_KEY_AND_SIG_GEN 1 \ No newline at end of file +#cmakedefine OQS_ALLOW_LMS_KEY_AND_SIG_GEN 1 diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index d0b1559e2d..498324d3da 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -281,7 +281,7 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uin //Aux Data size_t len_aux_data = DEFAULT_AUX_DATA; - uint8_t *aux_data = malloc(sizeof(uint8_t) * len_aux_data); + uint8_t *aux_data = calloc(len_aux_data, sizeof(uint8_t)); if (aux_data == NULL) { OQS_MEM_insecure_free( oqs_key_data->sec_key); OQS_MEM_insecure_free(oqs_key_data); diff --git a/tests/test_leaks.py b/tests/test_leaks.py index e0e8f395d3..f75fece11a 100644 --- a/tests/test_leaks.py +++ b/tests/test_leaks.py @@ -24,6 +24,22 @@ def test_sig_leak(sig_name): ["valgrind", "-s", "--error-exitcode=1", "--leak-check=full", "--show-leak-kinds=all", helpers.path_to_executable('test_sig'), sig_name], ) +@helpers.filtered_test +@pytest.mark.parametrize('sig_stfl_name', helpers.available_sig_stfls_by_name()) +def test_sig_stfl_leak(sig_stfl_name): + if not(helpers.is_sig_stfl_enabled_by_name(sig_stfl_name)): pytest.skip('Not enabled') + if sys.platform != "linux" or os.system("grep ubuntu /etc/os-release") != 0 or os.system("uname -a | grep x86_64") != 0: pytest.skip('Leak testing not supported on this platform') + if sig_stfl_name.startswith("XMSS"): + katfile = helpers.get_katfile("sig_stfl", sig_stfl_name) + if not katfile: pytest.skip("KATs file is missing") + helpers.run_subprocess( + ["valgrind", "-s", "--error-exitcode=1", "--leak-check=full", "--show-leak-kinds=all", helpers.path_to_executable('test_sig_stfl'), sig_stfl_name, katfile], + ) + else: + helpers.run_subprocess( + ["valgrind", "-s", "--error-exitcode=1", "--leak-check=full", "--show-leak-kinds=all", helpers.path_to_executable('test_sig_stfl'), sig_stfl_name], + ) + if __name__ == "__main__": import sys pytest.main(sys.argv) diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 5626eee5b3..30894ee19f 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -1029,7 +1029,7 @@ int main(int argc, char **argv) { printf("Testing stateful signature algorithms using liboqs version %s\n", OQS_version()); if (argc < 2) { - fprintf(stderr, "Usage: test_sig_stfl algname katfile\n"); + fprintf(stderr, "Usage: test_sig_stfl algname [katfile]\n"); fprintf(stderr, " algname: "); for (size_t i = 0; i < OQS_SIG_STFL_algs_length; i++) { if (i > 0) { @@ -1049,6 +1049,11 @@ int main(int argc, char **argv) { int is_xmss = 0; if (strstr(alg_name, "XMSS") != NULL) { is_xmss = 1; + if (argc < 3) { + fprintf(stderr, "KAT file must be provided for XMSS.\n"); + OQS_destroy(); + return EXIT_FAILURE; + } } /* From b0758784cc5f4171ff264964a9f79e62e9503e30 Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Mon, 22 Apr 2024 13:57:24 -0400 Subject: [PATCH 53/68] Clean up OQS_SIG_STFL_SECRET_KEY_free --- src/sig_stfl/sig_stfl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index d0047108c8..4015297572 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -1347,8 +1347,7 @@ OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk) { sk->free_key(sk); /* Free sk object */ - OQS_MEM_secure_free(sk, sizeof(sk)); - sk = NULL; + OQS_MEM_secure_free(sk, sizeof(*sk)); } OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context) { From db000c263a87d6830b125e045059664fc6b95cb5 Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Thu, 25 Apr 2024 20:39:42 -0400 Subject: [PATCH 54/68] Remove unused sig member --- src/sig_stfl/sig_stfl.h | 3 --- src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index 615c18738f..976e19e51b 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -292,9 +292,6 @@ typedef struct OQS_SIG_STFL { typedef struct OQS_SIG_STFL_SECRET_KEY { - /** Associated signature object */ - OQS_SIG_STFL *sig; - /* The (maximum) length, in bytes, of secret keys for this signature scheme. */ size_t length_secret_key; diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c index 1ccc8e8c09..ba526bc7e8 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c @@ -39,9 +39,6 @@ extern inline OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_new(size_t length_sec // Set application specific context sk->context = NULL; - // Point to associated OQS_SIG_STFL object - sk->sig = NULL; - // Mutual exclusion struct sk->mutex = NULL; From 9b60f60b42a5570b86a511439925dcca48554c00 Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Fri, 26 Apr 2024 09:42:21 -0400 Subject: [PATCH 55/68] Naming convention for serialize / deserialize functions --- src/sig_stfl/sig_stfl.c | 4 ++-- src/sig_stfl/sig_stfl.h | 4 ++-- tests/test_sig_stfl.c | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 4015297572..415a607295 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -1358,7 +1358,7 @@ OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, s } /* Convert secret key object to byte string */ -OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk) { +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_serialize(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk) { if (sk == NULL || sk_len == NULL || sk_buf_ptr == NULL || sk->serialize_key == NULL) { return OQS_ERROR; } @@ -1367,7 +1367,7 @@ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(uint8_t **sk_buf_ptr, size_ } /* Insert secret key byte string in an Stateful secret key object */ -OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t key_len, const uint8_t *sk_buf, void *context) { +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_deserialize(OQS_SIG_STFL_SECRET_KEY *sk, const size_t key_len, const uint8_t *sk_buf, void *context) { if (sk == NULL || sk_buf == NULL || sk->deserialize_key == NULL) { return OQS_ERROR; } diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index 976e19e51b..b6eded5d76 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -634,7 +634,7 @@ OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, s * * @note The function allocates memory for the byte array, and it is the caller's responsibility to free this memory after use. */ -OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_serialize(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); /** * Deserialize a byte array into an OQS_SIG_STFL_SECRET_KEY object. @@ -650,7 +650,7 @@ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_serialize_key(uint8_t **sk_buf_ptr, size_ * * @attention The caller is responsible for freeing the `sk_buf` memory when it is no longer needed. */ -OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf, void *context); +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_deserialize(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf, void *context); #if defined(__cplusplus) // extern "C" diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 30894ee19f..a916a4fd96 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -470,7 +470,7 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name, const char goto err; } - rc = OQS_SECRET_KEY_STFL_serialize_key(&sk_buf, &sk_buf_len, secret_key); + rc = OQS_SIG_STFL_SECRET_KEY_serialize(&sk_buf, &sk_buf_len, secret_key); if (rc != OQS_SUCCESS) { goto err; } @@ -631,7 +631,7 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name, const char * } /* write sk key to disk */ - rc = OQS_SECRET_KEY_STFL_serialize_key(&to_file_sk_buf, &to_file_sk_len, sk); + rc = OQS_SIG_STFL_SECRET_KEY_serialize(&to_file_sk_buf, &to_file_sk_len, sk); if (rc != OQS_SUCCESS) { goto err; } @@ -669,7 +669,7 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name, const char * } context_2 = strdup(file_store_name); - rc = OQS_SECRET_KEY_STFL_deserialize_key(sk_from_file, from_file_sk_len, from_file_sk_buf, (void *)context_2); + rc = OQS_SIG_STFL_SECRET_KEY_deserialize(sk_from_file, from_file_sk_len, from_file_sk_buf, (void *)context_2); if (rc != OQS_SUCCESS) { fprintf(stderr, "OQS restore %s from file failed.\n", method_name); From f9a4f03109d5495d2b35f0dc8248f087c14e5377 Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Fri, 26 Apr 2024 10:27:52 -0400 Subject: [PATCH 56/68] Switch order of params for deserialize Signed-off-by: Spencer Wilson --- src/sig_stfl/sig_stfl.c | 2 +- src/sig_stfl/sig_stfl.h | 2 +- tests/test_sig_stfl.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 415a607295..00d02436bc 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -1367,7 +1367,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_serialize(uint8_t **sk_buf_ptr, size_ } /* Insert secret key byte string in an Stateful secret key object */ -OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_deserialize(OQS_SIG_STFL_SECRET_KEY *sk, const size_t key_len, const uint8_t *sk_buf, void *context) { +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_deserialize(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, const size_t key_len, void *context) { if (sk == NULL || sk_buf == NULL || sk->deserialize_key == NULL) { return OQS_ERROR; } diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index b6eded5d76..dfdc8145d4 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -650,7 +650,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_serialize(uint8_t **sk_buf_ptr, size_ * * @attention The caller is responsible for freeing the `sk_buf` memory when it is no longer needed. */ -OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_deserialize(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf, void *context); +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_deserialize(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, size_t key_len, void *context); #if defined(__cplusplus) // extern "C" diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index a916a4fd96..a21119138a 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -669,7 +669,7 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name, const char * } context_2 = strdup(file_store_name); - rc = OQS_SIG_STFL_SECRET_KEY_deserialize(sk_from_file, from_file_sk_len, from_file_sk_buf, (void *)context_2); + rc = OQS_SIG_STFL_SECRET_KEY_deserialize(sk_from_file, from_file_sk_buf, from_file_sk_len, (void *)context_2); if (rc != OQS_SUCCESS) { fprintf(stderr, "OQS restore %s from file failed.\n", method_name); From 8c1529d4a8abe06b3d7996b8e20559ad1c71301d Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Fri, 26 Apr 2024 11:24:12 -0400 Subject: [PATCH 57/68] Swap param order down the stack; rename length param; update documentation Signed-off-by: Spencer Wilson --- src/sig_stfl/lms/sig_stfl_lms.c | 6 +++--- src/sig_stfl/lms/sig_stfl_lms.h | 2 +- src/sig_stfl/lms/sig_stfl_lms_functions.c | 2 +- src/sig_stfl/sig_stfl.c | 10 +++++----- src/sig_stfl/sig_stfl.h | 20 +++++++++---------- src/sig_stfl/xmss/sig_stfl_xmss.h | 2 +- .../xmss/sig_stfl_xmss_secret_key_functions.c | 2 +- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/sig_stfl/lms/sig_stfl_lms.c b/src/sig_stfl/lms/sig_stfl_lms.c index 7e5e99ea45..33d18b6c3c 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.c +++ b/src/sig_stfl/lms/sig_stfl_lms.c @@ -55,7 +55,7 @@ OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8_keypair(uint8_t *public_key static OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); /* Insert lms byte string in an LMS secret key object */ -static OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); +static OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, const size_t sk_len, void *context); static void OQS_SECRET_KEY_LMS_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); @@ -288,8 +288,8 @@ static OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(uint8_t **sk_buf_ptr, size_t } /* Insert lms byte string in an LMS secret key object */ -static OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context) { - return oqs_deserialize_lms_key(sk, sk_len, sk_buf, context); +static OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, const size_t sk_len, void *context) { + return oqs_deserialize_lms_key(sk, sk_buf, sk_len, context); } static void OQS_SECRET_KEY_LMS_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context) { diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h index c5deed2f40..941f17a0ff 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.h +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -326,7 +326,7 @@ int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, const uint8_t *sm, si void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk); OQS_STATUS oqs_serialize_lms_key(uint8_t **sk_key, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); -OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); +OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, const size_t sk_len, void *context); void oqs_lms_key_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); // ---------------------------- FUNCTIONS INDEPENDENT OF VARIANT ----------------------------------------- diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index 498324d3da..f3660e40d8 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -728,7 +728,7 @@ OQS_STATUS oqs_serialize_lms_key(uint8_t **sk_key, size_t *sk_len, const OQS_SIG * Writes secret key + aux data if present * key_len is priv key length + aux length */ -OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context) { +OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, const size_t sk_len, void *context) { oqs_lms_key_data *lms_key_data = NULL; uint8_t *lms_sk = NULL; diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 00d02436bc..51d7865373 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -1358,21 +1358,21 @@ OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, s } /* Convert secret key object to byte string */ -OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_serialize(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk) { - if (sk == NULL || sk_len == NULL || sk_buf_ptr == NULL || sk->serialize_key == NULL) { +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_serialize(uint8_t **sk_buf_ptr, size_t *sk_buf_len, const OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL || sk_buf_len == NULL || sk_buf_ptr == NULL || sk->serialize_key == NULL) { return OQS_ERROR; } - return sk->serialize_key(sk_buf_ptr, sk_len, sk); + return sk->serialize_key(sk_buf_ptr, sk_buf_len, sk); } /* Insert secret key byte string in an Stateful secret key object */ -OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_deserialize(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, const size_t key_len, void *context) { +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_deserialize(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, const size_t sk_buf_len, void *context) { if (sk == NULL || sk_buf == NULL || sk->deserialize_key == NULL) { return OQS_ERROR; } - return sk->deserialize_key(sk, key_len, sk_buf, context); + return sk->deserialize_key(sk, sk_buf, sk_buf_len, context); } /* OQS_SIG_STFL_SECRET_KEY_SET_lock callback function*/ diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index dfdc8145d4..91df350add 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -313,13 +313,13 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { * The `sk_len` will contain the length of the byte stream. * * @param[out] sk_buf_ptr Pointer to the byte stream representing the serialized secret key. - * @param[out] sk_len Pointer to the length of the serialized byte stream. + * @param[out] sk_buf_len Pointer to the length of the serialized byte stream. * @param[in] sk Pointer to the `OQS_SIG_STFL_SECRET_KEY` object to serialize. * @return The number of bytes in the serialized byte stream upon success, or an OQS error code on failure. * * @attention The caller is responsible for ensuring that `sk` is a valid object before calling this function. */ - OQS_STATUS (*serialize_key)(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); + OQS_STATUS (*serialize_key)(uint8_t **sk_buf_ptr, size_t *sk_buf_len, const OQS_SIG_STFL_SECRET_KEY *sk); /** * Deserialize a byte stream into the internal representation of a stateful secret key. @@ -329,14 +329,14 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { * useful for reconstructing key objects from persisted or transmitted state. * * @param[out] sk Pointer to an uninitialized `OQS_SIG_STFL_SECRET_KEY` object to hold the secret key. - * @param[in] sk_len The length of the secret key byte stream. * @param[in] sk_buf Pointer to the byte stream containing the serialized secret key data. + * @param[in] sk_buf_len The length of the secret key byte stream. * @param[in] context Pointer to application-specific data, handled externally, associated with the key. * @returns OQS_SUCCESS if the deserialization succeeds, with the `sk` object populated with the key material. * * @attention The caller is responsible for ensuring that `sk_buf` is securely deallocated when it's no longer needed. */ - OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); + OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, const size_t sk_buf_len, void *context); /** * Secret Key Locking Function @@ -360,14 +360,14 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { * Callback function used to securely store key data after a signature generation. * When populated, this pointer points to the application-supplied secure storage function. * @param[in] sk_buf The serialized secret key data to secure store - * @param[in] buf_len length of data to secure + * @param[in] sk_buf_len length of data to secure * @param[in] context application supplied data used to locate where this secret key * is stored (passed in at the time the function pointer was set). * * @return OQS_SUCCESS or OQS_ERROR * Ideally written to a secure device. */ - OQS_STATUS (*secure_store_scrt_key)(uint8_t *sk_buf, size_t buf_len, void *context); + OQS_STATUS (*secure_store_scrt_key)(uint8_t *sk_buf, size_t sk_buf_len, void *context); /** * Free internal variant-specific data @@ -628,13 +628,13 @@ OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, s * Converts an OQS_SIG_STFL_SECRET_KEY object into a byte array for storage or transmission. * * @param[out] sk_buf_ptr Pointer to the allocated byte array containing the serialized key. - * @param[out] sk_len Length of the serialized key byte array. + * @param[out] sk_buf_len Length of the serialized key byte array. * @param[in] sk Pointer to the OQS_SIG_STFL_SECRET_KEY object to be serialized. * @return OQS_SUCCESS on success, or an OQS error code on failure. * * @note The function allocates memory for the byte array, and it is the caller's responsibility to free this memory after use. */ -OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_serialize(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_serialize(uint8_t **sk_buf_ptr, size_t *sk_buf_len, const OQS_SIG_STFL_SECRET_KEY *sk); /** * Deserialize a byte array into an OQS_SIG_STFL_SECRET_KEY object. @@ -643,14 +643,14 @@ OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_serialize(uint8_t **sk_buf_ptr, size_ * After deserialization, the secret key object can be used for subsequent cryptographic operations. * * @param[out] sk A pointer to the secret key object that will be populated from the binary data. - * @param[in] key_len The length of the binary secret key data in bytes. * @param[in] sk_buf The buffer containing the serialized secret key data. + * @param[in] sk_buf_len The length of the binary secret key data in bytes. * @param[in] context Application-specific data used to maintain context about the secret key. * @return OQS_SUCCESS if deserialization was successful; otherwise, OQS_ERROR. * * @attention The caller is responsible for freeing the `sk_buf` memory when it is no longer needed. */ -OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_deserialize(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, size_t key_len, void *context); +OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_deserialize(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, size_t sk_buf_len, void *context); #if defined(__cplusplus) // extern "C" diff --git a/src/sig_stfl/xmss/sig_stfl_xmss.h b/src/sig_stfl/xmss/sig_stfl_xmss.h index 6ee03f3b12..a6d0aad55b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss.h +++ b/src/sig_stfl/xmss/sig_stfl_xmss.h @@ -573,7 +573,7 @@ OQS_STATUS OQS_SECRET_KEY_XMSS_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_le OQS_STATUS OQS_SECRET_KEY_XMSS_inner_serialize_key(uint8_t **sk_buf_ptr, size_t *sk_len, const OQS_SIG_STFL_SECRET_KEY *sk); /* Deserialize XMSS byte string into an XMSS secret key data */ -OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, void *context); +OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, const size_t sk_len, void *context); /* Store Secret Key Function, ideally written to secure device */ void OQS_SECRET_KEY_XMSS_set_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context); diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c index ba526bc7e8..6903135cb0 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c @@ -111,7 +111,7 @@ OQS_STATUS OQS_SECRET_KEY_XMSS_inner_serialize_key(uint8_t **sk_buf_ptr, size_t } /* Deserialize XMSS byte string into an XMSS secret key data. */ -OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, XMSS_UNUSED_ATT void *context) { +OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, const size_t sk_len, XMSS_UNUSED_ATT void *context) { #ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN return OQS_ERROR; #endif From c408cee90727c3a69e7fa5f256f467842ef23220 Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Fri, 26 Apr 2024 13:34:51 -0400 Subject: [PATCH 58/68] Update src/sig_stfl/sig_stfl.h Co-authored-by: Jason Goertzen <133878263+jgoertzen-sb@users.noreply.github.com> Signed-off-by: Spencer Wilson --- src/sig_stfl/sig_stfl.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index 91df350add..6154f47a64 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -654,6 +654,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_deserialize(OQS_SIG_STFL_SECRET_KEY * #if defined(__cplusplus) // extern "C" +} #endif #endif /* OQS_SIG_STATEFUL_H */ From 7dd4ea0a9ecadce45050bdffe07e2d9fb4b338cc Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Mon, 29 Apr 2024 11:06:23 -0400 Subject: [PATCH 59/68] Test stateful sigs on arm64, s390x, and powerpc (#1772) --- .circleci/config.yml | 1 + .travis.yml | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5c15e2dc37..6dda717b1d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -344,6 +344,7 @@ workflows: <<: *require_buildcheck name: arm64 PYTEST_ARGS: --numprocesses=auto --maxprocesses=10 --ignore=tests/test_kat_all.py + CMAKE_ARGS: -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON commit-to-main: when: diff --git a/.travis.yml b/.travis.yml index fd13edc301..882b92b755 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ jobs: compiler: gcc if: NOT branch =~ /^ghactionsonly-/ script: - - mkdir build && cd build && cmake -GNinja .. && cmake -LA .. && ninja + - mkdir build && cd build && cmake -GNinja -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_STFL_SIG_KEY_SIG_GEN=ON .. && cmake -LA .. && ninja - cd build & ninja run_tests - arch: s390x os: linux @@ -17,5 +17,5 @@ jobs: compiler: gcc if: NOT branch =~ /^ghactionsonly-/ script: - - mkdir build && cd build && cmake -GNinja .. && cmake -LA .. && ninja + - mkdir build && cd build && cmake -GNinja -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_STFL_SIG_KEY_SIG_GEN=ON .. && cmake -LA .. && ninja - cd build & ninja run_tests From 4ebd1b94ebd71181a43653e441700226d537026f Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Sat, 11 May 2024 22:57:04 -0400 Subject: [PATCH 60/68] Update tests/example_sig_stfl.c Co-authored-by: Douglas Stebila Signed-off-by: Norman Ashley --- tests/example_sig_stfl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/example_sig_stfl.c b/tests/example_sig_stfl.c index a2b3ba21c1..f653ccba4c 100644 --- a/tests/example_sig_stfl.c +++ b/tests/example_sig_stfl.c @@ -112,7 +112,7 @@ static OQS_STATUS stfl_example(char *method_name) { //cleanup OQS_MEM_insecure_free(public_key); OQS_MEM_insecure_free(sk_fname); - OQS_MEM_insecure_free(message); + OQS_MEM_secure_free(message, message_len); OQS_MEM_insecure_free(signature); OQS_SIG_STFL_free(sig); OQS_SIG_STFL_SECRET_KEY_free(secret_key); From 0c3d39c26ccf37333092f404bc149be7218174d4 Mon Sep 17 00:00:00 2001 From: Duc Tri Nguyen Date: Tue, 14 May 2024 15:14:00 -0400 Subject: [PATCH 61/68] Zeroing internal state memory on heap (#1790) * Address stateful-sigs comments in #1650 (#1656) * Add sig_stfl to configure.md * Add OQS_MEM_checked_malloc and OQS_MEM_checked_aligned_alloc * Use memcpy and checked_malloc * Zeroing internal state memory on heap Signed-off-by: Duc Tri Nguyen * make astyle happy Signed-off-by: Duc Tri Nguyen * secure free for wots key,sig tree stack Signed-off-by: Duc Tri Nguyen * revert * fix markdown link invalid Signed-off-by: Duc Tri Nguyen * fix markdown link, work with doxygen 1.10 Signed-off-by: Duc Tri Nguyen --------- Signed-off-by: Duc Tri Nguyen Co-authored-by: Duc Nguyen <106774416+ducnguyen-sb@users.noreply.github.com> --- CONFIGURE.md | 4 +- src/sig_stfl/lms/sig_stfl_lms.c | 2 - src/sig_stfl/lms/sig_stfl_lms.h | 1 - src/sig_stfl/xmss/external/wots.c | 10 ++- src/sig_stfl/xmss/external/xmss_core_fast.c | 86 ++++++++++++--------- 5 files changed, 58 insertions(+), 45 deletions(-) diff --git a/CONFIGURE.md b/CONFIGURE.md index a537f94be5..7ffcebae25 100644 --- a/CONFIGURE.md +++ b/CONFIGURE.md @@ -11,7 +11,7 @@ The following options can be passed to CMake before the build file generation pr - [OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG/OQS_ENABLE_SIG_STFL_ALG](#OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG/OQS_ENABLE_SIG_STFL_ALG) - [OQS_MINIMAL_BUILD](#OQS_MINIMAL_BUILD) - [OQS_DIST_BUILD](#OQS_DIST_BUILD) -- [OQS_USE_CPUFEATURE_INSTRUCTIONS](OQS_USE_CPUFEATURE_INSTRUCTIONS) +- [OQS_USE_CPUFEATURE_INSTRUCTIONS](#OQS_USE_CPUFEATURE_INSTRUCTIONS) - [OQS_USE_OPENSSL](#OQS_USE_OPENSSL) - [OQS_OPT_TARGET](#OQS_OPT_TARGET) - [OQS_SPEED_USE_ARM_PMU](#OQS_SPEED_USE_ARM_PMU) @@ -60,7 +60,7 @@ For a full list of such options and their default values, consult [.CMake/alg_su A selected algorithm set is enabled. Possible values are "STD" selecting all algorithms standardized by NIST; "NIST_R4" selecting all algorithms evaluated in round 4 of the NIST PQC competition; "All" (or any other value) selecting all algorithms integrated into liboqs. Parameter setting "STD" minimizes library size but may require re-running code generator scripts in projects integrating `liboqs`; e.g., [oqs-provider](https://github.com/open-quantum-safe/oqs-provider) and [oqs-boringssl](https://github.com/open-quantum-safe/boringssl). -**Attention**: If you use any predefined value (`STD` or `NIST_R4` as of now) for this variable, the values added via [OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG](#OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG) variables will be ignored. +**Attention**: If you use any predefined value (`STD` or `NIST_R4` as of now) for this variable, the values added via [OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG/OQS_ENABLE_SIG_STFL_ALG](#OQS_ENABLE_KEM_ALG/OQS_ENABLE_SIG_ALG/OQS_ENABLE_SIG_STFL_ALG) variables will be ignored. **Default**: `All`. diff --git a/src/sig_stfl/lms/sig_stfl_lms.c b/src/sig_stfl/lms/sig_stfl_lms.c index 33d18b6c3c..88dc5938fc 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.c +++ b/src/sig_stfl/lms/sig_stfl_lms.c @@ -27,7 +27,6 @@ OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w2_keypair(uint8_t *public_key, OQS_S OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); - // OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void); // OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void); OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); @@ -267,7 +266,6 @@ LMS_ALG(sha256_h20_w8_h15_w8, SHA256_H20_W8_H15_W8) LMS_ALG(sha256_h20_w8_h20_w8, SHA256_H20_W8_H20_W8) //2-Level LMS - void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk) { oqs_secret_lms_key_free(sk); } diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h index 941f17a0ff..13ef40f704 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.h +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -252,7 +252,6 @@ OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *totaln, const void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk); - //2-Level LMS #define OQS_SIG_STFL_alg_lms_length_private_key 64 #define OQS_SIG_STFL_alg_lms_length_public_key 60 diff --git a/src/sig_stfl/xmss/external/wots.c b/src/sig_stfl/xmss/external/wots.c index 067d48e6e4..0d5b57fd57 100644 --- a/src/sig_stfl/xmss/external/wots.c +++ b/src/sig_stfl/xmss/external/wots.c @@ -128,7 +128,8 @@ void wots_pkgen(const xmss_params *params, const unsigned char *pub_seed, uint32_t addr[8]) { unsigned int i; - unsigned char *buf = malloc(2 * params->padding_len + 4 * params->n + 64); + const size_t buf_size = 2 * params->padding_len + 4 * params->n + 64; + unsigned char *buf = malloc(buf_size); if (buf == NULL) { return; } @@ -142,7 +143,7 @@ void wots_pkgen(const xmss_params *params, 0, params->wots_w - 1, pub_seed, addr, buf); } - OQS_MEM_insecure_free(buf); + OQS_MEM_secure_free(buf, buf_size); } /** @@ -154,8 +155,9 @@ void wots_sign(const xmss_params *params, const unsigned char *seed, const unsigned char *pub_seed, uint32_t addr[8]) { + const size_t buf_size = 2 * params->padding_len + 4 * params->n + 64; unsigned int *lengths = calloc(params->wots_len, sizeof(unsigned int)); - unsigned char *buf = malloc(2 * params->padding_len + 4 * params->n + 64); + unsigned char *buf = malloc(buf_size); unsigned int i; if (lengths == NULL || buf == NULL) { return; @@ -173,7 +175,7 @@ void wots_sign(const xmss_params *params, } OQS_MEM_insecure_free(lengths); - OQS_MEM_insecure_free(buf); + OQS_MEM_secure_free(buf, buf_size); } /** diff --git a/src/sig_stfl/xmss/external/xmss_core_fast.c b/src/sig_stfl/xmss/external/xmss_core_fast.c index ed8886501f..9ad19e3908 100644 --- a/src/sig_stfl/xmss/external/xmss_core_fast.c +++ b/src/sig_stfl/xmss/external/xmss_core_fast.c @@ -171,11 +171,11 @@ static void deep_state_swap(const xmss_params *params, } // TODO (from upstream) this is extremely ugly and should be refactored // TODO (from upstream) right now, this ensures that both 'stack' and 'retain' fit - unsigned char *t = malloc( - ((params->tree_height + 1) > ((1 << params->bds_k) - params->bds_k - 1) + const size_t t_size = ((params->tree_height + 1) > ((1 << params->bds_k) - params->bds_k - 1) ? (params->tree_height + 1) : ((1 << params->bds_k) - params->bds_k - 1)) - * params->n); + * params->n; + unsigned char *t = malloc(t_size); if (t == NULL) { return; } @@ -198,7 +198,7 @@ static void deep_state_swap(const xmss_params *params, memswap(a->retain, b->retain, t, ((1 << params->bds_k) - params->bds_k - 1) * params->n); memswap(&a->next_leaf, &b->next_leaf, t, sizeof(a->next_leaf)); - OQS_MEM_insecure_free(t); + OQS_MEM_secure_free(t, t_size); } static int treehash_minheight_on_stack(const xmss_params *params, @@ -241,9 +241,11 @@ static void treehash_init(const xmss_params *params, /* The subtree has at most 2^20 leafs, so uint32_t suffices. */ uint32_t idx = index; uint32_t lastnode = index +(1<padding_len + 6 * params->n + 32; + const size_t stack_size = ((height+1)*params->n)* sizeof(unsigned char); unsigned char *stack = calloc((height+1)*params->n, sizeof(unsigned char)); unsigned int *stacklevels = malloc((height + 1)*sizeof(unsigned int)); - unsigned char *thash_buf = malloc(2 * params->padding_len + 6 * params->n + 32); + unsigned char *thash_buf = malloc(thash_buf_size); if (stack == NULL || stacklevels == NULL || thash_buf == NULL) { return; @@ -293,8 +295,8 @@ static void treehash_init(const xmss_params *params, memcpy(node, stack, params->n); OQS_MEM_insecure_free(stacklevels); - OQS_MEM_insecure_free(stack); - OQS_MEM_insecure_free(thash_buf); + OQS_MEM_secure_free(stack, stack_size); + OQS_MEM_secure_free(thash_buf, thash_buf_size); } static void treehash_update(const xmss_params *params, @@ -318,11 +320,13 @@ static void treehash_update(const xmss_params *params, set_ltree_addr(ltree_addr, treehash->next_idx); set_ots_addr(ots_addr, treehash->next_idx); - unsigned char *nodebuffer = malloc(2 * params->n); - unsigned char *thash_buf = malloc(2 * params->padding_len + 6 * params->n + 32); - if (nodebuffer == NULL || thash_buf == NULL) { + const size_t buf_size = 2 * params->n + 2 * params->padding_len + 6 * params->n + 32; + unsigned char *buf = malloc(buf_size); + if (buf == NULL) { return; } + unsigned char *nodebuffer = buf; + unsigned char *thash_buf = buf + 2 * params->n; unsigned int nodeheight = 0; gen_leaf_wots(params, nodebuffer, sk_seed, pub_seed, ltree_addr, ots_addr); @@ -348,8 +352,7 @@ static void treehash_update(const xmss_params *params, treehash->next_idx++; } - OQS_MEM_insecure_free(nodebuffer); - OQS_MEM_insecure_free(thash_buf); + OQS_MEM_secure_free(buf, buf_size); } /** @@ -406,21 +409,22 @@ static char bds_state_update(const xmss_params *params, return -1; } + unsigned int nodeh; + int idx = state->next_leaf; + if (idx == 1 << params->tree_height) { + return -1; + } + uint32_t ltree_addr[8] = {0}; uint32_t node_addr[8] = {0}; uint32_t ots_addr[8] = {0}; - unsigned char *thash_buf = malloc(2 * params->padding_len + 6 * params->n + 32); + const size_t thash_buf_size = 2 * params->padding_len + 6 * params->n + 32; + unsigned char *thash_buf = malloc(thash_buf_size); if (thash_buf == NULL) { return -1; } - unsigned int nodeh; - int idx = state->next_leaf; - if (idx == 1 << params->tree_height) { - return -1; - } - // only copy layer and tree address parts copy_subtree_addr(ots_addr, addr); // type = ots @@ -462,7 +466,7 @@ static char bds_state_update(const xmss_params *params, } state->next_leaf++; - OQS_MEM_insecure_free(thash_buf); + OQS_MEM_secure_free(thash_buf, thash_buf_size); return 0; } @@ -480,11 +484,12 @@ static void bds_round(const xmss_params *params, unsigned int tau = params->tree_height; unsigned int startidx; unsigned int offset, rowidx; - unsigned char *buf = malloc(2 * params->n); - unsigned char *thash_buf = malloc(2 * params->padding_len + 6 * params->n + 32); - if (buf == NULL || thash_buf == NULL) { + const size_t buf_size = 2 * params->n + 2 * params->padding_len + 6 * params->n + 32; + unsigned char *buf = malloc(buf_size); + if (buf == NULL) { return; } + unsigned char *thash_buf = buf + 2 * params->n; uint32_t ots_addr[8] = {0}; uint32_t ltree_addr[8] = {0}; @@ -545,8 +550,7 @@ static void bds_round(const xmss_params *params, } } - OQS_MEM_insecure_free(buf); - OQS_MEM_insecure_free(thash_buf); + OQS_MEM_secure_free(buf, buf_size); } /** @@ -584,6 +588,7 @@ int xmss_core_keypair(const xmss_params *params, // TODO (from upstream) refactor BDS state not to need separate treehash instances bds_state state; + const size_t treehash_size = (params->tree_height - params->bds_k)*sizeof(treehash_inst); treehash_inst *treehash = calloc(params->tree_height - params->bds_k, sizeof(treehash_inst)); if (treehash == NULL) { return -1; @@ -616,7 +621,7 @@ int xmss_core_keypair(const xmss_params *params, /* Write the BDS state into sk. */ xmss_serialize_state(params, sk, &state); - OQS_MEM_insecure_free(treehash); + OQS_MEM_secure_free(treehash, treehash_size); return 0; } @@ -645,8 +650,10 @@ int xmss_core_sign(const xmss_params *params, // TODO (from upstream) refactor BDS state not to need separate treehash instances bds_state state; + const size_t treehash_size = (params->tree_height - params->bds_k) * sizeof(treehash_inst); + const size_t tmp_size = 5 * params->n + params->padding_len + params->n + 32; treehash_inst *treehash = calloc(params->tree_height - params->bds_k, sizeof(treehash_inst)); - unsigned char *tmp = malloc(5 * params->n + params->padding_len + params->n + 32); + unsigned char *tmp = malloc(tmp_size); if (treehash == NULL || tmp == NULL) { return -1; } @@ -720,7 +727,8 @@ int xmss_core_sign(const xmss_params *params, unsigned long long prefix_length = params->padding_len + 3*params->n; unsigned char *m_with_prefix = malloc((size_t)(mlen + prefix_length)); if (m_with_prefix == NULL) { - return -1; + ret = -1; + goto cleanup; } memcpy(m_with_prefix, sm + params->sig_bytes - prefix_length, (size_t)prefix_length); memcpy(m_with_prefix + prefix_length, m, (size_t)mlen); @@ -780,10 +788,10 @@ int xmss_core_sign(const xmss_params *params, ret = 0; OQS_MEM_insecure_free(m_with_prefix); - OQS_MEM_insecure_free(tmp); cleanup: - OQS_MEM_insecure_free(treehash); + OQS_MEM_secure_free(tmp, tmp_size); + OQS_MEM_secure_free(treehash, treehash_size); return ret; } @@ -801,6 +809,8 @@ int xmssmt_core_keypair(const xmss_params *params, unsigned char *wots_sigs; // TODO (from upstream) refactor BDS state not to need separate treehash instances + const size_t states_size = (2*params->d - 1)* sizeof(bds_state); + const size_t treehash_size = ((2*params->d - 1) * (params->tree_height - params->bds_k))* sizeof(treehash_inst); bds_state *states = calloc(2*params->d - 1, sizeof(bds_state)); treehash_inst *treehash = calloc((2*params->d - 1) * (params->tree_height - params->bds_k), sizeof(treehash_inst)); if (states == NULL || treehash == NULL) { @@ -844,8 +854,8 @@ int xmssmt_core_keypair(const xmss_params *params, xmssmt_serialize_state(params, sk, states); - OQS_MEM_insecure_free(treehash); - OQS_MEM_insecure_free(states); + OQS_MEM_secure_free(treehash, treehash_size); + OQS_MEM_secure_free(states, states_size); return 0; } @@ -876,9 +886,13 @@ int xmssmt_core_sign(const xmss_params *params, unsigned int updates; // TODO (from upstream) refactor BDS state not to need separate treehash instances + const size_t states_size = (2*params->d - 1)* sizeof(bds_state); + const size_t treehash_size = (2*params->d - 1) * (params->tree_height - params->bds_k) * sizeof(treehash_inst); + const size_t tmp_size = 5 * params->n + + params->padding_len + params->n + 32; bds_state *states = calloc(2*params->d - 1, sizeof(bds_state)); treehash_inst *treehash = calloc((2*params->d - 1) * (params->tree_height - params->bds_k), sizeof(treehash_inst)); - unsigned char *tmp = malloc(5 * params->n + + unsigned char *tmp = malloc(5 * params->n + params->padding_len + params->n + 32); if (states == NULL || treehash == NULL || tmp == NULL) { return -1; @@ -1090,9 +1104,9 @@ int xmssmt_core_sign(const xmss_params *params, xmssmt_serialize_state(params, sk, states); cleanup: - OQS_MEM_insecure_free(treehash); - OQS_MEM_insecure_free(states); - OQS_MEM_insecure_free(tmp); + OQS_MEM_secure_free(treehash, treehash_size); + OQS_MEM_secure_free(states, states_size); + OQS_MEM_secure_free(tmp, tmp_size); OQS_MEM_insecure_free(m_with_prefix); return ret; From 31bdf13d4b8717b143f9ed584dfb8faceb80ebd9 Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Tue, 14 May 2024 16:58:36 -0400 Subject: [PATCH 62/68] Clean up unresolved comments on stateful-sigs PR (#1793) * Simplify security assumption in docs * Get rid of commented functions * Rename sm variable; use OQS_MEM_cleanse * Clean up TODOs * Update markdown files --- docs/algorithms/sig_stfl/lms.md | 2 +- docs/algorithms/sig_stfl/lms.yml | 2 +- docs/algorithms/sig_stfl/xmss.md | 2 +- docs/algorithms/sig_stfl/xmss.yml | 4 ++-- src/sig_stfl/lms/sig_stfl_lms.c | 4 ---- src/sig_stfl/lms/sig_stfl_lms_functions.c | 23 +++++++++-------------- 6 files changed, 14 insertions(+), 23 deletions(-) diff --git a/docs/algorithms/sig_stfl/lms.md b/docs/algorithms/sig_stfl/lms.md index 8357d0a8f6..d436b6b616 100644 --- a/docs/algorithms/sig_stfl/lms.md +++ b/docs/algorithms/sig_stfl/lms.md @@ -1,7 +1,7 @@ # LMS - **Algorithm type**: Digital signature scheme. -- **Main cryptographic assumption**: hash function second-preimage resistance. +- **Main cryptographic assumption**: hash-based signatures. - **Principal submitters**: Scott Fluhrer. - **Auxiliary submitters**: C Martin, Maurice Hieronymus. - **Authors' website**: https://www.rfc-editor.org/info/rfc8554 diff --git a/docs/algorithms/sig_stfl/lms.yml b/docs/algorithms/sig_stfl/lms.yml index 2741a3afea..9293ff70c3 100644 --- a/docs/algorithms/sig_stfl/lms.yml +++ b/docs/algorithms/sig_stfl/lms.yml @@ -6,7 +6,7 @@ auxiliary-submitters: - C Martin - Maurice Hieronymus -crypto-assumption: hash function second-preimage resistance +crypto-assumption: hash-based signatures website: https://www.rfc-editor.org/info/rfc8554 nist-round: spec-version: diff --git a/docs/algorithms/sig_stfl/xmss.md b/docs/algorithms/sig_stfl/xmss.md index b68bfc3020..446adcd8e1 100644 --- a/docs/algorithms/sig_stfl/xmss.md +++ b/docs/algorithms/sig_stfl/xmss.md @@ -1,7 +1,7 @@ # XMSS - **Algorithm type**: Digital signature scheme. -- **Main cryptographic assumption**: hash function second-preimage resistance. +- **Main cryptographic assumption**: hash-based signatures. - **Principal submitters**: Joost Rijneveld, A. Huelsing, David Cooper, Bas Westerbaan. - **Authors' website**: https://www.rfc-editor.org/info/rfc8391 - **Specification version**: None. diff --git a/docs/algorithms/sig_stfl/xmss.yml b/docs/algorithms/sig_stfl/xmss.yml index ccc92c26ea..dccefa12f9 100644 --- a/docs/algorithms/sig_stfl/xmss.yml +++ b/docs/algorithms/sig_stfl/xmss.yml @@ -7,7 +7,7 @@ principal-submitters: - Bas Westerbaan auxiliary-submitters: -crypto-assumption: hash function second-preimage resistance +crypto-assumption: hash-based signatures website: https://www.rfc-editor.org/info/rfc8391 nist-round: spec-version: @@ -184,4 +184,4 @@ parameter-sets: claimed-security: length-public-key: 64 length-secret-key: 38095 - length-signature: 27688 \ No newline at end of file + length-signature: 27688 diff --git a/src/sig_stfl/lms/sig_stfl_lms.c b/src/sig_stfl/lms/sig_stfl_lms.c index 88dc5938fc..acc218a6ba 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.c +++ b/src/sig_stfl/lms/sig_stfl_lms.c @@ -27,11 +27,7 @@ OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w2_keypair(uint8_t *public_key, OQS_S OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h25_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -// OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void); -// OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void); OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); -// OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w2_new(void); -// OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W2_new(void); OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w2_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w4_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w8_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index f3660e40d8..60d1d0c60b 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -116,7 +116,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signatu err: if (*signature_length) { - memset(signature, 0, *signature_length); + OQS_MEM_cleanse(signature, *signature_length); } *signature_length = 0; @@ -252,7 +252,6 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uin if (sk->secret_key_data) { //this means a key pair has already been recreated - //TODO log error. return -1; } @@ -535,21 +534,19 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uin return -1; } - /* TODO: store key pair, file handler */ - ret = 0; return ret; } #endif #ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN -int oqs_sig_stfl_lms_sign(UNUSED OQS_SIG_STFL_SECRET_KEY *sk, UNUSED uint8_t *sm, UNUSED size_t *smlen, +int oqs_sig_stfl_lms_sign(UNUSED OQS_SIG_STFL_SECRET_KEY *sk, UNUSED uint8_t *signature, UNUSED size_t *signature_len, UNUSED const uint8_t *m, UNUSED size_t mlen) { return -1; } #else int oqs_sig_stfl_lms_sign(OQS_SIG_STFL_SECRET_KEY *sk, - uint8_t *sm, size_t *smlen, + uint8_t *signature, size_t *signature_len, const uint8_t *m, size_t mlen) { size_t sig_len; @@ -616,8 +613,8 @@ int oqs_sig_stfl_lms_sign(OQS_SIG_STFL_SECRET_KEY *sk, return -1; } - *smlen = sig_len; - memcpy(sm, sig, sig_len); + *signature_len = sig_len; + memcpy(signature, sig, sig_len); OQS_MEM_insecure_free(sig); hss_free_working_key(w); @@ -626,15 +623,15 @@ int oqs_sig_stfl_lms_sign(OQS_SIG_STFL_SECRET_KEY *sk, #endif int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, - const uint8_t *sm, size_t smlen, + const uint8_t *signature, size_t signature_len, const uint8_t *pk) { struct hss_validate_inc ctx; (void)hss_validate_signature_init( &ctx, /* Incremental validate context */ (const unsigned char *)pk, /* Public key */ - (const unsigned char *)sm, - (size_t)smlen, /* Signature */ + (const unsigned char *)signature, + (size_t)signature_len, /* Signature */ 0); /* Use the defaults for extra info */ (void)hss_validate_signature_update( @@ -644,7 +641,7 @@ int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, bool status = hss_validate_signature_finalize( &ctx, /* Incremental validate context */ - (const unsigned char *)sm, /* Signature */ + (const unsigned char *)signature, /* Signature */ 0); /* Use the defaults for extra info */ if (status) { @@ -661,8 +658,6 @@ void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk) { return; } - //TODO: cleanup lock_key - if (sk->secret_key_data) { oqs_lms_key_data *key_data = (oqs_lms_key_data *)sk->secret_key_data; if (key_data) { From 8e75f98929042052a97a18f70ec7193abe8798de Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Thu, 23 May 2024 11:43:06 -0400 Subject: [PATCH 63/68] Update config variable name --- .CMake/alg_support.cmake | 8 ++++---- .circleci/config.yml | 2 +- .github/workflows/android.yml | 2 +- .github/workflows/apple.yml | 2 +- .github/workflows/unix.yml | 18 +++++++++--------- .github/workflows/windows.yml | 4 ++-- .travis.yml | 4 ++-- CONFIGURE.md | 6 +++--- src/oqsconfig.h.cmake | 2 +- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index 3810585a9c..2b0eec0c18 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -563,16 +563,16 @@ cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h10_w8 "" ON "OQS_E cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h15_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h20_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) -option(OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN "Enable stateful key and signature generation for research and experimentation" OFF) -cmake_dependent_option(OQS_ALLOW_STFL_KEY_AND_SIG_GEN "" ON "OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN" OFF) +option(OQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN "Enable stateful key and signature generation for research and experimentation" OFF) +cmake_dependent_option(OQS_ALLOW_STFL_KEY_AND_SIG_GEN "" ON "OQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN" OFF) -if (${OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN} AND ${OQS_ENABLE_SIG_STFL_XMSS}) +if (${OQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN} AND ${OQS_ENABLE_SIG_STFL_XMSS}) set(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN ON) else() set(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN OFF) endif() -if (${OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN} AND ${OQS_ENABLE_SIG_STFL_LMS}) +if (${OQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN} AND ${OQS_ENABLE_SIG_STFL_LMS}) set(OQS_ALLOW_LMS_KEY_AND_SIG_GEN ON) else() set(OQS_ALLOW_LMS_KEY_AND_SIG_GEN OFF) diff --git a/.circleci/config.yml b/.circleci/config.yml index 6dda717b1d..a5a31cd1c0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -344,7 +344,7 @@ workflows: <<: *require_buildcheck name: arm64 PYTEST_ARGS: --numprocesses=auto --maxprocesses=10 --ignore=tests/test_kat_all.py - CMAKE_ARGS: -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON + CMAKE_ARGS: -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON commit-to-main: when: diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index d54b6ebcde..930aec691f 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -16,4 +16,4 @@ jobs: - name: Checkout code uses: actions/checkout@v3 - name: Build project - run: ./scripts/build-android.sh $ANDROID_NDK_HOME -a ${{ matrix.abi }} -f "-DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }}" + run: ./scripts/build-android.sh $ANDROID_NDK_HOME -a ${{ matrix.abi }} -f "-DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }}" diff --git a/.github/workflows/apple.yml b/.github/workflows/apple.yml index 69021d60a9..34dae893f5 100644 --- a/.github/workflows/apple.yml +++ b/.github/workflows/apple.yml @@ -17,6 +17,6 @@ jobs: - name: Generate project run: | cmake -B build --toolchain .CMake/apple.cmake -DOQS_USE_OPENSSL=OFF -DPLATFORM=${{ matrix.platform }} \ - -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . + -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . - name: Build project run: cmake --build build diff --git a/.github/workflows/unix.yml b/.github/workflows/unix.yml index fa459f9aed..0645616dce 100644 --- a/.github/workflows/unix.yml +++ b/.github/workflows/unix.yml @@ -74,19 +74,19 @@ jobs: include: - name: alpine container: openquantumsafe/ci-alpine-amd64:latest - CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: alpine-no-stfl-key-sig-gen container: openquantumsafe/ci-alpine-amd64:latest - CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: alpine-openssl-all container: openquantumsafe/ci-alpine-amd64:latest - CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_USE_AES_OPENSSL=ON -DOQS_USE_SHA2_OPENSSL=ON -DOQS_USE_SHA3_OPENSSL=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DOQS_USE_AES_OPENSSL=ON -DOQS_USE_SHA2_OPENSSL=ON -DOQS_USE_SHA3_OPENSSL=ON -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: alpine-noopenssl container: openquantumsafe/ci-alpine-amd64:latest - CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=OFF -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=OFF -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: focal-nistr4-openssl container: openquantumsafe/ci-ubuntu-focal-x86_64:latest @@ -102,11 +102,11 @@ jobs: PYTEST_ARGS: --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py - name: address-sanitizer container: openquantumsafe/ci-ubuntu-focal-x86_64:latest - CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_distbuild.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py --numprocesses=auto --maxprocesses=10 - name: address-sanitizer-no-stfl-key-sig-gen container: openquantumsafe/ci-ubuntu-focal-x86_64:latest - CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_distbuild.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py --numprocesses=auto --maxprocesses=10 container: image: ${{ matrix.container }} @@ -145,11 +145,11 @@ jobs: include: - name: armhf ARCH: armhf - CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: armhf-no-stfl-key-sig-gen ARCH: armhf - CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py # no longer supporting armel # - name: armel @@ -215,7 +215,7 @@ jobs: - macos-13 - macos-14 CMAKE_ARGS: - - -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + - -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON - -DCMAKE_C_COMPILER=gcc-13 - -DOQS_USE_OPENSSL=OFF - -DBUILD_SHARED_LIBS=ON -DOQS_DIST_BUILD=OFF diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 3c3e483337..d2552fae4c 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Generate Project - run: cmake -B build --toolchain .CMake/toolchain_windows_arm64.cmake -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . + run: cmake -B build --toolchain .CMake/toolchain_windows_arm64.cmake -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . - name: Build Project run: cmake --build build @@ -26,7 +26,7 @@ jobs: steps: - uses: actions/checkout@v3 - name: Generate Project - run: cmake -B build --toolchain ${{ matrix.toolchain }} -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . + run: cmake -B build --toolchain ${{ matrix.toolchain }} -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=${{ matrix.stfl_opt }} . - name: Build Project run: cmake --build build - name: Test dependencies diff --git a/.travis.yml b/.travis.yml index 882b92b755..1ebffdf879 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ jobs: compiler: gcc if: NOT branch =~ /^ghactionsonly-/ script: - - mkdir build && cd build && cmake -GNinja -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_STFL_SIG_KEY_SIG_GEN=ON .. && cmake -LA .. && ninja + - mkdir build && cd build && cmake -GNinja -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_STFL_SIG_KEY_SIG_GEN=ON .. && cmake -LA .. && ninja - cd build & ninja run_tests - arch: s390x os: linux @@ -17,5 +17,5 @@ jobs: compiler: gcc if: NOT branch =~ /^ghactionsonly-/ script: - - mkdir build && cd build && cmake -GNinja -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_STFL_SIG_KEY_SIG_GEN=ON .. && cmake -LA .. && ninja + - mkdir build && cd build && cmake -GNinja -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_STFL_SIG_KEY_SIG_GEN=ON .. && cmake -LA .. && ninja - cd build & ninja run_tests diff --git a/CONFIGURE.md b/CONFIGURE.md index 7ffcebae25..00d60cdfa7 100644 --- a/CONFIGURE.md +++ b/CONFIGURE.md @@ -125,10 +125,10 @@ Only has an effect if the system supports `dlopen` and ELF binary format, such a XMSS and LMS are the two supported Hash-Based Signatures schemes. `OQS_ENABLE_SIG_STFL_XMSS` and `OQS_ENABLE_SIG_STFL_LMS` control these algorithms, which are disabled by default. -A third variable, `OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN`, also controls the ability to generate keys and signatures. This is also disabled by default. +A third variable, `OQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN`, also controls the ability to generate keys and signatures. This is also disabled by default. Each of these variables can be set to `ON` or `OFF`. When all three are `ON`, stateful signatures are fully functional and can generate key pairs, sign data, and verify signatures. -If `OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN` is `OFF` signature verification is the only functional operation. +If `OQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN` is `OFF` signature verification is the only functional operation. Standards bodies, such as NIST, recommend that key and signature generation only by done in hardware in order to best enforce the one-time use of secret keys. Keys stored in a file system are extremely susceptible to simultaneous use. @@ -137,7 +137,7 @@ When enabled in this library a warning message will be generated by the config p By default, - `OQS_ENABLE_SIG_STFL_XMSS` is `OFF` - `OQS_ENABLE_SIG_STFL_LMS` is `OFF` -- `OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN` is `OFF`. +- `OQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN` is `OFF`. **Default**: `OFF`. diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index 414b759cfa..0617d30661 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -237,7 +237,7 @@ #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 1 -#cmakedefine OQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN 1 +#cmakedefine OQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN 1 #cmakedefine OQS_ALLOW_STFL_KEY_AND_SIG_GEN 1 #cmakedefine OQS_ALLOW_XMSS_KEY_AND_SIG_GEN 1 #cmakedefine OQS_ALLOW_LMS_KEY_AND_SIG_GEN 1 From ca2792266d06409b9fb05ee2280cf3c8cc767e2b Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Thu, 23 May 2024 11:45:49 -0400 Subject: [PATCH 64/68] Strengthen warning in CONFIGURE.md --- CONFIGURE.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CONFIGURE.md b/CONFIGURE.md index 00d60cdfa7..9bae9f5af2 100644 --- a/CONFIGURE.md +++ b/CONFIGURE.md @@ -133,6 +133,9 @@ If `OQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN` is `OFF` signature v Standards bodies, such as NIST, recommend that key and signature generation only by done in hardware in order to best enforce the one-time use of secret keys. Keys stored in a file system are extremely susceptible to simultaneous use. When enabled in this library a warning message will be generated by the config process. +The name of the configuration variable has been chosen to make every user of this feature aware of its security risks. +The OQS team explicitly discourages enabling this variable and reserves the right to remove this feature in future releases if its use causes actual harm. +It remains present as long as it is responsibly used as per the stated warnings. By default, - `OQS_ENABLE_SIG_STFL_XMSS` is `OFF` From 6f35f43ad06aef313bc84f4be78808522dd3f94b Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Thu, 30 May 2024 13:55:38 -0400 Subject: [PATCH 65/68] DCO sign-off [skip ci] I, Douglas Stebila, retroactively sign off on these commits: commit b0c06fa966360bad2c128b5b37255ced1266d9e3 Fix API and build issues commit 7b591542e3455b9407be44a54e0a67ffb455eb97 Add SIG_STFL to tests/dump_alg_info commit 8e1dd5ce0f6efbf221f3eb1ead8c295f72ab460e Update sig_stfl dummy scheme and add basic test program commit c9c3835c577e52d5da0fdf3c83334d59594fcfa8 Re-add OQS_SECRET_KEY (#1493) Signed-off-by: Douglas Stebila From 20d39aa6d8fa0c7a1d5c7d41a32a130f3e9e0e3e Mon Sep 17 00:00:00 2001 From: Spencer Wilson Date: Thu, 30 May 2024 15:27:49 -0400 Subject: [PATCH 66/68] I, Spencer Wilson, retroactively sign off on these commits: commit 001e96a03a853d07518f8215634a98f439d5eab3 Update GitHub Actions workflows for stateful signatures (#1692) commit 8524a16c4e3a4daa6e067af1f4a1dbb3858093d6 Post-rebase cleanup commit 5da49e33c6dd35780dc65dd5b1a4200191436405 Satisfy astyle commit a535114d514dc5871a8f4d7ce9515954b9befc3a Fix macOS build error: lld -> llu commit 71ee535eca8398f170a489ad45556464816782de Bring EVP_DigestUpdate calls in line with main commit 154d8e4b1c07c5fa4f0c12303a9c2a38aa3a36b3 Fix test program linkage for cross-compiling commit e92aab307f41b492c684438c4fdd8caae7b7a820 Stateful sigs: Rename keygen / sign option, add more tests, fix memory errors (#1755) commit b0758784cc5f4171ff264964a9f79e62e9503e30 Clean up OQS_SIG_STFL_SECRET_KEY_free commit db000c263a87d6830b125e045059664fc6b95cb5 Remove unused sig member commit 9b60f60b42a5570b86a511439925dcca48554c00 Naming convention for serialize / deserialize functions commit 7dd4ea0a9ecadce45050bdffe07e2d9fb4b338cc Test stateful sigs on arm64, s390x, and powerpc (#1772) commit 31bdf13d4b8717b143f9ed584dfb8faceb80ebd9 Clean up unresolved comments on stateful-sigs PR (#1793) commit 8e75f98929042052a97a18f70ec7193abe8798de Update config variable name commit ca2792266d06409b9fb05ee2280cf3c8cc767e2b Strengthen warning in CONFIGURE.md Signed-off-by: Spencer Wilson From d37f20dea787fc26398d8d09116e80493806a326 Mon Sep 17 00:00:00 2001 From: Duc Tri Nguyen Date: Thu, 30 May 2024 17:02:08 -0400 Subject: [PATCH 67/68] I, Duc Nguyen, retroactively sign off on these commits: commit 244288f8acdab63813fbb9514f85b5bf6f8d372c Add XMSS parameter xmss_sha256_h10 (#1482) commit a7e26d95451a5386b7726a614337a2db7045f24e Add 12 XMSS and 16 XMSSMT parameters. (#1489) commit 4694fc3b6e03720b25a8bb1ab292111dccb5bb28 Add secret key object to XMSS (#1530) commit 99067be855c99de792d4e25a3beb736ef9ecf80b Add XMSS Serialize/Deserialize (#1542) commit 2dbfc400734501386fd51d50c2739b3f09d25b3d Update XMSS secret key object APIs, sync with LMS (#1588) commit 47740ad98cc5361c9916abca1944f1e6a24c0158 Enforce idx from unsigned int to uint32_t. (#1611) commit 9610576db49c8ebb1c21a8a4bcde942d0ade53f9 Fix windows-x86 and arm compiling error. (#1634) commit bb658b79261e3f7187bd03c8ee19223555b2a96a Address stateful-sigs comments in #1650 (#1656) commit 7db8ddfe24a189e84e0d72dc127a8c09c8c89f24 Update `sig_stfl.h` document for #1650 (#1655) commit c3e57507e57cd406c420e35ec13cdd7214402be1 Add Apache 2.0 and MIT License to XMSS (#1662) commit e1f02b2d6dca61523094640868116a8d997eb14e Change XMSS License from `(Apache 2.0 AND MIT)` to `(Apache 2.0 OR MIT) AND CC0-1.0` (#1697) commit 17c12c3c7f0e1b0c92085f5001559e0f892f9d18 Add return status for XMSS lock/unlock functions. (#1712) commit 194163611c1353b417ac47f4568f74fdd9325cff Add return check for lock/unlock function (#1727) commit b45415c5ff2b4087c4e3091a6ef7dc3f25eb3940 Use `abort()` instead of exit to get the trace log. (#1728) commit ba63672527eabfe43139adaf9bc37e15e8a3657a Reduce number of `malloc/free` call in `XMSS/external` (#1724) Signed-off-by: Duc Tri Nguyen From 3621a6bfdd0f821de51223047df9628f4dd6d5f2 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Tue, 4 Jun 2024 13:26:45 -0400 Subject: [PATCH 68/68] I, Norman Ashley, retroactively sign off on these commits: commit e356ebf33167f7514466ce4c44c90a46e6f213bd Na lms (#1486) commit 55094c37f167ec4323411853ffc63da923741662 LMS H5_W1 (#1513) commit 4d773d785e1640889e8c3d84dfb3139c9804587b Convert to use OQS_SIG_STFL_SECRET_KEY struct (#1525) commit 245aede9970934f45801aa12ed9189b42c94993a LMS updated to use new SK API (#1533) commit a85a9aa172647fa42fbc3cf63a477a691ecb68c5 Stateful sigs secret key storage callback (#1553) commit 3934949d260909e22cdf347cfc32e3231ea30214 Na statful sig lock (#1559) commit 3db6b44f775fdb57440678c42153c57660ad50c1 Secret Key Query (#1572) commit 2446c64b3fd067452f6d07d283a660ac9af7b2cd Na stateful sigs lms var (#1574) commit 8df253944127c4da39d8a7068b98244c1619baea Stateful sigs XMSS updates (#1590) commit a7b29874fd7aec76165626c2e6ea8a66de91e0b9 SHA2 Increment with arbitrary length (non-block sizes) (#1614) commit 2dd9e07e07802c9afaf4cd3461d9473bccf44844 Na lms kat multi level (#1620) commit 982b44061b575ad573f81bb668325ef4dedb8014 Fix Build Errors (#1635) commit ddae6444b424343e7623b010d3dc304adc101ce6 Various fixes commit cc50ef00d14eef43e51c1b83ef32637a1f42f7af Fix warning commit cf03392510f426da2f1283b4c709d39fb92bcaf8 Update README.md commit 93257132a7b4687674803fd903ab986a32fd1143 Update README.md commit a52b2176eceed0ccff2df31302907b50c8d2dc22 Update README.md commit d442ac9ba861f9171b45a34de148f935a5de600d Update README.md commit 72ab47826cac51e47ea00cfccdeac2bc4c9c0485 Update README.md commit 5967f12281ac99b206407c44e340026fdb2ef7c7 Update src/CMakeLists.txt commit fc6d512ac18d08727a73b4232f1f5030eced7fe0 Update documentation and license text. (#1663) commit e7a83c7167032084a9fe8ab2ae86f4b2e19c4bf5 Disable Stateful Signatures in the build by default (#1676) commit 6c81bae0099c069c5e9b08fb0ea87d40302c07b9 Na stateful macro (#1687) Signed-off-by: Norman Ashley