From e3e504abd97d293abc3270b3b82c26b9c180417e Mon Sep 17 00:00:00 2001 From: Christian Paquin Date: Thu, 29 Aug 2019 19:56:46 -0400 Subject: [PATCH] Upgraged to v2.1.1 of picnic. --- docs/algorithms/sig_picnic.md | 2 +- src/sig/picnic/Makefile.am | 2 +- src/sig/picnic/external/README.md | 1 - src/sig/picnic/external/cpu.c | 2 +- src/sig/picnic/external/kdf_shake.h | 58 +- src/sig/picnic/external/lowmc.c | 15 +- src/sig/picnic/external/lowmc.h | 2 +- src/sig/picnic/external/lowmc_128_128_182.c | 1470 --------- src/sig/picnic/external/lowmc_128_128_182.h | 4 - src/sig/picnic/external/lowmc_128_128_20.c | 174 - src/sig/picnic/external/lowmc_128_128_20.h | 4 - src/sig/picnic/external/lowmc_192_192_284.c | 2286 ------------- src/sig/picnic/external/lowmc_192_192_284.h | 4 - src/sig/picnic/external/lowmc_192_192_30.c | 254 -- src/sig/picnic/external/lowmc_192_192_30.h | 4 - src/sig/picnic/external/lowmc_256_256_363.c | 2918 ----------------- src/sig/picnic/external/lowmc_256_256_363.h | 4 - src/sig/picnic/external/lowmc_256_256_38.c | 318 -- src/sig/picnic/external/lowmc_256_256_38.h | 4 - src/sig/picnic/external/lowmc_fns_s128_L1.h | 8 +- src/sig/picnic/external/lowmc_fns_s128_L3.h | 8 +- src/sig/picnic/external/lowmc_fns_s128_L5.h | 8 +- src/sig/picnic/external/lowmc_fns_s256_L1.h | 8 +- src/sig/picnic/external/lowmc_fns_s256_L3.h | 8 +- src/sig/picnic/external/lowmc_fns_s256_L5.h | 8 +- src/sig/picnic/external/lowmc_fns_uint64_L1.h | 8 +- src/sig/picnic/external/lowmc_fns_uint64_L3.h | 8 +- src/sig/picnic/external/lowmc_fns_uint64_L5.h | 8 +- src/sig/picnic/external/lowmc_impl.c.i | 36 +- src/sig/picnic/external/lowmc_pars.c | 63 - src/sig/picnic/external/lowmc_pars.h | 34 - src/sig/picnic/external/macros.h | 17 +- src/sig/picnic/external/mpc_lowmc.c | 8 + src/sig/picnic/external/mpc_lowmc_impl.c.i | 4 +- src/sig/picnic/external/mpc_lowmc_loop.c.i | 16 +- src/sig/picnic/external/mzd_additional.c | 718 ---- src/sig/picnic/external/mzd_additional.h | 70 - src/sig/picnic/external/picnic.c | 28 +- src/sig/picnic/external/picnic2_L1_FS/api.h | 1 + src/sig/picnic/external/picnic2_L3_FS/api.h | 1 + src/sig/picnic/external/picnic2_L5_FS/api.h | 1 + src/sig/picnic/external/picnic2_impl.c | 375 ++- src/sig/picnic/external/picnic2_simulate.c | 84 +- src/sig/picnic/external/picnic2_simulate.c.i | 96 +- src/sig/picnic/external/picnic2_simulate.h | 4 +- .../picnic/external/picnic2_simulate_mul.c | 776 ++--- .../picnic/external/picnic2_simulate_mul.h | 146 +- src/sig/picnic/external/picnic2_tree.c | 93 +- src/sig/picnic/external/picnic2_types.c | 51 +- src/sig/picnic/external/picnic2_types.h | 7 +- src/sig/picnic/external/picnic_L1_FS/api.h | 1 + src/sig/picnic/external/picnic_L1_UR/api.h | 1 + src/sig/picnic/external/picnic_L3_FS/api.h | 1 + src/sig/picnic/external/picnic_L3_UR/api.h | 1 + src/sig/picnic/external/picnic_L5_FS/api.h | 1 + src/sig/picnic/external/picnic_L5_UR/api.h | 1 + src/sig/picnic/external/picnic_impl.c | 105 +- src/sig/picnic/external/picnic_impl.h | 1 + src/sig/picnic/sig_picnic.c | 18 +- tests/KATs/sig/picnic2_L1_FS.kat | 6 +- tests/KATs/sig/picnic2_L3_FS.kat | 6 +- tests/KATs/sig/picnic2_L5_FS.kat | 6 +- 62 files changed, 1145 insertions(+), 9230 deletions(-) delete mode 100644 src/sig/picnic/external/lowmc_pars.c diff --git a/docs/algorithms/sig_picnic.md b/docs/algorithms/sig_picnic.md index b3d69e3c3..4376fd5ab 100644 --- a/docs/algorithms/sig_picnic.md +++ b/docs/algorithms/sig_picnic.md @@ -31,7 +31,7 @@ Implementation -------------- - **Source of implementation:** https://github.com/IAIK/Picnic -- **Implementation version:** https://github.com/IAIK/Picnic/tree/v2.0 +- **Implementation version:** https://github.com/IAIK/Picnic/tree/v2.1.1 - **License:** MIT License - **Language:** C - **Constant-time:** Yes diff --git a/src/sig/picnic/Makefile.am b/src/sig/picnic/Makefile.am index ad539804b..1f0061603 100644 --- a/src/sig/picnic/Makefile.am +++ b/src/sig/picnic/Makefile.am @@ -1,7 +1,7 @@ AUTOMAKE_OPTIONS = foreign noinst_LTLIBRARIES = libpicnic_i.la -libpicnic_i_la_SOURCES = sig_picnic.c external/aligned_alloc.c external/bitstream.c external/cpu.c external/io.c external/lowmc.c external/lowmc_pars.c external/lowmc_128_128_20.c external/lowmc_128_128_182.c external/lowmc_192_192_284.c external/lowmc_192_192_30.c external/lowmc_256_256_38.c external/lowmc_256_256_363.c external/mpc_lowmc.c external/mzd_additional.c external/picnic.c external/picnic_impl.c external/picnic2_impl.c external/picnic2_simulate.c external/picnic2_simulate_mul.c external/picnic2_tree.c external/picnic2_types.c external/sha3/KeccakHash.c external/sha3/KeccakSpongeWidth1600.c external/sha3/KeccakHashtimes4.c external/sha3/KeccakSpongeWidth1600times4.c external/sha3/opt64/KeccakP-1600-opt64.c external/sha3/opt64/KeccakP-1600-times4-on1.c +libpicnic_i_la_SOURCES = sig_picnic.c external/aligned_alloc.c external/bitstream.c external/cpu.c external/io.c external/lowmc.c external/lowmc_128_128_20.c external/lowmc_128_128_182.c external/lowmc_192_192_284.c external/lowmc_192_192_30.c external/lowmc_256_256_38.c external/lowmc_256_256_363.c external/mpc_lowmc.c external/mzd_additional.c external/picnic.c external/picnic_impl.c external/picnic2_impl.c external/picnic2_simulate.c external/picnic2_simulate_mul.c external/picnic2_tree.c external/picnic2_types.c external/sha3/KeccakHash.c external/sha3/KeccakSpongeWidth1600.c external/sha3/KeccakHashtimes4.c external/sha3/KeccakSpongeWidth1600times4.c external/sha3/opt64/KeccakP-1600-opt64.c external/sha3/opt64/KeccakP-1600-times4-on1.c libpicnic_i_la_CFLAGS = -Iexternal -Iexternal/sha3 -Iexternal/sha3/opt64 -DPICNIC_STATIC -DOPTIMIZED_LINEAR_LAYER_EVALUATION -DREDUCED_ROUND_KEY_COMPUTATION -DWITH_LOWMC_128_128_20 -DWITH_LOWMC_192_192_30 -DWITH_LOWMC_256_256_38 -DWITH_OPT -DWITH_POPCNT diff --git a/src/sig/picnic/external/README.md b/src/sig/picnic/external/README.md index ba9bdac2a..7639b0bce 100644 --- a/src/sig/picnic/external/README.md +++ b/src/sig/picnic/external/README.md @@ -31,7 +31,6 @@ The cmake based build system supports the following flags: * ``WITH_NEON``: Use NEON if available. * ``WITH_MARCH_NATIVE``: Build with -march=native -mtune=native (if supported). * ``WITH_LTO``: Enable link-time optimization (if supported). -* ``WITH_MUL_M4RI``: Use methods of four russians for matrix multiplication. * ``WITH_LOWMC_OPT={OFF,ORKC,OLLE}``: Enable optimized round key computation (ORKC) or optimized linear layer evaluation (OLLE) optimizations. * ``WITH_LOWMC_M1``: Enable LowMC instances with 1 Sbox minimizing the signature sizes. diff --git a/src/sig/picnic/external/cpu.c b/src/sig/picnic/external/cpu.c index fa05f26f2..f03d4774a 100644 --- a/src/sig/picnic/external/cpu.c +++ b/src/sig/picnic/external/cpu.c @@ -35,7 +35,7 @@ static unsigned int init_caps(void) { return caps; } -#elif (defined(__x86_64__) || defined(__i386__)) && (defined(__GNUC__) || defined(_MSC_VER)) +#elif (defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_AMD64)) && (defined(__GNUC__) || defined(_MSC_VER)) #ifdef _MSC_VER #include diff --git a/src/sig/picnic/external/kdf_shake.h b/src/sig/picnic/external/kdf_shake.h index af9534dde..e401e33de 100644 --- a/src/sig/picnic/external/kdf_shake.h +++ b/src/sig/picnic/external/kdf_shake.h @@ -10,7 +10,6 @@ #ifndef KDF_SHAKE_H #define KDF_SHAKE_H -#include #include #if !defined(KeccakP200_excluded) @@ -27,15 +26,20 @@ #if !defined(SUPERCOP) #include "sha3/KeccakHash.h" +#if defined(WITH_KECCAK_X4) +#include "sha3/KeccakHashtimes4.h" +#endif #else #include +#if defined(WITH_KECCAK_X4) +/* Keccakx4 is not fully supported by SUPERCOP, so we need to ship it ourselves. */ +#include "KeccakHashtimes4.h" +#endif #endif -// this is not in SUPERCOP, so we ship it ourselves -#include "sha3/KeccakHashtimes4.h" #include "picnic_impl.h" -typedef Keccak_HashInstance hash_context; +typedef Keccak_HashInstance hash_context ATTR_ALIGNED(32); static inline void hash_init(hash_context* ctx, const picnic_instance_t* pp) { if (pp->digest_size == 32) { @@ -63,7 +67,7 @@ static inline void hash_squeeze(hash_context* ctx, uint8_t* buffer, size_t bufle Keccak_HashSqueeze(ctx, buffer, buflen << 3); } -typedef Keccak_HashInstance kdf_shake_t; +typedef hash_context kdf_shake_t; #define kdf_shake_init(ctx, pp) hash_init((ctx), (pp)) #define kdf_shake_init_prefix(ctx, pp, prefix) hash_init_prefix((ctx), (pp), (prefix)) @@ -72,8 +76,45 @@ typedef Keccak_HashInstance kdf_shake_t; #define kdf_shake_get_randomness(ctx, dst, count) hash_squeeze((ctx), (dst), (count)) #define kdf_shake_clear(ctx) -// Instances that work with 4 states in parallel -typedef Keccak_HashInstancetimes4 hash_context_x4; +#if !defined(WITH_KECCAK_X4) +/* Instances that work with 4 states in parallel using the base Keccak implementation. */ +typedef struct hash_context_x4_s { + hash_context instances[4]; +} hash_context_x4; + +static inline void hash_init_x4(hash_context_x4* ctx, const picnic_instance_t* pp) { + for (unsigned int i = 0; i < 4; ++i) { + hash_init(&ctx->instances[i], pp); + } +} + +static inline void hash_update_x4(hash_context_x4* ctx, const uint8_t** data, size_t size) { + for (unsigned int i = 0; i < 4; ++i) { + hash_update(&ctx->instances[i], data[i], size); + } +} + +static inline void hash_init_prefix_x4(hash_context_x4* ctx, const picnic_instance_t* pp, + const uint8_t prefix) { + for (unsigned int i = 0; i < 4; ++i) { + hash_init_prefix(&ctx->instances[i], pp, prefix); + } +} + +static inline void hash_final_x4(hash_context_x4* ctx) { + for (unsigned int i = 0; i < 4; ++i) { + hash_final(&ctx->instances[i]); + } +} + +static inline void hash_squeeze_x4(hash_context_x4* ctx, uint8_t** buffer, size_t buflen) { + for (unsigned int i = 0; i < 4; ++i) { + hash_squeeze(&ctx->instances[i], buffer[i], buflen); + } +} +#else +/* Instances that work with 4 states in parallel. */ +typedef Keccak_HashInstancetimes4 hash_context_x4 ATTR_ALIGNED(32); static inline void hash_init_x4(hash_context_x4* ctx, const picnic_instance_t* pp) { if (pp->digest_size == 32) { @@ -101,8 +142,9 @@ static inline void hash_final_x4(hash_context_x4* ctx) { static inline void hash_squeeze_x4(hash_context_x4* ctx, uint8_t** buffer, size_t buflen) { Keccak_HashSqueezetimes4(ctx, buffer, buflen << 3); } +#endif -typedef Keccak_HashInstancetimes4 kdf_shake_x4_t; +typedef hash_context_x4 kdf_shake_x4_t; #define kdf_shake_x4_init(ctx, pp) hash_init_x4((ctx), (pp)) #define kdf_shake_x4_init_prefix(ctx, pp, prefix) hash_init_prefix_x4((ctx), (pp), (prefix)) diff --git a/src/sig/picnic/external/lowmc.c b/src/sig/picnic/external/lowmc.c index 7567a4e48..bdc0cfb62 100644 --- a/src/sig/picnic/external/lowmc.c +++ b/src/sig/picnic/external/lowmc.c @@ -139,7 +139,7 @@ static void sbox_layer_1_uint64(uint64_t* d) { #define FN_ATTR ATTR_TARGET_AVX2 // L1 using AVX2 -#include "lowmc_fns_s128_L1.h" +#include "lowmc_fns_s256_L1.h" #undef LOWMC #define LOWMC lowmc_s256_128 #include "lowmc.c.i" @@ -162,7 +162,11 @@ static void sbox_layer_1_uint64(uint64_t* d) { #endif lowmc_implementation_f lowmc_get_implementation(const lowmc_t* lowmc) { +#if defined(WITH_LOWMC_M1) ASSUME(lowmc->m == 10 || lowmc->m == 1); +#else + ASSUME(lowmc->m == 10); +#endif ASSUME(lowmc->n == 128 || lowmc->n == 192 || lowmc->n == 256); #if defined(WITH_OPT) @@ -284,7 +288,11 @@ lowmc_implementation_f lowmc_get_implementation(const lowmc_t* lowmc) { } lowmc_store_implementation_f lowmc_store_get_implementation(const lowmc_t* lowmc) { +#if defined(WITH_LOWMC_M1) ASSUME(lowmc->m == 10 || lowmc->m == 1); +#else + ASSUME(lowmc->m == 10); +#endif ASSUME(lowmc->n == 128 || lowmc->n == 192 || lowmc->n == 256); #if defined(WITH_OPT) @@ -406,8 +414,13 @@ lowmc_store_implementation_f lowmc_store_get_implementation(const lowmc_t* lowmc } lowmc_compute_aux_implementation_f lowmc_compute_aux_get_implementation(const lowmc_t* lowmc) { +#if defined(WITH_LOWMC_M1) + ASSUME(lowmc->m == 10 || lowmc->m == 1); +#else ASSUME(lowmc->m == 10); +#endif ASSUME(lowmc->n == 128 || lowmc->n == 192 || lowmc->n == 256); + #if defined(WITH_OPT) #if defined(WITH_AVX2) if (CPU_SUPPORTS_AVX2) { diff --git a/src/sig/picnic/external/lowmc.h b/src/sig/picnic/external/lowmc.h index aecb40539..e62fceb72 100644 --- a/src/sig/picnic/external/lowmc.h +++ b/src/sig/picnic/external/lowmc.h @@ -19,7 +19,7 @@ typedef struct { // forward decleration to picnic2_types.h since we get some cyclic dependencies otherwise typedef struct randomTape_t randomTape_t; -typedef mzd_local_t* (*lowmc_implementation_f)(lowmc_key_t const*, mzd_local_t const*); +typedef void (*lowmc_implementation_f)(lowmc_key_t const*, mzd_local_t const*, mzd_local_t*); typedef void (*lowmc_store_implementation_f)(lowmc_key_t const*, mzd_local_t const*, recorded_state_t* state); typedef void (*lowmc_compute_aux_implementation_f)(lowmc_key_t const*, randomTape_t* tapes); diff --git a/src/sig/picnic/external/lowmc_128_128_182.c b/src/sig/picnic/external/lowmc_128_128_182.c index 6d8903a2b..511decde4 100644 --- a/src/sig/picnic/external/lowmc_128_128_182.c +++ b/src/sig/picnic/external/lowmc_128_128_182.c @@ -27096,3477 +27096,2013 @@ static const block_t Ri_180[] = { #endif -#if defined(MUL_M4RI) -static lowmc_round_t rounds[182] = { -#else static const lowmc_round_t rounds[182] = { -#endif { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_1, L_0, C_0, NULL, NULL -#else K_1, L_0, C_0 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_0, Ri_0, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_0, NULL #else L_0 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_2, L_1, C_1, NULL, NULL -#else K_2, L_1, C_1 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_1, Ri_1, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_1, NULL #else L_1 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_3, L_2, C_2, NULL, NULL -#else K_3, L_2, C_2 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_2, Ri_2, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_2, NULL #else L_2 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_4, L_3, C_3, NULL, NULL -#else K_4, L_3, C_3 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_3, Ri_3, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_3, NULL #else L_3 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_5, L_4, C_4, NULL, NULL -#else K_5, L_4, C_4 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_4, Ri_4, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_4, NULL #else L_4 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_6, L_5, C_5, NULL, NULL -#else K_6, L_5, C_5 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_5, Ri_5, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_5, NULL #else L_5 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_7, L_6, C_6, NULL, NULL -#else K_7, L_6, C_6 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_6, Ri_6, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_6, NULL #else L_6 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_8, L_7, C_7, NULL, NULL -#else K_8, L_7, C_7 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_7, Ri_7, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_7, NULL #else L_7 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_9, L_8, C_8, NULL, NULL -#else K_9, L_8, C_8 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_8, Ri_8, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_8, NULL #else L_8 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_10, L_9, C_9, NULL, NULL -#else K_10, L_9, C_9 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_9, Ri_9, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_9, NULL #else L_9 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_11, L_10, C_10, NULL, NULL -#else K_11, L_10, C_10 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_10, Ri_10, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_10, NULL #else L_10 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_12, L_11, C_11, NULL, NULL -#else K_12, L_11, C_11 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_11, Ri_11, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_11, NULL #else L_11 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_13, L_12, C_12, NULL, NULL -#else K_13, L_12, C_12 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_12, Ri_12, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_12, NULL #else L_12 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_14, L_13, C_13, NULL, NULL -#else K_14, L_13, C_13 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_13, Ri_13, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_13, NULL #else L_13 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_15, L_14, C_14, NULL, NULL -#else K_15, L_14, C_14 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_14, Ri_14, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_14, NULL #else L_14 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_16, L_15, C_15, NULL, NULL -#else K_16, L_15, C_15 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_15, Ri_15, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_15, NULL #else L_15 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_17, L_16, C_16, NULL, NULL -#else K_17, L_16, C_16 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_16, Ri_16, UINT64_C(0x6080000000000000), -#else -#if defined(MUL_M4RI) - L_16, NULL #else L_16 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_18, L_17, C_17, NULL, NULL -#else K_18, L_17, C_17 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_17, Ri_17, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_17, NULL #else L_17 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_19, L_18, C_18, NULL, NULL -#else K_19, L_18, C_18 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_18, Ri_18, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_18, NULL #else L_18 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_20, L_19, C_19, NULL, NULL -#else K_20, L_19, C_19 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_19, Ri_19, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_19, NULL #else L_19 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_21, L_20, C_20, NULL, NULL -#else K_21, L_20, C_20 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_20, Ri_20, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_20, NULL #else L_20 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_22, L_21, C_21, NULL, NULL -#else K_22, L_21, C_21 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_21, Ri_21, UINT64_C(0x6800000000000000), -#else -#if defined(MUL_M4RI) - L_21, NULL #else L_21 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_23, L_22, C_22, NULL, NULL -#else K_23, L_22, C_22 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_22, Ri_22, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_22, NULL #else L_22 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_24, L_23, C_23, NULL, NULL -#else K_24, L_23, C_23 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_23, Ri_23, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_23, NULL #else L_23 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_25, L_24, C_24, NULL, NULL -#else K_25, L_24, C_24 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_24, Ri_24, UINT64_C(0x5800000000000000), -#else -#if defined(MUL_M4RI) - L_24, NULL #else L_24 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_26, L_25, C_25, NULL, NULL -#else K_26, L_25, C_25 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_25, Ri_25, UINT64_C(0x5800000000000000), -#else -#if defined(MUL_M4RI) - L_25, NULL #else L_25 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_27, L_26, C_26, NULL, NULL -#else K_27, L_26, C_26 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_26, Ri_26, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_26, NULL #else L_26 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_28, L_27, C_27, NULL, NULL -#else K_28, L_27, C_27 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_27, Ri_27, UINT64_C(0xc080000000000000), -#else -#if defined(MUL_M4RI) - L_27, NULL #else L_27 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_29, L_28, C_28, NULL, NULL -#else K_29, L_28, C_28 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_28, Ri_28, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_28, NULL #else L_28 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_30, L_29, C_29, NULL, NULL -#else K_30, L_29, C_29 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_29, Ri_29, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_29, NULL #else L_29 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_31, L_30, C_30, NULL, NULL -#else K_31, L_30, C_30 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_30, Ri_30, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_30, NULL #else L_30 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_32, L_31, C_31, NULL, NULL -#else K_32, L_31, C_31 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_31, Ri_31, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_31, NULL #else L_31 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_33, L_32, C_32, NULL, NULL -#else K_33, L_32, C_32 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_32, Ri_32, UINT64_C(0xa020000000000000), -#else -#if defined(MUL_M4RI) - L_32, NULL #else L_32 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_34, L_33, C_33, NULL, NULL -#else K_34, L_33, C_33 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_33, Ri_33, UINT64_C(0x5200000000000000), -#else -#if defined(MUL_M4RI) - L_33, NULL #else L_33 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_35, L_34, C_34, NULL, NULL -#else K_35, L_34, C_34 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_34, Ri_34, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_34, NULL #else L_34 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_36, L_35, C_35, NULL, NULL -#else K_36, L_35, C_35 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_35, Ri_35, UINT64_C(0x3800000000000000), -#else -#if defined(MUL_M4RI) - L_35, NULL #else L_35 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_37, L_36, C_36, NULL, NULL -#else K_37, L_36, C_36 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_36, Ri_36, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_36, NULL #else L_36 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_38, L_37, C_37, NULL, NULL -#else K_38, L_37, C_37 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_37, Ri_37, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_37, NULL #else L_37 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_39, L_38, C_38, NULL, NULL -#else K_39, L_38, C_38 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_38, Ri_38, UINT64_C(0x3040000000000000), -#else -#if defined(MUL_M4RI) - L_38, NULL #else L_38 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_40, L_39, C_39, NULL, NULL -#else K_40, L_39, C_39 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_39, Ri_39, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_39, NULL #else L_39 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_41, L_40, C_40, NULL, NULL -#else K_41, L_40, C_40 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_40, Ri_40, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_40, NULL #else L_40 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_42, L_41, C_41, NULL, NULL -#else K_42, L_41, C_41 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_41, Ri_41, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_41, NULL #else L_41 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_43, L_42, C_42, NULL, NULL -#else K_43, L_42, C_42 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_42, Ri_42, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_42, NULL #else L_42 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_44, L_43, C_43, NULL, NULL -#else K_44, L_43, C_43 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_43, Ri_43, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_43, NULL #else L_43 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_45, L_44, C_44, NULL, NULL -#else K_45, L_44, C_44 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_44, Ri_44, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_44, NULL #else L_44 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_46, L_45, C_45, NULL, NULL -#else K_46, L_45, C_45 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_45, Ri_45, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_45, NULL #else L_45 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_47, L_46, C_46, NULL, NULL -#else K_47, L_46, C_46 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_46, Ri_46, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_46, NULL #else L_46 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_48, L_47, C_47, NULL, NULL -#else K_48, L_47, C_47 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_47, Ri_47, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_47, NULL #else L_47 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_49, L_48, C_48, NULL, NULL -#else K_49, L_48, C_48 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_48, Ri_48, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_48, NULL #else L_48 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_50, L_49, C_49, NULL, NULL -#else K_50, L_49, C_49 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_49, Ri_49, UINT64_C(0xa200000000000000), -#else -#if defined(MUL_M4RI) - L_49, NULL #else L_49 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_51, L_50, C_50, NULL, NULL -#else K_51, L_50, C_50 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_50, Ri_50, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_50, NULL #else L_50 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_52, L_51, C_51, NULL, NULL -#else K_52, L_51, C_51 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_51, Ri_51, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_51, NULL #else L_51 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_53, L_52, C_52, NULL, NULL -#else K_53, L_52, C_52 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_52, Ri_52, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_52, NULL #else L_52 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_54, L_53, C_53, NULL, NULL -#else K_54, L_53, C_53 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_53, Ri_53, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_53, NULL #else L_53 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_55, L_54, C_54, NULL, NULL -#else K_55, L_54, C_54 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_54, Ri_54, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_54, NULL #else L_54 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_56, L_55, C_55, NULL, NULL -#else K_56, L_55, C_55 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_55, Ri_55, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_55, NULL #else L_55 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_57, L_56, C_56, NULL, NULL -#else K_57, L_56, C_56 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_56, Ri_56, UINT64_C(0xa200000000000000), -#else -#if defined(MUL_M4RI) - L_56, NULL #else L_56 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_58, L_57, C_57, NULL, NULL -#else K_58, L_57, C_57 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_57, Ri_57, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_57, NULL #else L_57 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_59, L_58, C_58, NULL, NULL -#else K_59, L_58, C_58 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_58, Ri_58, UINT64_C(0x3400000000000000), -#else -#if defined(MUL_M4RI) - L_58, NULL #else L_58 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_60, L_59, C_59, NULL, NULL -#else K_60, L_59, C_59 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_59, Ri_59, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_59, NULL #else L_59 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_61, L_60, C_60, NULL, NULL -#else K_61, L_60, C_60 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_60, Ri_60, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_60, NULL #else L_60 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_62, L_61, C_61, NULL, NULL -#else K_62, L_61, C_61 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_61, Ri_61, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_61, NULL #else L_61 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_63, L_62, C_62, NULL, NULL -#else K_63, L_62, C_62 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_62, Ri_62, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_62, NULL #else L_62 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_64, L_63, C_63, NULL, NULL -#else K_64, L_63, C_63 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_63, Ri_63, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_63, NULL #else L_63 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_65, L_64, C_64, NULL, NULL -#else K_65, L_64, C_64 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_64, Ri_64, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_64, NULL #else L_64 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_66, L_65, C_65, NULL, NULL -#else K_66, L_65, C_65 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_65, Ri_65, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_65, NULL #else L_65 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_67, L_66, C_66, NULL, NULL -#else K_67, L_66, C_66 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_66, Ri_66, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_66, NULL #else L_66 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_68, L_67, C_67, NULL, NULL -#else K_68, L_67, C_67 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_67, Ri_67, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_67, NULL #else L_67 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_69, L_68, C_68, NULL, NULL -#else K_69, L_68, C_68 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_68, Ri_68, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_68, NULL #else L_68 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_70, L_69, C_69, NULL, NULL -#else K_70, L_69, C_69 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_69, Ri_69, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_69, NULL #else L_69 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_71, L_70, C_70, NULL, NULL -#else K_71, L_70, C_70 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_70, Ri_70, UINT64_C(0x6400000000000000), -#else -#if defined(MUL_M4RI) - L_70, NULL #else L_70 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_72, L_71, C_71, NULL, NULL -#else K_72, L_71, C_71 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_71, Ri_71, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_71, NULL #else L_71 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_73, L_72, C_72, NULL, NULL -#else K_73, L_72, C_72 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_72, Ri_72, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_72, NULL #else L_72 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_74, L_73, C_73, NULL, NULL -#else K_74, L_73, C_73 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_73, Ri_73, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_73, NULL #else L_73 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_75, L_74, C_74, NULL, NULL -#else K_75, L_74, C_74 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_74, Ri_74, UINT64_C(0xc100000000000000), -#else -#if defined(MUL_M4RI) - L_74, NULL #else L_74 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_76, L_75, C_75, NULL, NULL -#else K_76, L_75, C_75 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_75, Ri_75, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_75, NULL #else L_75 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_77, L_76, C_76, NULL, NULL -#else K_77, L_76, C_76 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_76, Ri_76, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_76, NULL #else L_76 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_78, L_77, C_77, NULL, NULL -#else K_78, L_77, C_77 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_77, Ri_77, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_77, NULL #else L_77 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_79, L_78, C_78, NULL, NULL -#else K_79, L_78, C_78 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_78, Ri_78, UINT64_C(0x3400000000000000), -#else -#if defined(MUL_M4RI) - L_78, NULL #else L_78 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_80, L_79, C_79, NULL, NULL -#else K_80, L_79, C_79 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_79, Ri_79, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_79, NULL #else L_79 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_81, L_80, C_80, NULL, NULL -#else K_81, L_80, C_80 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_80, Ri_80, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_80, NULL #else L_80 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_82, L_81, C_81, NULL, NULL -#else K_82, L_81, C_81 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_81, Ri_81, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_81, NULL #else L_81 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_83, L_82, C_82, NULL, NULL -#else K_83, L_82, C_82 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_82, Ri_82, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_82, NULL #else L_82 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_84, L_83, C_83, NULL, NULL -#else K_84, L_83, C_83 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_83, Ri_83, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_83, NULL #else L_83 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_85, L_84, C_84, NULL, NULL -#else K_85, L_84, C_84 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_84, Ri_84, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_84, NULL #else L_84 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_86, L_85, C_85, NULL, NULL -#else K_86, L_85, C_85 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_85, Ri_85, UINT64_C(0x5800000000000000), -#else -#if defined(MUL_M4RI) - L_85, NULL #else L_85 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_87, L_86, C_86, NULL, NULL -#else K_87, L_86, C_86 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_86, Ri_86, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_86, NULL #else L_86 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_88, L_87, C_87, NULL, NULL -#else K_88, L_87, C_87 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_87, Ri_87, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_87, NULL #else L_87 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_89, L_88, C_88, NULL, NULL -#else K_89, L_88, C_88 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_88, Ri_88, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_88, NULL #else L_88 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_90, L_89, C_89, NULL, NULL -#else K_90, L_89, C_89 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_89, Ri_89, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_89, NULL #else L_89 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_91, L_90, C_90, NULL, NULL -#else K_91, L_90, C_90 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_90, Ri_90, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_90, NULL #else L_90 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_92, L_91, C_91, NULL, NULL -#else K_92, L_91, C_91 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_91, Ri_91, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_91, NULL #else L_91 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_93, L_92, C_92, NULL, NULL -#else K_93, L_92, C_92 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_92, Ri_92, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_92, NULL #else L_92 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_94, L_93, C_93, NULL, NULL -#else K_94, L_93, C_93 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_93, Ri_93, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_93, NULL #else L_93 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_95, L_94, C_94, NULL, NULL -#else K_95, L_94, C_94 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_94, Ri_94, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_94, NULL #else L_94 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_96, L_95, C_95, NULL, NULL -#else K_96, L_95, C_95 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_95, Ri_95, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_95, NULL #else L_95 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_97, L_96, C_96, NULL, NULL -#else K_97, L_96, C_96 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_96, Ri_96, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_96, NULL #else L_96 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_98, L_97, C_97, NULL, NULL -#else K_98, L_97, C_97 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_97, Ri_97, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_97, NULL #else L_97 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_99, L_98, C_98, NULL, NULL -#else K_99, L_98, C_98 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_98, Ri_98, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_98, NULL #else L_98 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_100, L_99, C_99, NULL, NULL -#else K_100, L_99, C_99 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_99, Ri_99, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_99, NULL #else L_99 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_101, L_100, C_100, NULL, NULL -#else K_101, L_100, C_100 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_100, Ri_100, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_100, NULL #else L_100 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_102, L_101, C_101, NULL, NULL -#else K_102, L_101, C_101 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_101, Ri_101, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_101, NULL #else L_101 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_103, L_102, C_102, NULL, NULL -#else K_103, L_102, C_102 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_102, Ri_102, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_102, NULL #else L_102 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_104, L_103, C_103, NULL, NULL -#else K_104, L_103, C_103 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_103, Ri_103, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_103, NULL #else L_103 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_105, L_104, C_104, NULL, NULL -#else K_105, L_104, C_104 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_104, Ri_104, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_104, NULL #else L_104 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_106, L_105, C_105, NULL, NULL -#else K_106, L_105, C_105 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_105, Ri_105, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_105, NULL #else L_105 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_107, L_106, C_106, NULL, NULL -#else K_107, L_106, C_106 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_106, Ri_106, UINT64_C(0xa080000000000000), -#else -#if defined(MUL_M4RI) - L_106, NULL #else L_106 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_108, L_107, C_107, NULL, NULL -#else K_108, L_107, C_107 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_107, Ri_107, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_107, NULL #else L_107 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_109, L_108, C_108, NULL, NULL -#else K_109, L_108, C_108 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_108, Ri_108, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_108, NULL #else L_108 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_110, L_109, C_109, NULL, NULL -#else K_110, L_109, C_109 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_109, Ri_109, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_109, NULL #else L_109 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_111, L_110, C_110, NULL, NULL -#else K_111, L_110, C_110 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_110, Ri_110, UINT64_C(0x9400000000000000), -#else -#if defined(MUL_M4RI) - L_110, NULL #else L_110 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_112, L_111, C_111, NULL, NULL -#else K_112, L_111, C_111 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_111, Ri_111, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_111, NULL #else L_111 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_113, L_112, C_112, NULL, NULL -#else K_113, L_112, C_112 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_112, Ri_112, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_112, NULL #else L_112 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_114, L_113, C_113, NULL, NULL -#else K_114, L_113, C_113 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_113, Ri_113, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_113, NULL #else L_113 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_115, L_114, C_114, NULL, NULL -#else K_115, L_114, C_114 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_114, Ri_114, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_114, NULL #else L_114 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_116, L_115, C_115, NULL, NULL -#else K_116, L_115, C_115 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_115, Ri_115, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_115, NULL #else L_115 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_117, L_116, C_116, NULL, NULL -#else K_117, L_116, C_116 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_116, Ri_116, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_116, NULL #else L_116 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_118, L_117, C_117, NULL, NULL -#else K_118, L_117, C_117 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_117, Ri_117, UINT64_C(0x6800000000000000), -#else -#if defined(MUL_M4RI) - L_117, NULL #else L_117 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_119, L_118, C_118, NULL, NULL -#else K_119, L_118, C_118 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_118, Ri_118, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_118, NULL #else L_118 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_120, L_119, C_119, NULL, NULL -#else K_120, L_119, C_119 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_119, Ri_119, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_119, NULL #else L_119 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_121, L_120, C_120, NULL, NULL -#else K_121, L_120, C_120 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_120, Ri_120, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_120, NULL #else L_120 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_122, L_121, C_121, NULL, NULL -#else K_122, L_121, C_121 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_121, Ri_121, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_121, NULL #else L_121 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_123, L_122, C_122, NULL, NULL -#else K_123, L_122, C_122 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_122, Ri_122, UINT64_C(0xc080000000000000), -#else -#if defined(MUL_M4RI) - L_122, NULL #else L_122 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_124, L_123, C_123, NULL, NULL -#else K_124, L_123, C_123 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_123, Ri_123, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_123, NULL #else L_123 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_125, L_124, C_124, NULL, NULL -#else K_125, L_124, C_124 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_124, Ri_124, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_124, NULL #else L_124 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_126, L_125, C_125, NULL, NULL -#else K_126, L_125, C_125 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_125, Ri_125, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_125, NULL #else L_125 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_127, L_126, C_126, NULL, NULL -#else K_127, L_126, C_126 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_126, Ri_126, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_126, NULL #else L_126 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_128, L_127, C_127, NULL, NULL -#else K_128, L_127, C_127 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_127, Ri_127, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_127, NULL #else L_127 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_129, L_128, C_128, NULL, NULL -#else K_129, L_128, C_128 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_128, Ri_128, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_128, NULL #else L_128 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_130, L_129, C_129, NULL, NULL -#else K_130, L_129, C_129 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_129, Ri_129, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_129, NULL #else L_129 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_131, L_130, C_130, NULL, NULL -#else K_131, L_130, C_130 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_130, Ri_130, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_130, NULL #else L_130 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_132, L_131, C_131, NULL, NULL -#else K_132, L_131, C_131 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_131, Ri_131, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_131, NULL #else L_131 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_133, L_132, C_132, NULL, NULL -#else K_133, L_132, C_132 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_132, Ri_132, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_132, NULL #else L_132 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_134, L_133, C_133, NULL, NULL -#else K_134, L_133, C_133 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_133, Ri_133, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_133, NULL #else L_133 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_135, L_134, C_134, NULL, NULL -#else K_135, L_134, C_134 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_134, Ri_134, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_134, NULL #else L_134 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_136, L_135, C_135, NULL, NULL -#else K_136, L_135, C_135 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_135, Ri_135, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_135, NULL #else L_135 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_137, L_136, C_136, NULL, NULL -#else K_137, L_136, C_136 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_136, Ri_136, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_136, NULL #else L_136 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_138, L_137, C_137, NULL, NULL -#else K_138, L_137, C_137 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_137, Ri_137, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_137, NULL #else L_137 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_139, L_138, C_138, NULL, NULL -#else K_139, L_138, C_138 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_138, Ri_138, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_138, NULL #else L_138 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_140, L_139, C_139, NULL, NULL -#else K_140, L_139, C_139 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_139, Ri_139, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_139, NULL #else L_139 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_141, L_140, C_140, NULL, NULL -#else K_141, L_140, C_140 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_140, Ri_140, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_140, NULL #else L_140 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_142, L_141, C_141, NULL, NULL -#else K_142, L_141, C_141 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_141, Ri_141, UINT64_C(0x9100000000000000), -#else -#if defined(MUL_M4RI) - L_141, NULL #else L_141 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_143, L_142, C_142, NULL, NULL -#else K_143, L_142, C_142 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_142, Ri_142, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_142, NULL #else L_142 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_144, L_143, C_143, NULL, NULL -#else K_144, L_143, C_143 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_143, Ri_143, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_143, NULL #else L_143 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_145, L_144, C_144, NULL, NULL -#else K_145, L_144, C_144 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_144, Ri_144, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_144, NULL #else L_144 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_146, L_145, C_145, NULL, NULL -#else K_146, L_145, C_145 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_145, Ri_145, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_145, NULL #else L_145 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_147, L_146, C_146, NULL, NULL -#else K_147, L_146, C_146 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_146, Ri_146, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_146, NULL #else L_146 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_148, L_147, C_147, NULL, NULL -#else K_148, L_147, C_147 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_147, Ri_147, UINT64_C(0xa100000000000000), -#else -#if defined(MUL_M4RI) - L_147, NULL #else L_147 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_149, L_148, C_148, NULL, NULL -#else K_149, L_148, C_148 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_148, Ri_148, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_148, NULL #else L_148 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_150, L_149, C_149, NULL, NULL -#else K_150, L_149, C_149 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_149, Ri_149, UINT64_C(0xa040000000000000), -#else -#if defined(MUL_M4RI) - L_149, NULL #else L_149 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_151, L_150, C_150, NULL, NULL -#else K_151, L_150, C_150 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_150, Ri_150, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_150, NULL #else L_150 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_152, L_151, C_151, NULL, NULL -#else K_152, L_151, C_151 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_151, Ri_151, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_151, NULL #else L_151 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_153, L_152, C_152, NULL, NULL -#else K_153, L_152, C_152 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_152, Ri_152, UINT64_C(0x6200000000000000), -#else -#if defined(MUL_M4RI) - L_152, NULL #else L_152 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_154, L_153, C_153, NULL, NULL -#else K_154, L_153, C_153 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_153, Ri_153, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_153, NULL #else L_153 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_155, L_154, C_154, NULL, NULL -#else K_155, L_154, C_154 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_154, Ri_154, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_154, NULL #else L_154 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_156, L_155, C_155, NULL, NULL -#else K_156, L_155, C_155 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_155, Ri_155, UINT64_C(0x6400000000000000), -#else -#if defined(MUL_M4RI) - L_155, NULL #else L_155 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_157, L_156, C_156, NULL, NULL -#else K_157, L_156, C_156 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_156, Ri_156, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_156, NULL #else L_156 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_158, L_157, C_157, NULL, NULL -#else K_158, L_157, C_157 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_157, Ri_157, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_157, NULL #else L_157 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_159, L_158, C_158, NULL, NULL -#else K_159, L_158, C_158 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_158, Ri_158, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_158, NULL #else L_158 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_160, L_159, C_159, NULL, NULL -#else K_160, L_159, C_159 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_159, Ri_159, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_159, NULL #else L_159 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_161, L_160, C_160, NULL, NULL -#else K_161, L_160, C_160 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_160, Ri_160, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_160, NULL #else L_160 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_162, L_161, C_161, NULL, NULL -#else K_162, L_161, C_161 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_161, Ri_161, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_161, NULL #else L_161 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_163, L_162, C_162, NULL, NULL -#else K_163, L_162, C_162 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_162, Ri_162, UINT64_C(0xa080000000000000), -#else -#if defined(MUL_M4RI) - L_162, NULL #else L_162 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_164, L_163, C_163, NULL, NULL -#else K_164, L_163, C_163 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_163, Ri_163, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_163, NULL #else L_163 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_165, L_164, C_164, NULL, NULL -#else K_165, L_164, C_164 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_164, Ri_164, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_164, NULL #else L_164 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_166, L_165, C_165, NULL, NULL -#else K_166, L_165, C_165 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_165, Ri_165, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_165, NULL #else L_165 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_167, L_166, C_166, NULL, NULL -#else K_167, L_166, C_166 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_166, Ri_166, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_166, NULL #else L_166 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_168, L_167, C_167, NULL, NULL -#else K_168, L_167, C_167 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_167, Ri_167, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_167, NULL #else L_167 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_169, L_168, C_168, NULL, NULL -#else K_169, L_168, C_168 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_168, Ri_168, UINT64_C(0xc100000000000000), -#else -#if defined(MUL_M4RI) - L_168, NULL #else L_168 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_170, L_169, C_169, NULL, NULL -#else K_170, L_169, C_169 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_169, Ri_169, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_169, NULL #else L_169 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_171, L_170, C_170, NULL, NULL -#else K_171, L_170, C_170 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_170, Ri_170, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_170, NULL #else L_170 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_172, L_171, C_171, NULL, NULL -#else K_172, L_171, C_171 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_171, Ri_171, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_171, NULL #else L_171 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_173, L_172, C_172, NULL, NULL -#else K_173, L_172, C_172 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_172, Ri_172, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_172, NULL #else L_172 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_174, L_173, C_173, NULL, NULL -#else K_174, L_173, C_173 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_173, Ri_173, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_173, NULL #else L_173 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_175, L_174, C_174, NULL, NULL -#else K_175, L_174, C_174 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_174, Ri_174, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_174, NULL #else L_174 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_176, L_175, C_175, NULL, NULL -#else K_176, L_175, C_175 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_175, Ri_175, UINT64_C(0x3200000000000000), -#else -#if defined(MUL_M4RI) - L_175, NULL #else L_175 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_177, L_176, C_176, NULL, NULL -#else K_177, L_176, C_176 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_176, Ri_176, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_176, NULL #else L_176 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_178, L_177, C_177, NULL, NULL -#else K_178, L_177, C_177 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_177, Ri_177, UINT64_C(0x5400000000000000), -#else -#if defined(MUL_M4RI) - L_177, NULL #else L_177 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_179, L_178, C_178, NULL, NULL -#else K_179, L_178, C_178 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_178, Ri_178, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_178, NULL #else L_178 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_180, L_179, C_179, NULL, NULL -#else K_180, L_179, C_179 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_179, Ri_179, UINT64_C(0xa080000000000000), -#else -#if defined(MUL_M4RI) - L_179, NULL #else L_179 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_181, L_180, C_180, NULL, NULL -#else K_181, L_180, C_180 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_180, Ri_180, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_180, NULL #else L_180 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_182, L_181, C_181, NULL, NULL -#else K_182, L_181, C_181 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) NULL, NULL, 0, -#else -#if defined(MUL_M4RI) - L_181, NULL #else L_181 #endif -#endif #endif }, }; -#if defined(MUL_M4RI) -lowmc_t lowmc_128_128_182 = { -#else const lowmc_t lowmc_128_128_182 = { -#endif 1, 128, 182, 128, #if defined(REDUCED_ROUND_KEY_COMPUTATION) precomputed_round_key_matrix_linear_part, @@ -30575,16 +29111,10 @@ const lowmc_t lowmc_128_128_182 = { #endif #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Z_r, -#endif -#if defined(MUL_M4RI) - NULL, #endif rounds, #if defined(REDUCED_ROUND_KEY_COMPUTATION) precomputed_round_key_matrix_non_linear_part, -#if defined(MUL_M4RI) - NULL, -#endif precomputed_constant_linear_part, precomputed_constant_non_linear_part, #endif diff --git a/src/sig/picnic/external/lowmc_128_128_182.h b/src/sig/picnic/external/lowmc_128_128_182.h index 1a747d2aa..c50e1ab4d 100644 --- a/src/sig/picnic/external/lowmc_128_128_182.h +++ b/src/sig/picnic/external/lowmc_128_128_182.h @@ -3,10 +3,6 @@ #include "lowmc_pars.h" -#if !defined(MUL_M4RI) extern const lowmc_t lowmc_128_128_182; -#else -extern lowmc_t lowmc_128_128_182; -#endif #endif diff --git a/src/sig/picnic/external/lowmc_128_128_20.c b/src/sig/picnic/external/lowmc_128_128_20.c index f7b0d8780..b127c8cc2 100644 --- a/src/sig/picnic/external/lowmc_128_128_20.c +++ b/src/sig/picnic/external/lowmc_128_128_20.c @@ -3776,399 +3776,231 @@ static const block_t Ri_18[] = { #endif -#if defined(MUL_M4RI) -static lowmc_round_t rounds[20] = { -#else static const lowmc_round_t rounds[20] = { -#endif { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_1, L_0, C_0, NULL, NULL -#else K_1, L_0, C_0 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_0, Ri_0, UINT64_C(0xffffffda40000000), -#else -#if defined(MUL_M4RI) - L_0, NULL #else L_0 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_2, L_1, C_1, NULL, NULL -#else K_2, L_1, C_1 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_1, Ri_1, UINT64_C(0xffffffe700000000), -#else -#if defined(MUL_M4RI) - L_1, NULL #else L_1 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_3, L_2, C_2, NULL, NULL -#else K_3, L_2, C_2 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_2, Ri_2, UINT64_C(0xfffffffa00000000), -#else -#if defined(MUL_M4RI) - L_2, NULL #else L_2 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_4, L_3, C_3, NULL, NULL -#else K_4, L_3, C_3 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_3, Ri_3, UINT64_C(0xfffffff880000000), -#else -#if defined(MUL_M4RI) - L_3, NULL #else L_3 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_5, L_4, C_4, NULL, NULL -#else K_5, L_4, C_4 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_4, Ri_4, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_4, NULL #else L_4 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_6, L_5, C_5, NULL, NULL -#else K_6, L_5, C_5 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_5, Ri_5, UINT64_C(0xffffffdc40000000), -#else -#if defined(MUL_M4RI) - L_5, NULL #else L_5 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_7, L_6, C_6, NULL, NULL -#else K_7, L_6, C_6 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_6, Ri_6, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_6, NULL #else L_6 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_8, L_7, C_7, NULL, NULL -#else K_8, L_7, C_7 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_7, Ri_7, UINT64_C(0xfffffffa00000000), -#else -#if defined(MUL_M4RI) - L_7, NULL #else L_7 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_9, L_8, C_8, NULL, NULL -#else K_9, L_8, C_8 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_8, Ri_8, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_8, NULL #else L_8 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_10, L_9, C_9, NULL, NULL -#else K_10, L_9, C_9 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_9, Ri_9, UINT64_C(0xfffffff840000000), -#else -#if defined(MUL_M4RI) - L_9, NULL #else L_9 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_11, L_10, C_10, NULL, NULL -#else K_11, L_10, C_10 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_10, Ri_10, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_10, NULL #else L_10 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_12, L_11, C_11, NULL, NULL -#else K_12, L_11, C_11 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_11, Ri_11, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_11, NULL #else L_11 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_13, L_12, C_12, NULL, NULL -#else K_13, L_12, C_12 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_12, Ri_12, UINT64_C(0xfffffffa00000000), -#else -#if defined(MUL_M4RI) - L_12, NULL #else L_12 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_14, L_13, C_13, NULL, NULL -#else K_14, L_13, C_13 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_13, Ri_13, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_13, NULL #else L_13 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_15, L_14, C_14, NULL, NULL -#else K_15, L_14, C_14 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_14, Ri_14, UINT64_C(0xfffffffa00000000), -#else -#if defined(MUL_M4RI) - L_14, NULL #else L_14 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_16, L_15, C_15, NULL, NULL -#else K_16, L_15, C_15 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_15, Ri_15, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_15, NULL #else L_15 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_17, L_16, C_16, NULL, NULL -#else K_17, L_16, C_16 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_16, Ri_16, UINT64_C(0xfffffffa00000000), -#else -#if defined(MUL_M4RI) - L_16, NULL #else L_16 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_18, L_17, C_17, NULL, NULL -#else K_18, L_17, C_17 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_17, Ri_17, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_17, NULL #else L_17 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_19, L_18, C_18, NULL, NULL -#else K_19, L_18, C_18 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_18, Ri_18, UINT64_C(0xffffffe580000000), -#else -#if defined(MUL_M4RI) - L_18, NULL #else L_18 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_20, L_19, C_19, NULL, NULL -#else K_20, L_19, C_19 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) NULL, NULL, 0, -#else -#if defined(MUL_M4RI) - L_19, NULL #else L_19 #endif -#endif #endif }, }; -#if defined(MUL_M4RI) -lowmc_t lowmc_128_128_20 = { -#else const lowmc_t lowmc_128_128_20 = { -#endif 10, 128, 20, 128, #if defined(REDUCED_ROUND_KEY_COMPUTATION) precomputed_round_key_matrix_linear_part, @@ -4177,16 +4009,10 @@ const lowmc_t lowmc_128_128_20 = { #endif #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Z_r, -#endif -#if defined(MUL_M4RI) - NULL, #endif rounds, #if defined(REDUCED_ROUND_KEY_COMPUTATION) precomputed_round_key_matrix_non_linear_part, -#if defined(MUL_M4RI) - NULL, -#endif precomputed_constant_linear_part, precomputed_constant_non_linear_part, #endif diff --git a/src/sig/picnic/external/lowmc_128_128_20.h b/src/sig/picnic/external/lowmc_128_128_20.h index 99b1db04f..759b1a01b 100644 --- a/src/sig/picnic/external/lowmc_128_128_20.h +++ b/src/sig/picnic/external/lowmc_128_128_20.h @@ -3,10 +3,6 @@ #include "lowmc_pars.h" -#if !defined(MUL_M4RI) extern const lowmc_t lowmc_128_128_20; -#else -extern lowmc_t lowmc_128_128_20; -#endif #endif diff --git a/src/sig/picnic/external/lowmc_192_192_284.c b/src/sig/picnic/external/lowmc_192_192_284.c index 95a3f9e14..eb4b509dc 100644 --- a/src/sig/picnic/external/lowmc_192_192_284.c +++ b/src/sig/picnic/external/lowmc_192_192_284.c @@ -115808,5415 +115808,3135 @@ static const block_t Ri_282[] = { #endif -#if defined(MUL_M4RI) -static lowmc_round_t rounds[284] = { -#else static const lowmc_round_t rounds[284] = { -#endif { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_1, L_0, C_0, NULL, NULL -#else K_1, L_0, C_0 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_0, Ri_0, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_0, NULL #else L_0 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_2, L_1, C_1, NULL, NULL -#else K_2, L_1, C_1 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_1, Ri_1, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_1, NULL #else L_1 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_3, L_2, C_2, NULL, NULL -#else K_3, L_2, C_2 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_2, Ri_2, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_2, NULL #else L_2 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_4, L_3, C_3, NULL, NULL -#else K_4, L_3, C_3 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_3, Ri_3, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_3, NULL #else L_3 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_5, L_4, C_4, NULL, NULL -#else K_5, L_4, C_4 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_4, Ri_4, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_4, NULL #else L_4 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_6, L_5, C_5, NULL, NULL -#else K_6, L_5, C_5 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_5, Ri_5, UINT64_C(0x6800000000000000), -#else -#if defined(MUL_M4RI) - L_5, NULL #else L_5 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_7, L_6, C_6, NULL, NULL -#else K_7, L_6, C_6 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_6, Ri_6, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_6, NULL #else L_6 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_8, L_7, C_7, NULL, NULL -#else K_8, L_7, C_7 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_7, Ri_7, UINT64_C(0x3400000000000000), -#else -#if defined(MUL_M4RI) - L_7, NULL #else L_7 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_9, L_8, C_8, NULL, NULL -#else K_9, L_8, C_8 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_8, Ri_8, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_8, NULL #else L_8 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_10, L_9, C_9, NULL, NULL -#else K_10, L_9, C_9 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_9, Ri_9, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_9, NULL #else L_9 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_11, L_10, C_10, NULL, NULL -#else K_11, L_10, C_10 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_10, Ri_10, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_10, NULL #else L_10 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_12, L_11, C_11, NULL, NULL -#else K_12, L_11, C_11 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_11, Ri_11, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_11, NULL #else L_11 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_13, L_12, C_12, NULL, NULL -#else K_13, L_12, C_12 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_12, Ri_12, UINT64_C(0x5080000000000000), -#else -#if defined(MUL_M4RI) - L_12, NULL #else L_12 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_14, L_13, C_13, NULL, NULL -#else K_14, L_13, C_13 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_13, Ri_13, UINT64_C(0x6800000000000000), -#else -#if defined(MUL_M4RI) - L_13, NULL #else L_13 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_15, L_14, C_14, NULL, NULL -#else K_15, L_14, C_14 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_14, Ri_14, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_14, NULL #else L_14 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_16, L_15, C_15, NULL, NULL -#else K_16, L_15, C_15 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_15, Ri_15, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_15, NULL #else L_15 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_17, L_16, C_16, NULL, NULL -#else K_17, L_16, C_16 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_16, Ri_16, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_16, NULL #else L_16 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_18, L_17, C_17, NULL, NULL -#else K_18, L_17, C_17 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_17, Ri_17, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_17, NULL #else L_17 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_19, L_18, C_18, NULL, NULL -#else K_19, L_18, C_18 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_18, Ri_18, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_18, NULL #else L_18 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_20, L_19, C_19, NULL, NULL -#else K_20, L_19, C_19 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_19, Ri_19, UINT64_C(0x6800000000000000), -#else -#if defined(MUL_M4RI) - L_19, NULL #else L_19 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_21, L_20, C_20, NULL, NULL -#else K_21, L_20, C_20 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_20, Ri_20, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_20, NULL #else L_20 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_22, L_21, C_21, NULL, NULL -#else K_22, L_21, C_21 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_21, Ri_21, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_21, NULL #else L_21 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_23, L_22, C_22, NULL, NULL -#else K_23, L_22, C_22 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_22, Ri_22, UINT64_C(0x9400000000000000), -#else -#if defined(MUL_M4RI) - L_22, NULL #else L_22 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_24, L_23, C_23, NULL, NULL -#else K_24, L_23, C_23 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_23, Ri_23, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_23, NULL #else L_23 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_25, L_24, C_24, NULL, NULL -#else K_25, L_24, C_24 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_24, Ri_24, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_24, NULL #else L_24 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_26, L_25, C_25, NULL, NULL -#else K_26, L_25, C_25 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_25, Ri_25, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_25, NULL #else L_25 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_27, L_26, C_26, NULL, NULL -#else K_27, L_26, C_26 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_26, Ri_26, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_26, NULL #else L_26 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_28, L_27, C_27, NULL, NULL -#else K_28, L_27, C_27 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_27, Ri_27, UINT64_C(0x9200000000000000), -#else -#if defined(MUL_M4RI) - L_27, NULL #else L_27 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_29, L_28, C_28, NULL, NULL -#else K_29, L_28, C_28 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_28, Ri_28, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_28, NULL #else L_28 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_30, L_29, C_29, NULL, NULL -#else K_30, L_29, C_29 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_29, Ri_29, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_29, NULL #else L_29 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_31, L_30, C_30, NULL, NULL -#else K_31, L_30, C_30 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_30, Ri_30, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_30, NULL #else L_30 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_32, L_31, C_31, NULL, NULL -#else K_32, L_31, C_31 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_31, Ri_31, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_31, NULL #else L_31 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_33, L_32, C_32, NULL, NULL -#else K_33, L_32, C_32 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_32, Ri_32, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_32, NULL #else L_32 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_34, L_33, C_33, NULL, NULL -#else K_34, L_33, C_33 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_33, Ri_33, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_33, NULL #else L_33 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_35, L_34, C_34, NULL, NULL -#else K_35, L_34, C_34 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_34, Ri_34, UINT64_C(0x6800000000000000), -#else -#if defined(MUL_M4RI) - L_34, NULL #else L_34 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_36, L_35, C_35, NULL, NULL -#else K_36, L_35, C_35 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_35, Ri_35, UINT64_C(0xa200000000000000), -#else -#if defined(MUL_M4RI) - L_35, NULL #else L_35 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_37, L_36, C_36, NULL, NULL -#else K_37, L_36, C_36 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_36, Ri_36, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_36, NULL #else L_36 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_38, L_37, C_37, NULL, NULL -#else K_38, L_37, C_37 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_37, Ri_37, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_37, NULL #else L_37 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_39, L_38, C_38, NULL, NULL -#else K_39, L_38, C_38 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_38, Ri_38, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_38, NULL #else L_38 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_40, L_39, C_39, NULL, NULL -#else K_40, L_39, C_39 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_39, Ri_39, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_39, NULL #else L_39 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_41, L_40, C_40, NULL, NULL -#else K_41, L_40, C_40 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_40, Ri_40, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_40, NULL #else L_40 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_42, L_41, C_41, NULL, NULL -#else K_42, L_41, C_41 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_41, Ri_41, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_41, NULL #else L_41 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_43, L_42, C_42, NULL, NULL -#else K_43, L_42, C_42 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_42, Ri_42, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_42, NULL #else L_42 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_44, L_43, C_43, NULL, NULL -#else K_44, L_43, C_43 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_43, Ri_43, UINT64_C(0x5800000000000000), -#else -#if defined(MUL_M4RI) - L_43, NULL #else L_43 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_45, L_44, C_44, NULL, NULL -#else K_45, L_44, C_44 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_44, Ri_44, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_44, NULL #else L_44 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_46, L_45, C_45, NULL, NULL -#else K_46, L_45, C_45 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_45, Ri_45, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_45, NULL #else L_45 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_47, L_46, C_46, NULL, NULL -#else K_47, L_46, C_46 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_46, Ri_46, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_46, NULL #else L_46 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_48, L_47, C_47, NULL, NULL -#else K_48, L_47, C_47 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_47, Ri_47, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_47, NULL #else L_47 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_49, L_48, C_48, NULL, NULL -#else K_49, L_48, C_48 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_48, Ri_48, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_48, NULL #else L_48 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_50, L_49, C_49, NULL, NULL -#else K_50, L_49, C_49 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_49, Ri_49, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_49, NULL #else L_49 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_51, L_50, C_50, NULL, NULL -#else K_51, L_50, C_50 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_50, Ri_50, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_50, NULL #else L_50 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_52, L_51, C_51, NULL, NULL -#else K_52, L_51, C_51 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_51, Ri_51, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_51, NULL #else L_51 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_53, L_52, C_52, NULL, NULL -#else K_53, L_52, C_52 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_52, Ri_52, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_52, NULL #else L_52 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_54, L_53, C_53, NULL, NULL -#else K_54, L_53, C_53 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_53, Ri_53, UINT64_C(0x2c00000000000000), -#else -#if defined(MUL_M4RI) - L_53, NULL #else L_53 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_55, L_54, C_54, NULL, NULL -#else K_55, L_54, C_54 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_54, Ri_54, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_54, NULL #else L_54 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_56, L_55, C_55, NULL, NULL -#else K_56, L_55, C_55 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_55, Ri_55, UINT64_C(0xa200000000000000), -#else -#if defined(MUL_M4RI) - L_55, NULL #else L_55 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_57, L_56, C_56, NULL, NULL -#else K_57, L_56, C_56 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_56, Ri_56, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_56, NULL #else L_56 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_58, L_57, C_57, NULL, NULL -#else K_58, L_57, C_57 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_57, Ri_57, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_57, NULL #else L_57 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_59, L_58, C_58, NULL, NULL -#else K_59, L_58, C_58 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_58, Ri_58, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_58, NULL #else L_58 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_60, L_59, C_59, NULL, NULL -#else K_60, L_59, C_59 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_59, Ri_59, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_59, NULL #else L_59 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_61, L_60, C_60, NULL, NULL -#else K_61, L_60, C_60 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_60, Ri_60, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_60, NULL #else L_60 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_62, L_61, C_61, NULL, NULL -#else K_62, L_61, C_61 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_61, Ri_61, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_61, NULL #else L_61 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_63, L_62, C_62, NULL, NULL -#else K_63, L_62, C_62 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_62, Ri_62, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_62, NULL #else L_62 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_64, L_63, C_63, NULL, NULL -#else K_64, L_63, C_63 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_63, Ri_63, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_63, NULL #else L_63 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_65, L_64, C_64, NULL, NULL -#else K_65, L_64, C_64 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_64, Ri_64, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_64, NULL #else L_64 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_66, L_65, C_65, NULL, NULL -#else K_66, L_65, C_65 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_65, Ri_65, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_65, NULL #else L_65 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_67, L_66, C_66, NULL, NULL -#else K_67, L_66, C_66 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_66, Ri_66, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_66, NULL #else L_66 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_68, L_67, C_67, NULL, NULL -#else K_68, L_67, C_67 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_67, Ri_67, UINT64_C(0x6800000000000000), -#else -#if defined(MUL_M4RI) - L_67, NULL #else L_67 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_69, L_68, C_68, NULL, NULL -#else K_69, L_68, C_68 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_68, Ri_68, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_68, NULL #else L_68 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_70, L_69, C_69, NULL, NULL -#else K_70, L_69, C_69 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_69, Ri_69, UINT64_C(0x1c00000000000000), -#else -#if defined(MUL_M4RI) - L_69, NULL #else L_69 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_71, L_70, C_70, NULL, NULL -#else K_71, L_70, C_70 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_70, Ri_70, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_70, NULL #else L_70 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_72, L_71, C_71, NULL, NULL -#else K_72, L_71, C_71 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_71, Ri_71, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_71, NULL #else L_71 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_73, L_72, C_72, NULL, NULL -#else K_73, L_72, C_72 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_72, Ri_72, UINT64_C(0xa200000000000000), -#else -#if defined(MUL_M4RI) - L_72, NULL #else L_72 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_74, L_73, C_73, NULL, NULL -#else K_74, L_73, C_73 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_73, Ri_73, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_73, NULL #else L_73 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_75, L_74, C_74, NULL, NULL -#else K_75, L_74, C_74 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_74, Ri_74, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_74, NULL #else L_74 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_76, L_75, C_75, NULL, NULL -#else K_76, L_75, C_75 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_75, Ri_75, UINT64_C(0x9400000000000000), -#else -#if defined(MUL_M4RI) - L_75, NULL #else L_75 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_77, L_76, C_76, NULL, NULL -#else K_77, L_76, C_76 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_76, Ri_76, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_76, NULL #else L_76 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_78, L_77, C_77, NULL, NULL -#else K_78, L_77, C_77 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_77, Ri_77, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_77, NULL #else L_77 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_79, L_78, C_78, NULL, NULL -#else K_79, L_78, C_78 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_78, Ri_78, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_78, NULL #else L_78 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_80, L_79, C_79, NULL, NULL -#else K_80, L_79, C_79 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_79, Ri_79, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_79, NULL #else L_79 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_81, L_80, C_80, NULL, NULL -#else K_81, L_80, C_80 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_80, Ri_80, UINT64_C(0x5800000000000000), -#else -#if defined(MUL_M4RI) - L_80, NULL #else L_80 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_82, L_81, C_81, NULL, NULL -#else K_82, L_81, C_81 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_81, Ri_81, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_81, NULL #else L_81 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_83, L_82, C_82, NULL, NULL -#else K_83, L_82, C_82 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_82, Ri_82, UINT64_C(0x9200000000000000), -#else -#if defined(MUL_M4RI) - L_82, NULL #else L_82 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_84, L_83, C_83, NULL, NULL -#else K_84, L_83, C_83 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_83, Ri_83, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_83, NULL #else L_83 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_85, L_84, C_84, NULL, NULL -#else K_85, L_84, C_84 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_84, Ri_84, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_84, NULL #else L_84 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_86, L_85, C_85, NULL, NULL -#else K_86, L_85, C_85 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_85, Ri_85, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_85, NULL #else L_85 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_87, L_86, C_86, NULL, NULL -#else K_87, L_86, C_86 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_86, Ri_86, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_86, NULL #else L_86 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_88, L_87, C_87, NULL, NULL -#else K_88, L_87, C_87 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_87, Ri_87, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_87, NULL #else L_87 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_89, L_88, C_88, NULL, NULL -#else K_89, L_88, C_88 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_88, Ri_88, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_88, NULL #else L_88 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_90, L_89, C_89, NULL, NULL -#else K_90, L_89, C_89 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_89, Ri_89, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_89, NULL #else L_89 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_91, L_90, C_90, NULL, NULL -#else K_91, L_90, C_90 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_90, Ri_90, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_90, NULL #else L_90 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_92, L_91, C_91, NULL, NULL -#else K_92, L_91, C_91 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_91, Ri_91, UINT64_C(0x9400000000000000), -#else -#if defined(MUL_M4RI) - L_91, NULL #else L_91 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_93, L_92, C_92, NULL, NULL -#else K_93, L_92, C_92 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_92, Ri_92, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_92, NULL #else L_92 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_94, L_93, C_93, NULL, NULL -#else K_94, L_93, C_93 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_93, Ri_93, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_93, NULL #else L_93 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_95, L_94, C_94, NULL, NULL -#else K_95, L_94, C_94 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_94, Ri_94, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_94, NULL #else L_94 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_96, L_95, C_95, NULL, NULL -#else K_96, L_95, C_95 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_95, Ri_95, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_95, NULL #else L_95 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_97, L_96, C_96, NULL, NULL -#else K_97, L_96, C_96 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_96, Ri_96, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_96, NULL #else L_96 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_98, L_97, C_97, NULL, NULL -#else K_98, L_97, C_97 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_97, Ri_97, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_97, NULL #else L_97 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_99, L_98, C_98, NULL, NULL -#else K_99, L_98, C_98 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_98, Ri_98, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_98, NULL #else L_98 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_100, L_99, C_99, NULL, NULL -#else K_100, L_99, C_99 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_99, Ri_99, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_99, NULL #else L_99 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_101, L_100, C_100, NULL, NULL -#else K_101, L_100, C_100 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_100, Ri_100, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_100, NULL #else L_100 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_102, L_101, C_101, NULL, NULL -#else K_102, L_101, C_101 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_101, Ri_101, UINT64_C(0x6800000000000000), -#else -#if defined(MUL_M4RI) - L_101, NULL #else L_101 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_103, L_102, C_102, NULL, NULL -#else K_103, L_102, C_102 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_102, Ri_102, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_102, NULL #else L_102 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_104, L_103, C_103, NULL, NULL -#else K_104, L_103, C_103 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_103, Ri_103, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_103, NULL #else L_103 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_105, L_104, C_104, NULL, NULL -#else K_105, L_104, C_104 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_104, Ri_104, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_104, NULL #else L_104 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_106, L_105, C_105, NULL, NULL -#else K_106, L_105, C_105 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_105, Ri_105, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_105, NULL #else L_105 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_107, L_106, C_106, NULL, NULL -#else K_107, L_106, C_106 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_106, Ri_106, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_106, NULL #else L_106 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_108, L_107, C_107, NULL, NULL -#else K_108, L_107, C_107 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_107, Ri_107, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_107, NULL #else L_107 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_109, L_108, C_108, NULL, NULL -#else K_109, L_108, C_108 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_108, Ri_108, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_108, NULL #else L_108 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_110, L_109, C_109, NULL, NULL -#else K_110, L_109, C_109 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_109, Ri_109, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_109, NULL #else L_109 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_111, L_110, C_110, NULL, NULL -#else K_111, L_110, C_110 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_110, Ri_110, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_110, NULL #else L_110 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_112, L_111, C_111, NULL, NULL -#else K_112, L_111, C_111 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_111, Ri_111, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_111, NULL #else L_111 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_113, L_112, C_112, NULL, NULL -#else K_113, L_112, C_112 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_112, Ri_112, UINT64_C(0xc080000000000000), -#else -#if defined(MUL_M4RI) - L_112, NULL #else L_112 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_114, L_113, C_113, NULL, NULL -#else K_114, L_113, C_113 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_113, Ri_113, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_113, NULL #else L_113 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_115, L_114, C_114, NULL, NULL -#else K_115, L_114, C_114 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_114, Ri_114, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_114, NULL #else L_114 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_116, L_115, C_115, NULL, NULL -#else K_116, L_115, C_115 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_115, Ri_115, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_115, NULL #else L_115 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_117, L_116, C_116, NULL, NULL -#else K_117, L_116, C_116 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_116, Ri_116, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_116, NULL #else L_116 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_118, L_117, C_117, NULL, NULL -#else K_118, L_117, C_117 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_117, Ri_117, UINT64_C(0xa100000000000000), -#else -#if defined(MUL_M4RI) - L_117, NULL #else L_117 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_119, L_118, C_118, NULL, NULL -#else K_119, L_118, C_118 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_118, Ri_118, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_118, NULL #else L_118 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_120, L_119, C_119, NULL, NULL -#else K_120, L_119, C_119 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_119, Ri_119, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_119, NULL #else L_119 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_121, L_120, C_120, NULL, NULL -#else K_121, L_120, C_120 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_120, Ri_120, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_120, NULL #else L_120 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_122, L_121, C_121, NULL, NULL -#else K_122, L_121, C_121 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_121, Ri_121, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_121, NULL #else L_121 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_123, L_122, C_122, NULL, NULL -#else K_123, L_122, C_122 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_122, Ri_122, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_122, NULL #else L_122 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_124, L_123, C_123, NULL, NULL -#else K_124, L_123, C_123 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_123, Ri_123, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_123, NULL #else L_123 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_125, L_124, C_124, NULL, NULL -#else K_125, L_124, C_124 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_124, Ri_124, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_124, NULL #else L_124 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_126, L_125, C_125, NULL, NULL -#else K_126, L_125, C_125 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_125, Ri_125, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_125, NULL #else L_125 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_127, L_126, C_126, NULL, NULL -#else K_127, L_126, C_126 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_126, Ri_126, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_126, NULL #else L_126 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_128, L_127, C_127, NULL, NULL -#else K_128, L_127, C_127 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_127, Ri_127, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_127, NULL #else L_127 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_129, L_128, C_128, NULL, NULL -#else K_129, L_128, C_128 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_128, Ri_128, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_128, NULL #else L_128 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_130, L_129, C_129, NULL, NULL -#else K_130, L_129, C_129 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_129, Ri_129, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_129, NULL #else L_129 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_131, L_130, C_130, NULL, NULL -#else K_131, L_130, C_130 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_130, Ri_130, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_130, NULL #else L_130 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_132, L_131, C_131, NULL, NULL -#else K_132, L_131, C_131 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_131, Ri_131, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_131, NULL #else L_131 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_133, L_132, C_132, NULL, NULL -#else K_133, L_132, C_132 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_132, Ri_132, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_132, NULL #else L_132 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_134, L_133, C_133, NULL, NULL -#else K_134, L_133, C_133 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_133, Ri_133, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_133, NULL #else L_133 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_135, L_134, C_134, NULL, NULL -#else K_135, L_134, C_134 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_134, Ri_134, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_134, NULL #else L_134 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_136, L_135, C_135, NULL, NULL -#else K_136, L_135, C_135 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_135, Ri_135, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_135, NULL #else L_135 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_137, L_136, C_136, NULL, NULL -#else K_137, L_136, C_136 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_136, Ri_136, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_136, NULL #else L_136 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_138, L_137, C_137, NULL, NULL -#else K_138, L_137, C_137 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_137, Ri_137, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_137, NULL #else L_137 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_139, L_138, C_138, NULL, NULL -#else K_139, L_138, C_138 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_138, Ri_138, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_138, NULL #else L_138 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_140, L_139, C_139, NULL, NULL -#else K_140, L_139, C_139 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_139, Ri_139, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_139, NULL #else L_139 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_141, L_140, C_140, NULL, NULL -#else K_141, L_140, C_140 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_140, Ri_140, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_140, NULL #else L_140 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_142, L_141, C_141, NULL, NULL -#else K_142, L_141, C_141 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_141, Ri_141, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_141, NULL #else L_141 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_143, L_142, C_142, NULL, NULL -#else K_143, L_142, C_142 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_142, Ri_142, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_142, NULL #else L_142 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_144, L_143, C_143, NULL, NULL -#else K_144, L_143, C_143 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_143, Ri_143, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_143, NULL #else L_143 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_145, L_144, C_144, NULL, NULL -#else K_145, L_144, C_144 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_144, Ri_144, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_144, NULL #else L_144 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_146, L_145, C_145, NULL, NULL -#else K_146, L_145, C_145 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_145, Ri_145, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_145, NULL #else L_145 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_147, L_146, C_146, NULL, NULL -#else K_147, L_146, C_146 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_146, Ri_146, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_146, NULL #else L_146 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_148, L_147, C_147, NULL, NULL -#else K_148, L_147, C_147 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_147, Ri_147, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_147, NULL #else L_147 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_149, L_148, C_148, NULL, NULL -#else K_149, L_148, C_148 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_148, Ri_148, UINT64_C(0xc100000000000000), -#else -#if defined(MUL_M4RI) - L_148, NULL #else L_148 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_150, L_149, C_149, NULL, NULL -#else K_150, L_149, C_149 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_149, Ri_149, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_149, NULL #else L_149 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_151, L_150, C_150, NULL, NULL -#else K_151, L_150, C_150 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_150, Ri_150, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_150, NULL #else L_150 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_152, L_151, C_151, NULL, NULL -#else K_152, L_151, C_151 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_151, Ri_151, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_151, NULL #else L_151 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_153, L_152, C_152, NULL, NULL -#else K_153, L_152, C_152 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_152, Ri_152, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_152, NULL #else L_152 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_154, L_153, C_153, NULL, NULL -#else K_154, L_153, C_153 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_153, Ri_153, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_153, NULL #else L_153 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_155, L_154, C_154, NULL, NULL -#else K_155, L_154, C_154 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_154, Ri_154, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_154, NULL #else L_154 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_156, L_155, C_155, NULL, NULL -#else K_156, L_155, C_155 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_155, Ri_155, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_155, NULL #else L_155 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_157, L_156, C_156, NULL, NULL -#else K_157, L_156, C_156 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_156, Ri_156, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_156, NULL #else L_156 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_158, L_157, C_157, NULL, NULL -#else K_158, L_157, C_157 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_157, Ri_157, UINT64_C(0xa100000000000000), -#else -#if defined(MUL_M4RI) - L_157, NULL #else L_157 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_159, L_158, C_158, NULL, NULL -#else K_159, L_158, C_158 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_158, Ri_158, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_158, NULL #else L_158 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_160, L_159, C_159, NULL, NULL -#else K_160, L_159, C_159 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_159, Ri_159, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_159, NULL #else L_159 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_161, L_160, C_160, NULL, NULL -#else K_161, L_160, C_160 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_160, Ri_160, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_160, NULL #else L_160 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_162, L_161, C_161, NULL, NULL -#else K_162, L_161, C_161 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_161, Ri_161, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_161, NULL #else L_161 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_163, L_162, C_162, NULL, NULL -#else K_163, L_162, C_162 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_162, Ri_162, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_162, NULL #else L_162 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_164, L_163, C_163, NULL, NULL -#else K_164, L_163, C_163 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_163, Ri_163, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_163, NULL #else L_163 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_165, L_164, C_164, NULL, NULL -#else K_165, L_164, C_164 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_164, Ri_164, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_164, NULL #else L_164 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_166, L_165, C_165, NULL, NULL -#else K_166, L_165, C_165 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_165, Ri_165, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_165, NULL #else L_165 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_167, L_166, C_166, NULL, NULL -#else K_167, L_166, C_166 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_166, Ri_166, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_166, NULL #else L_166 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_168, L_167, C_167, NULL, NULL -#else K_168, L_167, C_167 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_167, Ri_167, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_167, NULL #else L_167 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_169, L_168, C_168, NULL, NULL -#else K_169, L_168, C_168 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_168, Ri_168, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_168, NULL #else L_168 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_170, L_169, C_169, NULL, NULL -#else K_170, L_169, C_169 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_169, Ri_169, UINT64_C(0x6040000000000000), -#else -#if defined(MUL_M4RI) - L_169, NULL #else L_169 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_171, L_170, C_170, NULL, NULL -#else K_171, L_170, C_170 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_170, Ri_170, UINT64_C(0x5100000000000000), -#else -#if defined(MUL_M4RI) - L_170, NULL #else L_170 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_172, L_171, C_171, NULL, NULL -#else K_172, L_171, C_171 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_171, Ri_171, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_171, NULL #else L_171 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_173, L_172, C_172, NULL, NULL -#else K_173, L_172, C_172 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_172, Ri_172, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_172, NULL #else L_172 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_174, L_173, C_173, NULL, NULL -#else K_174, L_173, C_173 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_173, Ri_173, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_173, NULL #else L_173 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_175, L_174, C_174, NULL, NULL -#else K_175, L_174, C_174 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_174, Ri_174, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_174, NULL #else L_174 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_176, L_175, C_175, NULL, NULL -#else K_176, L_175, C_175 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_175, Ri_175, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_175, NULL #else L_175 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_177, L_176, C_176, NULL, NULL -#else K_177, L_176, C_176 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_176, Ri_176, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_176, NULL #else L_176 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_178, L_177, C_177, NULL, NULL -#else K_178, L_177, C_177 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_177, Ri_177, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_177, NULL #else L_177 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_179, L_178, C_178, NULL, NULL -#else K_179, L_178, C_178 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_178, Ri_178, UINT64_C(0x8a00000000000000), -#else -#if defined(MUL_M4RI) - L_178, NULL #else L_178 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_180, L_179, C_179, NULL, NULL -#else K_180, L_179, C_179 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_179, Ri_179, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_179, NULL #else L_179 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_181, L_180, C_180, NULL, NULL -#else K_181, L_180, C_180 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_180, Ri_180, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_180, NULL #else L_180 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_182, L_181, C_181, NULL, NULL -#else K_182, L_181, C_181 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_181, Ri_181, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_181, NULL #else L_181 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_183, L_182, C_182, NULL, NULL -#else K_183, L_182, C_182 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_182, Ri_182, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_182, NULL #else L_182 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_184, L_183, C_183, NULL, NULL -#else K_184, L_183, C_183 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_183, Ri_183, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_183, NULL #else L_183 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_185, L_184, C_184, NULL, NULL -#else K_185, L_184, C_184 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_184, Ri_184, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_184, NULL #else L_184 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_186, L_185, C_185, NULL, NULL -#else K_186, L_185, C_185 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_185, Ri_185, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_185, NULL #else L_185 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_187, L_186, C_186, NULL, NULL -#else K_187, L_186, C_186 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_186, Ri_186, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_186, NULL #else L_186 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_188, L_187, C_187, NULL, NULL -#else K_188, L_187, C_187 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_187, Ri_187, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_187, NULL #else L_187 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_189, L_188, C_188, NULL, NULL -#else K_189, L_188, C_188 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_188, Ri_188, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_188, NULL #else L_188 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_190, L_189, C_189, NULL, NULL -#else K_190, L_189, C_189 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_189, Ri_189, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_189, NULL #else L_189 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_191, L_190, C_190, NULL, NULL -#else K_191, L_190, C_190 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_190, Ri_190, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_190, NULL #else L_190 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_192, L_191, C_191, NULL, NULL -#else K_192, L_191, C_191 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_191, Ri_191, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_191, NULL #else L_191 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_193, L_192, C_192, NULL, NULL -#else K_193, L_192, C_192 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_192, Ri_192, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_192, NULL #else L_192 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_194, L_193, C_193, NULL, NULL -#else K_194, L_193, C_193 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_193, Ri_193, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_193, NULL #else L_193 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_195, L_194, C_194, NULL, NULL -#else K_195, L_194, C_194 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_194, Ri_194, UINT64_C(0xa100000000000000), -#else -#if defined(MUL_M4RI) - L_194, NULL #else L_194 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_196, L_195, C_195, NULL, NULL -#else K_196, L_195, C_195 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_195, Ri_195, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_195, NULL #else L_195 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_197, L_196, C_196, NULL, NULL -#else K_197, L_196, C_196 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_196, Ri_196, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_196, NULL #else L_196 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_198, L_197, C_197, NULL, NULL -#else K_198, L_197, C_197 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_197, Ri_197, UINT64_C(0x9080000000000000), -#else -#if defined(MUL_M4RI) - L_197, NULL #else L_197 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_199, L_198, C_198, NULL, NULL -#else K_199, L_198, C_198 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_198, Ri_198, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_198, NULL #else L_198 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_200, L_199, C_199, NULL, NULL -#else K_200, L_199, C_199 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_199, Ri_199, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_199, NULL #else L_199 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_201, L_200, C_200, NULL, NULL -#else K_201, L_200, C_200 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_200, Ri_200, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_200, NULL #else L_200 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_202, L_201, C_201, NULL, NULL -#else K_202, L_201, C_201 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_201, Ri_201, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_201, NULL #else L_201 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_203, L_202, C_202, NULL, NULL -#else K_203, L_202, C_202 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_202, Ri_202, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_202, NULL #else L_202 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_204, L_203, C_203, NULL, NULL -#else K_204, L_203, C_203 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_203, Ri_203, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_203, NULL #else L_203 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_205, L_204, C_204, NULL, NULL -#else K_205, L_204, C_204 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_204, Ri_204, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_204, NULL #else L_204 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_206, L_205, C_205, NULL, NULL -#else K_206, L_205, C_205 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_205, Ri_205, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_205, NULL #else L_205 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_207, L_206, C_206, NULL, NULL -#else K_207, L_206, C_206 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_206, Ri_206, UINT64_C(0x9400000000000000), -#else -#if defined(MUL_M4RI) - L_206, NULL #else L_206 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_208, L_207, C_207, NULL, NULL -#else K_208, L_207, C_207 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_207, Ri_207, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_207, NULL #else L_207 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_209, L_208, C_208, NULL, NULL -#else K_209, L_208, C_208 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_208, Ri_208, UINT64_C(0xc100000000000000), -#else -#if defined(MUL_M4RI) - L_208, NULL #else L_208 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_210, L_209, C_209, NULL, NULL -#else K_210, L_209, C_209 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_209, Ri_209, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_209, NULL #else L_209 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_211, L_210, C_210, NULL, NULL -#else K_211, L_210, C_210 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_210, Ri_210, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_210, NULL #else L_210 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_212, L_211, C_211, NULL, NULL -#else K_212, L_211, C_211 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_211, Ri_211, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_211, NULL #else L_211 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_213, L_212, C_212, NULL, NULL -#else K_213, L_212, C_212 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_212, Ri_212, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_212, NULL #else L_212 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_214, L_213, C_213, NULL, NULL -#else K_214, L_213, C_213 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_213, Ri_213, UINT64_C(0x9200000000000000), -#else -#if defined(MUL_M4RI) - L_213, NULL #else L_213 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_215, L_214, C_214, NULL, NULL -#else K_215, L_214, C_214 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_214, Ri_214, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_214, NULL #else L_214 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_216, L_215, C_215, NULL, NULL -#else K_216, L_215, C_215 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_215, Ri_215, UINT64_C(0xc080000000000000), -#else -#if defined(MUL_M4RI) - L_215, NULL #else L_215 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_217, L_216, C_216, NULL, NULL -#else K_217, L_216, C_216 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_216, Ri_216, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_216, NULL #else L_216 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_218, L_217, C_217, NULL, NULL -#else K_218, L_217, C_217 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_217, Ri_217, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_217, NULL #else L_217 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_219, L_218, C_218, NULL, NULL -#else K_219, L_218, C_218 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_218, Ri_218, UINT64_C(0x5004000000000000), -#else -#if defined(MUL_M4RI) - L_218, NULL #else L_218 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_220, L_219, C_219, NULL, NULL -#else K_220, L_219, C_219 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_219, Ri_219, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_219, NULL #else L_219 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_221, L_220, C_220, NULL, NULL -#else K_221, L_220, C_220 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_220, Ri_220, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_220, NULL #else L_220 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_222, L_221, C_221, NULL, NULL -#else K_222, L_221, C_221 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_221, Ri_221, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_221, NULL #else L_221 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_223, L_222, C_222, NULL, NULL -#else K_223, L_222, C_222 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_222, Ri_222, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_222, NULL #else L_222 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_224, L_223, C_223, NULL, NULL -#else K_224, L_223, C_223 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_223, Ri_223, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_223, NULL #else L_223 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_225, L_224, C_224, NULL, NULL -#else K_225, L_224, C_224 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_224, Ri_224, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_224, NULL #else L_224 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_226, L_225, C_225, NULL, NULL -#else K_226, L_225, C_225 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_225, Ri_225, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_225, NULL #else L_225 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_227, L_226, C_226, NULL, NULL -#else K_227, L_226, C_226 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_226, Ri_226, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_226, NULL #else L_226 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_228, L_227, C_227, NULL, NULL -#else K_228, L_227, C_227 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_227, Ri_227, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_227, NULL #else L_227 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_229, L_228, C_228, NULL, NULL -#else K_229, L_228, C_228 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_228, Ri_228, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_228, NULL #else L_228 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_230, L_229, C_229, NULL, NULL -#else K_230, L_229, C_229 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_229, Ri_229, UINT64_C(0x3800000000000000), -#else -#if defined(MUL_M4RI) - L_229, NULL #else L_229 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_231, L_230, C_230, NULL, NULL -#else K_231, L_230, C_230 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_230, Ri_230, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_230, NULL #else L_230 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_232, L_231, C_231, NULL, NULL -#else K_232, L_231, C_231 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_231, Ri_231, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_231, NULL #else L_231 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_233, L_232, C_232, NULL, NULL -#else K_233, L_232, C_232 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_232, Ri_232, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_232, NULL #else L_232 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_234, L_233, C_233, NULL, NULL -#else K_234, L_233, C_233 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_233, Ri_233, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_233, NULL #else L_233 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_235, L_234, C_234, NULL, NULL -#else K_235, L_234, C_234 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_234, Ri_234, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_234, NULL #else L_234 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_236, L_235, C_235, NULL, NULL -#else K_236, L_235, C_235 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_235, Ri_235, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_235, NULL #else L_235 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_237, L_236, C_236, NULL, NULL -#else K_237, L_236, C_236 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_236, Ri_236, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_236, NULL #else L_236 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_238, L_237, C_237, NULL, NULL -#else K_238, L_237, C_237 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_237, Ri_237, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_237, NULL #else L_237 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_239, L_238, C_238, NULL, NULL -#else K_239, L_238, C_238 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_238, Ri_238, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_238, NULL #else L_238 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_240, L_239, C_239, NULL, NULL -#else K_240, L_239, C_239 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_239, Ri_239, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_239, NULL #else L_239 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_241, L_240, C_240, NULL, NULL -#else K_241, L_240, C_240 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_240, Ri_240, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_240, NULL #else L_240 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_242, L_241, C_241, NULL, NULL -#else K_242, L_241, C_241 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_241, Ri_241, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_241, NULL #else L_241 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_243, L_242, C_242, NULL, NULL -#else K_243, L_242, C_242 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_242, Ri_242, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_242, NULL #else L_242 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_244, L_243, C_243, NULL, NULL -#else K_244, L_243, C_243 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_243, Ri_243, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_243, NULL #else L_243 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_245, L_244, C_244, NULL, NULL -#else K_245, L_244, C_244 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_244, Ri_244, UINT64_C(0x9400000000000000), -#else -#if defined(MUL_M4RI) - L_244, NULL #else L_244 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_246, L_245, C_245, NULL, NULL -#else K_246, L_245, C_245 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_245, Ri_245, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_245, NULL #else L_245 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_247, L_246, C_246, NULL, NULL -#else K_247, L_246, C_246 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_246, Ri_246, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_246, NULL #else L_246 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_248, L_247, C_247, NULL, NULL -#else K_248, L_247, C_247 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_247, Ri_247, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_247, NULL #else L_247 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_249, L_248, C_248, NULL, NULL -#else K_249, L_248, C_248 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_248, Ri_248, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_248, NULL #else L_248 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_250, L_249, C_249, NULL, NULL -#else K_250, L_249, C_249 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_249, Ri_249, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_249, NULL #else L_249 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_251, L_250, C_250, NULL, NULL -#else K_251, L_250, C_250 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_250, Ri_250, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_250, NULL #else L_250 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_252, L_251, C_251, NULL, NULL -#else K_252, L_251, C_251 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_251, Ri_251, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_251, NULL #else L_251 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_253, L_252, C_252, NULL, NULL -#else K_253, L_252, C_252 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_252, Ri_252, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_252, NULL #else L_252 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_254, L_253, C_253, NULL, NULL -#else K_254, L_253, C_253 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_253, Ri_253, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_253, NULL #else L_253 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_255, L_254, C_254, NULL, NULL -#else K_255, L_254, C_254 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_254, Ri_254, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_254, NULL #else L_254 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_256, L_255, C_255, NULL, NULL -#else K_256, L_255, C_255 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_255, Ri_255, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_255, NULL #else L_255 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_257, L_256, C_256, NULL, NULL -#else K_257, L_256, C_256 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_256, Ri_256, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_256, NULL #else L_256 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_258, L_257, C_257, NULL, NULL -#else K_258, L_257, C_257 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_257, Ri_257, UINT64_C(0x9100000000000000), -#else -#if defined(MUL_M4RI) - L_257, NULL #else L_257 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_259, L_258, C_258, NULL, NULL -#else K_259, L_258, C_258 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_258, Ri_258, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_258, NULL #else L_258 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_260, L_259, C_259, NULL, NULL -#else K_260, L_259, C_259 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_259, Ri_259, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_259, NULL #else L_259 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_261, L_260, C_260, NULL, NULL -#else K_261, L_260, C_260 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_260, Ri_260, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_260, NULL #else L_260 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_262, L_261, C_261, NULL, NULL -#else K_262, L_261, C_261 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_261, Ri_261, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_261, NULL #else L_261 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_263, L_262, C_262, NULL, NULL -#else K_263, L_262, C_262 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_262, Ri_262, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_262, NULL #else L_262 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_264, L_263, C_263, NULL, NULL -#else K_264, L_263, C_263 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_263, Ri_263, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_263, NULL #else L_263 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_265, L_264, C_264, NULL, NULL -#else K_265, L_264, C_264 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_264, Ri_264, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_264, NULL #else L_264 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_266, L_265, C_265, NULL, NULL -#else K_266, L_265, C_265 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_265, Ri_265, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_265, NULL #else L_265 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_267, L_266, C_266, NULL, NULL -#else K_267, L_266, C_266 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_266, Ri_266, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_266, NULL #else L_266 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_268, L_267, C_267, NULL, NULL -#else K_268, L_267, C_267 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_267, Ri_267, UINT64_C(0x9400000000000000), -#else -#if defined(MUL_M4RI) - L_267, NULL #else L_267 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_269, L_268, C_268, NULL, NULL -#else K_269, L_268, C_268 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_268, Ri_268, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_268, NULL #else L_268 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_270, L_269, C_269, NULL, NULL -#else K_270, L_269, C_269 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_269, Ri_269, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_269, NULL #else L_269 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_271, L_270, C_270, NULL, NULL -#else K_271, L_270, C_270 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_270, Ri_270, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_270, NULL #else L_270 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_272, L_271, C_271, NULL, NULL -#else K_272, L_271, C_271 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_271, Ri_271, UINT64_C(0x5800000000000000), -#else -#if defined(MUL_M4RI) - L_271, NULL #else L_271 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_273, L_272, C_272, NULL, NULL -#else K_273, L_272, C_272 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_272, Ri_272, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_272, NULL #else L_272 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_274, L_273, C_273, NULL, NULL -#else K_274, L_273, C_273 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_273, Ri_273, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_273, NULL #else L_273 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_275, L_274, C_274, NULL, NULL -#else K_275, L_274, C_274 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_274, Ri_274, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_274, NULL #else L_274 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_276, L_275, C_275, NULL, NULL -#else K_276, L_275, C_275 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_275, Ri_275, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_275, NULL #else L_275 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_277, L_276, C_276, NULL, NULL -#else K_277, L_276, C_276 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_276, Ri_276, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_276, NULL #else L_276 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_278, L_277, C_277, NULL, NULL -#else K_278, L_277, C_277 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_277, Ri_277, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_277, NULL #else L_277 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_279, L_278, C_278, NULL, NULL -#else K_279, L_278, C_278 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_278, Ri_278, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_278, NULL #else L_278 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_280, L_279, C_279, NULL, NULL -#else K_280, L_279, C_279 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_279, Ri_279, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_279, NULL #else L_279 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_281, L_280, C_280, NULL, NULL -#else K_281, L_280, C_280 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_280, Ri_280, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_280, NULL #else L_280 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_282, L_281, C_281, NULL, NULL -#else K_282, L_281, C_281 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_281, Ri_281, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_281, NULL #else L_281 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_283, L_282, C_282, NULL, NULL -#else K_283, L_282, C_282 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_282, Ri_282, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_282, NULL #else L_282 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_284, L_283, C_283, NULL, NULL -#else K_284, L_283, C_283 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) NULL, NULL, 0, -#else -#if defined(MUL_M4RI) - L_283, NULL #else L_283 #endif -#endif #endif }, }; -#if defined(MUL_M4RI) -lowmc_t lowmc_192_192_284 = { -#else const lowmc_t lowmc_192_192_284 = { -#endif 1, 192, 284, 192, #if defined(REDUCED_ROUND_KEY_COMPUTATION) precomputed_round_key_matrix_linear_part, @@ -121225,16 +118945,10 @@ const lowmc_t lowmc_192_192_284 = { #endif #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Z_r, -#endif -#if defined(MUL_M4RI) - NULL, #endif rounds, #if defined(REDUCED_ROUND_KEY_COMPUTATION) precomputed_round_key_matrix_non_linear_part, -#if defined(MUL_M4RI) - NULL, -#endif precomputed_constant_linear_part, precomputed_constant_non_linear_part, #endif diff --git a/src/sig/picnic/external/lowmc_192_192_284.h b/src/sig/picnic/external/lowmc_192_192_284.h index 16862e401..c9f64f614 100644 --- a/src/sig/picnic/external/lowmc_192_192_284.h +++ b/src/sig/picnic/external/lowmc_192_192_284.h @@ -3,10 +3,6 @@ #include "lowmc_pars.h" -#if !defined(MUL_M4RI) extern const lowmc_t lowmc_192_192_284; -#else -extern lowmc_t lowmc_192_192_284; -#endif #endif diff --git a/src/sig/picnic/external/lowmc_192_192_30.c b/src/sig/picnic/external/lowmc_192_192_30.c index 11cc8e54b..f736b3a98 100644 --- a/src/sig/picnic/external/lowmc_192_192_30.c +++ b/src/sig/picnic/external/lowmc_192_192_30.c @@ -14504,589 +14504,341 @@ static const block_t Ri_28[] = { #endif -#if defined(MUL_M4RI) -static lowmc_round_t rounds[30] = { -#else static const lowmc_round_t rounds[30] = { -#endif { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_1, L_0, C_0, NULL, NULL -#else K_1, L_0, C_0 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_0, Ri_0, UINT64_C(0xffffffde00000000), -#else -#if defined(MUL_M4RI) - L_0, NULL #else L_0 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_2, L_1, C_1, NULL, NULL -#else K_2, L_1, C_1 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_1, Ri_1, UINT64_C(0xffffffde00000000), -#else -#if defined(MUL_M4RI) - L_1, NULL #else L_1 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_3, L_2, C_2, NULL, NULL -#else K_3, L_2, C_2 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_2, Ri_2, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_2, NULL #else L_2 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_4, L_3, C_3, NULL, NULL -#else K_4, L_3, C_3 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_3, Ri_3, UINT64_C(0xffffffed00000000), -#else -#if defined(MUL_M4RI) - L_3, NULL #else L_3 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_5, L_4, C_4, NULL, NULL -#else K_5, L_4, C_4 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_4, Ri_4, UINT64_C(0xffffffbd00000000), -#else -#if defined(MUL_M4RI) - L_4, NULL #else L_4 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_6, L_5, C_5, NULL, NULL -#else K_6, L_5, C_5 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_5, Ri_5, UINT64_C(0xfffffff210000000), -#else -#if defined(MUL_M4RI) - L_5, NULL #else L_5 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_7, L_6, C_6, NULL, NULL -#else K_7, L_6, C_6 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_6, Ri_6, UINT64_C(0xffffffec80000000), -#else -#if defined(MUL_M4RI) - L_6, NULL #else L_6 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_8, L_7, C_7, NULL, NULL -#else K_8, L_7, C_7 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_7, Ri_7, UINT64_C(0xfffffff880000000), -#else -#if defined(MUL_M4RI) - L_7, NULL #else L_7 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_9, L_8, C_8, NULL, NULL -#else K_9, L_8, C_8 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_8, Ri_8, UINT64_C(0xfffffff500000000), -#else -#if defined(MUL_M4RI) - L_8, NULL #else L_8 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_10, L_9, C_9, NULL, NULL -#else K_10, L_9, C_9 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_9, Ri_9, UINT64_C(0xffffffdc20000000), -#else -#if defined(MUL_M4RI) - L_9, NULL #else L_9 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_11, L_10, C_10, NULL, NULL -#else K_11, L_10, C_10 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_10, Ri_10, UINT64_C(0xfffffff900000000), -#else -#if defined(MUL_M4RI) - L_10, NULL #else L_10 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_12, L_11, C_11, NULL, NULL -#else K_12, L_11, C_11 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_11, Ri_11, UINT64_C(0xffffffde00000000), -#else -#if defined(MUL_M4RI) - L_11, NULL #else L_11 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_13, L_12, C_12, NULL, NULL -#else K_13, L_12, C_12 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_12, Ri_12, UINT64_C(0xfffffff900000000), -#else -#if defined(MUL_M4RI) - L_12, NULL #else L_12 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_14, L_13, C_13, NULL, NULL -#else K_14, L_13, C_13 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_13, Ri_13, UINT64_C(0xfffffff500000000), -#else -#if defined(MUL_M4RI) - L_13, NULL #else L_13 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_15, L_14, C_14, NULL, NULL -#else K_15, L_14, C_14 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_14, Ri_14, UINT64_C(0xfffffff900000000), -#else -#if defined(MUL_M4RI) - L_14, NULL #else L_14 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_16, L_15, C_15, NULL, NULL -#else K_16, L_15, C_15 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_15, Ri_15, UINT64_C(0xfffffff808000000), -#else -#if defined(MUL_M4RI) - L_15, NULL #else L_15 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_17, L_16, C_16, NULL, NULL -#else K_17, L_16, C_16 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_16, Ri_16, UINT64_C(0xffffffaf00000000), -#else -#if defined(MUL_M4RI) - L_16, NULL #else L_16 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_18, L_17, C_17, NULL, NULL -#else K_18, L_17, C_17 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_17, Ri_17, UINT64_C(0xffffffee00000000), -#else -#if defined(MUL_M4RI) - L_17, NULL #else L_17 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_19, L_18, C_18, NULL, NULL -#else K_19, L_18, C_18 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_18, Ri_18, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_18, NULL #else L_18 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_20, L_19, C_19, NULL, NULL -#else K_20, L_19, C_19 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_19, Ri_19, UINT64_C(0xfffffff900000000), -#else -#if defined(MUL_M4RI) - L_19, NULL #else L_19 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_21, L_20, C_20, NULL, NULL -#else K_21, L_20, C_20 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_20, Ri_20, UINT64_C(0xffffff7620000000), -#else -#if defined(MUL_M4RI) - L_20, NULL #else L_20 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_22, L_21, C_21, NULL, NULL -#else K_22, L_21, C_21 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_21, Ri_21, UINT64_C(0xfffffff280000000), -#else -#if defined(MUL_M4RI) - L_21, NULL #else L_21 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_23, L_22, C_22, NULL, NULL -#else K_23, L_22, C_22 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_22, Ri_22, UINT64_C(0xffffffee00000000), -#else -#if defined(MUL_M4RI) - L_22, NULL #else L_22 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_24, L_23, C_23, NULL, NULL -#else K_24, L_23, C_23 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_23, Ri_23, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_23, NULL #else L_23 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_25, L_24, C_24, NULL, NULL -#else K_25, L_24, C_24 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_24, Ri_24, UINT64_C(0xfffffff600000000), -#else -#if defined(MUL_M4RI) - L_24, NULL #else L_24 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_26, L_25, C_25, NULL, NULL -#else K_26, L_25, C_25 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_25, Ri_25, UINT64_C(0xffffff7e00000000), -#else -#if defined(MUL_M4RI) - L_25, NULL #else L_25 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_27, L_26, C_26, NULL, NULL -#else K_27, L_26, C_26 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_26, Ri_26, UINT64_C(0xfffffff500000000), -#else -#if defined(MUL_M4RI) - L_26, NULL #else L_26 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_28, L_27, C_27, NULL, NULL -#else K_28, L_27, C_27 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_27, Ri_27, UINT64_C(0xfffffffa00000000), -#else -#if defined(MUL_M4RI) - L_27, NULL #else L_27 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_29, L_28, C_28, NULL, NULL -#else K_29, L_28, C_28 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_28, Ri_28, UINT64_C(0xfffffff600000000), -#else -#if defined(MUL_M4RI) - L_28, NULL #else L_28 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_30, L_29, C_29, NULL, NULL -#else K_30, L_29, C_29 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) NULL, NULL, 0, -#else -#if defined(MUL_M4RI) - L_29, NULL #else L_29 #endif -#endif #endif }, }; -#if defined(MUL_M4RI) -lowmc_t lowmc_192_192_30 = { -#else const lowmc_t lowmc_192_192_30 = { -#endif 10, 192, 30, 192, #if defined(REDUCED_ROUND_KEY_COMPUTATION) precomputed_round_key_matrix_linear_part, @@ -15095,16 +14847,10 @@ const lowmc_t lowmc_192_192_30 = { #endif #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Z_r, -#endif -#if defined(MUL_M4RI) - NULL, #endif rounds, #if defined(REDUCED_ROUND_KEY_COMPUTATION) precomputed_round_key_matrix_non_linear_part, -#if defined(MUL_M4RI) - NULL, -#endif precomputed_constant_linear_part, precomputed_constant_non_linear_part, #endif diff --git a/src/sig/picnic/external/lowmc_192_192_30.h b/src/sig/picnic/external/lowmc_192_192_30.h index 1ac45e685..d6ece51a9 100644 --- a/src/sig/picnic/external/lowmc_192_192_30.h +++ b/src/sig/picnic/external/lowmc_192_192_30.h @@ -3,10 +3,6 @@ #include "lowmc_pars.h" -#if !defined(MUL_M4RI) extern const lowmc_t lowmc_192_192_30; -#else -extern lowmc_t lowmc_192_192_30; -#endif #endif diff --git a/src/sig/picnic/external/lowmc_256_256_363.c b/src/sig/picnic/external/lowmc_256_256_363.c index 4bcf5c3d8..a65687c81 100644 --- a/src/sig/picnic/external/lowmc_256_256_363.c +++ b/src/sig/picnic/external/lowmc_256_256_363.c @@ -194523,6916 +194523,4004 @@ static const block_t Ri_361[] = { #endif -#if defined(MUL_M4RI) -static lowmc_round_t rounds[363] = { -#else static const lowmc_round_t rounds[363] = { -#endif { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_1, L_0, C_0, NULL, NULL -#else K_1, L_0, C_0 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_0, Ri_0, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_0, NULL #else L_0 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_2, L_1, C_1, NULL, NULL -#else K_2, L_1, C_1 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_1, Ri_1, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_1, NULL #else L_1 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_3, L_2, C_2, NULL, NULL -#else K_3, L_2, C_2 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_2, Ri_2, UINT64_C(0xa100000000000000), -#else -#if defined(MUL_M4RI) - L_2, NULL #else L_2 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_4, L_3, C_3, NULL, NULL -#else K_4, L_3, C_3 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_3, Ri_3, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_3, NULL #else L_3 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_5, L_4, C_4, NULL, NULL -#else K_5, L_4, C_4 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_4, Ri_4, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_4, NULL #else L_4 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_6, L_5, C_5, NULL, NULL -#else K_6, L_5, C_5 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_5, Ri_5, UINT64_C(0x5400000000000000), -#else -#if defined(MUL_M4RI) - L_5, NULL #else L_5 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_7, L_6, C_6, NULL, NULL -#else K_7, L_6, C_6 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_6, Ri_6, UINT64_C(0x0e00000000000000), -#else -#if defined(MUL_M4RI) - L_6, NULL #else L_6 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_8, L_7, C_7, NULL, NULL -#else K_8, L_7, C_7 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_7, Ri_7, UINT64_C(0x6800000000000000), -#else -#if defined(MUL_M4RI) - L_7, NULL #else L_7 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_9, L_8, C_8, NULL, NULL -#else K_9, L_8, C_8 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_8, Ri_8, UINT64_C(0x5800000000000000), -#else -#if defined(MUL_M4RI) - L_8, NULL #else L_8 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_10, L_9, C_9, NULL, NULL -#else K_10, L_9, C_9 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_9, Ri_9, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_9, NULL #else L_9 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_11, L_10, C_10, NULL, NULL -#else K_11, L_10, C_10 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_10, Ri_10, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_10, NULL #else L_10 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_12, L_11, C_11, NULL, NULL -#else K_12, L_11, C_11 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_11, Ri_11, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_11, NULL #else L_11 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_13, L_12, C_12, NULL, NULL -#else K_13, L_12, C_12 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_12, Ri_12, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_12, NULL #else L_12 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_14, L_13, C_13, NULL, NULL -#else K_14, L_13, C_13 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_13, Ri_13, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_13, NULL #else L_13 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_15, L_14, C_14, NULL, NULL -#else K_15, L_14, C_14 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_14, Ri_14, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_14, NULL #else L_14 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_16, L_15, C_15, NULL, NULL -#else K_16, L_15, C_15 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_15, Ri_15, UINT64_C(0x8500000000000000), -#else -#if defined(MUL_M4RI) - L_15, NULL #else L_15 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_17, L_16, C_16, NULL, NULL -#else K_17, L_16, C_16 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_16, Ri_16, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_16, NULL #else L_16 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_18, L_17, C_17, NULL, NULL -#else K_18, L_17, C_17 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_17, Ri_17, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_17, NULL #else L_17 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_19, L_18, C_18, NULL, NULL -#else K_19, L_18, C_18 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_18, Ri_18, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_18, NULL #else L_18 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_20, L_19, C_19, NULL, NULL -#else K_20, L_19, C_19 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_19, Ri_19, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_19, NULL #else L_19 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_21, L_20, C_20, NULL, NULL -#else K_21, L_20, C_20 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_20, Ri_20, UINT64_C(0x5400000000000000), -#else -#if defined(MUL_M4RI) - L_20, NULL #else L_20 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_22, L_21, C_21, NULL, NULL -#else K_22, L_21, C_21 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_21, Ri_21, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_21, NULL #else L_21 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_23, L_22, C_22, NULL, NULL -#else K_23, L_22, C_22 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_22, Ri_22, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_22, NULL #else L_22 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_24, L_23, C_23, NULL, NULL -#else K_24, L_23, C_23 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_23, Ri_23, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_23, NULL #else L_23 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_25, L_24, C_24, NULL, NULL -#else K_25, L_24, C_24 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_24, Ri_24, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_24, NULL #else L_24 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_26, L_25, C_25, NULL, NULL -#else K_26, L_25, C_25 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_25, Ri_25, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_25, NULL #else L_25 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_27, L_26, C_26, NULL, NULL -#else K_27, L_26, C_26 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_26, Ri_26, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_26, NULL #else L_26 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_28, L_27, C_27, NULL, NULL -#else K_28, L_27, C_27 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_27, Ri_27, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_27, NULL #else L_27 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_29, L_28, C_28, NULL, NULL -#else K_29, L_28, C_28 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_28, Ri_28, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_28, NULL #else L_28 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_30, L_29, C_29, NULL, NULL -#else K_30, L_29, C_29 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_29, Ri_29, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_29, NULL #else L_29 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_31, L_30, C_30, NULL, NULL -#else K_31, L_30, C_30 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_30, Ri_30, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_30, NULL #else L_30 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_32, L_31, C_31, NULL, NULL -#else K_32, L_31, C_31 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_31, Ri_31, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_31, NULL #else L_31 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_33, L_32, C_32, NULL, NULL -#else K_33, L_32, C_32 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_32, Ri_32, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_32, NULL #else L_32 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_34, L_33, C_33, NULL, NULL -#else K_34, L_33, C_33 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_33, Ri_33, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_33, NULL #else L_33 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_35, L_34, C_34, NULL, NULL -#else K_35, L_34, C_34 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_34, Ri_34, UINT64_C(0x5800000000000000), -#else -#if defined(MUL_M4RI) - L_34, NULL #else L_34 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_36, L_35, C_35, NULL, NULL -#else K_36, L_35, C_35 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_35, Ri_35, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_35, NULL #else L_35 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_37, L_36, C_36, NULL, NULL -#else K_37, L_36, C_36 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_36, Ri_36, UINT64_C(0x9200000000000000), -#else -#if defined(MUL_M4RI) - L_36, NULL #else L_36 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_38, L_37, C_37, NULL, NULL -#else K_38, L_37, C_37 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_37, Ri_37, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_37, NULL #else L_37 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_39, L_38, C_38, NULL, NULL -#else K_39, L_38, C_38 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_38, Ri_38, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_38, NULL #else L_38 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_40, L_39, C_39, NULL, NULL -#else K_40, L_39, C_39 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_39, Ri_39, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_39, NULL #else L_39 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_41, L_40, C_40, NULL, NULL -#else K_41, L_40, C_40 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_40, Ri_40, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_40, NULL #else L_40 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_42, L_41, C_41, NULL, NULL -#else K_42, L_41, C_41 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_41, Ri_41, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_41, NULL #else L_41 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_43, L_42, C_42, NULL, NULL -#else K_43, L_42, C_42 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_42, Ri_42, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_42, NULL #else L_42 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_44, L_43, C_43, NULL, NULL -#else K_44, L_43, C_43 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_43, Ri_43, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_43, NULL #else L_43 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_45, L_44, C_44, NULL, NULL -#else K_45, L_44, C_44 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_44, Ri_44, UINT64_C(0x6400000000000000), -#else -#if defined(MUL_M4RI) - L_44, NULL #else L_44 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_46, L_45, C_45, NULL, NULL -#else K_46, L_45, C_45 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_45, Ri_45, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_45, NULL #else L_45 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_47, L_46, C_46, NULL, NULL -#else K_47, L_46, C_46 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_46, Ri_46, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_46, NULL #else L_46 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_48, L_47, C_47, NULL, NULL -#else K_48, L_47, C_47 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_47, Ri_47, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_47, NULL #else L_47 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_49, L_48, C_48, NULL, NULL -#else K_49, L_48, C_48 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_48, Ri_48, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_48, NULL #else L_48 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_50, L_49, C_49, NULL, NULL -#else K_50, L_49, C_49 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_49, Ri_49, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_49, NULL #else L_49 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_51, L_50, C_50, NULL, NULL -#else K_51, L_50, C_50 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_50, Ri_50, UINT64_C(0xc020000000000000), -#else -#if defined(MUL_M4RI) - L_50, NULL #else L_50 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_52, L_51, C_51, NULL, NULL -#else K_52, L_51, C_51 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_51, Ri_51, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_51, NULL #else L_51 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_53, L_52, C_52, NULL, NULL -#else K_53, L_52, C_52 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_52, Ri_52, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_52, NULL #else L_52 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_54, L_53, C_53, NULL, NULL -#else K_54, L_53, C_53 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_53, Ri_53, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_53, NULL #else L_53 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_55, L_54, C_54, NULL, NULL -#else K_55, L_54, C_54 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_54, Ri_54, UINT64_C(0x4a00000000000000), -#else -#if defined(MUL_M4RI) - L_54, NULL #else L_54 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_56, L_55, C_55, NULL, NULL -#else K_56, L_55, C_55 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_55, Ri_55, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_55, NULL #else L_55 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_57, L_56, C_56, NULL, NULL -#else K_57, L_56, C_56 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_56, Ri_56, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_56, NULL #else L_56 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_58, L_57, C_57, NULL, NULL -#else K_58, L_57, C_57 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_57, Ri_57, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_57, NULL #else L_57 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_59, L_58, C_58, NULL, NULL -#else K_59, L_58, C_58 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_58, Ri_58, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_58, NULL #else L_58 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_60, L_59, C_59, NULL, NULL -#else K_60, L_59, C_59 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_59, Ri_59, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_59, NULL #else L_59 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_61, L_60, C_60, NULL, NULL -#else K_61, L_60, C_60 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_60, Ri_60, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_60, NULL #else L_60 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_62, L_61, C_61, NULL, NULL -#else K_62, L_61, C_61 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_61, Ri_61, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_61, NULL #else L_61 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_63, L_62, C_62, NULL, NULL -#else K_63, L_62, C_62 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_62, Ri_62, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_62, NULL #else L_62 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_64, L_63, C_63, NULL, NULL -#else K_64, L_63, C_63 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_63, Ri_63, UINT64_C(0x6400000000000000), -#else -#if defined(MUL_M4RI) - L_63, NULL #else L_63 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_65, L_64, C_64, NULL, NULL -#else K_65, L_64, C_64 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_64, Ri_64, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_64, NULL #else L_64 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_66, L_65, C_65, NULL, NULL -#else K_66, L_65, C_65 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_65, Ri_65, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_65, NULL #else L_65 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_67, L_66, C_66, NULL, NULL -#else K_67, L_66, C_66 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_66, Ri_66, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_66, NULL #else L_66 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_68, L_67, C_67, NULL, NULL -#else K_68, L_67, C_67 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_67, Ri_67, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_67, NULL #else L_67 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_69, L_68, C_68, NULL, NULL -#else K_69, L_68, C_68 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_68, Ri_68, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_68, NULL #else L_68 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_70, L_69, C_69, NULL, NULL -#else K_70, L_69, C_69 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_69, Ri_69, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_69, NULL #else L_69 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_71, L_70, C_70, NULL, NULL -#else K_71, L_70, C_70 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_70, Ri_70, UINT64_C(0x6800000000000000), -#else -#if defined(MUL_M4RI) - L_70, NULL #else L_70 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_72, L_71, C_71, NULL, NULL -#else K_72, L_71, C_71 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_71, Ri_71, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_71, NULL #else L_71 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_73, L_72, C_72, NULL, NULL -#else K_73, L_72, C_72 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_72, Ri_72, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_72, NULL #else L_72 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_74, L_73, C_73, NULL, NULL -#else K_74, L_73, C_73 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_73, Ri_73, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_73, NULL #else L_73 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_75, L_74, C_74, NULL, NULL -#else K_75, L_74, C_74 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_74, Ri_74, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_74, NULL #else L_74 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_76, L_75, C_75, NULL, NULL -#else K_76, L_75, C_75 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_75, Ri_75, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_75, NULL #else L_75 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_77, L_76, C_76, NULL, NULL -#else K_77, L_76, C_76 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_76, Ri_76, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_76, NULL #else L_76 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_78, L_77, C_77, NULL, NULL -#else K_78, L_77, C_77 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_77, Ri_77, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_77, NULL #else L_77 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_79, L_78, C_78, NULL, NULL -#else K_79, L_78, C_78 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_78, Ri_78, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_78, NULL #else L_78 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_80, L_79, C_79, NULL, NULL -#else K_80, L_79, C_79 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_79, Ri_79, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_79, NULL #else L_79 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_81, L_80, C_80, NULL, NULL -#else K_81, L_80, C_80 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_80, Ri_80, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_80, NULL #else L_80 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_82, L_81, C_81, NULL, NULL -#else K_82, L_81, C_81 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_81, Ri_81, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_81, NULL #else L_81 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_83, L_82, C_82, NULL, NULL -#else K_83, L_82, C_82 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_82, Ri_82, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_82, NULL #else L_82 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_84, L_83, C_83, NULL, NULL -#else K_84, L_83, C_83 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_83, Ri_83, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_83, NULL #else L_83 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_85, L_84, C_84, NULL, NULL -#else K_85, L_84, C_84 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_84, Ri_84, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_84, NULL #else L_84 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_86, L_85, C_85, NULL, NULL -#else K_86, L_85, C_85 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_85, Ri_85, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_85, NULL #else L_85 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_87, L_86, C_86, NULL, NULL -#else K_87, L_86, C_86 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_86, Ri_86, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_86, NULL #else L_86 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_88, L_87, C_87, NULL, NULL -#else K_88, L_87, C_87 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_87, Ri_87, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_87, NULL #else L_87 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_89, L_88, C_88, NULL, NULL -#else K_89, L_88, C_88 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_88, Ri_88, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_88, NULL #else L_88 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_90, L_89, C_89, NULL, NULL -#else K_90, L_89, C_89 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_89, Ri_89, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_89, NULL #else L_89 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_91, L_90, C_90, NULL, NULL -#else K_91, L_90, C_90 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_90, Ri_90, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_90, NULL #else L_90 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_92, L_91, C_91, NULL, NULL -#else K_92, L_91, C_91 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_91, Ri_91, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_91, NULL #else L_91 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_93, L_92, C_92, NULL, NULL -#else K_93, L_92, C_92 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_92, Ri_92, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_92, NULL #else L_92 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_94, L_93, C_93, NULL, NULL -#else K_94, L_93, C_93 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_93, Ri_93, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_93, NULL #else L_93 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_95, L_94, C_94, NULL, NULL -#else K_95, L_94, C_94 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_94, Ri_94, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_94, NULL #else L_94 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_96, L_95, C_95, NULL, NULL -#else K_96, L_95, C_95 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_95, Ri_95, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_95, NULL #else L_95 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_97, L_96, C_96, NULL, NULL -#else K_97, L_96, C_96 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_96, Ri_96, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_96, NULL #else L_96 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_98, L_97, C_97, NULL, NULL -#else K_98, L_97, C_97 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_97, Ri_97, UINT64_C(0xc100000000000000), -#else -#if defined(MUL_M4RI) - L_97, NULL #else L_97 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_99, L_98, C_98, NULL, NULL -#else K_99, L_98, C_98 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_98, Ri_98, UINT64_C(0x3100000000000000), -#else -#if defined(MUL_M4RI) - L_98, NULL #else L_98 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_100, L_99, C_99, NULL, NULL -#else K_100, L_99, C_99 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_99, Ri_99, UINT64_C(0xc100000000000000), -#else -#if defined(MUL_M4RI) - L_99, NULL #else L_99 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_101, L_100, C_100, NULL, NULL -#else K_101, L_100, C_100 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_100, Ri_100, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_100, NULL #else L_100 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_102, L_101, C_101, NULL, NULL -#else K_102, L_101, C_101 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_101, Ri_101, UINT64_C(0x4c00000000000000), -#else -#if defined(MUL_M4RI) - L_101, NULL #else L_101 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_103, L_102, C_102, NULL, NULL -#else K_103, L_102, C_102 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_102, Ri_102, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_102, NULL #else L_102 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_104, L_103, C_103, NULL, NULL -#else K_104, L_103, C_103 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_103, Ri_103, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_103, NULL #else L_103 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_105, L_104, C_104, NULL, NULL -#else K_105, L_104, C_104 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_104, Ri_104, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_104, NULL #else L_104 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_106, L_105, C_105, NULL, NULL -#else K_106, L_105, C_105 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_105, Ri_105, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_105, NULL #else L_105 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_107, L_106, C_106, NULL, NULL -#else K_107, L_106, C_106 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_106, Ri_106, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_106, NULL #else L_106 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_108, L_107, C_107, NULL, NULL -#else K_108, L_107, C_107 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_107, Ri_107, UINT64_C(0x9010000000000000), -#else -#if defined(MUL_M4RI) - L_107, NULL #else L_107 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_109, L_108, C_108, NULL, NULL -#else K_109, L_108, C_108 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_108, Ri_108, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_108, NULL #else L_108 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_110, L_109, C_109, NULL, NULL -#else K_110, L_109, C_109 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_109, Ri_109, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_109, NULL #else L_109 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_111, L_110, C_110, NULL, NULL -#else K_111, L_110, C_110 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_110, Ri_110, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_110, NULL #else L_110 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_112, L_111, C_111, NULL, NULL -#else K_112, L_111, C_111 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_111, Ri_111, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_111, NULL #else L_111 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_113, L_112, C_112, NULL, NULL -#else K_113, L_112, C_112 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_112, Ri_112, UINT64_C(0xa200000000000000), -#else -#if defined(MUL_M4RI) - L_112, NULL #else L_112 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_114, L_113, C_113, NULL, NULL -#else K_114, L_113, C_113 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_113, Ri_113, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_113, NULL #else L_113 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_115, L_114, C_114, NULL, NULL -#else K_115, L_114, C_114 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_114, Ri_114, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_114, NULL #else L_114 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_116, L_115, C_115, NULL, NULL -#else K_116, L_115, C_115 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_115, Ri_115, UINT64_C(0x4600000000000000), -#else -#if defined(MUL_M4RI) - L_115, NULL #else L_115 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_117, L_116, C_116, NULL, NULL -#else K_117, L_116, C_116 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_116, Ri_116, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_116, NULL #else L_116 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_118, L_117, C_117, NULL, NULL -#else K_118, L_117, C_117 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_117, Ri_117, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_117, NULL #else L_117 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_119, L_118, C_118, NULL, NULL -#else K_119, L_118, C_118 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_118, Ri_118, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_118, NULL #else L_118 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_120, L_119, C_119, NULL, NULL -#else K_120, L_119, C_119 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_119, Ri_119, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_119, NULL #else L_119 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_121, L_120, C_120, NULL, NULL -#else K_121, L_120, C_120 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_120, Ri_120, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_120, NULL #else L_120 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_122, L_121, C_121, NULL, NULL -#else K_122, L_121, C_121 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_121, Ri_121, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_121, NULL #else L_121 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_123, L_122, C_122, NULL, NULL -#else K_123, L_122, C_122 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_122, Ri_122, UINT64_C(0x4600000000000000), -#else -#if defined(MUL_M4RI) - L_122, NULL #else L_122 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_124, L_123, C_123, NULL, NULL -#else K_124, L_123, C_123 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_123, Ri_123, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_123, NULL #else L_123 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_125, L_124, C_124, NULL, NULL -#else K_125, L_124, C_124 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_124, Ri_124, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_124, NULL #else L_124 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_126, L_125, C_125, NULL, NULL -#else K_126, L_125, C_125 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_125, Ri_125, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_125, NULL #else L_125 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_127, L_126, C_126, NULL, NULL -#else K_127, L_126, C_126 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_126, Ri_126, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_126, NULL #else L_126 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_128, L_127, C_127, NULL, NULL -#else K_128, L_127, C_127 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_127, Ri_127, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_127, NULL #else L_127 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_129, L_128, C_128, NULL, NULL -#else K_129, L_128, C_128 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_128, Ri_128, UINT64_C(0x3040000000000000), -#else -#if defined(MUL_M4RI) - L_128, NULL #else L_128 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_130, L_129, C_129, NULL, NULL -#else K_130, L_129, C_129 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_129, Ri_129, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_129, NULL #else L_129 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_131, L_130, C_130, NULL, NULL -#else K_131, L_130, C_130 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_130, Ri_130, UINT64_C(0x6200000000000000), -#else -#if defined(MUL_M4RI) - L_130, NULL #else L_130 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_132, L_131, C_131, NULL, NULL -#else K_132, L_131, C_131 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_131, Ri_131, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_131, NULL #else L_131 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_133, L_132, C_132, NULL, NULL -#else K_133, L_132, C_132 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_132, Ri_132, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_132, NULL #else L_132 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_134, L_133, C_133, NULL, NULL -#else K_134, L_133, C_133 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_133, Ri_133, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_133, NULL #else L_133 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_135, L_134, C_134, NULL, NULL -#else K_135, L_134, C_134 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_134, Ri_134, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_134, NULL #else L_134 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_136, L_135, C_135, NULL, NULL -#else K_136, L_135, C_135 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_135, Ri_135, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_135, NULL #else L_135 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_137, L_136, C_136, NULL, NULL -#else K_137, L_136, C_136 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_136, Ri_136, UINT64_C(0x6800000000000000), -#else -#if defined(MUL_M4RI) - L_136, NULL #else L_136 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_138, L_137, C_137, NULL, NULL -#else K_138, L_137, C_137 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_137, Ri_137, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_137, NULL #else L_137 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_139, L_138, C_138, NULL, NULL -#else K_139, L_138, C_138 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_138, Ri_138, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_138, NULL #else L_138 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_140, L_139, C_139, NULL, NULL -#else K_140, L_139, C_139 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_139, Ri_139, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_139, NULL #else L_139 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_141, L_140, C_140, NULL, NULL -#else K_141, L_140, C_140 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_140, Ri_140, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_140, NULL #else L_140 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_142, L_141, C_141, NULL, NULL -#else K_142, L_141, C_141 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_141, Ri_141, UINT64_C(0xa200000000000000), -#else -#if defined(MUL_M4RI) - L_141, NULL #else L_141 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_143, L_142, C_142, NULL, NULL -#else K_143, L_142, C_142 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_142, Ri_142, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_142, NULL #else L_142 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_144, L_143, C_143, NULL, NULL -#else K_144, L_143, C_143 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_143, Ri_143, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_143, NULL #else L_143 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_145, L_144, C_144, NULL, NULL -#else K_145, L_144, C_144 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_144, Ri_144, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_144, NULL #else L_144 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_146, L_145, C_145, NULL, NULL -#else K_146, L_145, C_145 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_145, Ri_145, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_145, NULL #else L_145 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_147, L_146, C_146, NULL, NULL -#else K_147, L_146, C_146 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_146, Ri_146, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_146, NULL #else L_146 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_148, L_147, C_147, NULL, NULL -#else K_148, L_147, C_147 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_147, Ri_147, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_147, NULL #else L_147 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_149, L_148, C_148, NULL, NULL -#else K_149, L_148, C_148 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_148, Ri_148, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_148, NULL #else L_148 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_150, L_149, C_149, NULL, NULL -#else K_150, L_149, C_149 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_149, Ri_149, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_149, NULL #else L_149 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_151, L_150, C_150, NULL, NULL -#else K_151, L_150, C_150 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_150, Ri_150, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_150, NULL #else L_150 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_152, L_151, C_151, NULL, NULL -#else K_152, L_151, C_151 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_151, Ri_151, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_151, NULL #else L_151 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_153, L_152, C_152, NULL, NULL -#else K_153, L_152, C_152 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_152, Ri_152, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_152, NULL #else L_152 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_154, L_153, C_153, NULL, NULL -#else K_154, L_153, C_153 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_153, Ri_153, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_153, NULL #else L_153 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_155, L_154, C_154, NULL, NULL -#else K_155, L_154, C_154 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_154, Ri_154, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_154, NULL #else L_154 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_156, L_155, C_155, NULL, NULL -#else K_156, L_155, C_155 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_155, Ri_155, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_155, NULL #else L_155 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_157, L_156, C_156, NULL, NULL -#else K_157, L_156, C_156 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_156, Ri_156, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_156, NULL #else L_156 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_158, L_157, C_157, NULL, NULL -#else K_158, L_157, C_157 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_157, Ri_157, UINT64_C(0x9080000000000000), -#else -#if defined(MUL_M4RI) - L_157, NULL #else L_157 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_159, L_158, C_158, NULL, NULL -#else K_159, L_158, C_158 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_158, Ri_158, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_158, NULL #else L_158 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_160, L_159, C_159, NULL, NULL -#else K_160, L_159, C_159 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_159, Ri_159, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_159, NULL #else L_159 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_161, L_160, C_160, NULL, NULL -#else K_161, L_160, C_160 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_160, Ri_160, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_160, NULL #else L_160 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_162, L_161, C_161, NULL, NULL -#else K_162, L_161, C_161 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_161, Ri_161, UINT64_C(0x5200000000000000), -#else -#if defined(MUL_M4RI) - L_161, NULL #else L_161 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_163, L_162, C_162, NULL, NULL -#else K_163, L_162, C_162 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_162, Ri_162, UINT64_C(0xa200000000000000), -#else -#if defined(MUL_M4RI) - L_162, NULL #else L_162 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_164, L_163, C_163, NULL, NULL -#else K_164, L_163, C_163 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_163, Ri_163, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_163, NULL #else L_163 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_165, L_164, C_164, NULL, NULL -#else K_165, L_164, C_164 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_164, Ri_164, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_164, NULL #else L_164 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_166, L_165, C_165, NULL, NULL -#else K_166, L_165, C_165 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_165, Ri_165, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_165, NULL #else L_165 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_167, L_166, C_166, NULL, NULL -#else K_167, L_166, C_166 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_166, Ri_166, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_166, NULL #else L_166 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_168, L_167, C_167, NULL, NULL -#else K_168, L_167, C_167 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_167, Ri_167, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_167, NULL #else L_167 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_169, L_168, C_168, NULL, NULL -#else K_169, L_168, C_168 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_168, Ri_168, UINT64_C(0xc040000000000000), -#else -#if defined(MUL_M4RI) - L_168, NULL #else L_168 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_170, L_169, C_169, NULL, NULL -#else K_170, L_169, C_169 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_169, Ri_169, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_169, NULL #else L_169 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_171, L_170, C_170, NULL, NULL -#else K_171, L_170, C_170 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_170, Ri_170, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_170, NULL #else L_170 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_172, L_171, C_171, NULL, NULL -#else K_172, L_171, C_171 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_171, Ri_171, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_171, NULL #else L_171 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_173, L_172, C_172, NULL, NULL -#else K_173, L_172, C_172 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_172, Ri_172, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_172, NULL #else L_172 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_174, L_173, C_173, NULL, NULL -#else K_174, L_173, C_173 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_173, Ri_173, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_173, NULL #else L_173 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_175, L_174, C_174, NULL, NULL -#else K_175, L_174, C_174 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_174, Ri_174, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_174, NULL #else L_174 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_176, L_175, C_175, NULL, NULL -#else K_176, L_175, C_175 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_175, Ri_175, UINT64_C(0x6400000000000000), -#else -#if defined(MUL_M4RI) - L_175, NULL #else L_175 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_177, L_176, C_176, NULL, NULL -#else K_177, L_176, C_176 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_176, Ri_176, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_176, NULL #else L_176 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_178, L_177, C_177, NULL, NULL -#else K_178, L_177, C_177 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_177, Ri_177, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_177, NULL #else L_177 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_179, L_178, C_178, NULL, NULL -#else K_179, L_178, C_178 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_178, Ri_178, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_178, NULL #else L_178 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_180, L_179, C_179, NULL, NULL -#else K_180, L_179, C_179 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_179, Ri_179, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_179, NULL #else L_179 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_181, L_180, C_180, NULL, NULL -#else K_181, L_180, C_180 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_180, Ri_180, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_180, NULL #else L_180 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_182, L_181, C_181, NULL, NULL -#else K_182, L_181, C_181 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_181, Ri_181, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_181, NULL #else L_181 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_183, L_182, C_182, NULL, NULL -#else K_183, L_182, C_182 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_182, Ri_182, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_182, NULL #else L_182 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_184, L_183, C_183, NULL, NULL -#else K_184, L_183, C_183 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_183, Ri_183, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_183, NULL #else L_183 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_185, L_184, C_184, NULL, NULL -#else K_185, L_184, C_184 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_184, Ri_184, UINT64_C(0x9200000000000000), -#else -#if defined(MUL_M4RI) - L_184, NULL #else L_184 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_186, L_185, C_185, NULL, NULL -#else K_186, L_185, C_185 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_185, Ri_185, UINT64_C(0x6800000000000000), -#else -#if defined(MUL_M4RI) - L_185, NULL #else L_185 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_187, L_186, C_186, NULL, NULL -#else K_187, L_186, C_186 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_186, Ri_186, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_186, NULL #else L_186 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_188, L_187, C_187, NULL, NULL -#else K_188, L_187, C_187 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_187, Ri_187, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_187, NULL #else L_187 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_189, L_188, C_188, NULL, NULL -#else K_189, L_188, C_188 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_188, Ri_188, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_188, NULL #else L_188 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_190, L_189, C_189, NULL, NULL -#else K_190, L_189, C_189 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_189, Ri_189, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_189, NULL #else L_189 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_191, L_190, C_190, NULL, NULL -#else K_191, L_190, C_190 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_190, Ri_190, UINT64_C(0x6200000000000000), -#else -#if defined(MUL_M4RI) - L_190, NULL #else L_190 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_192, L_191, C_191, NULL, NULL -#else K_192, L_191, C_191 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_191, Ri_191, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_191, NULL #else L_191 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_193, L_192, C_192, NULL, NULL -#else K_193, L_192, C_192 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_192, Ri_192, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_192, NULL #else L_192 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_194, L_193, C_193, NULL, NULL -#else K_194, L_193, C_193 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_193, Ri_193, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_193, NULL #else L_193 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_195, L_194, C_194, NULL, NULL -#else K_195, L_194, C_194 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_194, Ri_194, UINT64_C(0xa200000000000000), -#else -#if defined(MUL_M4RI) - L_194, NULL #else L_194 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_196, L_195, C_195, NULL, NULL -#else K_196, L_195, C_195 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_195, Ri_195, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_195, NULL #else L_195 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_197, L_196, C_196, NULL, NULL -#else K_197, L_196, C_196 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_196, Ri_196, UINT64_C(0x9400000000000000), -#else -#if defined(MUL_M4RI) - L_196, NULL #else L_196 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_198, L_197, C_197, NULL, NULL -#else K_198, L_197, C_197 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_197, Ri_197, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_197, NULL #else L_197 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_199, L_198, C_198, NULL, NULL -#else K_199, L_198, C_198 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_198, Ri_198, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_198, NULL #else L_198 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_200, L_199, C_199, NULL, NULL -#else K_200, L_199, C_199 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_199, Ri_199, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_199, NULL #else L_199 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_201, L_200, C_200, NULL, NULL -#else K_201, L_200, C_200 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_200, Ri_200, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_200, NULL #else L_200 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_202, L_201, C_201, NULL, NULL -#else K_202, L_201, C_201 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_201, Ri_201, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_201, NULL #else L_201 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_203, L_202, C_202, NULL, NULL -#else K_203, L_202, C_202 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_202, Ri_202, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_202, NULL #else L_202 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_204, L_203, C_203, NULL, NULL -#else K_204, L_203, C_203 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_203, Ri_203, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_203, NULL #else L_203 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_205, L_204, C_204, NULL, NULL -#else K_205, L_204, C_204 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_204, Ri_204, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_204, NULL #else L_204 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_206, L_205, C_205, NULL, NULL -#else K_206, L_205, C_205 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_205, Ri_205, UINT64_C(0x5800000000000000), -#else -#if defined(MUL_M4RI) - L_205, NULL #else L_205 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_207, L_206, C_206, NULL, NULL -#else K_207, L_206, C_206 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_206, Ri_206, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_206, NULL #else L_206 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_208, L_207, C_207, NULL, NULL -#else K_208, L_207, C_207 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_207, Ri_207, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_207, NULL #else L_207 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_209, L_208, C_208, NULL, NULL -#else K_209, L_208, C_208 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_208, Ri_208, UINT64_C(0x8c00000000000000), -#else -#if defined(MUL_M4RI) - L_208, NULL #else L_208 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_210, L_209, C_209, NULL, NULL -#else K_210, L_209, C_209 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_209, Ri_209, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_209, NULL #else L_209 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_211, L_210, C_210, NULL, NULL -#else K_211, L_210, C_210 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_210, Ri_210, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_210, NULL #else L_210 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_212, L_211, C_211, NULL, NULL -#else K_212, L_211, C_211 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_211, Ri_211, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_211, NULL #else L_211 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_213, L_212, C_212, NULL, NULL -#else K_213, L_212, C_212 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_212, Ri_212, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_212, NULL #else L_212 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_214, L_213, C_213, NULL, NULL -#else K_214, L_213, C_213 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_213, Ri_213, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_213, NULL #else L_213 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_215, L_214, C_214, NULL, NULL -#else K_215, L_214, C_214 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_214, Ri_214, UINT64_C(0x4900000000000000), -#else -#if defined(MUL_M4RI) - L_214, NULL #else L_214 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_216, L_215, C_215, NULL, NULL -#else K_216, L_215, C_215 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_215, Ri_215, UINT64_C(0xc080000000000000), -#else -#if defined(MUL_M4RI) - L_215, NULL #else L_215 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_217, L_216, C_216, NULL, NULL -#else K_217, L_216, C_216 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_216, Ri_216, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_216, NULL #else L_216 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_218, L_217, C_217, NULL, NULL -#else K_218, L_217, C_217 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_217, Ri_217, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_217, NULL #else L_217 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_219, L_218, C_218, NULL, NULL -#else K_219, L_218, C_218 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_218, Ri_218, UINT64_C(0x2a00000000000000), -#else -#if defined(MUL_M4RI) - L_218, NULL #else L_218 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_220, L_219, C_219, NULL, NULL -#else K_220, L_219, C_219 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_219, Ri_219, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_219, NULL #else L_219 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_221, L_220, C_220, NULL, NULL -#else K_221, L_220, C_220 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_220, Ri_220, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_220, NULL #else L_220 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_222, L_221, C_221, NULL, NULL -#else K_222, L_221, C_221 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_221, Ri_221, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_221, NULL #else L_221 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_223, L_222, C_222, NULL, NULL -#else K_223, L_222, C_222 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_222, Ri_222, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_222, NULL #else L_222 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_224, L_223, C_223, NULL, NULL -#else K_224, L_223, C_223 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_223, Ri_223, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_223, NULL #else L_223 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_225, L_224, C_224, NULL, NULL -#else K_225, L_224, C_224 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_224, Ri_224, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_224, NULL #else L_224 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_226, L_225, C_225, NULL, NULL -#else K_226, L_225, C_225 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_225, Ri_225, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_225, NULL #else L_225 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_227, L_226, C_226, NULL, NULL -#else K_227, L_226, C_226 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_226, Ri_226, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_226, NULL #else L_226 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_228, L_227, C_227, NULL, NULL -#else K_228, L_227, C_227 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_227, Ri_227, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_227, NULL #else L_227 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_229, L_228, C_228, NULL, NULL -#else K_229, L_228, C_228 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_228, Ri_228, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_228, NULL #else L_228 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_230, L_229, C_229, NULL, NULL -#else K_230, L_229, C_229 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_229, Ri_229, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_229, NULL #else L_229 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_231, L_230, C_230, NULL, NULL -#else K_231, L_230, C_230 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_230, Ri_230, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_230, NULL #else L_230 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_232, L_231, C_231, NULL, NULL -#else K_232, L_231, C_231 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_231, Ri_231, UINT64_C(0xa200000000000000), -#else -#if defined(MUL_M4RI) - L_231, NULL #else L_231 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_233, L_232, C_232, NULL, NULL -#else K_233, L_232, C_232 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_232, Ri_232, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_232, NULL #else L_232 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_234, L_233, C_233, NULL, NULL -#else K_234, L_233, C_233 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_233, Ri_233, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_233, NULL #else L_233 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_235, L_234, C_234, NULL, NULL -#else K_235, L_234, C_234 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_234, Ri_234, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_234, NULL #else L_234 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_236, L_235, C_235, NULL, NULL -#else K_236, L_235, C_235 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_235, Ri_235, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_235, NULL #else L_235 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_237, L_236, C_236, NULL, NULL -#else K_237, L_236, C_236 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_236, Ri_236, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_236, NULL #else L_236 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_238, L_237, C_237, NULL, NULL -#else K_238, L_237, C_237 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_237, Ri_237, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_237, NULL #else L_237 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_239, L_238, C_238, NULL, NULL -#else K_239, L_238, C_238 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_238, Ri_238, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_238, NULL #else L_238 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_240, L_239, C_239, NULL, NULL -#else K_240, L_239, C_239 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_239, Ri_239, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_239, NULL #else L_239 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_241, L_240, C_240, NULL, NULL -#else K_241, L_240, C_240 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_240, Ri_240, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_240, NULL #else L_240 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_242, L_241, C_241, NULL, NULL -#else K_242, L_241, C_241 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_241, Ri_241, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_241, NULL #else L_241 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_243, L_242, C_242, NULL, NULL -#else K_243, L_242, C_242 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_242, Ri_242, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_242, NULL #else L_242 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_244, L_243, C_243, NULL, NULL -#else K_244, L_243, C_243 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_243, Ri_243, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_243, NULL #else L_243 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_245, L_244, C_244, NULL, NULL -#else K_245, L_244, C_244 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_244, Ri_244, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_244, NULL #else L_244 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_246, L_245, C_245, NULL, NULL -#else K_246, L_245, C_245 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_245, Ri_245, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_245, NULL #else L_245 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_247, L_246, C_246, NULL, NULL -#else K_247, L_246, C_246 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_246, Ri_246, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_246, NULL #else L_246 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_248, L_247, C_247, NULL, NULL -#else K_248, L_247, C_247 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_247, Ri_247, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_247, NULL #else L_247 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_249, L_248, C_248, NULL, NULL -#else K_249, L_248, C_248 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_248, Ri_248, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_248, NULL #else L_248 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_250, L_249, C_249, NULL, NULL -#else K_250, L_249, C_249 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_249, Ri_249, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_249, NULL #else L_249 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_251, L_250, C_250, NULL, NULL -#else K_251, L_250, C_250 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_250, Ri_250, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_250, NULL #else L_250 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_252, L_251, C_251, NULL, NULL -#else K_252, L_251, C_251 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_251, Ri_251, UINT64_C(0x9200000000000000), -#else -#if defined(MUL_M4RI) - L_251, NULL #else L_251 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_253, L_252, C_252, NULL, NULL -#else K_253, L_252, C_252 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_252, Ri_252, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_252, NULL #else L_252 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_254, L_253, C_253, NULL, NULL -#else K_254, L_253, C_253 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_253, Ri_253, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_253, NULL #else L_253 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_255, L_254, C_254, NULL, NULL -#else K_255, L_254, C_254 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_254, Ri_254, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_254, NULL #else L_254 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_256, L_255, C_255, NULL, NULL -#else K_256, L_255, C_255 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_255, Ri_255, UINT64_C(0x5200000000000000), -#else -#if defined(MUL_M4RI) - L_255, NULL #else L_255 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_257, L_256, C_256, NULL, NULL -#else K_257, L_256, C_256 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_256, Ri_256, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_256, NULL #else L_256 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_258, L_257, C_257, NULL, NULL -#else K_258, L_257, C_257 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_257, Ri_257, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_257, NULL #else L_257 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_259, L_258, C_258, NULL, NULL -#else K_259, L_258, C_258 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_258, Ri_258, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_258, NULL #else L_258 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_260, L_259, C_259, NULL, NULL -#else K_260, L_259, C_259 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_259, Ri_259, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_259, NULL #else L_259 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_261, L_260, C_260, NULL, NULL -#else K_261, L_260, C_260 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_260, Ri_260, UINT64_C(0x5200000000000000), -#else -#if defined(MUL_M4RI) - L_260, NULL #else L_260 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_262, L_261, C_261, NULL, NULL -#else K_262, L_261, C_261 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_261, Ri_261, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_261, NULL #else L_261 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_263, L_262, C_262, NULL, NULL -#else K_263, L_262, C_262 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_262, Ri_262, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_262, NULL #else L_262 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_264, L_263, C_263, NULL, NULL -#else K_264, L_263, C_263 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_263, Ri_263, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_263, NULL #else L_263 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_265, L_264, C_264, NULL, NULL -#else K_265, L_264, C_264 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_264, Ri_264, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_264, NULL #else L_264 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_266, L_265, C_265, NULL, NULL -#else K_266, L_265, C_265 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_265, Ri_265, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_265, NULL #else L_265 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_267, L_266, C_266, NULL, NULL -#else K_267, L_266, C_266 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_266, Ri_266, UINT64_C(0xa100000000000000), -#else -#if defined(MUL_M4RI) - L_266, NULL #else L_266 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_268, L_267, C_267, NULL, NULL -#else K_268, L_267, C_267 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_267, Ri_267, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_267, NULL #else L_267 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_269, L_268, C_268, NULL, NULL -#else K_269, L_268, C_268 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_268, Ri_268, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_268, NULL #else L_268 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_270, L_269, C_269, NULL, NULL -#else K_270, L_269, C_269 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_269, Ri_269, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_269, NULL #else L_269 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_271, L_270, C_270, NULL, NULL -#else K_271, L_270, C_270 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_270, Ri_270, UINT64_C(0x6400000000000000), -#else -#if defined(MUL_M4RI) - L_270, NULL #else L_270 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_272, L_271, C_271, NULL, NULL -#else K_272, L_271, C_271 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_271, Ri_271, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_271, NULL #else L_271 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_273, L_272, C_272, NULL, NULL -#else K_273, L_272, C_272 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_272, Ri_272, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_272, NULL #else L_272 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_274, L_273, C_273, NULL, NULL -#else K_274, L_273, C_273 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_273, Ri_273, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_273, NULL #else L_273 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_275, L_274, C_274, NULL, NULL -#else K_275, L_274, C_274 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_274, Ri_274, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_274, NULL #else L_274 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_276, L_275, C_275, NULL, NULL -#else K_276, L_275, C_275 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_275, Ri_275, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_275, NULL #else L_275 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_277, L_276, C_276, NULL, NULL -#else K_277, L_276, C_276 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_276, Ri_276, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_276, NULL #else L_276 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_278, L_277, C_277, NULL, NULL -#else K_278, L_277, C_277 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_277, Ri_277, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_277, NULL #else L_277 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_279, L_278, C_278, NULL, NULL -#else K_279, L_278, C_278 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_278, Ri_278, UINT64_C(0x4c00000000000000), -#else -#if defined(MUL_M4RI) - L_278, NULL #else L_278 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_280, L_279, C_279, NULL, NULL -#else K_280, L_279, C_279 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_279, Ri_279, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_279, NULL #else L_279 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_281, L_280, C_280, NULL, NULL -#else K_281, L_280, C_280 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_280, Ri_280, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_280, NULL #else L_280 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_282, L_281, C_281, NULL, NULL -#else K_282, L_281, C_281 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_281, Ri_281, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_281, NULL #else L_281 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_283, L_282, C_282, NULL, NULL -#else K_283, L_282, C_282 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_282, Ri_282, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_282, NULL #else L_282 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_284, L_283, C_283, NULL, NULL -#else K_284, L_283, C_283 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_283, Ri_283, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_283, NULL #else L_283 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_285, L_284, C_284, NULL, NULL -#else K_285, L_284, C_284 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_284, Ri_284, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_284, NULL #else L_284 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_286, L_285, C_285, NULL, NULL -#else K_286, L_285, C_285 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_285, Ri_285, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_285, NULL #else L_285 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_287, L_286, C_286, NULL, NULL -#else K_287, L_286, C_286 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_286, Ri_286, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_286, NULL #else L_286 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_288, L_287, C_287, NULL, NULL -#else K_288, L_287, C_287 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_287, Ri_287, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_287, NULL #else L_287 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_289, L_288, C_288, NULL, NULL -#else K_289, L_288, C_288 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_288, Ri_288, UINT64_C(0x5800000000000000), -#else -#if defined(MUL_M4RI) - L_288, NULL #else L_288 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_290, L_289, C_289, NULL, NULL -#else K_290, L_289, C_289 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_289, Ri_289, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_289, NULL #else L_289 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_291, L_290, C_290, NULL, NULL -#else K_291, L_290, C_290 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_290, Ri_290, UINT64_C(0x6200000000000000), -#else -#if defined(MUL_M4RI) - L_290, NULL #else L_290 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_292, L_291, C_291, NULL, NULL -#else K_292, L_291, C_291 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_291, Ri_291, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_291, NULL #else L_291 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_293, L_292, C_292, NULL, NULL -#else K_293, L_292, C_292 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_292, Ri_292, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_292, NULL #else L_292 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_294, L_293, C_293, NULL, NULL -#else K_294, L_293, C_293 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_293, Ri_293, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_293, NULL #else L_293 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_295, L_294, C_294, NULL, NULL -#else K_295, L_294, C_294 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_294, Ri_294, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_294, NULL #else L_294 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_296, L_295, C_295, NULL, NULL -#else K_296, L_295, C_295 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_295, Ri_295, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_295, NULL #else L_295 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_297, L_296, C_296, NULL, NULL -#else K_297, L_296, C_296 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_296, Ri_296, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_296, NULL #else L_296 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_298, L_297, C_297, NULL, NULL -#else K_298, L_297, C_297 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_297, Ri_297, UINT64_C(0x6800000000000000), -#else -#if defined(MUL_M4RI) - L_297, NULL #else L_297 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_299, L_298, C_298, NULL, NULL -#else K_299, L_298, C_298 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_298, Ri_298, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_298, NULL #else L_298 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_300, L_299, C_299, NULL, NULL -#else K_300, L_299, C_299 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_299, Ri_299, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_299, NULL #else L_299 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_301, L_300, C_300, NULL, NULL -#else K_301, L_300, C_300 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_300, Ri_300, UINT64_C(0x4a00000000000000), -#else -#if defined(MUL_M4RI) - L_300, NULL #else L_300 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_302, L_301, C_301, NULL, NULL -#else K_302, L_301, C_301 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_301, Ri_301, UINT64_C(0x5200000000000000), -#else -#if defined(MUL_M4RI) - L_301, NULL #else L_301 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_303, L_302, C_302, NULL, NULL -#else K_303, L_302, C_302 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_302, Ri_302, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_302, NULL #else L_302 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_304, L_303, C_303, NULL, NULL -#else K_304, L_303, C_303 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_303, Ri_303, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_303, NULL #else L_303 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_305, L_304, C_304, NULL, NULL -#else K_305, L_304, C_304 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_304, Ri_304, UINT64_C(0xa100000000000000), -#else -#if defined(MUL_M4RI) - L_304, NULL #else L_304 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_306, L_305, C_305, NULL, NULL -#else K_306, L_305, C_305 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_305, Ri_305, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_305, NULL #else L_305 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_307, L_306, C_306, NULL, NULL -#else K_307, L_306, C_306 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_306, Ri_306, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_306, NULL #else L_306 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_308, L_307, C_307, NULL, NULL -#else K_308, L_307, C_307 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_307, Ri_307, UINT64_C(0xc040000000000000), -#else -#if defined(MUL_M4RI) - L_307, NULL #else L_307 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_309, L_308, C_308, NULL, NULL -#else K_309, L_308, C_308 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_308, Ri_308, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_308, NULL #else L_308 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_310, L_309, C_309, NULL, NULL -#else K_310, L_309, C_309 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_309, Ri_309, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_309, NULL #else L_309 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_311, L_310, C_310, NULL, NULL -#else K_311, L_310, C_310 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_310, Ri_310, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_310, NULL #else L_310 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_312, L_311, C_311, NULL, NULL -#else K_312, L_311, C_311 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_311, Ri_311, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_311, NULL #else L_311 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_313, L_312, C_312, NULL, NULL -#else K_313, L_312, C_312 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_312, Ri_312, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_312, NULL #else L_312 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_314, L_313, C_313, NULL, NULL -#else K_314, L_313, C_313 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_313, Ri_313, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_313, NULL #else L_313 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_315, L_314, C_314, NULL, NULL -#else K_315, L_314, C_314 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_314, Ri_314, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_314, NULL #else L_314 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_316, L_315, C_315, NULL, NULL -#else K_316, L_315, C_315 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_315, Ri_315, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_315, NULL #else L_315 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_317, L_316, C_316, NULL, NULL -#else K_317, L_316, C_316 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_316, Ri_316, UINT64_C(0xa400000000000000), -#else -#if defined(MUL_M4RI) - L_316, NULL #else L_316 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_318, L_317, C_317, NULL, NULL -#else K_318, L_317, C_317 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_317, Ri_317, UINT64_C(0x9100000000000000), -#else -#if defined(MUL_M4RI) - L_317, NULL #else L_317 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_319, L_318, C_318, NULL, NULL -#else K_319, L_318, C_318 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_318, Ri_318, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_318, NULL #else L_318 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_320, L_319, C_319, NULL, NULL -#else K_320, L_319, C_319 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_319, Ri_319, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_319, NULL #else L_319 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_321, L_320, C_320, NULL, NULL -#else K_321, L_320, C_320 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_320, Ri_320, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_320, NULL #else L_320 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_322, L_321, C_321, NULL, NULL -#else K_322, L_321, C_321 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_321, Ri_321, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_321, NULL #else L_321 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_323, L_322, C_322, NULL, NULL -#else K_323, L_322, C_322 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_322, Ri_322, UINT64_C(0x9800000000000000), -#else -#if defined(MUL_M4RI) - L_322, NULL #else L_322 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_324, L_323, C_323, NULL, NULL -#else K_324, L_323, C_323 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_323, Ri_323, UINT64_C(0xc400000000000000), -#else -#if defined(MUL_M4RI) - L_323, NULL #else L_323 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_325, L_324, C_324, NULL, NULL -#else K_325, L_324, C_324 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_324, Ri_324, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_324, NULL #else L_324 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_326, L_325, C_325, NULL, NULL -#else K_326, L_325, C_325 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_325, Ri_325, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_325, NULL #else L_325 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_327, L_326, C_326, NULL, NULL -#else K_327, L_326, C_326 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_326, Ri_326, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_326, NULL #else L_326 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_328, L_327, C_327, NULL, NULL -#else K_328, L_327, C_327 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_327, Ri_327, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_327, NULL #else L_327 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_329, L_328, C_328, NULL, NULL -#else K_329, L_328, C_328 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_328, Ri_328, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_328, NULL #else L_328 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_330, L_329, C_329, NULL, NULL -#else K_330, L_329, C_329 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_329, Ri_329, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_329, NULL #else L_329 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_331, L_330, C_330, NULL, NULL -#else K_331, L_330, C_330 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_330, Ri_330, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_330, NULL #else L_330 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_332, L_331, C_331, NULL, NULL -#else K_332, L_331, C_331 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_331, Ri_331, UINT64_C(0x7000000000000000), -#else -#if defined(MUL_M4RI) - L_331, NULL #else L_331 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_333, L_332, C_332, NULL, NULL -#else K_333, L_332, C_332 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_332, Ri_332, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_332, NULL #else L_332 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_334, L_333, C_333, NULL, NULL -#else K_334, L_333, C_333 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_333, Ri_333, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_333, NULL #else L_333 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_335, L_334, C_334, NULL, NULL -#else K_335, L_334, C_334 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_334, Ri_334, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_334, NULL #else L_334 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_336, L_335, C_335, NULL, NULL -#else K_336, L_335, C_335 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_335, Ri_335, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_335, NULL #else L_335 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_337, L_336, C_336, NULL, NULL -#else K_337, L_336, C_336 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_336, Ri_336, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_336, NULL #else L_336 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_338, L_337, C_337, NULL, NULL -#else K_338, L_337, C_337 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_337, Ri_337, UINT64_C(0x5200000000000000), -#else -#if defined(MUL_M4RI) - L_337, NULL #else L_337 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_339, L_338, C_338, NULL, NULL -#else K_339, L_338, C_338 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_338, Ri_338, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_338, NULL #else L_338 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_340, L_339, C_339, NULL, NULL -#else K_340, L_339, C_339 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_339, Ri_339, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_339, NULL #else L_339 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_341, L_340, C_340, NULL, NULL -#else K_341, L_340, C_340 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_340, Ri_340, UINT64_C(0x5800000000000000), -#else -#if defined(MUL_M4RI) - L_340, NULL #else L_340 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_342, L_341, C_341, NULL, NULL -#else K_342, L_341, C_341 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_341, Ri_341, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_341, NULL #else L_341 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_343, L_342, C_342, NULL, NULL -#else K_343, L_342, C_342 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_342, Ri_342, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_342, NULL #else L_342 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_344, L_343, C_343, NULL, NULL -#else K_344, L_343, C_343 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_343, Ri_343, UINT64_C(0x4a00000000000000), -#else -#if defined(MUL_M4RI) - L_343, NULL #else L_343 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_345, L_344, C_344, NULL, NULL -#else K_345, L_344, C_344 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_344, Ri_344, UINT64_C(0xc800000000000000), -#else -#if defined(MUL_M4RI) - L_344, NULL #else L_344 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_346, L_345, C_345, NULL, NULL -#else K_346, L_345, C_345 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_345, Ri_345, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_345, NULL #else L_345 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_347, L_346, C_346, NULL, NULL -#else K_347, L_346, C_346 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_346, Ri_346, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_346, NULL #else L_346 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_348, L_347, C_347, NULL, NULL -#else K_348, L_347, C_347 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_347, Ri_347, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_347, NULL #else L_347 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_349, L_348, C_348, NULL, NULL -#else K_349, L_348, C_348 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_348, Ri_348, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_348, NULL #else L_348 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_350, L_349, C_349, NULL, NULL -#else K_350, L_349, C_349 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_349, Ri_349, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_349, NULL #else L_349 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_351, L_350, C_350, NULL, NULL -#else K_351, L_350, C_350 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_350, Ri_350, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_350, NULL #else L_350 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_352, L_351, C_351, NULL, NULL -#else K_352, L_351, C_351 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_351, Ri_351, UINT64_C(0xc200000000000000), -#else -#if defined(MUL_M4RI) - L_351, NULL #else L_351 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_353, L_352, C_352, NULL, NULL -#else K_353, L_352, C_352 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_352, Ri_352, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_352, NULL #else L_352 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_354, L_353, C_353, NULL, NULL -#else K_354, L_353, C_353 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_353, Ri_353, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_353, NULL #else L_353 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_355, L_354, C_354, NULL, NULL -#else K_355, L_354, C_354 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_354, Ri_354, UINT64_C(0xd000000000000000), -#else -#if defined(MUL_M4RI) - L_354, NULL #else L_354 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_356, L_355, C_355, NULL, NULL -#else K_356, L_355, C_355 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_355, Ri_355, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_355, NULL #else L_355 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_357, L_356, C_356, NULL, NULL -#else K_357, L_356, C_356 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_356, Ri_356, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_356, NULL #else L_356 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_358, L_357, C_357, NULL, NULL -#else K_358, L_357, C_357 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_357, Ri_357, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_357, NULL #else L_357 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_359, L_358, C_358, NULL, NULL -#else K_359, L_358, C_358 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_358, Ri_358, UINT64_C(0xb000000000000000), -#else -#if defined(MUL_M4RI) - L_358, NULL #else L_358 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_360, L_359, C_359, NULL, NULL -#else K_360, L_359, C_359 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_359, Ri_359, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_359, NULL #else L_359 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_361, L_360, C_360, NULL, NULL -#else K_361, L_360, C_360 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_360, Ri_360, UINT64_C(0xe000000000000000), -#else -#if defined(MUL_M4RI) - L_360, NULL #else L_360 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_362, L_361, C_361, NULL, NULL -#else K_362, L_361, C_361 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_361, Ri_361, UINT64_C(0xa800000000000000), -#else -#if defined(MUL_M4RI) - L_361, NULL #else L_361 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_363, L_362, C_362, NULL, NULL -#else K_363, L_362, C_362 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) NULL, NULL, 0, -#else -#if defined(MUL_M4RI) - L_362, NULL #else L_362 #endif -#endif #endif }, }; -#if defined(MUL_M4RI) -lowmc_t lowmc_256_256_363 = { -#else const lowmc_t lowmc_256_256_363 = { -#endif 1, 256, 363, 256, #if defined(REDUCED_ROUND_KEY_COMPUTATION) precomputed_round_key_matrix_linear_part, @@ -201441,16 +198529,10 @@ const lowmc_t lowmc_256_256_363 = { #endif #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Z_r, -#endif -#if defined(MUL_M4RI) - NULL, #endif rounds, #if defined(REDUCED_ROUND_KEY_COMPUTATION) precomputed_round_key_matrix_non_linear_part, -#if defined(MUL_M4RI) - NULL, -#endif precomputed_constant_linear_part, precomputed_constant_non_linear_part, #endif diff --git a/src/sig/picnic/external/lowmc_256_256_363.h b/src/sig/picnic/external/lowmc_256_256_363.h index e41e9d99b..f3d17e34a 100644 --- a/src/sig/picnic/external/lowmc_256_256_363.h +++ b/src/sig/picnic/external/lowmc_256_256_363.h @@ -3,10 +3,6 @@ #include "lowmc_pars.h" -#if !defined(MUL_M4RI) extern const lowmc_t lowmc_256_256_363; -#else -extern lowmc_t lowmc_256_256_363; -#endif #endif diff --git a/src/sig/picnic/external/lowmc_256_256_38.c b/src/sig/picnic/external/lowmc_256_256_38.c index 8f012fed7..c08db105c 100644 --- a/src/sig/picnic/external/lowmc_256_256_38.c +++ b/src/sig/picnic/external/lowmc_256_256_38.c @@ -23296,741 +23296,429 @@ static const block_t Ri_36[] = { #endif -#if defined(MUL_M4RI) -static lowmc_round_t rounds[38] = { -#else static const lowmc_round_t rounds[38] = { -#endif { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_1, L_0, C_0, NULL, NULL -#else K_1, L_0, C_0 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_0, Ri_0, UINT64_C(0xffffffee00000000), -#else -#if defined(MUL_M4RI) - L_0, NULL #else L_0 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_2, L_1, C_1, NULL, NULL -#else K_2, L_1, C_1 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_1, Ri_1, UINT64_C(0xffffffdc40000000), -#else -#if defined(MUL_M4RI) - L_1, NULL #else L_1 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_3, L_2, C_2, NULL, NULL -#else K_3, L_2, C_2 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_2, Ri_2, UINT64_C(0xfffffff880000000), -#else -#if defined(MUL_M4RI) - L_2, NULL #else L_2 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_4, L_3, C_3, NULL, NULL -#else K_4, L_3, C_3 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_3, Ri_3, UINT64_C(0xffffffee00000000), -#else -#if defined(MUL_M4RI) - L_3, NULL #else L_3 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_5, L_4, C_4, NULL, NULL -#else K_5, L_4, C_4 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_4, Ri_4, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_4, NULL #else L_4 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_6, L_5, C_5, NULL, NULL -#else K_6, L_5, C_5 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_5, Ri_5, UINT64_C(0xffffffe980000000), -#else -#if defined(MUL_M4RI) - L_5, NULL #else L_5 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_7, L_6, C_6, NULL, NULL -#else K_7, L_6, C_6 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_6, Ri_6, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_6, NULL #else L_6 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_8, L_7, C_7, NULL, NULL -#else K_8, L_7, C_7 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_7, Ri_7, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_7, NULL #else L_7 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_9, L_8, C_8, NULL, NULL -#else K_9, L_8, C_8 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_8, Ri_8, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_8, NULL #else L_8 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_10, L_9, C_9, NULL, NULL -#else K_10, L_9, C_9 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_9, Ri_9, UINT64_C(0xfffffffa00000000), -#else -#if defined(MUL_M4RI) - L_9, NULL #else L_9 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_11, L_10, C_10, NULL, NULL -#else K_11, L_10, C_10 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_10, Ri_10, UINT64_C(0xffffffb700000000), -#else -#if defined(MUL_M4RI) - L_10, NULL #else L_10 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_12, L_11, C_11, NULL, NULL -#else K_12, L_11, C_11 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_11, Ri_11, UINT64_C(0xffffffd508000000), -#else -#if defined(MUL_M4RI) - L_11, NULL #else L_11 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_13, L_12, C_12, NULL, NULL -#else K_13, L_12, C_12 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_12, Ri_12, UINT64_C(0xfffffff900000000), -#else -#if defined(MUL_M4RI) - L_12, NULL #else L_12 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_14, L_13, C_13, NULL, NULL -#else K_14, L_13, C_13 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_13, Ri_13, UINT64_C(0xfffffffa00000000), -#else -#if defined(MUL_M4RI) - L_13, NULL #else L_13 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_15, L_14, C_14, NULL, NULL -#else K_15, L_14, C_14 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_14, Ri_14, UINT64_C(0xfffffff900000000), -#else -#if defined(MUL_M4RI) - L_14, NULL #else L_14 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_16, L_15, C_15, NULL, NULL -#else K_16, L_15, C_15 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_15, Ri_15, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_15, NULL #else L_15 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_17, L_16, C_16, NULL, NULL -#else K_17, L_16, C_16 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_16, Ri_16, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_16, NULL #else L_16 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_18, L_17, C_17, NULL, NULL -#else K_18, L_17, C_17 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_17, Ri_17, UINT64_C(0xffffffde00000000), -#else -#if defined(MUL_M4RI) - L_17, NULL #else L_17 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_19, L_18, C_18, NULL, NULL -#else K_19, L_18, C_18 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_18, Ri_18, UINT64_C(0xfffffff900000000), -#else -#if defined(MUL_M4RI) - L_18, NULL #else L_18 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_20, L_19, C_19, NULL, NULL -#else K_20, L_19, C_19 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_19, Ri_19, UINT64_C(0xfffffff300000000), -#else -#if defined(MUL_M4RI) - L_19, NULL #else L_19 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_21, L_20, C_20, NULL, NULL -#else K_21, L_20, C_20 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_20, Ri_20, UINT64_C(0xffffffed00000000), -#else -#if defined(MUL_M4RI) - L_20, NULL #else L_20 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_22, L_21, C_21, NULL, NULL -#else K_22, L_21, C_21 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_21, Ri_21, UINT64_C(0xfffffff300000000), -#else -#if defined(MUL_M4RI) - L_21, NULL #else L_21 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_23, L_22, C_22, NULL, NULL -#else K_23, L_22, C_22 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_22, Ri_22, UINT64_C(0xfffffffa00000000), -#else -#if defined(MUL_M4RI) - L_22, NULL #else L_22 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_24, L_23, C_23, NULL, NULL -#else K_24, L_23, C_23 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_23, Ri_23, UINT64_C(0xffffffec20000000), -#else -#if defined(MUL_M4RI) - L_23, NULL #else L_23 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_25, L_24, C_24, NULL, NULL -#else K_25, L_24, C_24 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_24, Ri_24, UINT64_C(0xfffffff900000000), -#else -#if defined(MUL_M4RI) - L_24, NULL #else L_24 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_26, L_25, C_25, NULL, NULL -#else K_26, L_25, C_25 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_25, Ri_25, UINT64_C(0xfffffff880000000), -#else -#if defined(MUL_M4RI) - L_25, NULL #else L_25 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_27, L_26, C_26, NULL, NULL -#else K_27, L_26, C_26 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_26, Ri_26, UINT64_C(0xfffffff600000000), -#else -#if defined(MUL_M4RI) - L_26, NULL #else L_26 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_28, L_27, C_27, NULL, NULL -#else K_28, L_27, C_27 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_27, Ri_27, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_27, NULL #else L_27 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_29, L_28, C_28, NULL, NULL -#else K_29, L_28, C_28 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_28, Ri_28, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_28, NULL #else L_28 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_30, L_29, C_29, NULL, NULL -#else K_30, L_29, C_29 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_29, Ri_29, UINT64_C(0xffffff7700000000), -#else -#if defined(MUL_M4RI) - L_29, NULL #else L_29 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_31, L_30, C_30, NULL, NULL -#else K_31, L_30, C_30 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_30, Ri_30, UINT64_C(0xfffffff600000000), -#else -#if defined(MUL_M4RI) - L_30, NULL #else L_30 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_32, L_31, C_31, NULL, NULL -#else K_32, L_31, C_31 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_31, Ri_31, UINT64_C(0xffffffbc40000000), -#else -#if defined(MUL_M4RI) - L_31, NULL #else L_31 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_33, L_32, C_32, NULL, NULL -#else K_33, L_32, C_32 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_32, Ri_32, UINT64_C(0xfffffffa00000000), -#else -#if defined(MUL_M4RI) - L_32, NULL #else L_32 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_34, L_33, C_33, NULL, NULL -#else K_34, L_33, C_33 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_33, Ri_33, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_33, NULL #else L_33 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_35, L_34, C_34, NULL, NULL -#else K_35, L_34, C_34 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_34, Ri_34, UINT64_C(0xfffffff600000000), -#else -#if defined(MUL_M4RI) - L_34, NULL #else L_34 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_36, L_35, C_35, NULL, NULL -#else K_36, L_35, C_35 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_35, Ri_35, UINT64_C(0xfffffffc00000000), -#else -#if defined(MUL_M4RI) - L_35, NULL #else L_35 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_37, L_36, C_36, NULL, NULL -#else K_37, L_36, C_36 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Zi_36, Ri_36, UINT64_C(0xffffffe700000000), -#else -#if defined(MUL_M4RI) - L_36, NULL #else L_36 #endif -#endif #endif }, { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) -#if defined(MUL_M4RI) - K_38, L_37, C_37, NULL, NULL -#else K_38, L_37, C_37 -#endif #else #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) NULL, NULL, 0, -#else -#if defined(MUL_M4RI) - L_37, NULL #else L_37 #endif -#endif #endif }, }; -#if defined(MUL_M4RI) -lowmc_t lowmc_256_256_38 = { -#else const lowmc_t lowmc_256_256_38 = { -#endif 10, 256, 38, 256, #if defined(REDUCED_ROUND_KEY_COMPUTATION) precomputed_round_key_matrix_linear_part, @@ -24039,16 +23727,10 @@ const lowmc_t lowmc_256_256_38 = { #endif #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) Z_r, -#endif -#if defined(MUL_M4RI) - NULL, #endif rounds, #if defined(REDUCED_ROUND_KEY_COMPUTATION) precomputed_round_key_matrix_non_linear_part, -#if defined(MUL_M4RI) - NULL, -#endif precomputed_constant_linear_part, precomputed_constant_non_linear_part, #endif diff --git a/src/sig/picnic/external/lowmc_256_256_38.h b/src/sig/picnic/external/lowmc_256_256_38.h index eeda15b87..12ea03284 100644 --- a/src/sig/picnic/external/lowmc_256_256_38.h +++ b/src/sig/picnic/external/lowmc_256_256_38.h @@ -3,10 +3,6 @@ #include "lowmc_pars.h" -#if !defined(MUL_M4RI) extern const lowmc_t lowmc_256_256_38; -#else -extern lowmc_t lowmc_256_256_38; -#endif #endif diff --git a/src/sig/picnic/external/lowmc_fns_s128_L1.h b/src/sig/picnic/external/lowmc_fns_s128_L1.h index 0cf0971f9..51de6be8f 100644 --- a/src/sig/picnic/external/lowmc_fns_s128_L1.h +++ b/src/sig/picnic/external/lowmc_fns_s128_L1.h @@ -9,14 +9,14 @@ #include "lowmc_fns_undef.h" -#define ADDMUL SELECT_V_VL(mzd_addmul_v_s128_128, mzd_addmul_vl_s128_128) -#define MUL SELECT_V_VL(mzd_mul_v_s128_128, mzd_mul_vl_s128_128) +#define ADDMUL mzd_addmul_v_s128_128 +#define MUL mzd_mul_v_s128_128 #define SHUFFLE mzd_shuffle_128 #define XOR mzd_xor_s128_128 #define COPY mzd_copy_s128_128 -#define MUL_MC_1 SELECT_V_VL(mzd_mul_v_s128_128_640, mzd_mul_vl_s128_128_640) -#define MUL_MC_10 SELECT_V_VL(mzd_mul_v_s128_128_640, mzd_mul_vl_s128_128_640) +#define MUL_MC_1 mzd_mul_v_s128_128_640 +#define MUL_MC_10 mzd_mul_v_s128_128_640 #define ADDMUL_R_1 mzd_addmul_v_s128_3_128 #define ADDMUL_R_10 mzd_addmul_v_s128_30_128 #define MUL_Z_1 mzd_mul_v_parity_uint64_128_3 diff --git a/src/sig/picnic/external/lowmc_fns_s128_L3.h b/src/sig/picnic/external/lowmc_fns_s128_L3.h index 4109453b1..72c4dc50c 100644 --- a/src/sig/picnic/external/lowmc_fns_s128_L3.h +++ b/src/sig/picnic/external/lowmc_fns_s128_L3.h @@ -9,14 +9,14 @@ #include "lowmc_fns_undef.h" -#define ADDMUL SELECT_V_VL(mzd_addmul_v_s128_192, mzd_addmul_vl_s128_192) -#define MUL SELECT_V_VL(mzd_mul_v_s128_192, mzd_mul_vl_s128_192) +#define ADDMUL mzd_addmul_v_s128_192 +#define MUL mzd_mul_v_s128_192 #define SHUFFLE mzd_shuffle_192 #define XOR mzd_xor_s128_256 #define COPY mzd_copy_s128_256 -#define MUL_MC_1 SELECT_V_VL(mzd_mul_v_s128_192_896, mzd_mul_vl_s128_192_896) -#define MUL_MC_10 SELECT_V_VL(mzd_mul_v_s128_192_1024, mzd_mul_vl_s128_192_1024) +#define MUL_MC_1 mzd_mul_v_s128_192_896 +#define MUL_MC_10 mzd_mul_v_s128_192_1024 #define ADDMUL_R_1 mzd_addmul_v_s128_3_192 #define ADDMUL_R_10 mzd_addmul_v_s128_30_192 #define MUL_Z_1 mzd_mul_v_parity_uint64_192_3 diff --git a/src/sig/picnic/external/lowmc_fns_s128_L5.h b/src/sig/picnic/external/lowmc_fns_s128_L5.h index 43b74cd5c..1f74318bd 100644 --- a/src/sig/picnic/external/lowmc_fns_s128_L5.h +++ b/src/sig/picnic/external/lowmc_fns_s128_L5.h @@ -9,14 +9,14 @@ #include "lowmc_fns_undef.h" -#define ADDMUL SELECT_V_VL(mzd_addmul_v_s128_256, mzd_addmul_vl_s128_256) -#define MUL SELECT_V_VL(mzd_mul_v_s128_256, mzd_mul_vl_s128_256) +#define ADDMUL mzd_addmul_v_s128_256 +#define MUL mzd_mul_v_s128_256 #define SHUFFLE mzd_shuffle_256 #define XOR mzd_xor_s128_256 #define COPY mzd_copy_s128_256 -#define MUL_MC_1 SELECT_V_VL(mzd_mul_v_s128_256_1152, mzd_mul_vl_s128_256_1152) -#define MUL_MC_10 SELECT_V_VL(mzd_mul_v_s128_256_1280, mzd_mul_vl_s128_256_1280) +#define MUL_MC_1 mzd_mul_v_s128_256_1152 +#define MUL_MC_10 mzd_mul_v_s128_256_1280 #define ADDMUL_R_1 mzd_addmul_v_s128_3_256 #define ADDMUL_R_10 mzd_addmul_v_s128_30_256 #define MUL_Z_1 mzd_mul_v_parity_uint64_256_3 diff --git a/src/sig/picnic/external/lowmc_fns_s256_L1.h b/src/sig/picnic/external/lowmc_fns_s256_L1.h index a640c7901..02c59677d 100644 --- a/src/sig/picnic/external/lowmc_fns_s256_L1.h +++ b/src/sig/picnic/external/lowmc_fns_s256_L1.h @@ -9,14 +9,14 @@ #include "lowmc_fns_undef.h" -#define ADDMUL SELECT_V_VL(mzd_addmul_v_s256_128, mzd_addmul_vl_s256_128) -#define MUL SELECT_V_VL(mzd_mul_v_s256_128, mzd_mul_vl_s256_128) +#define ADDMUL mzd_addmul_v_s256_128 +#define MUL mzd_mul_v_s256_128 #define SHUFFLE mzd_shuffle_pext_128 #define XOR mzd_xor_s256_128 #define COPY mzd_copy_s256_128 -#define MUL_MC_1 SELECT_V_VL(mzd_mul_v_s256_128_768, mzd_mul_vl_s256_128_768) -#define MUL_MC_10 SELECT_V_VL(mzd_mul_v_s256_128_768, mzd_mul_vl_s256_128_768) +#define MUL_MC_1 mzd_mul_v_s256_128_768 +#define MUL_MC_10 mzd_mul_v_s256_128_768 #define ADDMUL_R_1 mzd_addmul_v_s256_3_128 #define ADDMUL_R_10 mzd_addmul_v_s256_30_128 #define MUL_Z_1 mzd_mul_v_parity_uint64_128_3 diff --git a/src/sig/picnic/external/lowmc_fns_s256_L3.h b/src/sig/picnic/external/lowmc_fns_s256_L3.h index e6655f600..d7123dc35 100644 --- a/src/sig/picnic/external/lowmc_fns_s256_L3.h +++ b/src/sig/picnic/external/lowmc_fns_s256_L3.h @@ -9,14 +9,14 @@ #include "lowmc_fns_undef.h" -#define ADDMUL SELECT_V_VL(mzd_addmul_v_s256_192, mzd_addmul_vl_s256_192) -#define MUL SELECT_V_VL(mzd_mul_v_s256_192, mzd_mul_vl_s256_192) +#define ADDMUL mzd_addmul_v_s256_192 +#define MUL mzd_mul_v_s256_192 #define SHUFFLE mzd_shuffle_pext_192 #define XOR mzd_xor_s256_256 #define COPY mzd_copy_s256_256 -#define MUL_MC_1 SELECT_V_VL(mzd_mul_v_s256_192_1024, mzd_mul_vl_s256_192_1024) -#define MUL_MC_10 SELECT_V_VL(mzd_mul_v_s256_192_1024, mzd_mul_vl_s256_192_1024) +#define MUL_MC_1 mzd_mul_v_s256_192_1024 +#define MUL_MC_10 mzd_mul_v_s256_192_1024 #define ADDMUL_R_1 mzd_addmul_v_s256_3_192 #define ADDMUL_R_10 mzd_addmul_v_s256_30_192 #define MUL_Z_1 mzd_mul_v_parity_uint64_192_3 diff --git a/src/sig/picnic/external/lowmc_fns_s256_L5.h b/src/sig/picnic/external/lowmc_fns_s256_L5.h index c685bf15e..eedb83ff1 100644 --- a/src/sig/picnic/external/lowmc_fns_s256_L5.h +++ b/src/sig/picnic/external/lowmc_fns_s256_L5.h @@ -9,14 +9,14 @@ #include "lowmc_fns_undef.h" -#define ADDMUL SELECT_V_VL(mzd_addmul_v_s256_256, mzd_addmul_vl_s256_256) -#define MUL SELECT_V_VL(mzd_mul_v_s256_256, mzd_mul_vl_s256_256) +#define ADDMUL mzd_addmul_v_s256_256 +#define MUL mzd_mul_v_s256_256 #define SHUFFLE mzd_shuffle_pext_256 #define XOR mzd_xor_s256_256 #define COPY mzd_copy_s256_256 -#define MUL_MC_1 SELECT_V_VL(mzd_mul_v_s256_256_1280, mzd_mul_vl_s256_256_1280) -#define MUL_MC_10 SELECT_V_VL(mzd_mul_v_s256_256_1280, mzd_mul_vl_s256_256_1280) +#define MUL_MC_1 mzd_mul_v_s256_256_1280 +#define MUL_MC_10 mzd_mul_v_s256_256_1280 #define ADDMUL_R_1 mzd_addmul_v_s256_3_256 #define ADDMUL_R_10 mzd_addmul_v_s256_30_256 #define MUL_Z_1 mzd_mul_v_parity_uint64_256_3 diff --git a/src/sig/picnic/external/lowmc_fns_uint64_L1.h b/src/sig/picnic/external/lowmc_fns_uint64_L1.h index 6ce60a6cf..dc6968192 100644 --- a/src/sig/picnic/external/lowmc_fns_uint64_L1.h +++ b/src/sig/picnic/external/lowmc_fns_uint64_L1.h @@ -9,14 +9,14 @@ #include "lowmc_fns_undef.h" -#define ADDMUL SELECT_V_VL(mzd_addmul_v_uint64_128, mzd_addmul_vl_uint64_128) -#define MUL SELECT_V_VL(mzd_mul_v_uint64_128, mzd_mul_vl_uint64_128) +#define ADDMUL mzd_addmul_v_uint64_128 +#define MUL mzd_mul_v_uint64_128 #define XOR mzd_xor_uint64_128 #define SHUFFLE mzd_shuffle_128 #define COPY mzd_copy_uint64_128 -#define MUL_MC_1 SELECT_V_VL(mzd_mul_v_uint64_128_576, mzd_mul_vl_uint64_128_576) -#define MUL_MC_10 SELECT_V_VL(mzd_mul_v_uint64_128_640, mzd_mul_vl_uint64_128_640) +#define MUL_MC_1 mzd_mul_v_uint64_128_576 +#define MUL_MC_10 mzd_mul_v_uint64_128_640 #define ADDMUL_R_1 mzd_addmul_v_uint64_3_128 #define ADDMUL_R_10 mzd_addmul_v_uint64_30_128 #define MUL_Z_1 mzd_mul_v_parity_uint64_128_3 diff --git a/src/sig/picnic/external/lowmc_fns_uint64_L3.h b/src/sig/picnic/external/lowmc_fns_uint64_L3.h index ba5fa0d7b..95d967001 100644 --- a/src/sig/picnic/external/lowmc_fns_uint64_L3.h +++ b/src/sig/picnic/external/lowmc_fns_uint64_L3.h @@ -9,14 +9,14 @@ #include "lowmc_fns_undef.h" -#define ADDMUL SELECT_V_VL(mzd_addmul_v_uint64_192, mzd_addmul_vl_uint64_192) -#define MUL SELECT_V_VL(mzd_mul_v_uint64_192, mzd_mul_vl_uint64_192) +#define ADDMUL mzd_addmul_v_uint64_192 +#define MUL mzd_mul_v_uint64_192 #define SHUFFLE mzd_shuffle_192 #define XOR mzd_xor_uint64_192 #define COPY mzd_copy_uint64_192 -#define MUL_MC_1 SELECT_V_VL(mzd_mul_v_uint64_192_896, mzd_mul_vl_uint64_192_896) -#define MUL_MC_10 SELECT_V_VL(mzd_mul_v_uint64_192_960, mzd_mul_vl_uint64_192_960) +#define MUL_MC_1 mzd_mul_v_uint64_192_896 +#define MUL_MC_10 mzd_mul_v_uint64_192_960 #define ADDMUL_R_1 mzd_addmul_v_uint64_3_192 #define ADDMUL_R_10 mzd_addmul_v_uint64_30_192 #define MUL_Z_1 mzd_mul_v_parity_uint64_192_3 diff --git a/src/sig/picnic/external/lowmc_fns_uint64_L5.h b/src/sig/picnic/external/lowmc_fns_uint64_L5.h index 3976f5f2b..5405f9a76 100644 --- a/src/sig/picnic/external/lowmc_fns_uint64_L5.h +++ b/src/sig/picnic/external/lowmc_fns_uint64_L5.h @@ -9,14 +9,14 @@ #include "lowmc_fns_undef.h" -#define ADDMUL SELECT_V_VL(mzd_addmul_v_uint64_256, mzd_addmul_vl_uint64_256) -#define MUL SELECT_V_VL(mzd_mul_v_uint64_256, mzd_mul_vl_uint64_256) +#define ADDMUL mzd_addmul_v_uint64_256 +#define MUL mzd_mul_v_uint64_256 #define SHUFFLE mzd_shuffle_256 #define XOR mzd_xor_uint64_256 #define COPY mzd_copy_uint64_256 -#define MUL_MC_1 SELECT_V_VL(mzd_mul_v_uint64_256_1152, mzd_mul_vl_uint64_256_1152) -#define MUL_MC_10 SELECT_V_VL(mzd_mul_v_uint64_256_1216, mzd_mul_vl_uint64_256_1216) +#define MUL_MC_1 mzd_mul_v_uint64_256_1152 +#define MUL_MC_10 mzd_mul_v_uint64_256_1216 #define ADDMUL_R_1 mzd_addmul_v_uint64_3_256 #define ADDMUL_R_10 mzd_addmul_v_uint64_30_256 #define MUL_Z_1 mzd_mul_v_parity_uint64_256_3 diff --git a/src/sig/picnic/external/lowmc_impl.c.i b/src/sig/picnic/external/lowmc_impl.c.i index 89efac290..5320c83a3 100644 --- a/src/sig/picnic/external/lowmc_impl.c.i +++ b/src/sig/picnic/external/lowmc_impl.c.i @@ -11,8 +11,6 @@ #error "OLLE is only implemented for 1 or 10 Sboxes" #endif -// TODO: fix PICNIC2_AUX_COMPUTATION for OFF & ORKC - #if defined(FN_ATTR) FN_ATTR #endif @@ -22,7 +20,7 @@ static void N_LOWMC(lowmc_key_t const* lowmc_key, randomTape_t* tapes) { #if defined(RECORD_STATE) static void N_LOWMC(lowmc_key_t const* lowmc_key, mzd_local_t const* p, recorded_state_t* state) { #else -static mzd_local_t* N_LOWMC(lowmc_key_t const* lowmc_key, mzd_local_t const* p) { +static void N_LOWMC(lowmc_key_t const* lowmc_key, mzd_local_t const* p, mzd_local_t* c) { #endif #endif mzd_local_t x[((LOWMC_N) + 255) / 256]; @@ -36,12 +34,12 @@ static mzd_local_t* N_LOWMC(lowmc_key_t const* lowmc_key, mzd_local_t const* p) #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) // LOWMC_OPT=OLLE #if defined(PICNIC2_AUX_COMPUTATION) - MUL(x, lowmc_key, CONCAT(LOWMC_INSTANCE.k0, matrix_postfix)); - MUL_MC(nl_part, lowmc_key, CONCAT(LOWMC_INSTANCE.precomputed_non_linear_part, matrix_postfix)); + MUL(x, lowmc_key, LOWMC_INSTANCE.k0_matrix); + MUL_MC(nl_part, lowmc_key, LOWMC_INSTANCE.precomputed_non_linear_part_matrix); #else XOR(x, p, LOWMC_INSTANCE.precomputed_constant_linear); - ADDMUL(x, lowmc_key, CONCAT(LOWMC_INSTANCE.k0, matrix_postfix)); - MUL_MC(nl_part, lowmc_key, CONCAT(LOWMC_INSTANCE.precomputed_non_linear_part, matrix_postfix)); + ADDMUL(x, lowmc_key, LOWMC_INSTANCE.k0_matrix); + MUL_MC(nl_part, lowmc_key, LOWMC_INSTANCE.precomputed_non_linear_part_matrix); XOR_MC(nl_part, nl_part, LOWMC_INSTANCE.precomputed_constant_non_linear); #endif @@ -99,17 +97,17 @@ static mzd_local_t* N_LOWMC(lowmc_key_t const* lowmc_key, mzd_local_t const* p) BLOCK(x, 0)->w64[(LOWMC_N) / (sizeof(word) * 8) - 1] ^= (nl << ((20 - (i % 21)) * 3)) & WORD_C(0xE000000000000000); #endif - MUL(y, x, CONCAT(LOWMC_INSTANCE.zr, matrix_postfix)); + MUL(y, x, LOWMC_INSTANCE.zr_matrix); COPY(x, y); #endif #else // LOWMC_OPT=ORKC #if defined(PICNIC2_AUX_COMPUTATION) - MUL(x, lowmc_key, CONCAT(LOWMC_INSTANCE.k0, matrix_postfix)); - MUL_MC(nl_part, lowmc_key, CONCAT(LOWMC_INSTANCE.precomputed_non_linear_part, matrix_postfix)); + MUL(x, lowmc_key, LOWMC_INSTANCE.k0_matrix); + MUL_MC(nl_part, lowmc_key, LOWMC_INSTANCE.precomputed_non_linear_part_matrix); #else XOR(x, p, LOWMC_INSTANCE.precomputed_constant_linear); - ADDMUL(x, lowmc_key, CONCAT(LOWMC_INSTANCE.k0, matrix_postfix)); - MUL_MC(nl_part, lowmc_key, CONCAT(LOWMC_INSTANCE.precomputed_non_linear_part, matrix_postfix)); + ADDMUL(x, lowmc_key, LOWMC_INSTANCE.k0_matrix); + MUL_MC(nl_part, lowmc_key, LOWMC_INSTANCE.precomputed_non_linear_part_matrix); XOR_MC(nl_part, nl_part, LOWMC_INSTANCE.precomputed_constant_non_linear); #endif @@ -133,16 +131,16 @@ static mzd_local_t* N_LOWMC(lowmc_key_t const* lowmc_key, mzd_local_t const* p) BLOCK(x, 0)->w64[(LOWMC_N) / (sizeof(word) * 8) - 1] ^= (nl << ((20 - (i % 21)) * 3)) & WORD_C(0xE000000000000000); #endif - MUL(y, x, CONCAT(round->l, matrix_postfix)); + MUL(y, x, round->l_matrix); COPY(x, y); } #endif #else // LOWMC_OPT=OFF #if defined(PICNIC2_AUX_COMPUTATION) - MUL(x, lowmc_key, CONCAT(LOWMC_INSTANCE.k0, matrix_postfix)); + MUL(x, lowmc_key, LOWMC_INSTANCE.k0_matrix); #else COPY(x, p); - ADDMUL(x, lowmc_key, CONCAT(LOWMC_INSTANCE.k0, matrix_postfix)); + ADDMUL(x, lowmc_key, LOWMC_INSTANCE.k0_matrix); #endif lowmc_round_t const* round = LOWMC_INSTANCE.rounds; @@ -156,13 +154,13 @@ static mzd_local_t* N_LOWMC(lowmc_key_t const* lowmc_key, mzd_local_t const* p) SBOX(x); #endif - MUL(y, x, CONCAT(round->l, matrix_postfix)); + MUL(y, x, round->l_matrix); #if !defined(PICNIC2_AUX_COMPUTATION) XOR(x, y, round->constant); #else COPY(x, y); #endif - ADDMUL(x, lowmc_key, CONCAT(round->k, matrix_postfix)); + ADDMUL(x, lowmc_key, round->k_matrix); } #endif @@ -170,9 +168,7 @@ static mzd_local_t* N_LOWMC(lowmc_key_t const* lowmc_key, mzd_local_t const* p) #if defined(RECORD_STATE) COPY(state->state[LOWMC_R], x); #else - mzd_local_t* res = mzd_local_init_ex(1, LOWMC_N, false); - COPY(res, x); - return res; + COPY(c, x); #endif #endif } diff --git a/src/sig/picnic/external/lowmc_pars.c b/src/sig/picnic/external/lowmc_pars.c deleted file mode 100644 index 055a86e64..000000000 --- a/src/sig/picnic/external/lowmc_pars.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of the optimized implementation of the Picnic signature scheme. - * See the accompanying documentation for complete details. - * - * The code is provided under the MIT license, see LICENSE for - * more details. - * SPDX-License-Identifier: MIT - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "lowmc_pars.h" - -#include "macros.h" -#include "mzd_additional.h" - -#if defined(MUL_M4RI) -bool lowmc_init(lowmc_t* lowmc) { - if (!lowmc) { - return false; - } - - if (lowmc->n - 3 * lowmc->m < 2 || lowmc->n != lowmc->k) { - return false; - } - - lowmc->k0_lookup = mzd_precompute_matrix_lookup(lowmc->k0_matrix, lowmc->n, lowmc->n); -#if defined(REDUCED_ROUND_KEY_COMPUTATION) - const unsigned int cols = lowmc->m == 1 ? ((lowmc->r + 20) / 21) * 64 : lowmc->r * 32; - lowmc->precomputed_non_linear_part_lookup = - mzd_precompute_matrix_lookup(lowmc->precomputed_non_linear_part_matrix, lowmc->n, cols); -#endif - for (unsigned int i = 0; i < lowmc->r; ++i) { - lowmc->rounds[i].l_lookup = - mzd_precompute_matrix_lookup(lowmc->rounds[i].l_matrix, lowmc->n, lowmc->n); -#if !defined(REDUCED_ROUND_KEY_COMPUTATION) - lowmc->rounds[i].k_lookup = - mzd_precompute_matrix_lookup(lowmc->rounds[i].k_matrix, lowmc->n, lowmc->n); -#endif - } - - return true; -} -#endif - -void lowmc_clear(lowmc_t* lowmc) { - for (unsigned int i = 0; i < lowmc->r; ++i) { -#if defined(MUL_M4RI) -#if !defined(REDUCED_ROUND_KEY_COMPUTATION) - mzd_local_free(lowmc->rounds[i].k_lookup); -#endif - mzd_local_free(lowmc->rounds[i].l_lookup); -#endif - } -#if defined(MUL_M4RI) - mzd_local_free(lowmc->k0_lookup); -#if defined(REDUCED_ROUND_KEY_COMPUTATION) - mzd_local_free(lowmc->precomputed_non_linear_part_lookup); -#endif -#endif -} diff --git a/src/sig/picnic/external/lowmc_pars.h b/src/sig/picnic/external/lowmc_pars.h index a91c932f9..33db15af7 100644 --- a/src/sig/picnic/external/lowmc_pars.h +++ b/src/sig/picnic/external/lowmc_pars.h @@ -79,13 +79,6 @@ typedef struct { #if !defined(REDUCED_ROUND_KEY_COMPUTATION) const mzd_local_t* constant; #endif - -#if defined(MUL_M4RI) -#if !defined(REDUCED_ROUND_KEY_COMPUTATION) - mzd_local_t* k_lookup; -#endif - mzd_local_t* l_lookup; -#endif } lowmc_round_t; /** @@ -101,40 +94,13 @@ typedef struct { #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) const mzd_local_t* zr_matrix; // combined linear layers #endif -#if defined(MUL_M4RI) - mzd_local_t* k0_lookup; -#endif -#if defined(MUL_M4RI) - lowmc_round_t* rounds; -#else const lowmc_round_t* rounds; -#endif #if defined(REDUCED_ROUND_KEY_COMPUTATION) const mzd_local_t* precomputed_non_linear_part_matrix; -#if defined(MUL_M4RI) - mzd_local_t* precomputed_non_linear_part_lookup; -#endif const mzd_local_t* precomputed_constant_linear; const mzd_local_t* precomputed_constant_non_linear; #endif - } lowmc_t; -#if defined(MUL_M4RI) -/** - * Initiaizes lookup tables of a LowMC instance - * - * \return parameters defining a LowMC instance - */ -bool lowmc_init(lowmc_t* lowmc); -#endif - -/** - * Clears the allocated LowMC parameters - * - * \param lowmc the LowMC parameters to be cleared - */ -void lowmc_clear(lowmc_t* lowmc); - #endif diff --git a/src/sig/picnic/external/macros.h b/src/sig/picnic/external/macros.h index d4700f408..98d404c58 100644 --- a/src/sig/picnic/external/macros.h +++ b/src/sig/picnic/external/macros.h @@ -89,6 +89,10 @@ #define ATTR_ALIGNED(i) #endif +/* round size to meet alignment requirements */ +#define ALIGNT(s, t) (((s) + sizeof(t) - 1) & ~(sizeof(t) - 1)) +#define ALIGNU64T(s) ALIGNT(s, uint64_t) + /* unreachable builtin */ #if GNUC_CHECK(4, 5) || __has_builtin(__builtin_unreachable) #define UNREACHABLE __builtin_unreachable() @@ -154,19 +158,6 @@ #define CONCAT2(a, b) a##_##b #define CONCAT(a, b) CONCAT2(a, b) -/* helper macros to select matrices and multiplicatiion functions */ -#if defined(MUL_M4RI) -#define matrix_postfix lookup -#else -#define matrix_postfix matrix -#endif - -#if defined(MUL_M4RI) -#define SELECT_V_VL(v, vl) vl -#else -#define SELECT_V_VL(v, vl) v -#endif - /* helper macros/functions for checked integer subtraction */ #if GNUC_CHECK(5, 0) || __has_builtin(__builtin_add_overflow) #define sub_overflow_size_t(x, y, diff) __builtin_sub_overflow(x, y, diff) diff --git a/src/sig/picnic/external/mpc_lowmc.c b/src/sig/picnic/external/mpc_lowmc.c index e3936094a..8cc3c59ef 100644 --- a/src/sig/picnic/external/mpc_lowmc.c +++ b/src/sig/picnic/external/mpc_lowmc.c @@ -330,7 +330,11 @@ static void mpc_sbox_layer_bitsliced_verify_uint64_1(uint64_t* in, view_t* view, #endif zkbpp_lowmc_implementation_f get_zkbpp_lowmc_implementation(const lowmc_t* lowmc) { +#if defined(WITH_LOWMC_M1) ASSUME(lowmc->m == 10 || lowmc->m == 1); +#else + ASSUME(lowmc->m == 10); +#endif ASSUME(lowmc->n == 128 || lowmc->n == 192 || lowmc->n == 256); #if defined(WITH_OPT) @@ -452,7 +456,11 @@ zkbpp_lowmc_implementation_f get_zkbpp_lowmc_implementation(const lowmc_t* lowmc } zkbpp_lowmc_verify_implementation_f get_zkbpp_lowmc_verify_implementation(const lowmc_t* lowmc) { +#if defined(WITH_LOWMC_M1) ASSUME(lowmc->m == 10 || lowmc->m == 1); +#else + ASSUME(lowmc->m == 10); +#endif ASSUME(lowmc->n == 128 || lowmc->n == 192 || lowmc->n == 256); #if defined(WITH_OPT) diff --git a/src/sig/picnic/external/mpc_lowmc_impl.c.i b/src/sig/picnic/external/mpc_lowmc_impl.c.i index 7177f19fe..c86bf0125 100644 --- a/src/sig/picnic/external/mpc_lowmc_impl.c.i +++ b/src/sig/picnic/external/mpc_lowmc_impl.c.i @@ -47,7 +47,7 @@ static void N_SIGN(mpc_lowmc_key_t const* lowmc_key, mzd_local_t const* p, view_ mzd_local_t x[SC_PROOF][((LOWMC_N) + 255) / 256]; mzd_local_t y[SC_PROOF][((LOWMC_N) + 255) / 256]; - MPC_LOOP_CONST(MUL, x, lowmc_key, CONCAT(LOWMC_INSTANCE.k0, matrix_postfix), reduced_shares); + MPC_LOOP_CONST(MUL, x, lowmc_key, LOWMC_INSTANCE.k0_matrix, reduced_shares); MPC_LOOP_CONST_C(XOR, x, x, p, reduced_shares, ch); #include "mpc_lowmc_loop.c.i" @@ -80,7 +80,7 @@ static void N_VERIFY(mzd_local_t const* p, view_t* views, in_out_shares_t* in_ou mzd_local_t x[SC_VERIFY][((LOWMC_N) + 255) / 256]; mzd_local_t y[SC_VERIFY][((LOWMC_N) + 255) / 256]; - MPC_LOOP_CONST(MUL, x, lowmc_key, CONCAT(LOWMC_INSTANCE.k0, matrix_postfix), SC_VERIFY); + MPC_LOOP_CONST(MUL, x, lowmc_key, LOWMC_INSTANCE.k0_matrix, SC_VERIFY); MPC_LOOP_CONST_C(XOR, x, x, p, SC_VERIFY, ch); #include "mpc_lowmc_loop.c.i" diff --git a/src/sig/picnic/external/mpc_lowmc_loop.c.i b/src/sig/picnic/external/mpc_lowmc_loop.c.i index 9ad48fd72..0ee96714f 100644 --- a/src/sig/picnic/external/mpc_lowmc_loop.c.i +++ b/src/sig/picnic/external/mpc_lowmc_loop.c.i @@ -21,7 +21,7 @@ lowmc_round_t const* round = LOWMC_INSTANCE.rounds; #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) MPC_LOOP_CONST_C(XOR, x, x, LOWMC_INSTANCE.precomputed_constant_linear, reduced_shares, ch); MPC_LOOP_CONST(MUL_MC, nl_part, lowmc_key, - CONCAT(LOWMC_INSTANCE.precomputed_non_linear_part, matrix_postfix), reduced_shares); + LOWMC_INSTANCE.precomputed_non_linear_part_matrix, reduced_shares); MPC_LOOP_CONST_C(XOR_MC, nl_part, nl_part, LOWMC_INSTANCE.precomputed_constant_non_linear, reduced_shares, ch); for (unsigned i = 0; i < (LOWMC_R-1); ++i, ++views, ++round) { RANDTAPE; @@ -39,13 +39,13 @@ lowmc_round_t const* round = LOWMC_INSTANCE.rounds; BLOCK(y[k], 0)->w64[(LOWMC_N) / (sizeof(word) * 8) - 1] ^= (nl << ((20-(i%21))*3)) & WORD_C(0xE000000000000000); #endif } - MPC_LOOP_CONST(MUL_Z, x, y, CONCAT(round->z, matrix_postfix), reduced_shares); + MPC_LOOP_CONST(MUL_Z, x, y, round->z_matrix, reduced_shares); for(unsigned int k = 0; k < reduced_shares; ++k) { MZD_SHUFFLE(y[k], round->r_mask); } - MPC_LOOP_CONST(ADDMUL_R, x, y, CONCAT(round->r, matrix_postfix), reduced_shares); + MPC_LOOP_CONST(ADDMUL_R, x, y, round->r_matrix, reduced_shares); for(unsigned int k = 0; k < reduced_shares; ++k) { #if defined(M_FIXED_10) BLOCK(y[k], 0)->w64[(LOWMC_N) / (sizeof(word) * 8) - 1] &= WORD_C(0x00000003FFFFFFFF); //clear nl part @@ -72,11 +72,11 @@ lowmc_round_t const* round = LOWMC_INSTANCE.rounds; BLOCK(y[k], 0)->w64[(LOWMC_N) / (sizeof(word) * 8) - 1] ^= (nl << ((20-(i%21))*3)) & WORD_C(0xE000000000000000); #endif } - MPC_LOOP_CONST(MUL, x, y, CONCAT(LOWMC_INSTANCE.zr, matrix_postfix), reduced_shares); + MPC_LOOP_CONST(MUL, x, y, LOWMC_INSTANCE.zr_matrix, reduced_shares); #else MPC_LOOP_CONST_C(XOR, x, x, LOWMC_INSTANCE.precomputed_constant_linear, reduced_shares, ch); MPC_LOOP_CONST(MUL_MC, nl_part, lowmc_key, - CONCAT(LOWMC_INSTANCE.precomputed_non_linear_part, matrix_postfix), reduced_shares); + LOWMC_INSTANCE.precomputed_non_linear_part_matrix, reduced_shares); MPC_LOOP_CONST_C(XOR_MC, nl_part, nl_part, LOWMC_INSTANCE.precomputed_constant_non_linear, reduced_shares, ch); for (unsigned i = 0; i < (LOWMC_R); ++i, ++views, ++round) { RANDTAPE; @@ -94,7 +94,7 @@ lowmc_round_t const* round = LOWMC_INSTANCE.rounds; BLOCK(y[k], 0)->w64[(LOWMC_N) / (sizeof(word) * 8) - 1] ^= (nl << ((20-(i%21))*3)) & WORD_C(0xE000000000000000); #endif } - MPC_LOOP_CONST(MUL, x, y, CONCAT(round->l, matrix_postfix), reduced_shares); + MPC_LOOP_CONST(MUL, x, y, round->l_matrix, reduced_shares); } #endif #else @@ -104,9 +104,9 @@ for (unsigned i = 0; i < (LOWMC_R); ++i, ++views, ++round) { RECOVER_FROM_STATE(x, i); #endif SBOX(sbox, y, x, views, r, LOWMC_N, shares, reduced_shares); - MPC_LOOP_CONST(MUL, x, y, CONCAT(round->l, matrix_postfix), reduced_shares); + MPC_LOOP_CONST(MUL, x, y, round->l_matrix, reduced_shares); MPC_LOOP_CONST_C(XOR, x, x, round->constant, reduced_shares, ch); - MPC_LOOP_CONST(ADDMUL, x, lowmc_key, CONCAT(round->k, matrix_postfix), reduced_shares); + MPC_LOOP_CONST(ADDMUL, x, lowmc_key, round->k_matrix, reduced_shares); } #endif #if defined(RECOVER_FROM_STATE) diff --git a/src/sig/picnic/external/mzd_additional.c b/src/sig/picnic/external/mzd_additional.c index c613f30f0..6c230e3d0 100644 --- a/src/sig/picnic/external/mzd_additional.c +++ b/src/sig/picnic/external/mzd_additional.c @@ -1105,724 +1105,6 @@ void mzd_mul_v_uint64_256_1216(mzd_local_t* c, mzd_local_t const* v, mzd_local_t } } -#if defined(MUL_M4RI) -#include - -static void xor_comb(const unsigned int len, const unsigned int rowstride, block_t* Bblock, - mzd_local_t const* A, unsigned int r_offset, unsigned comb) { - for (; comb; comb >>= 1, ++r_offset) { - if (comb & 0x1) { - const block_t* Ablock = CONST_BLOCK(A, r_offset * rowstride / 4); - unsigned int i = 0; - unsigned int j = len; - for (; i < len / 4; ++i, j -= 4) { - mzd_xor_uint64_block(&Bblock[i], &Bblock[i], &Ablock[i], 4); - } - mzd_xor_uint64_block(&Bblock[i], &Bblock[i], &Ablock[i], j); - } - } -} - -static void xor_comb_128(block_t* Bblock, const unsigned int boffset, mzd_local_t const* A, - unsigned int r_offset, unsigned comb) { - for (; comb; comb >>= 1, ++r_offset) { - if (comb & 0x1) { - const block_t* Ablock = CONST_BLOCK(A, r_offset / 2); - const unsigned int aoffset = (r_offset & 0x1) << 1; - - Bblock->w64[boffset] ^= Ablock->w64[aoffset]; - Bblock->w64[boffset + 1] ^= Ablock->w64[aoffset + 1]; - } - } -} - -/** - * Pre-compute matrices for faster mzd_addmul_v computions. - */ -mzd_local_t* mzd_precompute_matrix_lookup(mzd_local_t const* A, unsigned int rows, - unsigned int cols) { - mzd_local_t* B = mzd_local_init_ex(32 * rows, cols, true); - - const unsigned int len = calculate_width(cols); - const unsigned int rowstride = calculate_rowstride(len); - - for (unsigned int r = 0; r < 32 * rows; ++r) { - const unsigned int comb = r & 0xff; - const unsigned int r_offset = (r >> 8) << 3; - if (!comb) { - continue; - } - - if (len == 2) { - /* 128 columns are special. they have two rows per block */ - xor_comb_128(BLOCK(B, r / 2), (r & 0x1) << 1, A, r_offset, comb); - } else { - xor_comb(len, rowstride, BLOCK(B, r * rowstride / 4), A, r_offset, comb); - } - } - - return B; -} - -#if defined(WITH_OPT) -#if defined(WITH_SSE2) || defined(WITH_NEON) -ATTR_TARGET_S128 -void mzd_addmul_vl_s128_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 128; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - word128 cval[2] ATTR_ALIGNED(alignof(word128)) = {cblock->w128[0], mm128_zero}; - for (unsigned int w = 2; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - cval[0] = mm128_xor(cval[0], Ablock[(idx >> 1) & 0x7f].w128[idx & 0x1]); - Ablock += moff2; - cval[1] = mm128_xor(cval[1], Ablock[(idx >> 9) & 0x7f].w128[(idx >> 8) & 0x1]); - Ablock += moff2; - } - } - cblock->w128[0] = mm128_xor(cval[0], cval[1]); -} - -ATTR_TARGET_S128 -void mzd_mul_vl_s128_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 128; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - word128 cval[2] ATTR_ALIGNED(alignof(word128)) = {mm128_zero, mm128_zero}; - for (unsigned int w = 2; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - cval[0] = mm128_xor(cval[0], Ablock[(idx >> 1) & 0x7f].w128[idx & 0x1]); - Ablock += moff2; - cval[1] = mm128_xor(cval[1], Ablock[(idx >> 9) & 0x7f].w128[(idx >> 8) & 0x1]); - Ablock += moff2; - } - } - cblock->w128[0] = mm128_xor(cval[0], cval[1]); -} - -ATTR_TARGET_S128 -void mzd_addmul_vl_s128_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - word128 cval[4] ATTR_ALIGNED(alignof(word128)) = {cblock->w128[0], cblock->w128[1], mm128_zero, - mm128_zero}; - for (unsigned int w = 3; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - mm128_xor_region(&cval[0], Ablock[(idx >> 0) & 0xff].w128, 2); - Ablock += moff2; - mm128_xor_region(&cval[2], Ablock[(idx >> 8) & 0xff].w128, 2); - Ablock += moff2; - } - } - cblock->w128[0] = mm128_xor(cval[0], cval[2]); - cblock->w128[1] = mm128_xor(cval[1], cval[3]); -} - -ATTR_TARGET_S128 -void mzd_mul_vl_s128_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - word128 cval[4] ATTR_ALIGNED(alignof(word128)) = {mm128_zero, mm128_zero, mm128_zero, mm128_zero}; - for (unsigned int w = 3; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - mm128_xor_region(&cval[0], Ablock[(idx >> 0) & 0xff].w128, 2); - Ablock += moff2; - mm128_xor_region(&cval[2], Ablock[(idx >> 8) & 0xff].w128, 2); - Ablock += moff2; - } - } - cblock->w128[0] = mm128_xor(cval[0], cval[2]); - cblock->w128[1] = mm128_xor(cval[1], cval[3]); -} - -ATTR_TARGET_S128 -void mzd_addmul_vl_s128_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - word128 cval[4] ATTR_ALIGNED(alignof(word128)) = {cblock->w128[0], cblock->w128[1], mm128_zero, - mm128_zero}; - for (unsigned int w = 4; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - mm128_xor_region(&cval[0], Ablock[(idx >> 0) & 0xff].w128, 2); - Ablock += moff2; - mm128_xor_region(&cval[2], Ablock[(idx >> 8) & 0xff].w128, 2); - Ablock += moff2; - } - } - cblock->w128[0] = mm128_xor(cval[0], cval[2]); - cblock->w128[1] = mm128_xor(cval[1], cval[3]); -} - -ATTR_TARGET_S128 -void mzd_mul_vl_s128_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - word128 cval[4] ATTR_ALIGNED(alignof(word128)) = {mm128_zero, mm128_zero, mm128_zero, mm128_zero}; - for (unsigned int w = 4; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - mm128_xor_region(&cval[0], Ablock[(idx >> 0) & 0xff].w128, 2); - Ablock += moff2; - mm128_xor_region(&cval[2], Ablock[(idx >> 8) & 0xff].w128, 2); - Ablock += moff2; - } - } - cblock->w128[0] = mm128_xor(cval[0], cval[2]); - cblock->w128[1] = mm128_xor(cval[1], cval[3]); -} - -ATTR_TARGET_S128 -void mzd_mul_vl_s128_128_640(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256 * 3; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - for (unsigned int j = 0; j < 2; ++j) { - BLOCK(c, j)->w128[0] = BLOCK(c, j)->w128[1] = mm128_zero; - } - BLOCK(c, 2)->w128[0] = mm128_zero; - - for (unsigned int w = 2; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - const block_t* Ablock1 = &Ablock[((idx >> 0) & 0xff) * 3]; - mzd_xor_s128_blocks(cblock, cblock, Ablock1, 2); - cblock[2].w128[0] = mm128_xor(cblock[2].w128[0], Ablock1[2].w128[0]); - Ablock += moff2; - - const block_t* Ablock2 = &Ablock[((idx >> 8) & 0xff) * 3]; - mzd_xor_s128_blocks(cblock, cblock, Ablock2, 2); - cblock[2].w128[0] = mm128_xor(cblock[2].w128[0], Ablock2[2].w128[0]); - Ablock += moff2; - } - } -} - -ATTR_TARGET_S128 -void mzd_mul_vl_s128_192_896(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256 * 4; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - for (unsigned int j = 0; j < 3; ++j) { - BLOCK(c, j)->w128[0] = BLOCK(c, j)->w128[1] = mm128_zero; - } - BLOCK(c, 3)->w128[0] = mm128_zero; - - for (unsigned int w = 3; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - const block_t* Ablock1 = &Ablock[((idx >> 0) & 0xff) * 4]; - mzd_xor_s128_blocks(cblock, cblock, Ablock1, 3); - cblock[3].w128[0] = mm128_xor(cblock[3].w128[0], Ablock1[3].w128[0]); - Ablock += moff2; - - const block_t* Ablock2 = &Ablock[((idx >> 8) & 0xff) * 4]; - mzd_xor_s128_blocks(cblock, cblock, Ablock2, 3); - cblock[3].w128[0] = mm128_xor(cblock[3].w128[0], Ablock2[3].w128[0]); - Ablock += moff2; - } - } -} - -ATTR_TARGET_S128 -void mzd_mul_vl_s128_192_1024(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256 * 4; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - for (unsigned int j = 0; j < 4; ++j) { - BLOCK(c, j)->w128[0] = BLOCK(c, j)->w128[1] = mm128_zero; - } - - for (unsigned int w = 3; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - const block_t* Ablock1 = &Ablock[((idx >> 0) & 0xff) * 4]; - mzd_xor_s128_blocks(cblock, cblock, Ablock1, 4); - Ablock += moff2; - - const block_t* Ablock2 = &Ablock[((idx >> 8) & 0xff) * 4]; - mzd_xor_s128_blocks(cblock, cblock, Ablock2, 4); - Ablock += moff2; - } - } -} - -ATTR_TARGET_S128 -void mzd_mul_vl_s128_256_1152(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256 * 5; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - for (unsigned int j = 0; j < 4; ++j) { - BLOCK(c, j)->w128[0] = BLOCK(c, j)->w128[1] = mm128_zero; - } - BLOCK(c, 4)->w128[0] = mm128_zero; - - for (unsigned int w = 4; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - const block_t* Ablock1 = &Ablock[((idx >> 0) & 0xff) * 5]; - mzd_xor_s128_blocks(cblock, cblock, Ablock1, 4); - cblock[4].w128[0] = mm128_xor(cblock[4].w128[0], Ablock1[4].w128[0]); - Ablock += moff2; - - const block_t* Ablock2 = &Ablock[((idx >> 8) & 0xff) * 5]; - mzd_xor_s128_blocks(cblock, cblock, Ablock2, 4); - cblock[4].w128[0] = mm128_xor(cblock[4].w128[0], Ablock2[4].w128[0]); - Ablock += moff2; - } - } -} - -ATTR_TARGET_S128 -void mzd_mul_vl_s128_256_1280(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256 * 5; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - for (unsigned int j = 0; j < 5; ++j) { - BLOCK(c, j)->w128[0] = BLOCK(c, j)->w128[1] = mm128_zero; - } - - for (unsigned int w = 4; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - const block_t* Ablock1 = &Ablock[((idx >> 0) & 0xff) * 5]; - mzd_xor_s128_blocks(cblock, cblock, Ablock1, 5); - Ablock += moff2; - - const block_t* Ablock2 = &Ablock[((idx >> 8) & 0xff) * 5]; - mzd_xor_s128_blocks(cblock, cblock, Ablock2, 5); - Ablock += moff2; - } - } -} -#endif - -#if defined(WITH_AVX2) -ATTR_TARGET_AVX2 -void mzd_mul_vl_s256_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {mm256_zero, mm256_zero}; - for (unsigned int w = 4; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - cval[0] = mm256_xor(cval[0], Ablock[(idx >> 0) & 0xff].w256); - Ablock += moff2; - cval[1] = mm256_xor(cval[1], Ablock[(idx >> 8) & 0xff].w256); - Ablock += moff2; - } - } - cblock->w256 = _mm256_xor_si256(cval[0], cval[1]); -} - -ATTR_TARGET_AVX2 -void mzd_addmul_vl_s256_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {cblock->w256, mm256_zero}; - for (unsigned int w = 4; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - cval[0] = mm256_xor(cval[0], Ablock[(idx >> 0) & 0xff].w256); - Ablock += moff2; - cval[1] = mm256_xor(cval[1], Ablock[(idx >> 8) & 0xff].w256); - Ablock += moff2; - } - } - cblock->w256 = _mm256_xor_si256(cval[0], cval[1]); -} - -ATTR_TARGET_AVX2 -void mzd_mul_vl_s256_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {mm256_zero, mm256_zero}; - for (unsigned int w = 3; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - cval[0] = mm256_xor(cval[0], Ablock[(idx >> 0) & 0xff].w256); - Ablock += moff2; - cval[1] = mm256_xor(cval[1], Ablock[(idx >> 8) & 0xff].w256); - Ablock += moff2; - } - } - cblock->w256 = _mm256_xor_si256(cval[0], cval[1]); -} - -ATTR_TARGET_AVX2 -void mzd_addmul_vl_s256_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {cblock->w256, mm256_zero}; - for (unsigned int w = 3; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - cval[0] = mm256_xor(cval[0], Ablock[(idx >> 0) & 0xff].w256); - Ablock += moff2; - cval[1] = mm256_xor(cval[1], Ablock[(idx >> 8) & 0xff].w256); - Ablock += moff2; - } - } - cblock->w256 = _mm256_xor_si256(cval[0], cval[1]); -} - -ATTR_TARGET_AVX2 -void mzd_mul_vl_s256_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 128; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {mm256_zero, mm256_zero}; - for (unsigned int w = 2; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 4, idx >>= 32) { - const word256 t1 = - _mm256_set_m128i(Ablock[(idx >> 1) & 0x7f].w128[idx & 0x1], - Ablock[((idx >> 9) & 0x7f) + moff2].w128[(idx >> 8) & 0x1]); - cval[0] = mm256_xor(cval[0], t1); - Ablock += 2 * moff2; - - const word256 t2 = - _mm256_set_m128i(Ablock[(idx >> 17) & 0x7f].w128[(idx >> 16) & 0x1], - Ablock[((idx >> 25) & 0x7f) + moff2].w128[(idx >> 24) & 0x1]); - cval[1] = mm256_xor(cval[1], t2); - Ablock += 2 * moff2; - } - } - cval[0] = mm256_xor(cval[0], cval[1]); - cblock->w128[0] = - mm128_xor(_mm256_extractf128_si256(cval[0], 0), _mm256_extractf128_si256(cval[0], 1)); -} - -ATTR_TARGET_AVX2 -void mzd_addmul_vl_s256_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 128; - - block_t* cblock = BLOCK(c, 0); - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - word256 cval[2] ATTR_ALIGNED(alignof(word256)) = {_mm256_castsi128_si256(cblock->w128[0]), - mm256_zero}; - for (unsigned int w = 2; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 4, idx >>= 32) { - const word256 t1 = - _mm256_set_m128i(Ablock[(idx >> 1) & 0x7f].w128[idx & 0x1], - Ablock[((idx >> 9) & 0x7f) + moff2].w128[(idx >> 8) & 0x1]); - cval[0] = mm256_xor(cval[0], t1); - Ablock += 2 * moff2; - - const word256 t2 = - _mm256_set_m128i(Ablock[(idx >> 17) & 0x7f].w128[(idx >> 16) & 0x1], - Ablock[((idx >> 25) & 0x7f) + moff2].w128[(idx >> 24) & 0x1]); - cval[1] = mm256_xor(cval[1], t2); - Ablock += 2 * moff2; - } - } - cval[0] = mm256_xor(cval[0], cval[1]); - cblock->w128[0] = - mm128_xor(_mm256_extractf128_si256(cval[0], 0), _mm256_extractf128_si256(cval[0], 1)); -} - -ATTR_TARGET_AVX2 -void mzd_mul_vl_s256_128_768(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256 * 3; - - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - for (unsigned int j = 0; j < 3; ++j) { - BLOCK(c, j)->w256 = mm256_zero; - } - - for (unsigned int w = 2; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - mzd_xor_s256_blocks(BLOCK(c, 0), CONST_BLOCK(c, 0), &Ablock[((idx >> 0) & 0xff) * 3], 3); - Ablock += moff2; - mzd_xor_s256_blocks(BLOCK(c, 0), CONST_BLOCK(c, 0), &Ablock[((idx >> 8) & 0xff) * 3], 3); - Ablock += moff2; - } - } -} - -ATTR_TARGET_AVX2 -void mzd_mul_vl_s256_192_1024(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256 * 4; - - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - for (unsigned int j = 0; j < 4; ++j) { - BLOCK(c, j)->w256 = mm256_zero; - } - - for (unsigned int w = 3; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - mzd_xor_s256_blocks(BLOCK(c, 0), CONST_BLOCK(c, 0), &Ablock[((idx >> 0) & 0xff) * 4], 4); - Ablock += moff2; - mzd_xor_s256_blocks(BLOCK(c, 0), CONST_BLOCK(c, 0), &Ablock[((idx >> 8) & 0xff) * 4], 4); - Ablock += moff2; - } - } -} - -ATTR_TARGET_AVX2 -void mzd_mul_vl_s256_256_1280(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - static const unsigned int moff2 = 256 * 5; - - const block_t* Ablock = CONST_BLOCK(A, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - for (unsigned int j = 0; j < 5; ++j) { - BLOCK(c, j)->w256 = mm256_zero; - } - - for (unsigned int w = 4; w; --w, ++vptr) { - word idx = *vptr; - for (unsigned int s = sizeof(word); s; s -= 2, idx >>= 16) { - mzd_xor_s256_blocks(BLOCK(c, 0), CONST_BLOCK(c, 0), &Ablock[((idx >> 0) & 0xff) * 5], 5); - Ablock += moff2; - mzd_xor_s256_blocks(BLOCK(c, 0), CONST_BLOCK(c, 0), &Ablock[((idx >> 8) & 0xff) * 5], 5); - Ablock += moff2; - } - } -} -#endif -#endif - -void mzd_addmul_vl_uint64_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - block_t* cblock = BLOCK(c, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - for (unsigned int w = 0; w < 2; ++w, ++vptr) { - unsigned int add = 0; - for (word idx = *vptr; idx; idx >>= 8, add += 128) { - const word comb = idx & 0xff; - const unsigned int aoffset = (comb & 0x1) << 1; - const block_t* Ablock = CONST_BLOCK(A, w * sizeof(word) * 8 * 16 + add + (comb >> 1)); - - cblock->w64[0] ^= Ablock->w64[aoffset]; - cblock->w64[1] ^= Ablock->w64[aoffset + 1]; - } - } -} - -void mzd_mul_vl_uint64_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - clear_uint64_block(BLOCK(c, 0), 2); - mzd_addmul_vl_uint64_128(c, v, A); -} - -static void mzd_addmul_vl_uint64_256_len(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A, - const unsigned int len) { - block_t* cblock = BLOCK(c, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - for (unsigned int w = 0; w < len; ++w, ++vptr) { - unsigned int add = 0; - for (word idx = *vptr; idx; idx >>= 8, add += 256) { - const word comb = idx & 0xff; - - mzd_xor_uint64_block(cblock, cblock, CONST_BLOCK(A, w * sizeof(word) * 8 * 32 + add + comb), - len); - } - } -} - -void mzd_addmul_vl_uint64_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - mzd_addmul_vl_uint64_256_len(c, v, A, 3); -} - -void mzd_mul_vl_uint64_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - clear_uint64_block(BLOCK(c, 0), 3); - mzd_addmul_vl_uint64_192(c, v, A); -} - -void mzd_addmul_vl_uint64_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - mzd_addmul_vl_uint64_256_len(c, v, A, 4); -} - -void mzd_mul_vl_uint64_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - clear_uint64_block(BLOCK(c, 0), 4); - mzd_addmul_vl_uint64_256(c, v, A); -} - -void mzd_mul_vl_uint64_128_576(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - block_t* cblock = BLOCK(c, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - clear_uint64_blocks(cblock, 2); - clear_uint64_block(&cblock[2], 1); - - for (unsigned int w = 0; w < 2; ++w, ++vptr) { - unsigned int add = 0; - for (word idx = *vptr; idx; idx >>= 8, add += 256) { - const word comb = idx & 0xff; - const block_t* Ablock = CONST_BLOCK(A, (w * sizeof(word) * 8 * 32 + add + comb) * 3); - - mzd_xor_uint64_blocks(cblock, cblock, Ablock, 2); - mzd_xor_uint64_block(&cblock[2], &cblock[2], &Ablock[2], 1); - } - } -} - -void mzd_mul_vl_uint64_128_640(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - block_t* cblock = BLOCK(c, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - clear_uint64_blocks(cblock, 2); - clear_uint64_block(&cblock[2], 2); - - for (unsigned int w = 0; w < 2; ++w, ++vptr) { - unsigned int add = 0; - for (word idx = *vptr; idx; idx >>= 8, add += 256) { - const word comb = idx & 0xff; - const block_t* Ablock = CONST_BLOCK(A, (w * sizeof(word) * 8 * 32 + add + comb) * 3); - - mzd_xor_uint64_blocks(cblock, cblock, Ablock, 2); - mzd_xor_uint64_block(&cblock[2], &cblock[2], &Ablock[2], 2); - } - } -} - -void mzd_mul_vl_uint64_192_896(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - block_t* cblock = BLOCK(c, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - clear_uint64_blocks(cblock, 3); - clear_uint64_block(&cblock[3], 2); - - for (unsigned int w = 0; w < 3; ++w, ++vptr) { - unsigned int add = 0; - for (word idx = *vptr; idx; idx >>= 8, add += 256) { - const word comb = idx & 0xff; - const block_t* Ablock = CONST_BLOCK(A, (w * sizeof(word) * 8 * 32 + add + comb) * 4); - - mzd_xor_uint64_blocks(cblock, cblock, Ablock, 3); - mzd_xor_uint64_block(&cblock[3], &cblock[3], &Ablock[3], 2); - } - } -} - -void mzd_mul_vl_uint64_192_960(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - block_t* cblock = BLOCK(c, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - clear_uint64_blocks(cblock, 3); - clear_uint64_block(&cblock[3], 3); - - for (unsigned int w = 0; w < 3; ++w, ++vptr) { - unsigned int add = 0; - for (word idx = *vptr; idx; idx >>= 8, add += 256) { - const word comb = idx & 0xff; - const block_t* Ablock = CONST_BLOCK(A, (w * sizeof(word) * 8 * 32 + add + comb) * 4); - - mzd_xor_uint64_blocks(cblock, cblock, Ablock, 3); - mzd_xor_uint64_block(&cblock[3], &cblock[3], &Ablock[3], 3); - } - } -} - -void mzd_mul_vl_uint64_256_1152(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - block_t* cblock = BLOCK(c, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - clear_uint64_blocks(cblock, 4); - clear_uint64_block(&cblock[4], 2); - - for (unsigned int w = 0; w < 4; ++w, ++vptr) { - unsigned int add = 0; - for (word idx = *vptr; idx; idx >>= 8, add += 256) { - const word comb = idx & 0xff; - const block_t* Ablock = CONST_BLOCK(A, (w * sizeof(word) * 8 * 32 + add + comb) * 5); - - mzd_xor_uint64_blocks(cblock, cblock, Ablock, 4); - mzd_xor_uint64_block(&cblock[4], &cblock[4], &Ablock[4], 2); - } - } -} - -void mzd_mul_vl_uint64_256_1216(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) { - block_t* cblock = BLOCK(c, 0); - word const* vptr = CONST_BLOCK(v, 0)->w64; - - clear_uint64_blocks(cblock, 4); - clear_uint64_block(&cblock[4], 3); - - for (unsigned int w = 0; w < 4; ++w, ++vptr) { - unsigned int add = 0; - for (word idx = *vptr; idx; idx >>= 8, add += 256) { - const word comb = idx & 0xff; - const block_t* Ablock = CONST_BLOCK(A, (w * sizeof(word) * 8 * 32 + add + comb) * 5); - - mzd_xor_uint64_blocks(cblock, cblock, Ablock, 4); - mzd_xor_uint64_block(&cblock[4], &cblock[4], &Ablock[4], 3); - } - } -} -#endif - // specific instances #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) // bit extract, non-constant time for mask, but mask is public in our calls diff --git a/src/sig/picnic/external/mzd_additional.h b/src/sig/picnic/external/mzd_additional.h index a76739c96..145ace6a2 100644 --- a/src/sig/picnic/external/mzd_additional.h +++ b/src/sig/picnic/external/mzd_additional.h @@ -236,76 +236,6 @@ void mzd_addmul_v_s256_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t con void mzd_addmul_v_s256_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) ATTR_NONNULL; void mzd_addmul_v_s256_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) ATTR_NONNULL; -#if defined(MUL_M4RI) -/** - * Compute v * A optimized for v being a vector. - */ -void mzd_mul_vl_uint64_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_uint64_128_576(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_uint64_128_640(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_uint64_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_uint64_192_896(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_uint64_192_960(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_uint64_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_uint64_256_1152(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_uint64_256_1216(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s128_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s128_128_640(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s128_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s128_192_896(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s128_192_1024(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s128_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s128_256_1152(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s128_256_1280(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s256_128(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s256_128_768(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s256_192(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s256_192_1024(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s256_256(mzd_local_t* c, mzd_local_t const* v, mzd_local_t const* A) ATTR_NONNULL; -void mzd_mul_vl_s256_256_1280(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -/** - * Compute c + v * A optimized for c and v being vectors. - */ -void mzd_addmul_vl_uint64_128(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_addmul_vl_uint64_192(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_addmul_vl_uint64_256(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_addmul_vl_s128_128(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_addmul_vl_s128_192(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_addmul_vl_s128_256(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_addmul_vl_s256_128(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_addmul_vl_s256_192(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; -void mzd_addmul_vl_s256_256(mzd_local_t* c, mzd_local_t const* v, - mzd_local_t const* A) ATTR_NONNULL; - -/** - * Pre-compute matrices for mzd_{add,}mul_vl computions. - */ -mzd_local_t* mzd_precompute_matrix_lookup(mzd_local_t const* A, unsigned int r, - unsigned int c) ATTR_NONNULL; -#endif - /** * Shuffle vector x according to info in mask. Needed for OLLE optimiztaions. */ diff --git a/src/sig/picnic/external/picnic.c b/src/sig/picnic/external/picnic.c index 713431210..bbb16358e 100644 --- a/src/sig/picnic/external/picnic.c +++ b/src/sig/picnic/external/picnic.c @@ -120,30 +120,26 @@ int PICNIC_CALLING_CONVENTION picnic_sk_to_pk(const picnic_privatekey_t* sk, const size_t input_size = instance->input_size; const size_t output_size = instance->output_size; - const lowmc_t* lowmc = instance->lowmc; const uint8_t* sk_sk = SK_SK(sk); uint8_t* pk_c = PK_C(pk); uint8_t* pk_pt = PK_PT(pk); const uint8_t* sk_pt = SK_PT(sk); - mzd_local_t* plaintext = mzd_local_init_ex(1, lowmc->n, false); - mzd_local_t* privkey = mzd_local_init_ex(1, lowmc->k, false); + mzd_local_t plaintext[(MAX_LOWMC_BLOCK_SIZE_BITS + 255) / 256]; + mzd_local_t privkey[(MAX_LOWMC_BLOCK_SIZE_BITS + 255) / 256]; + mzd_local_t ciphertext[(MAX_LOWMC_BLOCK_SIZE_BITS + 255) / 256]; mzd_from_char_array(plaintext, sk_pt, output_size); mzd_from_char_array(privkey, sk_sk, input_size); // compute public key - mzd_local_t* ciphertext = instance->impls.lowmc(privkey, plaintext); + instance->impls.lowmc(privkey, plaintext, ciphertext); pk->data[0] = param; memcpy(pk_pt, sk_pt, output_size); mzd_to_char_array(pk_c, ciphertext, output_size); - mzd_local_free(ciphertext); - mzd_local_free(privkey); - mzd_local_free(plaintext); - return 0; } @@ -161,7 +157,6 @@ int PICNIC_CALLING_CONVENTION picnic_validate_keypair(const picnic_privatekey_t* const size_t input_size = instance->input_size; const size_t output_size = instance->output_size; - const lowmc_t* lowmc = instance->lowmc; const uint8_t* sk_sk = SK_SK(sk); const uint8_t* sk_pt = SK_PT(sk); const uint8_t* sk_c = SK_C(sk); @@ -174,22 +169,19 @@ int PICNIC_CALLING_CONVENTION picnic_validate_keypair(const picnic_privatekey_t* return -1; } - mzd_local_t* plaintext = mzd_local_init_ex(1, lowmc->n, false); - mzd_local_t* privkey = mzd_local_init_ex(1, lowmc->k, false); + mzd_local_t plaintext[(MAX_LOWMC_BLOCK_SIZE_BITS + 255) / 256]; + mzd_local_t privkey[(MAX_LOWMC_BLOCK_SIZE_BITS + 255) / 256]; + mzd_local_t ciphertext[(MAX_LOWMC_BLOCK_SIZE_BITS + 255) / 256]; mzd_from_char_array(plaintext, sk_pt, instance->output_size); mzd_from_char_array(privkey, sk_sk, instance->input_size); // compute public key - mzd_local_t* ciphertext = instance->impls.lowmc(privkey, plaintext); + instance->impls.lowmc(privkey, plaintext, ciphertext); uint8_t buffer[MAX_LOWMC_BLOCK_SIZE]; mzd_to_char_array(buffer, ciphertext, output_size); - mzd_local_free(ciphertext); - mzd_local_free(privkey); - mzd_local_free(plaintext); - return memcmp(buffer, pk_c, output_size); } @@ -215,7 +207,7 @@ int PICNIC_CALLING_CONVENTION picnic_sign(const picnic_privatekey_t* sk, const u if (param == Picnic2_L1_FS || param == Picnic2_L3_FS || param == Picnic2_L5_FS) return impl_sign_picnic2(instance, sk_pt, sk_sk, sk_c, message, message_len, signature, - signature_len); + signature_len); else return impl_sign(instance, sk_pt, sk_sk, sk_c, message, message_len, signature, signature_len); } @@ -240,7 +232,7 @@ int PICNIC_CALLING_CONVENTION picnic_verify(const picnic_publickey_t* pk, const if (param == Picnic2_L1_FS || param == Picnic2_L3_FS || param == Picnic2_L5_FS) return impl_verify_picnic2(instance, pk_pt, pk_c, message, message_len, signature, - signature_len); + signature_len); else return impl_verify(instance, pk_pt, pk_c, message, message_len, signature, signature_len); } diff --git a/src/sig/picnic/external/picnic2_L1_FS/api.h b/src/sig/picnic/external/picnic2_L1_FS/api.h index e95c439d0..bb1a4af47 100644 --- a/src/sig/picnic/external/picnic2_L1_FS/api.h +++ b/src/sig/picnic/external/picnic2_L1_FS/api.h @@ -5,6 +5,7 @@ #define CRYPTO_PUBLICKEYBYTES (1 + 2 * 16) #define CRYPTO_BYTES (4 + 13802) #define CRYPTO_ALGNAME "picnic2l1fs" +#define CRYPTO_DETERMINISTIC 1 int crypto_sign_keypair(unsigned char* pk, unsigned char* sk); int crypto_sign(unsigned char* sm, unsigned long long* smlen, const unsigned char* m, diff --git a/src/sig/picnic/external/picnic2_L3_FS/api.h b/src/sig/picnic/external/picnic2_L3_FS/api.h index c42d5b43b..9a2d0c4bc 100644 --- a/src/sig/picnic/external/picnic2_L3_FS/api.h +++ b/src/sig/picnic/external/picnic2_L3_FS/api.h @@ -5,6 +5,7 @@ #define CRYPTO_PUBLICKEYBYTES (1 + 2 * 24) #define CRYPTO_BYTES (4 + 29750) #define CRYPTO_ALGNAME "picnic2l3fs" +#define CRYPTO_DETERMINISTIC 1 int crypto_sign_keypair(unsigned char* pk, unsigned char* sk); int crypto_sign(unsigned char* sm, unsigned long long* smlen, const unsigned char* m, diff --git a/src/sig/picnic/external/picnic2_L5_FS/api.h b/src/sig/picnic/external/picnic2_L5_FS/api.h index 1ecebb94a..8b52192fe 100644 --- a/src/sig/picnic/external/picnic2_L5_FS/api.h +++ b/src/sig/picnic/external/picnic2_L5_FS/api.h @@ -5,6 +5,7 @@ #define CRYPTO_PUBLICKEYBYTES (1 + 2 * 32) #define CRYPTO_BYTES (4 + 54732) #define CRYPTO_ALGNAME "picnic2l5fs" +#define CRYPTO_DETERMINISTIC 1 int crypto_sign_keypair(unsigned char* pk, unsigned char* sk); int crypto_sign(unsigned char* sm, unsigned long long* smlen, const unsigned char* m, diff --git a/src/sig/picnic/external/picnic2_impl.c b/src/sig/picnic/external/picnic2_impl.c index 7666b2b86..b10216dcd 100644 --- a/src/sig/picnic/external/picnic2_impl.c +++ b/src/sig/picnic/external/picnic2_impl.c @@ -10,22 +10,22 @@ * SPDX-License-Identifier: MIT */ +#include #include #include #include #include #include -#include +#include "io.h" #include "kdf_shake.h" #include "macros.h" -#include "picnic_impl.h" -#include "picnic2_impl.h" #include "picnic.h" -#include "picnic2_types.h" -#include "picnic2_tree.h" +#include "picnic2_impl.h" #include "picnic2_simulate_mul.h" -#include "io.h" +#include "picnic2_tree.h" +#include "picnic2_types.h" +#include "picnic_impl.h" #define LOWMC_MAX_KEY_BITS 256 #define LOWMC_MAX_AND_GATES (3 * 38 * 10 + 4) /* Rounded to nearest byte */ @@ -40,7 +40,7 @@ static uint32_t numBytes(uint32_t numBits) { static void createRandomTapes(randomTape_t* tapes, uint8_t** seeds, uint8_t* salt, size_t t, const picnic_instance_t* params) { - Keccak_HashInstancetimes4 ctx; + hash_context_x4 ctx; size_t tapeSizeBytes = 2 * params->view_size + params->input_size; @@ -54,14 +54,15 @@ static void createRandomTapes(randomTape_t* tapes, uint8_t** seeds, uint8_t* sal const uint8_t* salt_ptr[4] = {salt, salt, salt, salt}; hash_update_x4(&ctx, salt_ptr, SALT_SIZE); uint16_t tLE = htole16((uint16_t)t); - const uint8_t* tLE_ptr[4] = {(const uint8_t*)&tLE, (const uint8_t*)&tLE, (const uint8_t*)&tLE, (const uint8_t*)&tLE}; + const uint8_t* tLE_ptr[4] = {(const uint8_t*)&tLE, (const uint8_t*)&tLE, (const uint8_t*)&tLE, + (const uint8_t*)&tLE}; hash_update_x4(&ctx, tLE_ptr, sizeof(uint16_t)); uint16_t iLE0 = htole16((uint16_t)(i + 0)); uint16_t iLE1 = htole16((uint16_t)(i + 1)); uint16_t iLE2 = htole16((uint16_t)(i + 2)); uint16_t iLE3 = htole16((uint16_t)(i + 3)); - const uint8_t* iLE_ptr[4] = {(const uint8_t*)&iLE0, (const uint8_t*)&iLE1, (const uint8_t*)&iLE2, - (const uint8_t*)&iLE3}; + const uint8_t* iLE_ptr[4] = {(const uint8_t*)&iLE0, (const uint8_t*)&iLE1, + (const uint8_t*)&iLE2, (const uint8_t*)&iLE3}; hash_update_x4(&ctx, iLE_ptr, sizeof(uint16_t)); hash_final_x4(&ctx); @@ -82,47 +83,62 @@ static void tapesToWords(shares_t* shares, randomTape_t* tapes) { } } -static uint64_t aux_mpc_AND(uint64_t mask_a, uint64_t mask_b, randomTape_t* tapes) { - // uint64_t mask_a = parity64_uint64(a); //inputs are already parity - // uint64_t mask_b = parity64_uint64(b); //inputs are already parity - uint64_t fresh_output_mask = tapesToWord(tapes); +static void aux_mpc_AND_bitsliced(uint64_t mask_a, uint64_t mask_b, uint64_t mask_c, uint64_t* ab, + uint64_t* bc, uint64_t* ca, randomTape_t* tapes) { - uint64_t and_helper = tapesToWord(tapes); + for (int i = 0; i < 10; i++) { + uint64_t fresh_output_maks_ab = tapesToParityOfWord(tapes, 0); + uint64_t and_helper_ab = tapesToParityOfWord(tapes, 1); + uint64_t fresh_output_maks_bc = tapesToParityOfWord(tapes, 0); + uint64_t and_helper_bc = tapesToParityOfWord(tapes, 1); + uint64_t fresh_output_maks_ca = tapesToParityOfWord(tapes, 0); + uint64_t and_helper_ca = tapesToParityOfWord(tapes, 1); - /* Zero the last party's share of the helper value, compute it based on the - * input masks; then update the tape. */ - setBit((uint8_t*)&and_helper, 63, 0); - uint64_t aux_bit = (mask_a & mask_b) ^ parity64_uint64(and_helper); - size_t lastParty = tapes->nTapes - 1; - setBit(tapes->tape[lastParty], tapes->pos - 1, (uint8_t)aux_bit); + uint64_t aux_bit_ab = (((mask_a & mask_b) >> (63 - 3 * i)) & 1) ^ and_helper_ab; + uint64_t aux_bit_bc = (((mask_b & mask_c) >> (63 - 3 * i)) & 1) ^ and_helper_bc; + uint64_t aux_bit_ca = (((mask_c & mask_a) >> (63 - 3 * i)) & 1) ^ and_helper_ca; - return fresh_output_mask; + setBit(tapes->tape[63], tapes->pos - 5, (uint8_t)aux_bit_ab); + setBit(tapes->tape[63], tapes->pos - 3, (uint8_t)aux_bit_bc); + setBit(tapes->tape[63], tapes->pos - 1, (uint8_t)aux_bit_ca); + setBit(tapes->aux_bits, tapes->aux_pos++, (uint8_t)aux_bit_ab); + setBit(tapes->aux_bits, tapes->aux_pos++, (uint8_t)aux_bit_bc); + setBit(tapes->aux_bits, tapes->aux_pos++, (uint8_t)aux_bit_ca); + + *ab <<= 3; + *ab |= fresh_output_maks_ab; + *bc <<= 3; + *bc |= fresh_output_maks_bc; + *ca <<= 3; + *ca |= fresh_output_maks_ca; + } + *ab <<= 36; + *bc <<= 36; + *ca <<= 36; } /** - * S-box for m = 10, for Picnic2 aux computation + * S-box for m = 10, for Picnic2 aux computation, as bitsliced as possible */ void sbox_layer_10_uint64_aux(uint64_t* d, randomTape_t* tapes) { - uint64_t dBE = htobe64(*d); - uint8_t state[sizeof(dBE)]; - memcpy(state, &dBE, sizeof(dBE)); + uint64_t in = *d; - for (uint32_t i = 0; i < 30; i += 3) { - const uint8_t a = getBit(state, i + 2); - const uint8_t b = getBit(state, i + 1); - const uint8_t c = getBit(state, i + 0); + // a, b, c + const uint64_t x0s = (in & MASK_X0I) << 2; + const uint64_t x1s = (in & MASK_X1I) << 1; + const uint64_t x2m = in & MASK_X2I; - const uint8_t ab = parity64_uint64(aux_mpc_AND(a, b, tapes)); - const uint8_t bc = parity64_uint64(aux_mpc_AND(b, c, tapes)); - const uint8_t ca = parity64_uint64(aux_mpc_AND(c, a, tapes)); + uint64_t ab = 0, bc = 0, ca = 0; + aux_mpc_AND_bitsliced(x0s, x1s, x2m, &ab, &bc, &ca, tapes); - setBit(state, i + 2, a ^ bc); - setBit(state, i + 1, a ^ b ^ ca); - setBit(state, i + 0, a ^ b ^ c ^ ab); - } + // (b & c) ^ a + const uint64_t t0 = (bc) ^ x0s; + // (c & a) ^ a ^ b + const uint64_t t1 = (ca) ^ x0s ^ x1s; + // (a & b) ^ a ^ b ^c + const uint64_t t2 = (ab) ^ x0s ^ x1s ^ x2m; - memcpy(&dBE, state, sizeof(dBE)); - *d = be64toh(dBE); + *d = (in & MASK_MASK) ^ (t0 >> 2) ^ (t1 >> 1) ^ t2; } /* Input is the tapes for one parallel repitition; i.e., tapes[t] @@ -131,37 +147,36 @@ void sbox_layer_10_uint64_aux(uint64_t* d, randomTape_t* tapes) { * holds on the mask values. */ static void computeAuxTape(randomTape_t* tapes, const picnic_instance_t* params) { - shares_t* key = allocateShares(params->lowmc->n); mzd_local_t* lowmc_key = mzd_local_init_ex(params->lowmc->n, 1, true); - tapesToWords(key, tapes); - uint8_t temp[32] = { 0, }; + // combine into key shares and calculate lowmc evaluation in plain - for (uint32_t i = 0; i < params->lowmc->n; i++) { - uint8_t key_bit = parity64_uint64(key->shares[i]); - setBit(temp, i, key_bit); + for (size_t i = 0; i < params->num_MPC_parties; i++) { + for (size_t j = 0; j < params->input_size; j++) { + temp[j] ^= tapes->tape[i][j]; + } } mzd_from_char_array(lowmc_key, temp, params->lowmc->n / 8); + tapes->pos = params->lowmc->n; lowmc_compute_aux_implementation_f lowmc_aux_impl = params->impls.lowmc_aux; - // Perform LowMC evaluation and record state before AND gates + // Perform LowMC evaluation and fix AND masks for all AND gates lowmc_aux_impl(lowmc_key, tapes); // Reset the random tape counter so that the online execution uses the // same random bits as when computing the aux shares tapes->pos = 0; - freeShares(key); mzd_local_free(lowmc_key); } static void commit(uint8_t* digest, const uint8_t* seed, const uint8_t* aux, const uint8_t* salt, size_t t, size_t j, const picnic_instance_t* params) { /* Compute C[t][j]; as digest = H(seed||[aux]) aux is optional */ - Keccak_HashInstance ctx; + hash_context ctx; hash_init(&ctx, params); hash_update(&ctx, seed, params->seed_size); @@ -178,10 +193,10 @@ static void commit(uint8_t* digest, const uint8_t* seed, const uint8_t* aux, con hash_squeeze(&ctx, digest, params->digest_size); } -static void commit_x4(uint8_t** digest, const uint8_t** seed, const uint8_t* salt, size_t t, size_t j, - const picnic_instance_t* params) { +static void commit_x4(uint8_t** digest, const uint8_t** seed, const uint8_t* salt, size_t t, + size_t j, const picnic_instance_t* params) { /* Compute C[t][j]; as digest = H(seed||[aux]) aux is optional */ - Keccak_HashInstancetimes4 ctx; + hash_context_x4 ctx; hash_init_x4(&ctx, params); hash_update_x4(&ctx, seed, params->seed_size); @@ -203,20 +218,37 @@ static void commit_x4(uint8_t** digest, const uint8_t** seed, const uint8_t* sal } static void commit_h(uint8_t* digest, const commitments_t* C, const picnic_instance_t* params) { - Keccak_HashInstance ctx; + hash_context ctx; hash_init(&ctx, params); for (size_t i = 0; i < params->num_MPC_parties; i++) { - hash_update(&ctx, C->hashes[i], params->seed_size); + hash_update(&ctx, C->hashes[i], params->digest_size); } hash_final(&ctx); hash_squeeze(&ctx, digest, params->digest_size); } +static void commit_h_x4(uint8_t** digest, const commitments_t* C, const picnic_instance_t* params) { + hash_context_x4 ctx; + + hash_init_x4(&ctx, params); + for (size_t i = 0; i < params->num_MPC_parties; i++) { + const uint8_t* data[4] = { + C[0].hashes[i], + C[1].hashes[i], + C[2].hashes[i], + C[3].hashes[i], + }; + hash_update_x4(&ctx, data, params->digest_size); + } + hash_final_x4(&ctx); + hash_squeeze_x4(&ctx, digest, params->digest_size); +} + // Commit to the views for one parallel rep static void commit_v(uint8_t* digest, const uint8_t* input, const msgs_t* msgs, const picnic_instance_t* params) { - Keccak_HashInstance ctx; + hash_context ctx; hash_init(&ctx, params); hash_update(&ctx, input, params->input_size); @@ -227,6 +259,26 @@ static void commit_v(uint8_t* digest, const uint8_t* input, const msgs_t* msgs, hash_squeeze(&ctx, digest, params->digest_size); } +static void commit_v_x4(uint8_t** digest, const uint8_t** input, const msgs_t* msgs, + const picnic_instance_t* params) { + hash_context_x4 ctx; + + hash_init_x4(&ctx, params); + hash_update_x4(&ctx, input, params->input_size); + for (size_t i = 0; i < params->num_MPC_parties; i++) { + assert(msgs[0].pos == msgs[1].pos && msgs[2].pos == msgs[3].pos && msgs[0].pos == msgs[2].pos); + const uint8_t* data[4] = { + msgs[0].msgs[i], + msgs[1].msgs[i], + msgs[2].msgs[i], + msgs[3].msgs[i], + }; + hash_update_x4(&ctx, data, numBytes(msgs->pos)); + } + hash_final_x4(&ctx); + hash_squeeze_x4(&ctx, digest, params->digest_size); +} + static int contains(const uint16_t* list, size_t len, uint16_t value) { for (size_t i = 0; i < len; i++) { if (list[i] == value) { @@ -246,20 +298,6 @@ static int indexOf(const uint16_t* list, size_t len, uint16_t value) { return -1; } -static void getAuxBits(uint8_t* output, randomTape_t* tapes, const picnic_instance_t* params) { - size_t firstAuxIndex = params->lowmc->n + 1; - size_t last = params->num_MPC_parties - 1; - size_t pos = 0; - - memset(output, 0, params->view_size); - size_t andSizeBits = 3 * params->lowmc->r * params->lowmc->m; - for (size_t i = 0; i < andSizeBits * 2; i += 2) { - uint8_t auxBit = getBit(tapes->tape[last], firstAuxIndex + i); - setBit(output, pos, auxBit); - pos++; - } -} - static void setAuxBits(randomTape_t* tapes, uint8_t* input, const picnic_instance_t* params) { size_t firstAuxIndex = params->lowmc->n + 1; size_t last = params->num_MPC_parties - 1; @@ -310,7 +348,7 @@ static size_t appendUnique(uint16_t* list, uint16_t value, size_t position) { static void HCP(uint16_t* challengeC, uint16_t* challengeP, commitments_t* Ch, uint8_t* hCv, uint8_t* salt, const uint32_t* pubKey, const uint32_t* plaintext, const uint8_t* message, size_t messageByteLength, const picnic_instance_t* params) { - Keccak_HashInstance ctx; + hash_context ctx; uint8_t h[MAX_DIGEST_SIZE] = {0}; assert(params->num_opened_rounds < params->num_rounds); @@ -331,7 +369,7 @@ static void HCP(uint16_t* challengeC, uint16_t* challengeP, commitments_t* Ch, u // Populate C uint32_t bitsPerChunkC = ceil_log2(params->num_rounds); uint32_t bitsPerChunkP = ceil_log2(params->num_MPC_parties); - uint16_t* chunks = calloc(params->digest_size * 8 / bitsPerChunkP, sizeof(uint16_t)); + uint16_t* chunks = calloc(params->digest_size * 8 / MIN(bitsPerChunkP,bitsPerChunkC), sizeof(uint16_t)); size_t countC = 0; while (countC < params->num_opened_rounds) { @@ -393,10 +431,12 @@ static uint16_t* getMissingLeavesList(uint16_t* challengeC, const picnic_instanc int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* plaintext, const uint8_t* message, size_t messageByteLength, const picnic_instance_t* params) { - commitments_t* C = allocateCommitments(params, 0); - commitments_t Ch = {0}; - commitments_t Cv = {0}; - msgs_t* msgs = allocateMsgs(params); + commitments_t C[4] = {0,}; + allocateCommitments2(&C[0], params, params->num_MPC_parties); + allocateCommitments2(&C[1], params, params->num_MPC_parties); + allocateCommitments2(&C[2], params, params->num_MPC_parties); + allocateCommitments2(&C[3], params, params->num_MPC_parties); + msgs_t* msgs = allocateMsgsVerify(params); tree_t* treeCv = createTree(params->num_rounds, params->digest_size); size_t challengeSizeBytes = params->num_opened_rounds * sizeof(uint16_t); uint16_t* challengeC = malloc(challengeSizeBytes); @@ -406,8 +446,18 @@ int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* pl tree_t* iSeedsTree = createTree(params->num_rounds, params->seed_size); int ret = reconstructSeeds(iSeedsTree, sig->challengeC, params->num_opened_rounds, sig->iSeedInfo, sig->iSeedInfoLen, sig->salt, 0, params); + const size_t last = params->num_MPC_parties - 1; lowmc_simulate_online_f simulateOnline = params->impls.lowmc_simulate_online; + commitments_t Ch = {0}; + allocateCommitments2(&Ch, params, params->num_rounds); + commitments_t Cv = {0}; + allocateCommitments2(&Cv, params, params->num_rounds); + shares_t* mask_shares = allocateShares(params->lowmc->n); + mzd_local_t* m_plaintext = mzd_local_init_ex(1, params->lowmc->n, false); + mzd_local_t* m_maskedKey = mzd_local_init_ex(1, params->lowmc->k, false); + mzd_from_char_array(m_plaintext, (const uint8_t*)plaintext, params->output_size); + if (ret != 0) { ret = -1; goto Exit; @@ -436,17 +486,14 @@ int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* pl goto Exit; } } - } + /* Commit */ - /* Commit */ - size_t last = params->num_MPC_parties - 1; - uint8_t auxBits[MAX_AUX_BYTES]; - for (size_t t = 0; t < params->num_rounds; t++) { /* Compute random tapes for all parties. One party for each repitition * challengeC will have a bogus seed; but we won't use that party's * random tape. */ createRandomTapes(&tapes[t], getLeaves(seeds[t]), sig->salt, t, params); + if (!contains(sig->challengeC, params->num_opened_rounds, t)) { /* We're given iSeed, have expanded the seeds, compute aux from scratch so we can comnpte * Com[t] */ @@ -454,10 +501,12 @@ int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* pl for (size_t j = 0; j < params->num_MPC_parties; j += 4) { const uint8_t* seed_ptr[4] = {getLeaf(seeds[t], j + 0), getLeaf(seeds[t], j + 1), getLeaf(seeds[t], j + 2), getLeaf(seeds[t], j + 3)}; - commit_x4(C[t].hashes + j, seed_ptr, sig->salt, t, j, params); + commit_x4(C[t%4].hashes + j, seed_ptr, sig->salt, t, j, params); } - getAuxBits(auxBits, &tapes[t], params); - commit(C[t].hashes[last], getLeaf(seeds[t], last), auxBits, sig->salt, t, last, params); + commit(C[t%4].hashes[last], getLeaf(seeds[t], last), tapes[t].aux_bits, sig->salt, t, last, + params); + /* after we have checked the tape, we do not need it anymore for this opened iteration */ + freeRandomTape(&tapes[t]); } else { /* We're given all seeds and aux bits, execpt for the unopened * party, we get their commitment */ @@ -465,27 +514,25 @@ int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* pl for (size_t j = 0; j < params->num_MPC_parties; j += 4) { const uint8_t* seed_ptr[4] = {getLeaf(seeds[t], j + 0), getLeaf(seeds[t], j + 1), getLeaf(seeds[t], j + 2), getLeaf(seeds[t], j + 3)}; - commit_x4(C[t].hashes + j, seed_ptr, sig->salt, t, j, params); + commit_x4(C[t%4].hashes + j, seed_ptr, sig->salt, t, j, params); } if (last != unopened) { - commit(C[t].hashes[last], getLeaf(seeds[t], last), sig->proofs[t].aux, sig->salt, t, last, + commit(C[t%4].hashes[last], getLeaf(seeds[t], last), sig->proofs[t].aux, sig->salt, t, last, params); } - memcpy(C[t].hashes[unopened], sig->proofs[t].C, params->digest_size); + memcpy(C[t%4].hashes[unopened], sig->proofs[t].C, params->digest_size); } - } + /* hash commitments every four iterations if possible, for the last few do single commitments */ + if(t >= params->num_rounds / 4 * 4) { + commit_h(Ch.hashes[t], &C[t%4], params); + } else if ((t + 1) % 4 == 0) { + size_t t4 = t / 4 * 4; + commit_h_x4(&Ch.hashes[t4], &C[0], params); + } + freeTree(seeds[t]); - /* Commit to the commitments */ - allocateCommitments2(&Ch, params, params->num_rounds); - for (size_t t = 0; t < params->num_rounds; t++) { - commit_h(Ch.hashes[t], &C[t], params); - } - - /* Commit to the views */ - allocateCommitments2(&Cv, params, params->num_rounds); - shares_t* mask_shares = allocateShares(params->lowmc->n); - for (size_t t = 0; t < params->num_rounds; t++) { + /* Commit to the views */ if (contains(sig->challengeC, params->num_opened_rounds, t)) { /* 2. When t is in C, we have everything we need to re-compute the view, as an honest signer * would. @@ -495,26 +542,28 @@ int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* pl size_t tapeLengthBytes = 2 * params->view_size + params->input_size; setAuxBits(&tapes[t], sig->proofs[t].aux, params); memset(tapes[t].tape[unopened], 0, tapeLengthBytes); - memcpy(msgs[t].msgs[unopened], sig->proofs[t].msgs, params->view_size + params->input_size); - msgs[t].unopened = unopened; + memcpy(msgs->msgs[unopened], sig->proofs[t].msgs, params->view_size + params->input_size); + msgs->pos = 0; + msgs->unopened = unopened; tapesToWords(mask_shares, &tapes[t]); - ret = simulateOnline((uint32_t*)sig->proofs[t].input, mask_shares, &tapes[t], &msgs[t], - plaintext, pubKey, params); + mzd_from_char_array(m_maskedKey, sig->proofs[t].input, params->input_size); + ret = simulateOnline(m_maskedKey, mask_shares, &tapes[t], msgs, + m_plaintext, pubKey, params); + + freeRandomTape(&tapes[t]); if (ret != 0) { #if !defined(NDEBUG) printf("MPC simulation failed for round %lu, signature invalid\n", t); #endif ret = -1; - freeShares(mask_shares); goto Exit; } - commit_v(Cv.hashes[t], sig->proofs[t].input, &msgs[t], params); + commit_v(Cv.hashes[t], sig->proofs[t].input, msgs, params); } else { Cv.hashes[t] = NULL; } } - freeShares(mask_shares); size_t missingLeavesSize = params->num_rounds - params->num_opened_rounds; uint16_t* missingLeaves = getMissingLeavesList(sig->challengeC, params); @@ -549,18 +598,20 @@ int verify_picnic2(signature2_t* sig, const uint32_t* pubKey, const uint32_t* pl Exit: + mzd_local_free(m_plaintext); + mzd_local_free(m_maskedKey); + freeShares(mask_shares); free(challengeC); free(challengeP); - freeCommitments(C); + freeCommitments2(&C[0]); + freeCommitments2(&C[1]); + freeCommitments2(&C[2]); + freeCommitments2(&C[3]); freeCommitments2(&Cv); freeCommitments2(&Ch); freeMsgs(msgs); freeTree(treeCv); freeTree(iSeedsTree); - for (size_t t = 0; t < params->num_rounds; t++) { - freeRandomTape(&tapes[t]); - freeTree(seeds[t]); - } free(seeds); free(tapes); @@ -571,7 +622,7 @@ static void computeSaltAndRootSeed(uint8_t* saltAndRoot, size_t saltAndRootLengt uint32_t* privateKey, uint32_t* pubKey, uint32_t* plaintext, const uint8_t* message, size_t messageByteLength, const picnic_instance_t* params) { - Keccak_HashInstance ctx; + hash_context ctx; hash_init(&ctx, params); hash_update(&ctx, (const uint8_t*)privateKey, params->input_size); @@ -600,63 +651,78 @@ int sign_picnic2(uint32_t* privateKey, uint32_t* pubKey, uint32_t* plaintext, randomTape_t* tapes = malloc(params->num_rounds * sizeof(randomTape_t)); tree_t** seeds = malloc(params->num_rounds * sizeof(tree_t*)); - for (size_t t = 0; t < params->num_rounds; t++) { - seeds[t] = generateSeeds(params->num_MPC_parties, iSeeds[t], sig->salt, t, params); - createRandomTapes(&tapes[t], getLeaves(seeds[t]), sig->salt, t, params); - } + commitments_t C[4]; + allocateCommitments2(&C[0], params, params->num_MPC_parties); + allocateCommitments2(&C[1], params, params->num_MPC_parties); + allocateCommitments2(&C[2], params, params->num_MPC_parties); + allocateCommitments2(&C[3], params, params->num_MPC_parties); - /* Preprocessing; compute aux tape for the N-th player, for each parallel rep */ - uint8_t auxBits[MAX_AUX_BYTES]; - for (size_t t = 0; t < params->num_rounds; t++) { - computeAuxTape(&tapes[t], params); - } - - /* Commit to seeds and aux bits */ - commitments_t* C = allocateCommitments(params, 0); - for (size_t t = 0; t < params->num_rounds; t++) { - assert(params->num_MPC_parties % 4 == 0); - for (size_t j = 0; j < params->num_MPC_parties; j += 4) { - const uint8_t* seed_ptr[4] = {getLeaf(seeds[t], j + 0), getLeaf(seeds[t], j + 1), - getLeaf(seeds[t], j + 2), getLeaf(seeds[t], j + 3)}; - commit_x4(C[t].hashes + j, seed_ptr, sig->salt, t, j, params); - } - size_t last = params->num_MPC_parties - 1; - getAuxBits(auxBits, &tapes[t], params); - commit(C[t].hashes[last], getLeaf(seeds[t], last), auxBits, sig->salt, t, last, params); - } - - /* Simulate the online phase of the MPC */ lowmc_simulate_online_f simulateOnline = params->impls.lowmc_simulate_online; inputs_t inputs = allocateInputs(params); msgs_t* msgs = allocateMsgs(params); shares_t* mask_shares = allocateShares(params->lowmc->n); + + /* Commitments to the commitments and views */ + commitments_t Ch; + allocateCommitments2(&Ch, params, params->num_rounds); + commitments_t Cv; + allocateCommitments2(&Cv, params, params->num_rounds); + + mzd_local_t* m_plaintext = mzd_local_init_ex(1, params->lowmc->n, false); + mzd_local_t* m_maskedKey = mzd_local_init_ex(1, params->lowmc->k, false); + + mzd_from_char_array(m_plaintext, (const uint8_t*)plaintext, params->output_size); + + for (size_t t = 0; t < params->num_rounds; t++) { + seeds[t] = generateSeeds(params->num_MPC_parties, iSeeds[t], sig->salt, t, params); + createRandomTapes(&tapes[t], getLeaves(seeds[t]), sig->salt, t, params); + /* Preprocessing; compute aux tape for the N-th player, for each parallel rep */ + computeAuxTape(&tapes[t], params); + /* Commit to seeds and aux bits */ + assert(params->num_MPC_parties % 4 == 0); + for (size_t j = 0; j < params->num_MPC_parties; j += 4) { + const uint8_t* seed_ptr[4] = {getLeaf(seeds[t], j + 0), getLeaf(seeds[t], j + 1), + getLeaf(seeds[t], j + 2), getLeaf(seeds[t], j + 3)}; + commit_x4(C[t%4].hashes + j, seed_ptr, sig->salt, t, j, params); + } + const size_t last = params->num_MPC_parties - 1; + commit(C[t%4].hashes[last], getLeaf(seeds[t], last), tapes[t].aux_bits, sig->salt, t, last, + params); + + /* Simulate the online phase of the MPC */ uint32_t* maskedKey = (uint32_t*)inputs[t]; tapesToWords(mask_shares, &tapes[t]); reconstructShares(maskedKey, mask_shares); // maskedKey = masks xor_word_array(maskedKey, maskedKey, privateKey, (params->input_size / 4)); // maskedKey += privateKey + mzd_from_char_array(m_maskedKey, (const uint8_t*)maskedKey, params->input_size); - int rv = simulateOnline(maskedKey, mask_shares, &tapes[t], &msgs[t], plaintext, pubKey, params); + int rv = simulateOnline(m_maskedKey, mask_shares, &tapes[t], &msgs[t], m_plaintext, pubKey, params); if (rv != 0) { #if !defined(NDEBUG) printf("MPC simulation failed, aborting signature\n"); #endif ret = -1; } + /* free the expanded random tape and associated buffers to reduce memory usage, + however, we are keeping the calculated aux bits for later (hence partial) */ + partialFreeRandomTape(&tapes[t]); + /* hash commitments every four iterations if possible, for the last few do single commitments */ + if(t >= params->num_rounds / 4 * 4) { + commit_h(Ch.hashes[t], &C[t%4], params); + commit_v(Cv.hashes[t], inputs[t], &msgs[t], params); + } else if ((t + 1) % 4 == 0) { + size_t t4 = t / 4 * 4; + commit_h_x4(&Ch.hashes[t4], &C[0], params); + commit_v_x4(&Cv.hashes[t4], (const uint8_t**)&inputs[t4], &msgs[t4], params); + } + } freeShares(mask_shares); - - /* Commit to the commitments and views */ - commitments_t Ch; - allocateCommitments2(&Ch, params, params->num_rounds); - commitments_t Cv; - allocateCommitments2(&Cv, params, params->num_rounds); - for (size_t t = 0; t < params->num_rounds; t++) { - commit_h(Ch.hashes[t], &C[t], params); - commit_v(Cv.hashes[t], inputs[t], &msgs[t], params); - } + mzd_local_free(m_maskedKey); + mzd_local_free(m_plaintext); /* Create a Merkle tree with Cv as the leaves */ tree_t* treeCv = createTree(params->num_rounds, params->digest_size); @@ -701,20 +767,28 @@ int sign_picnic2(uint32_t* privateKey, uint32_t* pubKey, uint32_t* plaintext, size_t last = params->num_MPC_parties - 1; if (challengeP[P_index] != last) { - getAuxBits(proofs[t].aux, &tapes[t], params); + memcpy(proofs[t].aux, tapes[t].aux_bits, params->view_size); } memcpy(proofs[t].input, inputs[t], params->input_size); memcpy(proofs[t].msgs, msgs[t].msgs[challengeP[P_index]], params->view_size + params->input_size); - memcpy(proofs[t].C, C[t].hashes[proofs[t].unOpenedIndex], params->digest_size); + + /* recompute commitment of unopened party since we did not store it for memory optimization */ + if (proofs[t].unOpenedIndex == params->num_MPC_parties - 1) { + commit(proofs[t].C, getLeaf(seeds[t], proofs[t].unOpenedIndex), + tapes[t].aux_bits, sig->salt, t, proofs[t].unOpenedIndex, params); + } else { + commit(proofs[t].C, getLeaf(seeds[t], proofs[t].unOpenedIndex), + NULL, sig->salt, t, proofs[t].unOpenedIndex, params); + } } } sig->proofs = proofs; for (size_t t = 0; t < params->num_rounds; t++) { - freeRandomTape(&tapes[t]); + finalFreeRandomTape(&tapes[t]); freeTree(seeds[t]); } free(tapes); @@ -722,9 +796,12 @@ int sign_picnic2(uint32_t* privateKey, uint32_t* pubKey, uint32_t* plaintext, freeTree(iSeedsTree); freeTree(treeCv); - freeCommitments(C); freeCommitments2(&Ch); freeCommitments2(&Cv); + freeCommitments2(&C[0]); + freeCommitments2(&C[1]); + freeCommitments2(&C[2]); + freeCommitments2(&C[3]); freeInputs(inputs); freeMsgs(msgs); diff --git a/src/sig/picnic/external/picnic2_simulate.c b/src/sig/picnic/external/picnic2_simulate.c index 932106b53..436a2641b 100644 --- a/src/sig/picnic/external/picnic2_simulate.c +++ b/src/sig/picnic/external/picnic2_simulate.c @@ -20,6 +20,7 @@ #include "io.h" #include "picnic2_simulate.h" #include "picnic2_simulate_mul.h" +#include "compat.h" static void wordToMsgsNoTranspose(uint64_t w, msgs_t* msgs) { ((uint64_t*)msgs->msgs[msgs->pos % 64])[msgs->pos / 64] = w; @@ -27,26 +28,26 @@ static void wordToMsgsNoTranspose(uint64_t w, msgs_t* msgs) { } static void msgsTranspose(msgs_t* msgs) { - uint64_t buffer_in[64]; - uint64_t buffer_out[64]; + uint64_t* buffer = aligned_alloc(32, 64 * sizeof(uint64_t)); size_t pos; for (pos = 0; pos < msgs->pos / 64; pos++) { for (size_t i = 0; i < 64; i++) { - buffer_in[i / 8 * 8 + 7 - i % 8] = ((uint64_t*)msgs->msgs[i])[pos]; + buffer[i] = ((uint64_t*)msgs->msgs[i])[pos]; } - transpose_64_64(buffer_in, buffer_out); + transpose_64_64(buffer, buffer); for (size_t i = 0; i < 64; i++) { - ((uint64_t*)msgs->msgs[i])[pos] = buffer_out[(i) / 8 * 8 + 7 - (i) % 8]; + ((uint64_t*)msgs->msgs[i])[pos] = buffer[i]; } } - memset(&buffer_in, 0, 64 * sizeof(uint64_t)); + memset(buffer, 0, 64 * sizeof(uint64_t)); for (size_t i = 0; i < msgs->pos % 64; i++) { - buffer_in[i / 8 * 8 + 7 - i % 8] = ((uint64_t*)msgs->msgs[i])[pos]; + buffer[i] = ((uint64_t*)msgs->msgs[i])[pos]; } - transpose_64_64(buffer_in, buffer_out); + transpose_64_64(buffer, buffer); for (size_t i = 0; i < 64; i++) { - ((uint64_t*)msgs->msgs[i])[pos] = buffer_out[(i) / 8 * 8 + 7 - (i) % 8]; + ((uint64_t*)msgs->msgs[i])[pos] = buffer[i]; } + aligned_free(buffer); } /* For each word in shares; write player i's share to their stream of msgs */ @@ -56,6 +57,12 @@ static void broadcast(shares_t* shares, msgs_t* msgs) { } } +/* For an input bit b = 0 or 1, return the word of all b bits, i.e., + * extend(1) = 0xFFFFFFFFFFFFFFFF + * extend(0) = 0x0000000000000000 + * Assumes inputs are always 0 or 1. If this doesn't hold, add "& 1" to the + * input. + */ static inline uint64_t extend(uint64_t bit) { return ~(bit - 1); } @@ -80,8 +87,10 @@ static uint8_t mpc_AND(uint8_t a, uint8_t b, uint64_t mask_a, uint64_t mask_b, r return (uint8_t)(parity64_uint64(s_shares) ^ (a & b)); } -static void mpc_sbox(uint32_t* state, shares_t* state_masks, randomTape_t* tapes, msgs_t* msgs, +static void mpc_sbox(mzd_local_t* statein, shares_t* state_masks, randomTape_t* tapes, msgs_t* msgs, uint8_t* unopenened_msg, const picnic_instance_t* params) { + uint8_t state[32]; + mzd_to_char_array(state, statein, params->lowmc->n / 8); for (size_t i = 0; i < params->lowmc->m * 3; i += 3) { uint8_t a = getBit((uint8_t*)state, i + 2); uint64_t mask_a = state_masks->shares[i + 2]; @@ -105,6 +114,7 @@ static void mpc_sbox(uint32_t* state, shares_t* state_masks, randomTape_t* tapes setBit((uint8_t*)state, i, a ^ b ^ c ^ ab); state_masks->shares[i] = mask_a ^ mask_b ^ mask_c ^ ab_mask; } + mzd_from_char_array(statein, state, params->lowmc->n / 8); } #if defined(REDUCED_ROUND_KEY_COMPUTATION) @@ -114,18 +124,21 @@ static void mpc_xor_masks_nl(shares_t* out, const shares_t* a, const shares_t* b out->shares[i] = a->shares[i] ^ b->shares[index + num - 1 - i]; } } - -static void mpc_xor2_nl(uint32_t* output, shares_t* output_masks, const uint32_t* x, - const shares_t* x_masks, const uint32_t* y, const shares_t* y_masks, - size_t index, size_t num) { - xor_array_RC((uint8_t*)output, (uint8_t*)x, (uint8_t*)&y[index / 32], 4); - // xor masks - mpc_xor_masks_nl(output_masks, x_masks, y_masks, index, num); -} #endif #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) -static void mpc_shuffle(uint8_t* state, shares_t* mask_shares, uint64_t r_mask) { +static void mpc_shuffle(mzd_local_t* state, shares_t* mask_shares, uint64_t r_mask) { + if (mask_shares->numWords == 128) { + mzd_shuffle_128_30(state, r_mask); + } + else if (mask_shares->numWords == 192) { + mzd_shuffle_192_30(state, r_mask); + } + else if (mask_shares->numWords == 256) { + mzd_shuffle_256_30(state, r_mask); + } else { + assert(false && "invalid state size"); + } for (int i = 63; i >= 0 && r_mask != UINT64_C(0xFFFFFFFC00000000); i--) { if (!((r_mask >> i) & 1)) { // bit is not set // find next 1 and swap all entries until then @@ -135,10 +148,6 @@ static void mpc_shuffle(uint8_t* state, shares_t* mask_shares, uint64_t r_mask) uint64_t t = mask_shares->shares[63 - k]; mask_shares->shares[63 - k] = mask_shares->shares[63 - k - 1]; mask_shares->shares[63 - k - 1] = t; - - uint8_t bit = getBit(state, 63 - k); - setBit(state, 63 - k, getBit(state, 63 - k - 1)); - setBit(state, 63 - k - 1, bit); } r_mask |= (UINT64_C(1) << i); // set bit i r_mask &= ~(UINT64_C(1) << j); // clear bit j @@ -158,16 +167,10 @@ static void mpc_xor_masks(shares_t* out, const shares_t* a, const shares_t* b) { out->shares[i] = a->shares[i] ^ b->shares[i]; } } - -static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x, - const shares_t* x_masks, const uint32_t* y, const shares_t* y_masks, - const picnic_instance_t* params) { - xor_word_array(output, x, y, (params->input_size / 4)); - mpc_xor_masks(output_masks, x_masks, y_masks); -} #endif /* PICNIC2_L1_FS */ +#define XOR mzd_xor_uint64_128 #define MPC_MUL mpc_matrix_mul_uint64_128 #define MPC_MUL_MC mpc_matrix_mul_nl_part_uint64_128 #define MPC_ADDMUL_R mpc_matrix_addmul_r_uint64_128 @@ -181,6 +184,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #define SIM_ONLINE lowmc_simulate_online_uint64_128_10 #include "picnic2_simulate.c.i" #endif +#undef XOR #undef MPC_MUL #undef MPC_MUL_MC #undef MPC_ADDMUL_R @@ -191,6 +195,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #undef SIM_ONLINE /* PICNIC2_L3_FS */ +#define XOR mzd_xor_uint64_192 #define MPC_MUL mpc_matrix_mul_uint64_192 #define MPC_MUL_MC mpc_matrix_mul_nl_part_uint64_192 #define MPC_ADDMUL_R mpc_matrix_addmul_r_uint64_192 @@ -204,6 +209,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #define SIM_ONLINE lowmc_simulate_online_uint64_192_10 #include "picnic2_simulate.c.i" #endif +#undef XOR #undef MPC_MUL #undef MPC_MUL_MC #undef MPC_ADDMUL_R @@ -214,6 +220,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #undef SIM_ONLINE /* PICNIC2_L5_FS */ +#define XOR mzd_xor_uint64_256 #define MPC_MUL mpc_matrix_mul_uint64_256 #define MPC_MUL_MC mpc_matrix_mul_nl_part_uint64_256 #define MPC_ADDMUL_R mpc_matrix_addmul_r_uint64_256 @@ -227,6 +234,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #define SIM_ONLINE lowmc_simulate_online_uint64_256_10 #include "picnic2_simulate.c.i" #endif +#undef XOR #undef MPC_MUL #undef MPC_MUL_MC #undef MPC_ADDMUL_R @@ -242,6 +250,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #define FN_ATTR ATTR_TARGET_SSE2 #endif /* PICNIC2_L1_FS */ +#define XOR mzd_xor_s128_128 #define MPC_MUL mpc_matrix_mul_s128_128 #define MPC_MUL_MC mpc_matrix_mul_nl_part_s128_128 #define MPC_ADDMUL_R mpc_matrix_addmul_r_s128_128 @@ -255,6 +264,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #define SIM_ONLINE lowmc_simulate_online_s128_128_10 #include "picnic2_simulate.c.i" #endif +#undef XOR #undef MPC_MUL #undef MPC_MUL_MC #undef MPC_ADDMUL_R @@ -265,6 +275,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #undef SIM_ONLINE /* PICNIC2_L3_FS */ +#define XOR mzd_xor_s128_256 #define MPC_MUL mpc_matrix_mul_s128_192 #define MPC_MUL_MC mpc_matrix_mul_nl_part_s128_192 #define MPC_ADDMUL_R mpc_matrix_addmul_r_s128_192 @@ -278,6 +289,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #define SIM_ONLINE lowmc_simulate_online_s128_192_10 #include "picnic2_simulate.c.i" #endif +#undef XOR #undef MPC_MUL #undef MPC_MUL_MC #undef MPC_ADDMUL_R @@ -288,6 +300,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #undef SIM_ONLINE /* PICNIC2_L5_FS */ +#define XOR mzd_xor_s128_256 #define MPC_MUL mpc_matrix_mul_s128_256 #define MPC_MUL_MC mpc_matrix_mul_nl_part_s128_256 #define MPC_ADDMUL_R mpc_matrix_addmul_r_s128_256 @@ -301,6 +314,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #define SIM_ONLINE lowmc_simulate_online_s128_256_10 #include "picnic2_simulate.c.i" #endif +#undef XOR #undef MPC_MUL #undef MPC_MUL_MC #undef MPC_ADDMUL_R @@ -316,6 +330,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #if defined(WITH_AVX2) #define FN_ATTR ATTR_TARGET_AVX2 /* PICNIC2_L1_FS */ +#define XOR mzd_xor_s256_128 #define MPC_MUL mpc_matrix_mul_s256_128 #define MPC_MUL_MC mpc_matrix_mul_nl_part_s256_128 #define MPC_ADDMUL_R mpc_matrix_addmul_r_s256_128 @@ -329,6 +344,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #define SIM_ONLINE lowmc_simulate_online_s256_128_10 #include "picnic2_simulate.c.i" #endif +#undef XOR #undef MPC_MUL #undef MPC_MUL_MC #undef MPC_ADDMUL_R @@ -339,6 +355,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #undef SIM_ONLINE /* PICNIC2_L3_FS */ +#define XOR mzd_xor_s256_256 #define MPC_MUL mpc_matrix_mul_s256_192 #define MPC_MUL_MC mpc_matrix_mul_nl_part_s256_192 #define MPC_ADDMUL_R mpc_matrix_addmul_r_s256_192 @@ -352,6 +369,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #define SIM_ONLINE lowmc_simulate_online_s256_192_10 #include "picnic2_simulate.c.i" #endif +#undef XOR #undef MPC_MUL #undef MPC_MUL_MC #undef MPC_ADDMUL_R @@ -362,6 +380,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #undef SIM_ONLINE /* PICNIC2_L5_FS */ +#define XOR mzd_xor_s256_256 #define MPC_MUL mpc_matrix_mul_s256_256 #define MPC_MUL_MC mpc_matrix_mul_nl_part_s256_256 #define MPC_ADDMUL_R mpc_matrix_addmul_r_s256_256 @@ -375,6 +394,7 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #define SIM_ONLINE lowmc_simulate_online_s256_256_10 #include "picnic2_simulate.c.i" #endif +#undef XOR #undef MPC_MUL #undef MPC_MUL_MC #undef MPC_ADDMUL_R @@ -389,7 +409,11 @@ static void mpc_xor2(uint32_t* output, shares_t* output_masks, const uint32_t* x #endif // WITH_OPT lowmc_simulate_online_f lowmc_simulate_online_get_implementation(const lowmc_t* lowmc) { +#if defined(WITH_LOWMC_M1) ASSUME(lowmc->m == 10 || lowmc->m == 1); +#else + ASSUME(lowmc->m == 10); +#endif ASSUME(lowmc->n == 128 || lowmc->n == 192 || lowmc->n == 256); #if defined(WITH_OPT) diff --git a/src/sig/picnic/external/picnic2_simulate.c.i b/src/sig/picnic/external/picnic2_simulate.c.i index a77d7d3c8..80e9559ee 100644 --- a/src/sig/picnic/external/picnic2_simulate.c.i +++ b/src/sig/picnic/external/picnic2_simulate.c.i @@ -16,6 +16,9 @@ #include #include #include +#if !defined(_MSC_VER) +#include +#endif #include "kdf_shake.h" #include "macros.h" @@ -26,18 +29,17 @@ #include "picnic2_tree.h" #include "io.h" - #if defined(FN_ATTR) FN_ATTR #endif -static int SIM_ONLINE(uint32_t* maskedKey, shares_t* mask_shares, randomTape_t* tapes, msgs_t* msgs, - const uint32_t* plaintext, const uint32_t* pubKey, +static int SIM_ONLINE(mzd_local_t* maskedKey, shares_t* mask_shares, randomTape_t* tapes, msgs_t* msgs, + const mzd_local_t* plaintext, const uint32_t* pubKey, const picnic_instance_t* params) { int ret = 0; - uint32_t* roundKey = malloc(LOWMC_N / 8); - uint32_t* state = malloc(LOWMC_N / 8); - uint32_t* state2 = malloc(LOWMC_N / 8); - uint32_t* nl_part = malloc(LOWMC_R * sizeof(uint32_t)); + mzd_local_t* state = mzd_local_init_ex(1, LOWMC_N, false); + mzd_local_t* state2 = mzd_local_init_ex(1, LOWMC_N, false); + mzd_local_t* roundKey = mzd_local_init_ex(1, LOWMC_N, false); + mzd_local_t* nl_part = mzd_local_init_ex(1, (LOWMC_R * 32), false); shares_t* nl_part_masks = allocateShares(LOWMC_R * 32); shares_t* key_masks = allocateShares(LOWMC_N); // Make a copy to use when computing each round key shares_t* mask2_shares = allocateShares(LOWMC_N); @@ -51,60 +53,66 @@ static int SIM_ONLINE(uint32_t* maskedKey, shares_t* mask_shares, randomTape_t* copyShares(key_masks, mask_shares); #if defined(REDUCED_ROUND_KEY_COMPUTATION) - MPC_MUL(state, maskedKey, LOWMC_INSTANCE.k0_matrix->w64, + MPC_MUL(state, maskedKey, LOWMC_INSTANCE.k0_matrix, mask_shares); // roundKey = maskedKey * KMatrix[0] - xor_word_array(state, state, plaintext, (LOWMC_N / 32)); // state = plaintext + roundKey - xor_array_RC((uint8_t*)state, (uint8_t*)state, - (uint8_t*)LOWMC_INSTANCE.precomputed_constant_linear, - LOWMC_N / 8); // state = state + precomp_const - MPC_MUL_MC(nl_part, maskedKey, LOWMC_INSTANCE.precomputed_non_linear_part_matrix->w64, - LOWMC_INSTANCE.precomputed_constant_non_linear->w64, nl_part_masks, key_masks); + + XOR(state, state, plaintext); + XOR(state, state, LOWMC_INSTANCE.precomputed_constant_linear); + MPC_MUL_MC(nl_part, maskedKey, LOWMC_INSTANCE.precomputed_non_linear_part_matrix, + LOWMC_INSTANCE.precomputed_constant_non_linear, nl_part_masks, key_masks); #if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) for (uint32_t r = 0; r < LOWMC_R - 1; r++) { mpc_sbox(state, mask_shares, tapes, msgs, unopened_msgs, params); - mpc_xor2_nl(state, mask_shares, state, mask_shares, nl_part, nl_part_masks, r * 32 + 2, - 30); // state += roundKey - MPC_MUL_Z(state2, state, mask2_shares, mask_shares, LOWMC_INSTANCE.rounds[r].z_matrix->w64); - mpc_shuffle((uint8_t*)state, mask_shares, LOWMC_INSTANCE.rounds[r].r_mask); - MPC_ADDMUL_R(state2, state, mask2_shares, mask_shares, LOWMC_INSTANCE.rounds[r].r_matrix->w64); + mpc_xor_masks_nl(mask_shares, mask_shares, nl_part_masks, r*32 + 2, 30); + const word nl = CONST_BLOCK(nl_part, r >> 3)->w64[(r & 0x7) >> 1]; + BLOCK(state, 0)->w64[(LOWMC_N) / (sizeof(word) * 8) - 1] ^= + (nl << (1 - (r & 1)) * 32) & WORD_C(0xFFFFFFFF00000000); + + MPC_MUL_Z(state2, state, mask2_shares, mask_shares, LOWMC_INSTANCE.rounds[r].z_matrix); + mpc_shuffle(state, mask_shares, LOWMC_INSTANCE.rounds[r].r_mask); + MPC_ADDMUL_R(state2, state, mask2_shares, mask_shares, LOWMC_INSTANCE.rounds[r].r_matrix); for (uint32_t i = 0; i < 30; i++) { mask_shares->shares[i] = 0; - setBit((uint8_t*)state, i, 0); } - mpc_xor2(state, mask_shares, state, mask_shares, state2, mask2_shares, params); + BLOCK(state, 0)->w64[(LOWMC_N) / (sizeof(word) * 8) - 1] &= + WORD_C(0x00000003FFFFFFFF); // clear nl part + XOR(state, state, state2); + mpc_xor_masks(mask_shares, mask_shares, mask2_shares); } mpc_sbox(state, mask_shares, tapes, msgs, unopened_msgs, params); - mpc_xor2_nl(state, mask_shares, state, mask_shares, nl_part, nl_part_masks, - (LOWMC_R - 1) * 32 + 2, 30); // state += roundKey - MPC_MUL(state, state, LOWMC_INSTANCE.zr_matrix->w64, + mpc_xor_masks_nl(mask_shares, mask_shares, nl_part_masks, (LOWMC_R-1)*32 + 2, 30); + const word nl = CONST_BLOCK(nl_part, (LOWMC_R-1) >> 3)->w64[((LOWMC_R-1) & 0x7) >> 1]; + BLOCK(state, 0)->w64[(LOWMC_N) / (sizeof(word) * 8) - 1] ^= + (nl << (1 - ((LOWMC_R-1) & 1)) * 32) & WORD_C(0xFFFFFFFF00000000); + MPC_MUL(state, state, LOWMC_INSTANCE.zr_matrix, mask_shares); // state = state * LMatrix (r-1) #else for (uint32_t r = 0; r < LOWMC_R; r++) { mpc_sbox(state, mask_shares, tapes, msgs, unopened_msgs, params); - mpc_xor2_nl(state, mask_shares, state, mask_shares, nl_part, nl_part_masks, r * 32 + 2, - 30); // state += roundKey - MPC_MUL(state, state, LOWMC_INSTANCE.rounds[r].l_matrix->w64, + mpc_xor_masks_nl(mask_shares, mask_shares, nl_part_masks, r*32 + 2, 30); + const word nl = CONST_BLOCK(nl_part, r >> 3)->w64[(r & 0x7) >> 1]; + BLOCK(state, 0)->w64[(LOWMC_N) / (sizeof(word) * 8) - 1] ^= + (nl << (1 - (r & 1)) * 32) & WORD_C(0xFFFFFFFF00000000); + MPC_MUL(state, state, LOWMC_INSTANCE.rounds[r].l_matrix, mask_shares); // state = state * LMatrix (r-1) } #endif #else - MPC_MUL(roundKey, maskedKey, LOWMC_INSTANCE.k0_matrix->w64, + MPC_MUL(roundKey, maskedKey, LOWMC_INSTANCE.k0_matrix, mask_shares); // roundKey = maskedKey * KMatrix[0] - xor_word_array(state, roundKey, plaintext, (LOWMC_N / 32)); // state = plaintext + roundKey + XOR(state, roundKey, plaintext); shares_t* round_key_masks = allocateShares(mask_shares->numWords); for (uint32_t r = 0; r < LOWMC_R; r++) { copyShares(round_key_masks, key_masks); - MPC_MUL(roundKey, maskedKey, LOWMC_INSTANCE.rounds[r].k_matrix->w64, round_key_masks); + MPC_MUL(roundKey, maskedKey, LOWMC_INSTANCE.rounds[r].k_matrix, round_key_masks); mpc_sbox(state, mask_shares, tapes, msgs, unopened_msgs, params); - MPC_MUL(state, state, LOWMC_INSTANCE.rounds[r].l_matrix->w64, + MPC_MUL(state, state, LOWMC_INSTANCE.rounds[r].l_matrix, mask_shares); // state = state * LMatrix (r-1) - xor_array_RC((uint8_t*)state, (uint8_t*)state, - (const uint8_t*)(LOWMC_INSTANCE.rounds[r].constant->w64), - LOWMC_N / 8); // state += RConstant - mpc_xor2(state, mask_shares, roundKey, round_key_masks, state, mask_shares, - params); // state += roundKey + XOR(state, state, LOWMC_INSTANCE.rounds[r].constant); + XOR(state, state, roundKey); + mpc_xor_masks(mask_shares, mask_shares, round_key_masks); } freeShares(round_key_masks); #endif @@ -118,19 +126,19 @@ static int SIM_ONLINE(uint32_t* maskedKey, shares_t* mask_shares, randomTape_t* setBit((uint8_t*)&mask_shares->shares[i], msgs->unopened, share); } } - uint32_t output[LOWMC_N / 8]; + uint32_t output[LOWMC_N / 32]; + uint32_t outstate[LOWMC_N / 32]; + mzd_to_char_array((uint8_t*)outstate, state, LOWMC_N/8); reconstructShares(output, mask_shares); - xor_word_array(output, output, state, (LOWMC_N / 32)); + xor_word_array(output, output, outstate, (LOWMC_N / 32)); if (memcmp(output, pubKey, LOWMC_N / 8) != 0) { #if !defined(NDEBUG) printf("%s: output does not match pubKey\n", __func__); - /* printf("pubKey: "); print_hex(stdout, (uint8_t*)pubKey, LOWMC_N / 8); printf("\noutput: "); print_hex(stdout, (uint8_t*)output, LOWMC_N / 8); - */ printf("\n"); #endif ret = -1; @@ -141,10 +149,10 @@ static int SIM_ONLINE(uint32_t* maskedKey, shares_t* mask_shares, randomTape_t* msgsTranspose(msgs); free(unopened_msgs); - free(state); - free(state2); - free(roundKey); - free(nl_part); + mzd_local_free(state); + mzd_local_free(state2); + mzd_local_free(roundKey); + mzd_local_free(nl_part); freeShares(key_masks); freeShares(mask2_shares); freeShares(nl_part_masks); diff --git a/src/sig/picnic/external/picnic2_simulate.h b/src/sig/picnic/external/picnic2_simulate.h index bbe65c3c9..860a9fc04 100644 --- a/src/sig/picnic/external/picnic2_simulate.h +++ b/src/sig/picnic/external/picnic2_simulate.h @@ -17,8 +17,8 @@ typedef struct shares_t shares_t; typedef struct msgs_t msgs_t; typedef struct picnic_instance_t picnic_instance_t; -typedef int (*lowmc_simulate_online_f)(uint32_t* maskedKey, shares_t* mask_shares, - randomTape_t* tapes, msgs_t* msgs, const uint32_t* plaintext, +typedef int (*lowmc_simulate_online_f)(mzd_local_t* maskedKey, shares_t* mask_shares, + randomTape_t* tapes, msgs_t* msgs, const mzd_local_t* plaintext, const uint32_t* pubKey, const picnic_instance_t* params); lowmc_simulate_online_f lowmc_simulate_online_get_implementation(const lowmc_t* lowmc); diff --git a/src/sig/picnic/external/picnic2_simulate_mul.c b/src/sig/picnic/external/picnic2_simulate_mul.c index db96498f0..fdf05347c 100644 --- a/src/sig/picnic/external/picnic2_simulate_mul.c +++ b/src/sig/picnic/external/picnic2_simulate_mul.c @@ -7,9 +7,10 @@ * SPDX-License-Identifier: MIT */ -#include #include +#include +#include "endian_compat.h" #include "picnic2_simulate_mul.h" #if defined(WITH_SSE2) @@ -117,7 +118,8 @@ static const block_t block_masks[] = { }}, }; -static block_t nl_part_block_masks[] = { +#if defined(REDUCED_ROUND_KEY_COMPUTATION) +static const block_t nl_part_block_masks[] = { {{ UINT64_C(0x0000000000000000), UINT64_C(0x0000000000000000), @@ -215,9 +217,13 @@ static block_t nl_part_block_masks[] = { UINT64_C(0xffffffffffffffff), }}, }; +#endif -/* transpose a 64x64 bit matrix using Eklundh's algorithm */ -void transpose_64_64(const uint64_t* in, uint64_t* out) { +/* transpose a 64x64 bit matrix using Eklundh's algorithm + this variant assumes that the bit with index 0 is the lsb of byte 0 + e.g., 76543210 fedcba98 ... + */ +void transpose_64_64_lsb(const uint64_t* in, uint64_t* out) { static const uint64_t TRANSPOSE_MASKS64[6] = { UINT64_C(0x00000000FFFFFFFF), UINT64_C(0x0000FFFF0000FFFF), UINT64_C(0x00FF00FF00FF00FF), UINT64_C(0x0F0F0F0F0F0F0F0F), UINT64_C(0x3333333333333333), UINT64_C(0x5555555555555555)}; @@ -249,18 +255,246 @@ void transpose_64_64(const uint64_t* in, uint64_t* out) { } } +/* transpose a 64x64 bit matrix using Eklundh's algorithm + this variant assumes that the bit with index 0 is the msb of byte 0 + e.g., 01234567 89abcdef ... + */ +static void transpose_64_64_uint64(const uint64_t* in, uint64_t* out) { + static const uint64_t TRANSPOSE_MASKS64[6] = { + UINT64_C(0xFFFFFFFF00000000), UINT64_C(0xFFFF0000FFFF0000), UINT64_C(0xFF00FF00FF00FF00), + UINT64_C(0xF0F0F0F0F0F0F0F0), UINT64_C(0xCCCCCCCCCCCCCCCC), UINT64_C(0xAAAAAAAAAAAAAAAA)}; + + uint32_t width = 32, nswaps = 1; + const uint32_t logn = 6; + + // copy in to out and transpose in-place + memcpy(out, in, 64 * sizeof(uint64_t)); + for (uint32_t i = 0; i < 64; i++) { + out[i] = bswap64(out[i]); + } + + for (uint32_t i = 0; i < logn; i++) { + uint64_t mask = TRANSPOSE_MASKS64[i]; + uint64_t inv_mask = ~mask; + + for (uint32_t j = 0; j < nswaps; j++) { + for (uint32_t k = 0; k < width; k++) { + uint32_t i1 = k + 2 * width * j; + uint32_t i2 = k + width + 2 * width * j; + + uint64_t t1 = out[i1]; + uint64_t t2 = out[i2]; + + out[i1] = (t1 & mask) ^ ((t2 & mask) >> width); + out[i2] = (t2 & inv_mask) ^ ((t1 & inv_mask) << width); + } + } + nswaps *= 2; + width /= 2; + } + for (uint32_t i = 0; i < 64; i++) { + out[i] = bswap64(out[i]); + } +} + +#if defined(WITH_OPT) +#if defined(WITH_SSE2) || defined(WITH_NEON) +/* transpose a 64x64 bit matrix using Eklundh's algorithm + this variant assumes that the bit with index 0 is the msb of byte 0 + e.g., 01234567 89abcdef ... + */ +ATTR_TARGET_S128 +static void transpose_64_64_s128(const uint64_t* in, uint64_t* out) { + static const uint64_t TRANSPOSE_MASKS64[6] = { + UINT64_C(0xFFFFFFFF00000000), UINT64_C(0xFFFF0000FFFF0000), UINT64_C(0xFF00FF00FF00FF00), + UINT64_C(0xF0F0F0F0F0F0F0F0), UINT64_C(0xCCCCCCCCCCCCCCCC), UINT64_C(0xAAAAAAAAAAAAAAAA)}; + + uint32_t width = 32, nswaps = 1; + const uint32_t logn = 6; + + // copy in to out and transpose in-place + memcpy(out, in, 64 * sizeof(uint64_t)); + for (uint32_t i = 0; i < 64; i++) { + out[i] = bswap64(out[i]); + } + + word128* out128 = (word128*)out; + + for (uint32_t i = 0; i < logn - 1; i++) { + word128 mask = _mm_set1_epi64x(TRANSPOSE_MASKS64[i]); + word128 inv_mask = mm128_xor(mask, _mm_set1_epi64x(UINT64_C(0xFFFFFFFFFFFFFFFF))); + + for (uint32_t j = 0; j < nswaps; j++) { + for (uint32_t k = 0; k < width; k += 2) { + // uint32_t i1 = k/2 + width * j; + // uint32_t i2 = i1 + width / 2; + uint32_t i1 = k + 2 * width * j; + uint32_t i2 = k + width + 2 * width * j; + + word128 t1 = out128[i1 / 2]; + word128 t2 = out128[i2 / 2]; + + out128[i1 / 2] = mm128_xor(mm128_and(t1, mask), _mm_srli_epi64(mm128_and(t2, mask), width)); + out128[i2 / 2] = + mm128_xor(mm128_and(t2, inv_mask), _mm_slli_epi64(mm128_and(t1, inv_mask), width)); + } + } + nswaps *= 2; + width /= 2; + } + uint64_t mask = TRANSPOSE_MASKS64[5]; + uint64_t inv_mask = ~mask; + for (uint32_t j = 0; j < nswaps; j++) { + for (uint32_t k = 0; k < width; k++) { + uint32_t i1 = k + 2 * width * j; + uint32_t i2 = k + width + 2 * width * j; + + uint64_t t1 = out[i1]; + uint64_t t2 = out[i2]; + + out[i1] = (t1 & mask) ^ ((t2 & mask) >> width); + out[i2] = (t2 & inv_mask) ^ ((t1 & inv_mask) << width); + } + } + for (uint32_t i = 0; i < 64; i++) { + out[i] = bswap64(out[i]); + } +} +#endif + +#if defined(WITH_AVX2) +/* transpose a 64x64 bit matrix using Eklundh's algorithm + this variant assumes that the bit with index 0 is the msb of byte 0 + e.g., 01234567 89abcdef ... + */ +ATTR_TARGET_AVX2 +static void transpose_64_64_s256(const uint64_t* in, uint64_t* out) { + static const uint64_t TRANSPOSE_MASKS64[6] = { + UINT64_C(0xFFFFFFFF00000000), UINT64_C(0xFFFF0000FFFF0000), UINT64_C(0xFF00FF00FF00FF00), + UINT64_C(0xF0F0F0F0F0F0F0F0), UINT64_C(0xCCCCCCCCCCCCCCCC), UINT64_C(0xAAAAAAAAAAAAAAAA)}; + + uint32_t width = 32, nswaps = 1; + const uint32_t logn = 6; + + // copy in to out and transpose in-place + memcpy(out, in, 64 * sizeof(uint64_t)); + for (uint32_t i = 0; i < 64; i++) { + out[i] = bswap64(out[i]); + } + + word256* out256 = (word256*)out; + + for (uint32_t i = 0; i < logn - 2; i++) { + word256 mask = _mm256_set1_epi64x(TRANSPOSE_MASKS64[i]); + word256 inv_mask = mm256_xor(mask, _mm256_set1_epi64x(UINT64_C(0xFFFFFFFFFFFFFFFF))); + + for (uint32_t j = 0; j < nswaps; j++) { + for (uint32_t k = 0; k < width; k += 4) { + uint32_t i1 = k + 2 * width * j; + uint32_t i2 = k + width + 2 * width * j; + + word256 t1 = out256[i1 / 4]; + word256 t2 = out256[i2 / 4]; + + out256[i1 / 4] = + mm256_xor(mm256_and(t1, mask), _mm256_srli_epi64(mm256_and(t2, mask), width)); + out256[i2 / 4] = + mm256_xor(mm256_and(t2, inv_mask), _mm256_slli_epi64(mm256_and(t1, inv_mask), width)); + } + } + nswaps *= 2; + width /= 2; + } + { + word128* out128 = (word128*)out; + word128 mask = _mm_set1_epi64x(TRANSPOSE_MASKS64[4]); + word128 inv_mask = mm128_xor(mask, _mm_set1_epi64x(UINT64_C(0xFFFFFFFFFFFFFFFF))); + + for (uint32_t j = 0; j < nswaps; j++) { + for (uint32_t k = 0; k < width; k += 2) { + uint32_t i1 = k + 2 * width * j; + uint32_t i2 = k + width + 2 * width * j; + + word128 t1 = out128[i1 / 2]; + word128 t2 = out128[i2 / 2]; + + out128[i1 / 2] = mm128_xor(mm128_and(t1, mask), _mm_srli_epi64(mm128_and(t2, mask), width)); + out128[i2 / 2] = + mm128_xor(mm128_and(t2, inv_mask), _mm_slli_epi64(mm128_and(t1, inv_mask), width)); + } + } + nswaps *= 2; + width /= 2; + } + + uint64_t mask = TRANSPOSE_MASKS64[5]; + uint64_t inv_mask = ~mask; + for (uint32_t j = 0; j < nswaps; j++) { + for (uint32_t k = 0; k < width; k++) { + uint32_t i1 = k + 2 * width * j; + uint32_t i2 = k + width + 2 * width * j; + + uint64_t t1 = out[i1]; + uint64_t t2 = out[i2]; + + out[i1] = (t1 & mask) ^ ((t2 & mask) >> width); + out[i2] = (t2 & inv_mask) ^ ((t1 & inv_mask) << width); + } + } + for (uint32_t i = 0; i < 64; i++) { + out[i] = bswap64(out[i]); + } +} +#endif +#endif + +void transpose_64_64(const uint64_t* in, uint64_t* out) { + +#if defined(WITH_OPT) +#if defined(WITH_AVX2) + if (CPU_SUPPORTS_AVX2) { + transpose_64_64_s256(in, out); + return; + } +#endif +#if defined(WITH_SSE2) || defined(WITH_NEON) + if (CPU_SUPPORTS_NEON || CPU_SUPPORTS_SSE2) { + transpose_64_64_s128(in, out); + return; + } +#endif +#endif + transpose_64_64_uint64(in, out); +} + +uint64_t tapesToParityOfWord(randomTape_t* tapes, uint8_t without_last) { + uint64_t shares; + + if (tapes->pos % 64 == 0) { + tapes->buffer[0] = 0; + for (size_t i = 0; i < 63; i++) { + tapes->buffer[0] ^= ((uint64_t*)tapes->tape[i])[tapes->pos / 64]; + } + tapes->buffer[1] = tapes->buffer[0]; + tapes->buffer[0] ^= ((uint64_t*)tapes->tape[63])[tapes->pos / 64]; + } + + shares = getBit((uint8_t*)&tapes->buffer[without_last ? 1 : 0], tapes->pos % 64); + tapes->pos++; + return shares; +} + uint64_t tapesToWord(randomTape_t* tapes) { uint64_t shares; if (tapes->pos % 64 == 0) { - uint64_t buffer[64]; for (size_t i = 0; i < 64; i++) { - buffer[i / 8 * 8 + 7 - i % 8] = ((uint64_t*)tapes->tape[i])[tapes->pos / 64]; + tapes->buffer[i] = ((uint64_t*)tapes->tape[i])[tapes->pos / 64]; } - transpose_64_64(buffer, tapes->buffer); + transpose_64_64(tapes->buffer, tapes->buffer); } - shares = tapes->buffer[(tapes->pos % 64) / 8 * 8 + 7 - (tapes->pos % 64) % 8]; + shares = tapes->buffer[tapes->pos % 64]; tapes->pos++; return shares; } @@ -282,15 +516,6 @@ void xor_array_RC(uint8_t* out, const uint8_t* in1, const uint8_t* in2, uint32_t out[i] = in1[i] ^ in2[length - 1 - i]; } } -/* For an input bit b = 0 or 1, return the word of all b bits, i.e., - * extend(1) = 0xFFFFFFFFFFFFFFFF - * extend(0) = 0x0000000000000000 - * Assumes inputs are always 0 or 1. If this doesn't hold, add "& 1" to the - * input. - */ -static inline uint64_t extend(uint64_t bit) { - return ~(bit - 1); -} /* Get one bit from a byte array */ uint8_t getBit(const uint8_t* array, uint32_t bitNumber) { @@ -308,22 +533,16 @@ void copyShares(shares_t* dst, shares_t* src) { memcpy(dst->shares, src->shares, dst->numWords * sizeof(dst->shares[0])); } -void mpc_matrix_mul_uint64_128(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_uint64_128(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares) { - uint8_t temp[16] = { - 0, - }; - const uint32_t rowstride = (128) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); for (size_t i = 0; i < 128; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)vec, 128 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[128 - 1 - i]; for (uint32_t j = 0; j < 128; j += 8) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (128 - 1 - j) / 8]; - temp[j / 8] ^= matrix_byte & vec_bit; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (128 - 1 - j) / 8]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -337,28 +556,24 @@ void mpc_matrix_mul_uint64_128(uint32_t* output, const uint32_t* vec, const uint tmp_mask->shares[j + 7] ^= mask_share & mask2->w64[3]; } } - memcpy(output, temp, 128 / 8); + mzd_local_t tmp; + mzd_copy_uint64_128(&tmp, vec); + mzd_mul_v_uint64_128(output, &tmp, matrix); copyShares(mask_shares, tmp_mask); freeShares(tmp_mask); } -void mpc_matrix_mul_uint64_192(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_uint64_192(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares) { - uint8_t temp[24] = { - 0, - }; - const uint32_t rowstride = (256) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); for (size_t i = 0; i < 192; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)vec, 192 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[192 - 1 - i]; for (uint32_t j = 0; j < 192; j += 8) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (192 - 1 - j) / 8]; - temp[j / 8] ^= matrix_byte & vec_bit; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (192 - 1 - j) / 8]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -373,27 +588,23 @@ void mpc_matrix_mul_uint64_192(uint32_t* output, const uint32_t* vec, const uint tmp_mask->shares[j + 7] ^= mask_share & mask2->w64[3]; } } - memcpy(output, temp, 192 / 8); + mzd_local_t tmp; + mzd_copy_uint64_192(&tmp, vec); + mzd_mul_v_uint64_192(output, &tmp, matrix); copyShares(mask_shares, tmp_mask); freeShares(tmp_mask); } -void mpc_matrix_mul_uint64_256(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_uint64_256(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares) { - uint8_t temp[32] = { - 0, - }; - const uint32_t rowstride = (256) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); for (size_t i = 0; i < 256; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)vec, 256 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[256 - 1 - i]; for (uint32_t j = 0; j < 256; j += 8) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (256 - 1 - j) / 8]; - temp[j / 8] ^= matrix_byte & vec_bit; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (256 - 1 - j) / 8]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -408,25 +619,23 @@ void mpc_matrix_mul_uint64_256(uint32_t* output, const uint32_t* vec, const uint tmp_mask->shares[j + 7] ^= mask_share & mask2->w64[3]; } } - memcpy(output, temp, 256 / 8); + mzd_local_t tmp; + mzd_copy_uint64_256(&tmp, vec); + mzd_mul_v_uint64_256(output, &tmp, matrix); copyShares(mask_shares, tmp_mask); freeShares(tmp_mask); } -void mpc_matrix_mul_z_uint64_128(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix) { +#if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) +void mpc_matrix_mul_z_uint64_128(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (128) / 8; memset(mask2_shares->shares, 0, sizeof(uint64_t) * 128); - memset(state2, 0, 128 / 8); for (size_t i = 0; i < 30; i++) { - uint8_t prod = 0; uint64_t new_mask_i = 0; for (uint32_t j = 0; j < 128 / 8; j++) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[i * rowstride + (128 / 8) - 1 - j]; - uint8_t vec_byte = ((const uint8_t*)state)[j]; - - prod ^= matrix_byte & vec_byte; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[i * rowstride + (128 / 8) - 1 - j]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -440,25 +649,19 @@ void mpc_matrix_mul_z_uint64_128(uint32_t* state2, const uint32_t* state, shares new_mask_i ^= mask_shares->shares[j * 8 + 6] & mask2->w64[2]; new_mask_i ^= mask_shares->shares[j * 8 + 7] & mask2->w64[3]; } - const uint8_t parity = parity64_uint8(prod); - setBit((uint8_t*)state2, 30 - 1 - i, parity); mask2_shares->shares[30 - 1 - i] = new_mask_i; } + mzd_mul_v_parity_uint64_128_30(state2, state, matrix); } -void mpc_matrix_mul_z_uint64_192(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix) { +void mpc_matrix_mul_z_uint64_192(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (256) / 8; memset(mask2_shares->shares, 0, sizeof(uint64_t) * 192); - memset(state2, 0, 192 / 8); for (size_t i = 0; i < 30; i++) { - uint8_t prod = 0; uint64_t new_mask_i = 0; for (uint32_t j = 0; j < 192 / 8; j++) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[i * rowstride + (192 / 8) - 1 - j]; - uint8_t vec_byte = ((const uint8_t*)state)[j]; - - prod ^= matrix_byte & vec_byte; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[i * rowstride + (192 / 8) - 1 - j]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -472,25 +675,19 @@ void mpc_matrix_mul_z_uint64_192(uint32_t* state2, const uint32_t* state, shares new_mask_i ^= mask_shares->shares[j * 8 + 6] & mask2->w64[2]; new_mask_i ^= mask_shares->shares[j * 8 + 7] & mask2->w64[3]; } - const uint8_t parity = parity64_uint8(prod); - setBit((uint8_t*)state2, 30 - 1 - i, parity); mask2_shares->shares[30 - 1 - i] = new_mask_i; } + mzd_mul_v_parity_uint64_192_30(state2, state, matrix); } -void mpc_matrix_mul_z_uint64_256(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix) { +void mpc_matrix_mul_z_uint64_256(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (256) / 8; memset(mask2_shares->shares, 0, sizeof(uint64_t) * 256); - memset(state2, 0, 256 / 8); for (size_t i = 0; i < 30; i++) { - uint8_t prod = 0; uint64_t new_mask_i = 0; for (uint32_t j = 0; j < 256 / 8; j++) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[i * rowstride + (256 / 8) - 1 - j]; - uint8_t vec_byte = ((const uint8_t*)state)[j]; - - prod ^= matrix_byte & vec_byte; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[i * rowstride + (256 / 8) - 1 - j]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -504,29 +701,22 @@ void mpc_matrix_mul_z_uint64_256(uint32_t* state2, const uint32_t* state, shares new_mask_i ^= mask_shares->shares[j * 8 + 6] & mask2->w64[2]; new_mask_i ^= mask_shares->shares[j * 8 + 7] & mask2->w64[3]; } - const uint8_t parity = parity64_uint8(prod); - setBit((uint8_t*)state2, 30 - 1 - i, parity); mask2_shares->shares[30 - 1 - i] = new_mask_i; } + mzd_mul_v_parity_uint64_256_30(state2, state, matrix); } -void mpc_matrix_addmul_r_uint64_128(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix) { - uint8_t temp[16] = { - 0, - }; - memcpy(temp, state2, 128 / 8); - +void mpc_matrix_addmul_r_uint64_128(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (128) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); copyShares(tmp_mask, mask2_shares); for (size_t i = 0; i < 30; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)state, 30 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[30 - 1 - i]; for (uint32_t j = 0; j < 128; j += 8) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (128 - 1 - j) / 8]; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (128 - 1 - j) / 8]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -539,33 +729,25 @@ void mpc_matrix_addmul_r_uint64_128(uint32_t* state2, const uint32_t* state, sha tmp_mask->shares[j + 5] ^= mask_share & mask2->w64[1]; tmp_mask->shares[j + 6] ^= mask_share & mask2->w64[2]; tmp_mask->shares[j + 7] ^= mask_share & mask2->w64[3]; - - temp[j / 8] ^= matrix_byte & vec_bit; } } - memcpy(state2, temp, 128 / 8); + mzd_addmul_v_uint64_30_128(state2, state, matrix); copyShares(mask2_shares, tmp_mask); freeShares(tmp_mask); } -void mpc_matrix_addmul_r_uint64_192(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix) { - uint8_t temp[24] = { - 0, - }; - memcpy(temp, state2, 192 / 8); - +void mpc_matrix_addmul_r_uint64_192(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = 256 / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); copyShares(tmp_mask, mask2_shares); for (size_t i = 0; i < 30; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)state, 30 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[30 - 1 - i]; for (uint32_t j = 0; j < 192; j += 8) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (192 - 1 - j) / 8]; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (192 - 1 - j) / 8]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -578,33 +760,25 @@ void mpc_matrix_addmul_r_uint64_192(uint32_t* state2, const uint32_t* state, sha tmp_mask->shares[j + 5] ^= mask_share & mask2->w64[1]; tmp_mask->shares[j + 6] ^= mask_share & mask2->w64[2]; tmp_mask->shares[j + 7] ^= mask_share & mask2->w64[3]; - - temp[j / 8] ^= matrix_byte & vec_bit; } } - memcpy(state2, temp, 192 / 8); + mzd_addmul_v_uint64_30_192(state2, state, matrix); copyShares(mask2_shares, tmp_mask); freeShares(tmp_mask); } -void mpc_matrix_addmul_r_uint64_256(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix) { - uint8_t temp[32] = { - 0, - }; - memcpy(temp, state2, 256 / 8); - +void mpc_matrix_addmul_r_uint64_256(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (256) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); copyShares(tmp_mask, mask2_shares); for (size_t i = 0; i < 30; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)state, 30 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[30 - 1 - i]; for (uint32_t j = 0; j < 256; j += 8) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (256 - 1 - j) / 8]; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (256 - 1 - j) / 8]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -617,30 +791,27 @@ void mpc_matrix_addmul_r_uint64_256(uint32_t* state2, const uint32_t* state, sha tmp_mask->shares[j + 5] ^= mask_share & mask2->w64[1]; tmp_mask->shares[j + 6] ^= mask_share & mask2->w64[2]; tmp_mask->shares[j + 7] ^= mask_share & mask2->w64[3]; - - temp[j / 8] ^= matrix_byte & vec_bit; } } - memcpy(state2, temp, 256 / 8); + mzd_addmul_v_uint64_30_256(state2, state, matrix); copyShares(mask2_shares, tmp_mask); freeShares(tmp_mask); } +#endif -void mpc_matrix_mul_nl_part_uint64_128(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +#if defined(REDUCED_ROUND_KEY_COMPUTATION) +void mpc_matrix_mul_nl_part_uint64_128(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks) { const uint32_t rowstride = ((20 * 32 + 255) / 256 * 256) / 8; - memset(nl_part, 0, 20 * sizeof(uint32_t)); for (size_t i = 0; i < 128; i++) { - uint8_t key_bit = extend(getBit((const uint8_t*)key, 128 - 1 - i)) & 0xFF; const uint64_t key_mask = key_masks->shares[128 - 1 - i]; for (uint32_t j = 0; j < 20 * 32; j += 8) { - uint8_t matrix_byte = ((const uint8_t*)precomputed_nl_matrix)[i * rowstride + j / 8]; - ((uint8_t*)nl_part)[j / 8] ^= matrix_byte & key_bit; + uint8_t matrix_byte = ((const uint8_t*)precomputed_nl_matrix->w64)[i * rowstride + j / 8]; const block_t* mask1 = &nl_part_block_masks[(matrix_byte >> 0) & 0xF]; const block_t* mask2 = &nl_part_block_masks[(matrix_byte >> 4) & 0xF]; @@ -655,23 +826,21 @@ void mpc_matrix_mul_nl_part_uint64_128(uint32_t* nl_part, const uint32_t* key, nl_part_masks->shares[j + 7] ^= key_mask & mask2->w64[3]; } } - xor_word_array(nl_part, nl_part, (const uint32_t*)precomputed_constant_nl, 20); + mzd_mul_v_uint64_128_640(nl_part, key, precomputed_nl_matrix); + mzd_xor_uint64_640(nl_part, nl_part, precomputed_constant_nl); } -void mpc_matrix_mul_nl_part_uint64_192(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_uint64_192(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks) { const uint32_t rowstride = ((30 * 32 + 255) / 256 * 256) / 8; - memset(nl_part, 0, 30 * sizeof(uint32_t)); for (size_t i = 0; i < 192; i++) { - uint8_t key_bit = extend(getBit((const uint8_t*)key, 192 - 1 - i)) & 0xFF; const uint64_t key_mask = key_masks->shares[192 - 1 - i]; for (uint32_t j = 0; j < 30 * 32; j += 8) { - uint8_t matrix_byte = ((const uint8_t*)precomputed_nl_matrix)[i * rowstride + j / 8]; - ((uint8_t*)nl_part)[j / 8] ^= matrix_byte & key_bit; + uint8_t matrix_byte = ((const uint8_t*)precomputed_nl_matrix->w64)[i * rowstride + j / 8]; const block_t* mask1 = &nl_part_block_masks[(matrix_byte >> 0) & 0xF]; const block_t* mask2 = &nl_part_block_masks[(matrix_byte >> 4) & 0xF]; @@ -686,23 +855,21 @@ void mpc_matrix_mul_nl_part_uint64_192(uint32_t* nl_part, const uint32_t* key, nl_part_masks->shares[j + 7] ^= key_mask & mask2->w64[3]; } } - xor_word_array(nl_part, nl_part, (const uint32_t*)precomputed_constant_nl, 30); + mzd_mul_v_uint64_192_960(nl_part, key, precomputed_nl_matrix); + mzd_xor_uint64_960(nl_part, nl_part, precomputed_constant_nl); } -void mpc_matrix_mul_nl_part_uint64_256(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_uint64_256(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks) { const uint32_t rowstride = ((38 * 32 + 255) / 256 * 256) / 8; - memset(nl_part, 0, 38 * sizeof(uint32_t)); for (size_t i = 0; i < 256; i++) { - uint8_t key_bit = extend(getBit((const uint8_t*)key, 256 - 1 - i)) & 0xFF; const uint64_t key_mask = key_masks->shares[256 - 1 - i]; for (uint32_t j = 0; j < 38 * 32; j += 8) { - uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix)[i * rowstride + j / 8]; - ((uint8_t*)nl_part)[j / 8] ^= matrix_byte & key_bit; + uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix->w64)[i * rowstride + j / 8]; const block_t* mask1 = &nl_part_block_masks[(matrix_byte >> 0) & 0xF]; const block_t* mask2 = &nl_part_block_masks[(matrix_byte >> 4) & 0xF]; @@ -717,23 +884,20 @@ void mpc_matrix_mul_nl_part_uint64_256(uint32_t* nl_part, const uint32_t* key, nl_part_masks->shares[j + 7] ^= key_mask & mask2->w64[3]; } } - xor_word_array(nl_part, nl_part, (const uint32_t*)precomputed_constant_nl, 38); + mzd_mul_v_uint64_256_1216(nl_part, key, precomputed_nl_matrix); + mzd_xor_uint64_1216(nl_part, nl_part, precomputed_constant_nl); } +#endif #if defined(WITH_OPT) #if defined(WITH_SSE2) || defined(WITH_NEON) ATTR_TARGET_S128 -void mpc_matrix_mul_s128_128(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_s128_128(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares) { - uint8_t temp[16] = { - 0, - }; - const uint32_t rowstride = (128) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); for (size_t i = 0; i < 128; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)vec, 128 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[128 - 1 - i]; const block_t mask_share2 = {{mask_share, mask_share, mask_share, mask_share}}; word128 mask1, mask2, mask3, mask4; @@ -741,8 +905,7 @@ void mpc_matrix_mul_s128_128(uint32_t* output, const uint32_t* vec, const uint64 word128* tmp_mask_block = (word128*)tmp_mask->shares; for (uint32_t j = 0; j < 128; j += 8, tmp_mask_block += 4) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (128 - 1 - j) / 8]; - temp[j / 8] ^= matrix_byte & vec_bit; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (128 - 1 - j) / 8]; mask1 = block_masks[(matrix_byte >> 4) & 0xf].w128[0]; mask2 = block_masks[(matrix_byte >> 4) & 0xf].w128[1]; @@ -755,24 +918,19 @@ void mpc_matrix_mul_s128_128(uint32_t* output, const uint32_t* vec, const uint64 tmp_mask_block[3] = mm128_xor_mask(tmp_mask_block[3], mask_share2.w128[0], mask4); } } - memcpy(output, temp, 128 / 8); + mzd_mul_v_s128_128(output, vec, matrix); copyShares(mask_shares, tmp_mask); freeShares(tmp_mask); } ATTR_TARGET_S128 -void mpc_matrix_mul_s128_192(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_s128_192(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares) { - uint8_t temp[24] = { - 0, - }; - const uint32_t rowstride = (256) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); for (size_t i = 0; i < 192; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)vec, 192 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[192 - 1 - i]; const block_t mask_share2 = {{mask_share, mask_share, mask_share, mask_share}}; word128 mask1, mask2, mask3, mask4; @@ -780,8 +938,7 @@ void mpc_matrix_mul_s128_192(uint32_t* output, const uint32_t* vec, const uint64 word128* tmp_mask_block = (word128*)tmp_mask->shares; for (uint32_t j = 0; j < 192; j += 8, tmp_mask_block += 4) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (192 - 1 - j) / 8]; - temp[j / 8] ^= matrix_byte & vec_bit; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (192 - 1 - j) / 8]; mask1 = block_masks[(matrix_byte >> 4) & 0xf].w128[0]; mask2 = block_masks[(matrix_byte >> 4) & 0xf].w128[1]; @@ -794,24 +951,19 @@ void mpc_matrix_mul_s128_192(uint32_t* output, const uint32_t* vec, const uint64 tmp_mask_block[3] = mm128_xor_mask(tmp_mask_block[3], mask_share2.w128[0], mask4); } } - memcpy(output, temp, 192 / 8); + mzd_mul_v_s128_192(output, vec, matrix); copyShares(mask_shares, tmp_mask); freeShares(tmp_mask); } ATTR_TARGET_S128 -void mpc_matrix_mul_s128_256(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_s128_256(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares) { - uint8_t temp[32] = { - 0, - }; - const uint32_t rowstride = (256) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); for (size_t i = 0; i < 256; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)vec, 256 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[256 - 1 - i]; const block_t mask_share2 = {{mask_share, mask_share, mask_share, mask_share}}; word128 mask1, mask2, mask3, mask4; @@ -819,8 +971,7 @@ void mpc_matrix_mul_s128_256(uint32_t* output, const uint32_t* vec, const uint64 word128* tmp_mask_block = (word128*)tmp_mask->shares; for (uint32_t j = 0; j < 256; j += 8, tmp_mask_block += 4) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (256 - 1 - j) / 8]; - temp[j / 8] ^= matrix_byte & vec_bit; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (256 - 1 - j) / 8]; mask1 = block_masks[(matrix_byte >> 4) & 0xf].w128[0]; mask2 = block_masks[(matrix_byte >> 4) & 0xf].w128[1]; @@ -833,27 +984,23 @@ void mpc_matrix_mul_s128_256(uint32_t* output, const uint32_t* vec, const uint64 tmp_mask_block[3] = mm128_xor_mask(tmp_mask_block[3], mask_share2.w128[0], mask4); } } - memcpy(output, temp, 256 / 8); + mzd_mul_v_s128_256(output, vec, matrix); copyShares(mask_shares, tmp_mask); freeShares(tmp_mask); } +#if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) ATTR_TARGET_S128 -void mpc_matrix_mul_z_s128_128(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix) { +void mpc_matrix_mul_z_s128_128(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (128) / 8; memset(mask2_shares->shares, 0, sizeof(uint64_t) * 128); - memset(state2, 0, 128 / 8); for (size_t i = 0; i < 30; i++) { - uint8_t prod = 0; block_t new_mask_i = {{0, 0, 0, 0}}; word128* tmp_mask_block = (word128*)mask_shares->shares; for (uint32_t j = 0; j < 128 / 8; j++, tmp_mask_block += 4) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[i * rowstride + (128 / 8) - 1 - j]; - uint8_t vec_byte = ((const uint8_t*)state)[j]; - - prod ^= matrix_byte & vec_byte; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[i * rowstride + (128 / 8) - 1 - j]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -863,28 +1010,22 @@ void mpc_matrix_mul_z_s128_128(uint32_t* state2, const uint32_t* state, shares_t new_mask_i.w128[0] = mm128_xor_mask(new_mask_i.w128[0], tmp_mask_block[2], mask2->w128[0]); new_mask_i.w128[1] = mm128_xor_mask(new_mask_i.w128[1], tmp_mask_block[3], mask2->w128[1]); } - const uint8_t parity = parity64_uint8(prod); - setBit((uint8_t*)state2, 30 - 1 - i, parity); mask2_shares->shares[30 - 1 - i] = new_mask_i.w64[0] ^ new_mask_i.w64[1] ^ new_mask_i.w64[2] ^ new_mask_i.w64[3]; } + mzd_mul_v_parity_uint64_128_30(state2, state, matrix); } ATTR_TARGET_S128 -void mpc_matrix_mul_z_s128_192(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix) { +void mpc_matrix_mul_z_s128_192(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (256) / 8; memset(mask2_shares->shares, 0, sizeof(uint64_t) * 192); - memset(state2, 0, 192 / 8); for (size_t i = 0; i < 30; i++) { - uint8_t prod = 0; block_t new_mask_i = {{0, 0, 0, 0}}; word128* tmp_mask_block = (word128*)mask_shares->shares; for (uint32_t j = 0; j < 192 / 8; j++, tmp_mask_block += 4) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[i * rowstride + (192 / 8) - 1 - j]; - uint8_t vec_byte = ((const uint8_t*)state)[j]; - - prod ^= matrix_byte & vec_byte; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[i * rowstride + (192 / 8) - 1 - j]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -894,28 +1035,22 @@ void mpc_matrix_mul_z_s128_192(uint32_t* state2, const uint32_t* state, shares_t new_mask_i.w128[0] = mm128_xor_mask(new_mask_i.w128[0], tmp_mask_block[2], mask2->w128[0]); new_mask_i.w128[1] = mm128_xor_mask(new_mask_i.w128[1], tmp_mask_block[3], mask2->w128[1]); } - const uint8_t parity = parity64_uint8(prod); - setBit((uint8_t*)state2, 30 - 1 - i, parity); mask2_shares->shares[30 - 1 - i] = new_mask_i.w64[0] ^ new_mask_i.w64[1] ^ new_mask_i.w64[2] ^ new_mask_i.w64[3]; } + mzd_mul_v_parity_uint64_192_30(state2, state, matrix); } ATTR_TARGET_S128 -void mpc_matrix_mul_z_s128_256(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix) { +void mpc_matrix_mul_z_s128_256(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (256) / 8; memset(mask2_shares->shares, 0, sizeof(uint64_t) * 256); - memset(state2, 0, 256 / 8); for (size_t i = 0; i < 30; i++) { - uint8_t prod = 0; block_t new_mask_i = {{0, 0, 0, 0}}; word128* tmp_mask_block = (word128*)mask_shares->shares; for (uint32_t j = 0; j < 256 / 8; j++, tmp_mask_block += 4) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[i * rowstride + (256 / 8) - 1 - j]; - uint8_t vec_byte = ((const uint8_t*)state)[j]; - - prod ^= matrix_byte & vec_byte; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[i * rowstride + (256 / 8) - 1 - j]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -925,34 +1060,27 @@ void mpc_matrix_mul_z_s128_256(uint32_t* state2, const uint32_t* state, shares_t new_mask_i.w128[0] = mm128_xor_mask(new_mask_i.w128[0], tmp_mask_block[2], mask2->w128[0]); new_mask_i.w128[1] = mm128_xor_mask(new_mask_i.w128[1], tmp_mask_block[3], mask2->w128[1]); } - const uint8_t parity = parity64_uint8(prod); - setBit((uint8_t*)state2, 30 - 1 - i, parity); mask2_shares->shares[30 - 1 - i] = new_mask_i.w64[0] ^ new_mask_i.w64[1] ^ new_mask_i.w64[2] ^ new_mask_i.w64[3]; } + mzd_mul_v_parity_uint64_256_30(state2, state, matrix); } ATTR_TARGET_S128 -void mpc_matrix_addmul_r_s128_128(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix) { - uint8_t temp[16] = { - 0, - }; - memcpy(temp, state2, 128 / 8); - +void mpc_matrix_addmul_r_s128_128(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (128) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); copyShares(tmp_mask, mask2_shares); for (size_t i = 0; i < 30; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)state, 30 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[30 - 1 - i]; const block_t mask_share2 = {{mask_share, mask_share, mask_share, mask_share}}; word128 mask1, mask2, mask3, mask4; word128* tmp_mask_block = (word128*)tmp_mask->shares; for (uint32_t j = 0; j < 128; j += 8, tmp_mask_block += 4) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (128 - 1 - j) / 8]; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (128 - 1 - j) / 8]; mask1 = block_masks[(matrix_byte >> 4) & 0xf].w128[0]; mask2 = block_masks[(matrix_byte >> 4) & 0xf].w128[1]; @@ -963,30 +1091,22 @@ void mpc_matrix_addmul_r_s128_128(uint32_t* state2, const uint32_t* state, share tmp_mask_block[1] = mm128_xor_mask(tmp_mask_block[1], mask_share2.w128[0], mask2); tmp_mask_block[2] = mm128_xor_mask(tmp_mask_block[2], mask_share2.w128[0], mask3); tmp_mask_block[3] = mm128_xor_mask(tmp_mask_block[3], mask_share2.w128[0], mask4); - - temp[j / 8] ^= matrix_byte & vec_bit; } } - memcpy(state2, temp, 128 / 8); + mzd_addmul_v_s128_30_128(state2, state, matrix); copyShares(mask2_shares, tmp_mask); freeShares(tmp_mask); } ATTR_TARGET_S128 -void mpc_matrix_addmul_r_s128_192(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix) { - uint8_t temp[24] = { - 0, - }; - memcpy(temp, state2, 192 / 8); - +void mpc_matrix_addmul_r_s128_192(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (256) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); copyShares(tmp_mask, mask2_shares); for (size_t i = 0; i < 30; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)state, 30 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[30 - 1 - i]; const block_t mask_share2 = {{mask_share, mask_share, mask_share, mask_share}}; word128 mask1, mask2, mask3, mask4; @@ -1004,30 +1124,22 @@ void mpc_matrix_addmul_r_s128_192(uint32_t* state2, const uint32_t* state, share tmp_mask_block[1] = mm128_xor_mask(tmp_mask_block[1], mask_share2.w128[0], mask2); tmp_mask_block[2] = mm128_xor_mask(tmp_mask_block[2], mask_share2.w128[0], mask3); tmp_mask_block[3] = mm128_xor_mask(tmp_mask_block[3], mask_share2.w128[0], mask4); - - temp[j / 8] ^= matrix_byte & vec_bit; } } - memcpy(state2, temp, 192 / 8); + mzd_addmul_v_s128_30_192(state2, state, matrix); copyShares(mask2_shares, tmp_mask); freeShares(tmp_mask); } ATTR_TARGET_S128 -void mpc_matrix_addmul_r_s128_256(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix) { - uint8_t temp[32] = { - 0, - }; - memcpy(temp, state2, 256 / 8); - +void mpc_matrix_addmul_r_s128_256(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (256) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); copyShares(tmp_mask, mask2_shares); for (size_t i = 0; i < 30; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)state, 30 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[30 - 1 - i]; const block_t mask_share2 = {{mask_share, mask_share, mask_share, mask_share}}; word128 mask1, mask2, mask3, mask4; @@ -1045,26 +1157,24 @@ void mpc_matrix_addmul_r_s128_256(uint32_t* state2, const uint32_t* state, share tmp_mask_block[1] = mm128_xor_mask(tmp_mask_block[1], mask_share2.w128[0], mask2); tmp_mask_block[2] = mm128_xor_mask(tmp_mask_block[2], mask_share2.w128[0], mask3); tmp_mask_block[3] = mm128_xor_mask(tmp_mask_block[3], mask_share2.w128[0], mask4); - - temp[j / 8] ^= matrix_byte & vec_bit; } } - memcpy(state2, temp, 256 / 8); + mzd_addmul_v_s128_30_256(state2, state, matrix); copyShares(mask2_shares, tmp_mask); freeShares(tmp_mask); } +#endif +#if defined(REDUCED_ROUND_KEY_COMPUTATION) ATTR_TARGET_S128 -void mpc_matrix_mul_nl_part_s128_128(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_s128_128(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks) { const uint32_t rowstride = ((20 * 32 + 255) / 256 * 256) / 8; - memset(nl_part, 0, 20 * sizeof(uint32_t)); for (size_t i = 0; i < 128; i++) { - uint8_t key_bit = extend(getBit((const uint8_t*)key, 128 - 1 - i)) & 0xFF; const uint64_t key_mask = key_masks->shares[128 - 1 - i]; const block_t mask_share2 = {{key_mask, key_mask, key_mask, key_mask}}; word128 mask1, mask2, mask3, mask4; @@ -1072,8 +1182,7 @@ void mpc_matrix_mul_nl_part_s128_128(uint32_t* nl_part, const uint32_t* key, word128* tmp_mask_block = (word128*)nl_part_masks->shares; for (uint32_t j = 0; j < 20 * 32; j += 8, tmp_mask_block += 4) { - uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix)[i * rowstride + j / 8]; - ((uint8_t*)nl_part)[j / 8] ^= matrix_byte & key_bit; + uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix->w64)[i * rowstride + j / 8]; mask1 = nl_part_block_masks[(matrix_byte >> 0) & 0xf].w128[0]; mask2 = nl_part_block_masks[(matrix_byte >> 0) & 0xf].w128[1]; @@ -1086,19 +1195,18 @@ void mpc_matrix_mul_nl_part_s128_128(uint32_t* nl_part, const uint32_t* key, tmp_mask_block[3] = mm128_xor_mask(tmp_mask_block[3], mask_share2.w128[0], mask4); } } - xor_word_array(nl_part, nl_part, (const uint32_t*)precomputed_constant_nl, 20); + mzd_mul_v_s128_128_640(nl_part, key, precomputed_nl_matrix); + mzd_xor_s128_640(nl_part, nl_part, precomputed_constant_nl); } ATTR_TARGET_S128 -void mpc_matrix_mul_nl_part_s128_192(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_s128_192(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks) { const uint32_t rowstride = ((30 * 32 + 255) / 256 * 256) / 8; - memset(nl_part, 0, 30 * sizeof(uint32_t)); for (size_t i = 0; i < 192; i++) { - uint8_t key_bit = extend(getBit((const uint8_t*)key, 192 - 1 - i)) & 0xFF; const uint64_t key_mask = key_masks->shares[192 - 1 - i]; const block_t mask_share2 = {{key_mask, key_mask, key_mask, key_mask}}; word128 mask1, mask2, mask3, mask4; @@ -1106,8 +1214,7 @@ void mpc_matrix_mul_nl_part_s128_192(uint32_t* nl_part, const uint32_t* key, word128* tmp_mask_block = (word128*)nl_part_masks->shares; for (uint32_t j = 0; j < 30 * 32; j += 8, tmp_mask_block += 4) { - uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix)[i * rowstride + j / 8]; - ((uint8_t*)nl_part)[j / 8] ^= matrix_byte & key_bit; + uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix->w64)[i * rowstride + j / 8]; mask1 = nl_part_block_masks[(matrix_byte >> 0) & 0xf].w128[0]; mask2 = nl_part_block_masks[(matrix_byte >> 0) & 0xf].w128[1]; @@ -1120,19 +1227,18 @@ void mpc_matrix_mul_nl_part_s128_192(uint32_t* nl_part, const uint32_t* key, tmp_mask_block[3] = mm128_xor_mask(tmp_mask_block[3], mask_share2.w128[0], mask4); } } - xor_word_array(nl_part, nl_part, (const uint32_t*)precomputed_constant_nl, 30); + mzd_mul_v_s128_192_1024(nl_part, key, precomputed_nl_matrix); + mzd_xor_s128_1024(nl_part, nl_part, precomputed_constant_nl); } ATTR_TARGET_S128 -void mpc_matrix_mul_nl_part_s128_256(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_s128_256(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks) { const uint32_t rowstride = ((38 * 32 + 255) / 256 * 256) / 8; - memset(nl_part, 0, 38 * sizeof(uint32_t)); for (size_t i = 0; i < 256; i++) { - uint8_t key_bit = extend(getBit((const uint8_t*)key, 256 - 1 - i)) & 0xFF; const uint64_t key_mask = key_masks->shares[256 - 1 - i]; const block_t mask_share2 = {{key_mask, key_mask, key_mask, key_mask}}; word128 mask1, mask2, mask3, mask4; @@ -1140,8 +1246,7 @@ void mpc_matrix_mul_nl_part_s128_256(uint32_t* nl_part, const uint32_t* key, word128* tmp_mask_block = (word128*)nl_part_masks->shares; for (uint32_t j = 0; j < 38 * 32; j += 8, tmp_mask_block += 4) { - uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix)[i * rowstride + j / 8]; - ((uint8_t*)nl_part)[j / 8] ^= matrix_byte & key_bit; + uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix->w64)[i * rowstride + j / 8]; mask1 = nl_part_block_masks[(matrix_byte >> 0) & 0xf].w128[0]; mask2 = nl_part_block_masks[(matrix_byte >> 0) & 0xf].w128[1]; @@ -1154,23 +1259,20 @@ void mpc_matrix_mul_nl_part_s128_256(uint32_t* nl_part, const uint32_t* key, tmp_mask_block[3] = mm128_xor_mask(tmp_mask_block[3], mask_share2.w128[0], mask4); } } - xor_word_array(nl_part, nl_part, (const uint32_t*)precomputed_constant_nl, 38); + mzd_mul_v_s128_256_1280(nl_part, key, precomputed_nl_matrix); + mzd_xor_s128_1280(nl_part, nl_part, precomputed_constant_nl); } #endif +#endif #if defined(WITH_AVX2) ATTR_TARGET_AVX2 -void mpc_matrix_mul_s256_128(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_s256_128(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares) { - uint8_t temp[16] = { - 0, - }; - const uint32_t rowstride = (128) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); for (size_t i = 0; i < 128; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)vec, 128 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[128 - 1 - i]; const word256 mask_share2 = _mm256_set1_epi64x(mask_share); word256 mask1, mask2; @@ -1179,7 +1281,6 @@ void mpc_matrix_mul_s256_128(uint32_t* output, const uint32_t* vec, const uint64 for (uint32_t j = 0; j < 128; j += 8, tmp_mask_block += 2) { uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (128 - 1 - j) / 8]; - temp[j / 8] ^= matrix_byte & vec_bit; mask1 = block_masks[(matrix_byte >> 4) & 0xf].w256; mask2 = block_masks[(matrix_byte >> 0) & 0xf].w256; @@ -1187,24 +1288,19 @@ void mpc_matrix_mul_s256_128(uint32_t* output, const uint32_t* vec, const uint64 tmp_mask_block[1] = mm256_xor_mask(tmp_mask_block[1], mask_share2, mask2); } } - memcpy(output, temp, 128 / 8); + mzd_mul_v_s256_128(output, vec, matrix); copyShares(mask_shares, tmp_mask); freeShares(tmp_mask); } ATTR_TARGET_AVX2 -void mpc_matrix_mul_s256_192(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_s256_192(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares) { - uint8_t temp[24] = { - 0, - }; - const uint32_t rowstride = (256) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); for (size_t i = 0; i < 192; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)vec, 192 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[192 - 1 - i]; const word256 mask_share2 = _mm256_set1_epi64x(mask_share); word256 mask1, mask2; @@ -1212,8 +1308,7 @@ void mpc_matrix_mul_s256_192(uint32_t* output, const uint32_t* vec, const uint64 word256* tmp_mask_block = (word256*)tmp_mask->shares; for (uint32_t j = 0; j < 192; j += 8, tmp_mask_block += 2) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (192 - 1 - j) / 8]; - temp[j / 8] ^= matrix_byte & vec_bit; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (192 - 1 - j) / 8]; mask1 = block_masks[(matrix_byte >> 4) & 0xf].w256; mask2 = block_masks[(matrix_byte >> 0) & 0xf].w256; @@ -1221,24 +1316,19 @@ void mpc_matrix_mul_s256_192(uint32_t* output, const uint32_t* vec, const uint64 tmp_mask_block[1] = mm256_xor_mask(tmp_mask_block[1], mask_share2, mask2); } } - memcpy(output, temp, 192 / 8); + mzd_mul_v_s256_192(output, vec, matrix); copyShares(mask_shares, tmp_mask); freeShares(tmp_mask); } ATTR_TARGET_AVX2 -void mpc_matrix_mul_s256_256(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_s256_256(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares) { - uint8_t temp[32] = { - 0, - }; - const uint32_t rowstride = (256) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); for (size_t i = 0; i < 256; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)vec, 256 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[256 - 1 - i]; const word256 mask_share2 = _mm256_set1_epi64x(mask_share); word256 mask1, mask2; @@ -1246,8 +1336,7 @@ void mpc_matrix_mul_s256_256(uint32_t* output, const uint32_t* vec, const uint64 word256* tmp_mask_block = (word256*)tmp_mask->shares; for (uint32_t j = 0; j < 256; j += 8, tmp_mask_block += 2) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (256 - 1 - j) / 8]; - temp[j / 8] ^= matrix_byte & vec_bit; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (256 - 1 - j) / 8]; mask1 = block_masks[(matrix_byte >> 4) & 0xf].w256; mask2 = block_masks[(matrix_byte >> 0) & 0xf].w256; @@ -1255,27 +1344,23 @@ void mpc_matrix_mul_s256_256(uint32_t* output, const uint32_t* vec, const uint64 tmp_mask_block[1] = mm256_xor_mask(tmp_mask_block[1], mask_share2, mask2); } } - memcpy(output, temp, 256 / 8); + mzd_mul_v_s256_256(output, vec, matrix); copyShares(mask_shares, tmp_mask); freeShares(tmp_mask); } +#if defined(OPTIMIZED_LINEAR_LAYER_EVALUATION) ATTR_TARGET_AVX2 -void mpc_matrix_mul_z_s256_128(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix) { +void mpc_matrix_mul_z_s256_128(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (128) / 8; memset(mask2_shares->shares, 0, sizeof(uint64_t) * 128); - memset(state2, 0, 128 / 8); for (size_t i = 0; i < 30; i++) { - uint8_t prod = 0; block_t new_mask_i = {{0, 0, 0, 0}}; word256* tmp_mask_block = (word256*)mask_shares->shares; for (uint32_t j = 0; j < 128 / 8; j++, tmp_mask_block += 2) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[i * rowstride + (128 / 8) - 1 - j]; - uint8_t vec_byte = ((const uint8_t*)state)[j]; - - prod ^= matrix_byte & vec_byte; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[i * rowstride + (128 / 8) - 1 - j]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -1283,28 +1368,22 @@ void mpc_matrix_mul_z_s256_128(uint32_t* state2, const uint32_t* state, shares_t new_mask_i.w256 = mm256_xor_mask(new_mask_i.w256, tmp_mask_block[0], mask1->w256); new_mask_i.w256 = mm256_xor_mask(new_mask_i.w256, tmp_mask_block[1], mask2->w256); } - const uint8_t parity = parity64_uint8(prod); - setBit((uint8_t*)state2, 30 - 1 - i, parity); mask2_shares->shares[30 - 1 - i] = new_mask_i.w64[0] ^ new_mask_i.w64[1] ^ new_mask_i.w64[2] ^ new_mask_i.w64[3]; } + mzd_mul_v_parity_uint64_128_30(state2, state, matrix); } ATTR_TARGET_AVX2 -void mpc_matrix_mul_z_s256_192(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix) { +void mpc_matrix_mul_z_s256_192(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (256) / 8; memset(mask2_shares->shares, 0, sizeof(uint64_t) * 192); - memset(state2, 0, 192 / 8); for (size_t i = 0; i < 30; i++) { - uint8_t prod = 0; block_t new_mask_i = {{0, 0, 0, 0}}; word256* tmp_mask_block = (word256*)mask_shares->shares; for (uint32_t j = 0; j < 192 / 8; j++, tmp_mask_block += 2) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[i * rowstride + (192 / 8) - 1 - j]; - uint8_t vec_byte = ((const uint8_t*)state)[j]; - - prod ^= matrix_byte & vec_byte; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[i * rowstride + (192 / 8) - 1 - j]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -1312,28 +1391,22 @@ void mpc_matrix_mul_z_s256_192(uint32_t* state2, const uint32_t* state, shares_t new_mask_i.w256 = mm256_xor_mask(new_mask_i.w256, tmp_mask_block[0], mask1->w256); new_mask_i.w256 = mm256_xor_mask(new_mask_i.w256, tmp_mask_block[1], mask2->w256); } - const uint8_t parity = parity64_uint8(prod); - setBit((uint8_t*)state2, 30 - 1 - i, parity); mask2_shares->shares[30 - 1 - i] = new_mask_i.w64[0] ^ new_mask_i.w64[1] ^ new_mask_i.w64[2] ^ new_mask_i.w64[3]; } + mzd_mul_v_parity_uint64_192_30(state2, state, matrix); } ATTR_TARGET_AVX2 -void mpc_matrix_mul_z_s256_256(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix) { +void mpc_matrix_mul_z_s256_256(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (256) / 8; memset(mask2_shares->shares, 0, sizeof(uint64_t) * 256); - memset(state2, 0, 256 / 8); for (size_t i = 0; i < 30; i++) { - uint8_t prod = 0; block_t new_mask_i = {{0, 0, 0, 0}}; word256* tmp_mask_block = (word256*)mask_shares->shares; for (uint32_t j = 0; j < 256 / 8; j++, tmp_mask_block += 2) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[i * rowstride + (256 / 8) - 1 - j]; - uint8_t vec_byte = ((const uint8_t*)state)[j]; - - prod ^= matrix_byte & vec_byte; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[i * rowstride + (256 / 8) - 1 - j]; const block_t* mask1 = &block_masks[(matrix_byte >> 4) & 0xF]; const block_t* mask2 = &block_masks[(matrix_byte >> 0) & 0xF]; @@ -1341,134 +1414,109 @@ void mpc_matrix_mul_z_s256_256(uint32_t* state2, const uint32_t* state, shares_t new_mask_i.w256 = mm256_xor_mask(new_mask_i.w256, tmp_mask_block[0], mask1->w256); new_mask_i.w256 = mm256_xor_mask(new_mask_i.w256, tmp_mask_block[1], mask2->w256); } - const uint8_t parity = parity64_uint8(prod); - setBit((uint8_t*)state2, 30 - 1 - i, parity); mask2_shares->shares[30 - 1 - i] = new_mask_i.w64[0] ^ new_mask_i.w64[1] ^ new_mask_i.w64[2] ^ new_mask_i.w64[3]; } + mzd_mul_v_parity_uint64_256_30(state2, state, matrix); } ATTR_TARGET_AVX2 -void mpc_matrix_addmul_r_s256_128(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix) { - uint8_t temp[16] = { - 0, - }; - memcpy(temp, state2, 128 / 8); +void mpc_matrix_addmul_r_s256_128(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (128) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); copyShares(tmp_mask, mask2_shares); for (size_t i = 0; i < 30; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)state, 30 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[30 - 1 - i]; const word256 mask_share2 = _mm256_set1_epi64x(mask_share); word256 mask1, mask2; word256* tmp_mask_block = (word256*)tmp_mask->shares; for (uint32_t j = 0; j < 128; j += 8, tmp_mask_block += 2) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (128 - 1 - j) / 8]; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (128 - 1 - j) / 8]; mask1 = block_masks[(matrix_byte >> 4) & 0xf].w256; mask2 = block_masks[(matrix_byte >> 0) & 0xf].w256; tmp_mask_block[0] = mm256_xor_mask(tmp_mask_block[0], mask_share2, mask1); tmp_mask_block[1] = mm256_xor_mask(tmp_mask_block[1], mask_share2, mask2); - - temp[j / 8] ^= matrix_byte & vec_bit; } } - memcpy(state2, temp, 128 / 8); - copyShares(mask2_shares, tmp_mask); + mzd_addmul_v_s256_30_128(state2, state, matrix); freeShares(tmp_mask); } ATTR_TARGET_AVX2 -void mpc_matrix_addmul_r_s256_192(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix) { - uint8_t temp[24] = { - 0, - }; - memcpy(temp, state2, 192 / 8); - +void mpc_matrix_addmul_r_s256_192(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (256) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); copyShares(tmp_mask, mask2_shares); for (size_t i = 0; i < 30; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)state, 30 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[30 - 1 - i]; const word256 mask_share2 = _mm256_set1_epi64x(mask_share); word256 mask1, mask2; word256* tmp_mask_block = (word256*)tmp_mask->shares; for (uint32_t j = 0; j < 192; j += 8, tmp_mask_block += 2) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (192 - 1 - j) / 8]; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (192 - 1 - j) / 8]; mask1 = block_masks[(matrix_byte >> 4) & 0xf].w256; mask2 = block_masks[(matrix_byte >> 0) & 0xf].w256; tmp_mask_block[0] = mm256_xor_mask(tmp_mask_block[0], mask_share2, mask1); tmp_mask_block[1] = mm256_xor_mask(tmp_mask_block[1], mask_share2, mask2); - - temp[j / 8] ^= matrix_byte & vec_bit; } } - memcpy(state2, temp, 192 / 8); + mzd_addmul_v_s256_30_192(state2, state, matrix); copyShares(mask2_shares, tmp_mask); freeShares(tmp_mask); } ATTR_TARGET_AVX2 -void mpc_matrix_addmul_r_s256_256(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix) { - uint8_t temp[32] = { - 0, - }; - memcpy(temp, state2, 256 / 8); - +void mpc_matrix_addmul_r_s256_256(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix) { const uint32_t rowstride = (256) / 8; shares_t* tmp_mask = allocateShares(mask_shares->numWords); copyShares(tmp_mask, mask2_shares); for (size_t i = 0; i < 30; i++) { - uint8_t vec_bit = extend(getBit((const uint8_t*)state, 30 - 1 - i)) & 0xFF; const uint64_t mask_share = mask_shares->shares[30 - 1 - i]; const word256 mask_share2 = _mm256_set1_epi64x(mask_share); word256 mask1, mask2; word256* tmp_mask_block = (word256*)tmp_mask->shares; for (uint32_t j = 0; j < 256; j += 8, tmp_mask_block += 2) { - uint8_t matrix_byte = ((const uint8_t*)matrix)[(i * rowstride) + (256 - 1 - j) / 8]; + uint8_t matrix_byte = ((const uint8_t*)matrix->w64)[(i * rowstride) + (256 - 1 - j) / 8]; mask1 = block_masks[(matrix_byte >> 4) & 0xf].w256; mask2 = block_masks[(matrix_byte >> 0) & 0xf].w256; tmp_mask_block[0] = mm256_xor_mask(tmp_mask_block[0], mask_share2, mask1); tmp_mask_block[1] = mm256_xor_mask(tmp_mask_block[1], mask_share2, mask2); - - temp[j / 8] ^= matrix_byte & vec_bit; } } - memcpy(state2, temp, 256 / 8); + mzd_addmul_v_s256_30_256(state2, state, matrix); copyShares(mask2_shares, tmp_mask); freeShares(tmp_mask); } +#endif +#if defined(REDUCED_ROUND_KEY_COMPUTATION) ATTR_TARGET_AVX2 -void mpc_matrix_mul_nl_part_s256_128(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_s256_128(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks) { const uint32_t rowstride = ((20 * 32 + 255) / 256 * 256) / 8; - memset(nl_part, 0, 20 * sizeof(uint32_t)); for (size_t i = 0; i < 128; i++) { - uint8_t key_bit = extend(getBit((const uint8_t*)key, 128 - 1 - i)) & 0xFF; const uint64_t key_mask = key_masks->shares[128 - 1 - i]; const word256 mask_share2 = _mm256_set1_epi64x(key_mask); word256 mask1, mask2; @@ -1476,8 +1524,7 @@ void mpc_matrix_mul_nl_part_s256_128(uint32_t* nl_part, const uint32_t* key, word256* tmp_mask_block = (word256*)nl_part_masks->shares; for (uint32_t j = 0; j < 20 * 32; j += 8, tmp_mask_block += 2) { - uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix)[i * rowstride + j / 8]; - ((uint8_t*)nl_part)[j / 8] ^= matrix_byte & key_bit; + uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix->w64)[i * rowstride + j / 8]; mask1 = nl_part_block_masks[(matrix_byte >> 0) & 0xf].w256; mask2 = nl_part_block_masks[(matrix_byte >> 4) & 0xf].w256; @@ -1486,19 +1533,18 @@ void mpc_matrix_mul_nl_part_s256_128(uint32_t* nl_part, const uint32_t* key, tmp_mask_block[1] = mm256_xor_mask(tmp_mask_block[1], mask_share2, mask2); } } - xor_word_array(nl_part, nl_part, (const uint32_t*)precomputed_constant_nl, 20); + mzd_mul_v_s256_128_768(nl_part, key, precomputed_nl_matrix); + mzd_xor_s256_768(nl_part, nl_part, precomputed_constant_nl); } ATTR_TARGET_AVX2 -void mpc_matrix_mul_nl_part_s256_192(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_s256_192(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks) { const uint32_t rowstride = ((30 * 32 + 255) / 256 * 256) / 8; - memset(nl_part, 0, 30 * sizeof(uint32_t)); for (size_t i = 0; i < 192; i++) { - uint8_t key_bit = extend(getBit((const uint8_t*)key, 192 - 1 - i)) & 0xFF; const uint64_t key_mask = key_masks->shares[192 - 1 - i]; const word256 mask_share2 = _mm256_set1_epi64x(key_mask); word256 mask1, mask2; @@ -1506,8 +1552,7 @@ void mpc_matrix_mul_nl_part_s256_192(uint32_t* nl_part, const uint32_t* key, word256* tmp_mask_block = (word256*)nl_part_masks->shares; for (uint32_t j = 0; j < 30 * 32; j += 8, tmp_mask_block += 2) { - uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix)[i * rowstride + j / 8]; - ((uint8_t*)nl_part)[j / 8] ^= matrix_byte & key_bit; + uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix->w64)[i * rowstride + j / 8]; mask1 = nl_part_block_masks[(matrix_byte >> 0) & 0xf].w256; mask2 = nl_part_block_masks[(matrix_byte >> 4) & 0xf].w256; @@ -1516,19 +1561,17 @@ void mpc_matrix_mul_nl_part_s256_192(uint32_t* nl_part, const uint32_t* key, tmp_mask_block[1] = mm256_xor_mask(tmp_mask_block[1], mask_share2, mask2); } } - xor_word_array(nl_part, nl_part, (const uint32_t*)precomputed_constant_nl, 30); + mzd_mul_v_s256_192_1024(nl_part, key, precomputed_nl_matrix); + mzd_xor_s256_1024(nl_part, nl_part, precomputed_constant_nl); } ATTR_TARGET_AVX2 -void mpc_matrix_mul_nl_part_s256_256(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_s256_256(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks) { - const uint32_t rowstride = ((38 * 32 + 255) / 256 * 256) / 8; - memset(nl_part, 0, 38 * sizeof(uint32_t)); for (size_t i = 0; i < 256; i++) { - uint8_t key_bit = extend(getBit((const uint8_t*)key, 256 - 1 - i)) & 0xFF; const uint64_t key_mask = key_masks->shares[256 - 1 - i]; const word256 mask_share2 = _mm256_set1_epi64x(key_mask); word256 mask1, mask2; @@ -1536,8 +1579,7 @@ void mpc_matrix_mul_nl_part_s256_256(uint32_t* nl_part, const uint32_t* key, word256* tmp_mask_block = (word256*)nl_part_masks->shares; for (uint32_t j = 0; j < 38 * 32; j += 8, tmp_mask_block += 2) { - uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix)[i * rowstride + j / 8]; - ((uint8_t*)nl_part)[j / 8] ^= matrix_byte & key_bit; + uint8_t matrix_byte = ((uint8_t*)precomputed_nl_matrix->w64)[i * rowstride + j / 8]; mask1 = nl_part_block_masks[(matrix_byte >> 0) & 0xf].w256; mask2 = nl_part_block_masks[(matrix_byte >> 4) & 0xf].w256; @@ -1546,7 +1588,9 @@ void mpc_matrix_mul_nl_part_s256_256(uint32_t* nl_part, const uint32_t* key, tmp_mask_block[1] = mm256_xor_mask(tmp_mask_block[1], mask_share2, mask2); } } - xor_word_array(nl_part, nl_part, (const uint32_t*)precomputed_constant_nl, 38); + mzd_mul_v_s256_256_1280(nl_part, key, precomputed_nl_matrix); + mzd_xor_s256_1280(nl_part, nl_part, precomputed_constant_nl); } #endif #endif +#endif diff --git a/src/sig/picnic/external/picnic2_simulate_mul.h b/src/sig/picnic/external/picnic2_simulate_mul.h index fc62ef863..3da2e8109 100644 --- a/src/sig/picnic/external/picnic2_simulate_mul.h +++ b/src/sig/picnic/external/picnic2_simulate_mul.h @@ -12,98 +12,98 @@ #include "picnic2_types.h" -void mpc_matrix_mul_uint64_128(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_uint64_128(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares); -void mpc_matrix_mul_uint64_192(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_uint64_192(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares); -void mpc_matrix_mul_uint64_256(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_uint64_256(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares); -void mpc_matrix_mul_s128_128(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_s128_128(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares); -void mpc_matrix_mul_s128_192(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_s128_192(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares); -void mpc_matrix_mul_s128_256(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_s128_256(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares); -void mpc_matrix_mul_s256_128(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_s256_128(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares); -void mpc_matrix_mul_s256_192(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_s256_192(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares); -void mpc_matrix_mul_s256_256(uint32_t* output, const uint32_t* vec, const uint64_t* matrix, +void mpc_matrix_mul_s256_256(mzd_local_t* output, const mzd_local_t* vec, const mzd_local_t* matrix, shares_t* mask_shares); -void mpc_matrix_mul_z_uint64_128(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_mul_z_uint64_192(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_mul_z_uint64_256(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_mul_z_s128_128(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_mul_z_s128_192(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_mul_z_s128_256(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_mul_z_s256_128(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_mul_z_s256_192(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_mul_z_s256_256(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - const shares_t* mask_shares, const uint64_t* matrix); +void mpc_matrix_mul_z_uint64_128(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_mul_z_uint64_192(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_mul_z_uint64_256(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_mul_z_s128_128(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_mul_z_s128_192(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_mul_z_s128_256(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_mul_z_s256_128(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_mul_z_s256_192(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_mul_z_s256_256(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + const shares_t* mask_shares, const mzd_local_t* matrix); -void mpc_matrix_addmul_r_uint64_128(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_addmul_r_uint64_192(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_addmul_r_uint64_256(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_addmul_r_s128_128(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_addmul_r_s128_192(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_addmul_r_s128_256(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_addmul_r_s256_128(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_addmul_r_s256_192(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix); -void mpc_matrix_addmul_r_s256_256(uint32_t* state2, const uint32_t* state, shares_t* mask2_shares, - shares_t* mask_shares, const uint64_t* matrix); +void mpc_matrix_addmul_r_uint64_128(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_addmul_r_uint64_192(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_addmul_r_uint64_256(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_addmul_r_s128_128(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_addmul_r_s128_192(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_addmul_r_s128_256(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_addmul_r_s256_128(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_addmul_r_s256_192(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix); +void mpc_matrix_addmul_r_s256_256(mzd_local_t* state2, const mzd_local_t* state, shares_t* mask2_shares, + shares_t* mask_shares, const mzd_local_t* matrix); -void mpc_matrix_mul_nl_part_uint64_128(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_uint64_128(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks); -void mpc_matrix_mul_nl_part_uint64_192(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_uint64_192(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks); -void mpc_matrix_mul_nl_part_uint64_256(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_uint64_256(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks); -void mpc_matrix_mul_nl_part_s128_128(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_s128_128(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks); -void mpc_matrix_mul_nl_part_s128_192(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_s128_192(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks); -void mpc_matrix_mul_nl_part_s128_256(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_s128_256(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks); -void mpc_matrix_mul_nl_part_s256_128(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_s256_128(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks); -void mpc_matrix_mul_nl_part_s256_192(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_s256_192(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks); -void mpc_matrix_mul_nl_part_s256_256(uint32_t* nl_part, const uint32_t* key, - const uint64_t* precomputed_nl_matrix, - const uint64_t* precomputed_constant_nl, +void mpc_matrix_mul_nl_part_s256_256(mzd_local_t* nl_part, const mzd_local_t* key, + const mzd_local_t* precomputed_nl_matrix, + const mzd_local_t* precomputed_constant_nl, shares_t* nl_part_masks, const shares_t* key_masks); /* helper functions */ @@ -113,7 +113,9 @@ void setBit(uint8_t* bytes, uint32_t bitNumber, uint8_t val); void xor_word_array(uint32_t* out, const uint32_t* in1, const uint32_t* in2, uint32_t length); void xor_array_RC(uint8_t* out, const uint8_t* in1, const uint8_t* in2, uint32_t length); uint64_t tapesToWord(randomTape_t* tapes); +uint64_t tapesToParityOfWord(randomTape_t* tapes, uint8_t without_last); void reconstructShares(uint32_t* output, shares_t* shares); +void transpose_64_64_lsb(const uint64_t* in, uint64_t* out); void transpose_64_64(const uint64_t* in, uint64_t* out); #endif diff --git a/src/sig/picnic/external/picnic2_tree.c b/src/sig/picnic/external/picnic2_tree.c index be21e7998..53cbcb94e 100644 --- a/src/sig/picnic/external/picnic2_tree.c +++ b/src/sig/picnic/external/picnic2_tree.c @@ -11,15 +11,15 @@ */ #include -#include #include +#include #include "endian_compat.h" #include "kdf_shake.h" #include "picnic.h" -#include "picnic_impl.h" #include "picnic2_tree.h" #include "picnic2_types.h" +#include "picnic_impl.h" static int contains(size_t* list, size_t len, size_t value) { for (size_t i = 0; i < len; i++) { @@ -94,12 +94,13 @@ static int hasRightChild(tree_t* tree, size_t node) { static size_t getParent(size_t node) { assert(node != 0); + return ((node + 1) >> 1) - 1; - if (isLeftChild(node)) { - /* (node - 1) / 2, but since node % 2 == 1, that's the same as node / 2 */ - return node >> 1; - } - return (node - 2) / 2; + //if (isLeftChild(node)) { + // /* (node - 1) / 2, but since node % 2 == 1, that's the same as node / 2 */ + // return node >> 1; + //} + //return (node - 2) / 2; } uint8_t** getLeaves(tree_t* tree) { @@ -114,7 +115,7 @@ uint8_t* getLeaf(tree_t* tree, size_t leafIndex) { static void hashSeed(uint8_t* digest, const uint8_t* inputSeed, uint8_t* salt, uint8_t hashPrefix, size_t repIndex, size_t nodeIndex, const picnic_instance_t* params) { - Keccak_HashInstance ctx; + hash_context ctx; hash_init_prefix(&ctx, params, hashPrefix); hash_update(&ctx, inputSeed, params->seed_size); @@ -127,15 +128,85 @@ static void hashSeed(uint8_t* digest, const uint8_t* inputSeed, uint8_t* salt, u hash_squeeze(&ctx, digest, 2 * params->seed_size); } +static void hashSeed_x4(uint8_t** digest, const uint8_t** inputSeed, uint8_t* salt, + uint8_t hashPrefix, size_t repIndex, size_t nodeIndex, + const picnic_instance_t* params) { + hash_context_x4 ctx; + + hash_init_prefix_x4(&ctx, params, hashPrefix); + hash_update_x4(&ctx, inputSeed, params->seed_size); + const uint8_t* salts[4] = {salt, salt, salt, salt}; + hash_update_x4(&ctx, salts, SALT_SIZE); + uint16_t repIndexLE = htole16((uint16_t)repIndex); + const uint8_t* reps[4] = {(uint8_t*)&repIndexLE, (uint8_t*)&repIndexLE, (uint8_t*)&repIndexLE, + (uint8_t*)&repIndexLE}; + hash_update_x4(&ctx, reps, sizeof(uint16_t)); + uint16_t nodeIndexLE[4] = {htole16((uint16_t)nodeIndex), htole16((uint16_t)nodeIndex + 1), + htole16((uint16_t)nodeIndex + 2), htole16((uint16_t)nodeIndex + 3)}; + const uint8_t* nodes[4] = {(uint8_t*)&nodeIndexLE[0], (uint8_t*)&nodeIndexLE[1], + (uint8_t*)&nodeIndexLE[2], (uint8_t*)&nodeIndexLE[3]}; + hash_update_x4(&ctx, nodes, sizeof(uint16_t)); + hash_final_x4(&ctx); + hash_squeeze_x4(&ctx, digest, 2 * params->seed_size); +} + static void expandSeeds(tree_t* tree, uint8_t* salt, size_t repIndex, const picnic_instance_t* params) { - uint8_t tmp[2 * MAX_SEED_SIZE_BYTES]; + uint8_t tmp[4 * 2 * MAX_SEED_SIZE_BYTES]; + uint8_t* tmp_ptr[4] = {&tmp[0], &tmp[2 * MAX_SEED_SIZE_BYTES], &tmp[2 * 2 * MAX_SEED_SIZE_BYTES], + &tmp[3 * 2 * MAX_SEED_SIZE_BYTES]}; /* Walk the tree, expanding seeds where possible. Compute children of * non-leaf nodes. */ size_t lastNonLeaf = getParent(tree->numNodes - 1); + size_t i = 0; + /* expand the first 4 seeds*/ + for (; i <= 2; i++) { + if (!tree->haveNode[i]) { + continue; + } - for (size_t i = 0; i <= lastNonLeaf; i++) { + hashSeed(tmp, tree->nodes[i], salt, HASH_PREFIX_1, repIndex, i, params); + + if (!tree->haveNode[2 * i + 1]) { + /* left child = H_left(seed_i || salt || t || i) */ + memcpy(tree->nodes[2 * i + 1], tmp, params->seed_size); + tree->haveNode[2 * i + 1] = 1; + } + + /* The last non-leaf node will only have a left child when there are an odd number of leaves */ + if (exists(tree, 2 * i + 2) && !tree->haveNode[2 * i + 2]) { + /* right child = H_right(seed_i || salt || t || i) */ + memcpy(tree->nodes[2 * i + 2], tmp + params->seed_size, params->seed_size); + tree->haveNode[2 * i + 2] = 1; + } + } + /* now hash in groups of 4 for faster hashing */ + for (; i <= lastNonLeaf / 4 * 4; i += 4) { + + hashSeed_x4(tmp_ptr, (const uint8_t**) &tree->nodes[i], salt, HASH_PREFIX_1, repIndex, i, params); + + for (size_t j = i; j < i + 4; j++) { + if (!tree->haveNode[j]) { + continue; + } + if (!tree->haveNode[2 * j + 1]) { + /* left child = H_left(seed_i || salt || t || j) */ + memcpy(tree->nodes[2 * j + 1], tmp_ptr[j-i], params->seed_size); + tree->haveNode[2 * j + 1] = 1; + } + + /* The last non-leaf node will only have a left child when there are an odd number of leaves + */ + if (exists(tree, 2 * j + 2) && !tree->haveNode[2 * j + 2]) { + /* right child = H_right(seed_i || salt || t || j) */ + memcpy(tree->nodes[2 * j + 2], tmp_ptr[j-i] + params->seed_size, params->seed_size); + tree->haveNode[2 * j + 2] = 1; + } + } + } + /* handle last few, which are not a multiple of 4 */ + for (; i <= lastNonLeaf; i++) { if (!tree->haveNode[i]) { continue; } @@ -350,7 +421,7 @@ static void computeParentHash(tree_t* tree, size_t child, uint8_t* salt, } /* Compute parent data = H(left child data || [right child data] || salt || parent idx) */ - Keccak_HashInstance ctx; + hash_context ctx; hash_init_prefix(&ctx, params, HASH_PREFIX_3); hash_update(&ctx, tree->nodes[2 * parent + 1], params->digest_size); diff --git a/src/sig/picnic/external/picnic2_types.c b/src/sig/picnic/external/picnic2_types.c index 188333a2e..03fad5b8b 100644 --- a/src/sig/picnic/external/picnic2_types.c +++ b/src/sig/picnic/external/picnic2_types.c @@ -12,10 +12,10 @@ #include "picnic2_types.h" #include "compat.h" -#include -#include -#include #include +#include +#include +#include shares_t* allocateShares(size_t count) { shares_t* shares = malloc(sizeof(shares_t)); @@ -33,20 +33,39 @@ void freeShares(shares_t* shares) { void allocateRandomTape(randomTape_t* tape, const picnic_instance_t* params) { tape->nTapes = params->num_MPC_parties; tape->tape = malloc(tape->nTapes * sizeof(uint8_t*)); + tape->aux_bits = calloc(1, params->view_size); + tape->buffer = aligned_alloc(32, tape->nTapes * sizeof(uint64_t)); size_t tapeSizeBytes = 2 * params->view_size + params->input_size; - tapeSizeBytes = ((tapeSizeBytes + 7) / 8) * 8; - uint8_t* slab = calloc(1, tape->nTapes * tapeSizeBytes); + tapeSizeBytes = ((tapeSizeBytes + 7) / 8) * 8; // round up to multiple of 64 bit for transpose + uint8_t* slab = calloc(1, tape->nTapes * tapeSizeBytes); for (uint8_t i = 0; i < tape->nTapes; i++) { tape->tape[i] = slab; slab += tapeSizeBytes; } - tape->pos = 0; + tape->pos = 0; + tape->aux_pos = 0; } void freeRandomTape(randomTape_t* tape) { if (tape != NULL) { free(tape->tape[0]); free(tape->tape); + aligned_free(tape->buffer); + free(tape->aux_bits); + } +} + +void partialFreeRandomTape(randomTape_t* tape) { + if (tape != NULL) { + free(tape->tape[0]); + free(tape->tape); + aligned_free(tape->buffer); + } +} + +void finalFreeRandomTape(randomTape_t* tape) { + if (tape != NULL) { + free(tape->aux_bits); } } @@ -181,6 +200,26 @@ msgs_t* allocateMsgs(const picnic_instance_t* params) { return msgs; } +msgs_t* allocateMsgsVerify(const picnic_instance_t* params) { + msgs_t* msgs = malloc(sizeof(msgs_t)); + + uint8_t* slab = + calloc(1, (params->num_MPC_parties * ((params->view_size + params->input_size + 7) / 8 * 8) + + params->num_MPC_parties * sizeof(uint8_t*))); + + msgs->pos = 0; + msgs->unopened = -1; + msgs->msgs = (uint8_t**)slab; + slab += params->num_MPC_parties * sizeof(uint8_t*); + + for (uint32_t j = 0; j < params->num_MPC_parties; j++) { + msgs->msgs[j] = slab; + slab += (params->view_size + params->input_size + 7) / 8 * 8; + } + + return msgs; +} + void freeMsgs(msgs_t* msgs) { free(msgs[0].msgs); free(msgs); diff --git a/src/sig/picnic/external/picnic2_types.h b/src/sig/picnic/external/picnic2_types.h index 5e2636291..463073e56 100644 --- a/src/sig/picnic/external/picnic2_types.h +++ b/src/sig/picnic/external/picnic2_types.h @@ -18,9 +18,11 @@ /* Type definitions */ typedef struct randomTape_t { uint8_t** tape; + uint8_t* aux_bits; uint32_t pos; + uint32_t aux_pos; size_t nTapes; - uint64_t buffer[64]; + uint64_t* buffer; } randomTape_t; typedef struct commitments_t { @@ -45,6 +47,8 @@ typedef struct shares_t { void allocateRandomTape(randomTape_t* tape, const picnic_instance_t* params); void freeRandomTape(randomTape_t* tape); +void partialFreeRandomTape(randomTape_t* tape); +void finalFreeRandomTape(randomTape_t* tape); void allocateProof2(proof2_t* proof, const picnic_instance_t* params); void freeProof2(proof2_t* proof); @@ -60,6 +64,7 @@ inputs_t allocateInputs(const picnic_instance_t* params); void freeInputs(inputs_t inputs); msgs_t* allocateMsgs(const picnic_instance_t* params); +msgs_t* allocateMsgsVerify(const picnic_instance_t* params); void freeMsgs(msgs_t* msgs); shares_t* allocateShares(size_t count); diff --git a/src/sig/picnic/external/picnic_L1_FS/api.h b/src/sig/picnic/external/picnic_L1_FS/api.h index 6a811ca06..fdbfec152 100644 --- a/src/sig/picnic/external/picnic_L1_FS/api.h +++ b/src/sig/picnic/external/picnic_L1_FS/api.h @@ -5,6 +5,7 @@ #define CRYPTO_PUBLICKEYBYTES (1 + 2 * 16) #define CRYPTO_BYTES (4 + 34032) #define CRYPTO_ALGNAME "picnicl1fs" +#define CRYPTO_DETERMINISTIC 1 int crypto_sign_keypair(unsigned char* pk, unsigned char* sk); int crypto_sign(unsigned char* sm, unsigned long long* smlen, const unsigned char* m, diff --git a/src/sig/picnic/external/picnic_L1_UR/api.h b/src/sig/picnic/external/picnic_L1_UR/api.h index 33d88ec02..f1c49e69e 100644 --- a/src/sig/picnic/external/picnic_L1_UR/api.h +++ b/src/sig/picnic/external/picnic_L1_UR/api.h @@ -5,6 +5,7 @@ #define CRYPTO_PUBLICKEYBYTES (1 + 2 * 16) #define CRYPTO_BYTES (4 + 53961) #define CRYPTO_ALGNAME "picnicl1ur" +#define CRYPTO_DETERMINISTIC 1 int crypto_sign_keypair(unsigned char* pk, unsigned char* sk); int crypto_sign(unsigned char* sm, unsigned long long* smlen, const unsigned char* m, diff --git a/src/sig/picnic/external/picnic_L3_FS/api.h b/src/sig/picnic/external/picnic_L3_FS/api.h index fe1bbeadc..d7028fa89 100644 --- a/src/sig/picnic/external/picnic_L3_FS/api.h +++ b/src/sig/picnic/external/picnic_L3_FS/api.h @@ -5,6 +5,7 @@ #define CRYPTO_PUBLICKEYBYTES (1 + 2 * 24) #define CRYPTO_BYTES (4 + 76772) #define CRYPTO_ALGNAME "picnicl3fs" +#define CRYPTO_DETERMINISTIC 1 int crypto_sign_keypair(unsigned char* pk, unsigned char* sk); int crypto_sign(unsigned char* sm, unsigned long long* smlen, const unsigned char* m, diff --git a/src/sig/picnic/external/picnic_L3_UR/api.h b/src/sig/picnic/external/picnic_L3_UR/api.h index 5a17b839a..87bc9fa6a 100644 --- a/src/sig/picnic/external/picnic_L3_UR/api.h +++ b/src/sig/picnic/external/picnic_L3_UR/api.h @@ -5,6 +5,7 @@ #define CRYPTO_PUBLICKEYBYTES (1 + 2 * 24) #define CRYPTO_BYTES (4 + 121845) #define CRYPTO_ALGNAME "picnicl3ur" +#define CRYPTO_DETERMINISTIC 1 int crypto_sign_keypair(unsigned char* pk, unsigned char* sk); int crypto_sign(unsigned char* sm, unsigned long long* smlen, const unsigned char* m, diff --git a/src/sig/picnic/external/picnic_L5_FS/api.h b/src/sig/picnic/external/picnic_L5_FS/api.h index 6766a1d09..0959519c7 100644 --- a/src/sig/picnic/external/picnic_L5_FS/api.h +++ b/src/sig/picnic/external/picnic_L5_FS/api.h @@ -5,6 +5,7 @@ #define CRYPTO_PUBLICKEYBYTES (1 + 2 * 32) #define CRYPTO_BYTES (4 + 132856) #define CRYPTO_ALGNAME "picnicl5fs" +#define CRYPTO_DETERMINISTIC 1 int crypto_sign_keypair(unsigned char* pk, unsigned char* sk); int crypto_sign(unsigned char* sm, unsigned long long* smlen, const unsigned char* m, diff --git a/src/sig/picnic/external/picnic_L5_UR/api.h b/src/sig/picnic/external/picnic_L5_UR/api.h index 3160057f9..d9f99e631 100644 --- a/src/sig/picnic/external/picnic_L5_UR/api.h +++ b/src/sig/picnic/external/picnic_L5_UR/api.h @@ -5,6 +5,7 @@ #define CRYPTO_PUBLICKEYBYTES (1 + 2 * 32) #define CRYPTO_BYTES (4 + 209506) #define CRYPTO_ALGNAME "picnicl5ur" +#define CRYPTO_DETERMINISTIC 1 int crypto_sign_keypair(unsigned char* pk, unsigned char* sk); int crypto_sign(unsigned char* sm, unsigned long long* smlen, const unsigned char* m, diff --git a/src/sig/picnic/external/picnic_impl.c b/src/sig/picnic/external/picnic_impl.c index 4220b00ee..cac679dd5 100644 --- a/src/sig/picnic/external/picnic_impl.c +++ b/src/sig/picnic/external/picnic_impl.c @@ -53,8 +53,6 @@ const uint8_t HASH_PREFIX_3 = 3; const uint8_t HASH_PREFIX_4 = 4; const uint8_t HASH_PREFIX_5 = 5; -#define LOWMC_UNSPECFIED_ARG UINT32_MAX - /** * Collapse challenge from one char per challenge to bit array. */ @@ -96,9 +94,6 @@ static bool expand_challenge(uint8_t* challenge, const picnic_instance_t* pp, return true; } -#define ALIGNT(s, t) (((s) + sizeof(t) - 1) & ~(sizeof(t) - 1)) -#define ALIGNU64T(s) ALIGNT(s, uint64_t) - static sig_proof_t* proof_new(const picnic_instance_t* pp) { const size_t digest_size = pp->digest_size; const size_t seed_size = pp->seed_size; @@ -468,7 +463,7 @@ static void hash_commitment_x4(const picnic_instance_t* pp, proof_round_t* prf_r /** * Compute commitment to 4 views, for verification */ -static void hash_commitment_x4_verify(const picnic_instance_t* pp, sorting_helper_t* helper, +static void hash_commitment_x4_verify(const picnic_instance_t* pp, const sorting_helper_t* helper, const unsigned int vidx) { const size_t hashlen = pp->digest_size; @@ -767,7 +762,7 @@ static void unruh_G_x4(const picnic_instance_t* pp, proof_round_t* prf_round, un /* * 4x G permutation for Unruh transform, for verification */ -static void unruh_G_x4_verify(const picnic_instance_t* pp, sorting_helper_t* helper, +static void unruh_G_x4_verify(const picnic_instance_t* pp, const sorting_helper_t* helper, unsigned int vidx, bool include_is) { hash_context_x4 ctx; @@ -999,7 +994,7 @@ static void generate_seeds(const picnic_instance_t* pp, const uint8_t* private_k #if defined(WITH_EXTRA_RANDOMNESS) // Add extra randomn bytes for fault attack mitigation unsigned char buffer[2 * MAX_DIGEST_SIZE]; - rand_bytes(buffer, 2 * seed_size); + OQS_randombytes(buffer, 2 * seed_size); kdf_shake_update_key(&ctx, buffer, 2 * seed_size); #endif kdf_shake_finalize_key(&ctx); @@ -1055,7 +1050,7 @@ static int sign_impl(const picnic_instance_t* pp, const uint8_t* private_key, proof_round_t* round = prf->round; // use 4 parallel instances of keccak for speedup uint8_t* tape_bytes_x4[SC_PROOF][4]; - for (unsigned k = 0; k < SC_PROOF; k++) { /* OQS note: changed i to k to avoid shadowing i */ + for (unsigned k = 0; k < SC_PROOF; k++) { for (unsigned j = 0; j < 4; j++) { tape_bytes_x4[k][j] = malloc(view_size); } @@ -1163,8 +1158,8 @@ static int sign_impl(const picnic_instance_t* pp, const uint8_t* private_key, const int ret = sig_proof_to_char_array(pp, prf, sig, siglen); // clean up - for (unsigned k = 0; k < SC_PROOF; k++) { - for (unsigned j = 0; j < 4; j++) { + for (unsigned int k = 0; k < SC_PROOF; ++k) { + for (unsigned int j = 0; j < 4; ++j) { free(tape_bytes_x4[k][j]); } } @@ -1229,8 +1224,8 @@ static int verify_impl(const picnic_instance_t* pp, const uint8_t* plaintext, mz num_current_rounds++; } } - unsigned int i = 0; - sorting_helper_t* helper = sorted_rounds; + unsigned int i = 0; + const sorting_helper_t* helper = sorted_rounds; for (; i < (num_current_rounds / 4) * 4; i += 4, helper += 4) { const unsigned int a_i = current_chal; const unsigned int b_i = (a_i + 1) % 3; @@ -1457,15 +1452,6 @@ int impl_verify(const picnic_instance_t* pp, const uint8_t* plaintext, const uin #define LOWMC_L5_1_OR_NULL NULL #endif -#if defined(MUL_M4RI) -static bool lowmc_instances_initialized[6]; -static lowmc_t* const lowmc_instances[6] = { -#else -static const lowmc_t* const lowmc_instances[6] = { -#endif - LOWMC_L1_OR_NULL, LOWMC_L3_OR_NULL, LOWMC_L5_OR_NULL, - LOWMC_L1_1_OR_NULL, LOWMC_L3_1_OR_NULL, LOWMC_L5_1_OR_NULL}; - #define NULL_FNS \ { NULL, NULL, NULL, NULL, NULL, NULL, NULL } @@ -1505,70 +1491,8 @@ static picnic_instance_t instances[PARAMETER_SET_MAX_INDEX] = { PICNIC_SIGNATURE_SIZE_Picnic_L5_1_UR, Picnic_L5_1_UR, TRANSFORM_UR, NULL_FNS}}; static bool instance_initialized[PARAMETER_SET_MAX_INDEX]; -static const lowmc_t* lowmc_get_instance(unsigned int idx) { -#if defined(MUL_M4RI) - if (!lowmc_instances_initialized[idx]) { - if (lowmc_init(lowmc_instances[idx])) { - lowmc_instances_initialized[idx] = true; - return lowmc_instances[idx]; - } - return NULL; - } -#endif - return lowmc_instances[idx]; -} - -#if defined(MUL_M4RI) -static void clear_lowmc_instance(unsigned int idx) { - if (lowmc_instances_initialized[idx]) { - lowmc_clear(lowmc_instances[idx]); - lowmc_instances_initialized[idx] = false; - } -} -#endif - -static bool create_instance(picnic_instance_t* pp, picnic_params_t param) { - const lowmc_t* lowmc_instance = NULL; - - switch (param) { - case Picnic_L1_FS: - case Picnic_L1_UR: - case Picnic2_L1_FS: - lowmc_instance = lowmc_get_instance(0); - break; - - case Picnic_L3_FS: - case Picnic_L3_UR: - case Picnic2_L3_FS: - lowmc_instance = lowmc_get_instance(1); - break; - - case Picnic_L5_FS: - case Picnic_L5_UR: - case Picnic2_L5_FS: - lowmc_instance = lowmc_get_instance(2); - break; - - case Picnic_L1_1_FS: - case Picnic_L1_1_UR: - lowmc_instance = lowmc_get_instance(3); - break; - - case Picnic_L3_1_FS: - case Picnic_L3_1_UR: - lowmc_instance = lowmc_get_instance(4); - break; - - case Picnic_L5_1_FS: - case Picnic_L5_1_UR: - lowmc_instance = lowmc_get_instance(5); - break; - - default: - return false; - } - - if (!lowmc_instance) { +static bool create_instance(picnic_instance_t* pp) { + if (!pp->lowmc) { return false; } @@ -1589,7 +1513,7 @@ const picnic_instance_t* picnic_instance_get(picnic_params_t param) { } if (!instance_initialized[param]) { - if (!create_instance(&instances[param], param)) { + if (!create_instance(&instances[param])) { return NULL; } instance_initialized[param] = true; @@ -1604,11 +1528,4 @@ ATTR_DTOR static void clear_instances(void) { instance_initialized[p] = false; } } - -#if defined(MUL_M4RI) - for (unsigned int i = 0; - i < sizeof(lowmc_instances_initialized) / sizeof(lowmc_instances_initialized[0]); ++i) { - clear_lowmc_instance(i); - } -#endif } diff --git a/src/sig/picnic/external/picnic_impl.h b/src/sig/picnic/external/picnic_impl.h index 412240f9a..61686c2d8 100644 --- a/src/sig/picnic/external/picnic_impl.h +++ b/src/sig/picnic/external/picnic_impl.h @@ -17,6 +17,7 @@ #define MAX_DIGEST_SIZE 64 #define MAX_NUM_ROUNDS 438 +#define MAX_LOWMC_BLOCK_SIZE_BITS (MAX_LOWMC_BLOCK_SIZE * 8) typedef enum { TRANSFORM_FS, TRANSFORM_UR } transform_t; diff --git a/src/sig/picnic/sig_picnic.c b/src/sig/picnic/sig_picnic.c index 37e166b8a..ff5bd89ef 100644 --- a/src/sig/picnic/sig_picnic.c +++ b/src/sig/picnic/sig_picnic.c @@ -113,7 +113,7 @@ OQS_SIG *OQS_SIG_picnic_L1_FS_new() { return NULL; } sig->method_name = OQS_SIG_alg_picnic_L1_FS; - sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.0"; + sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1"; sig->claimed_nist_level = 1; sig->euf_cma = true; @@ -152,7 +152,7 @@ OQS_SIG *OQS_SIG_picnic_L1_UR_new() { return NULL; } sig->method_name = OQS_SIG_alg_picnic_L1_UR; - sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.0"; + sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1"; sig->claimed_nist_level = 1; sig->euf_cma = true; @@ -191,7 +191,7 @@ OQS_SIG *OQS_SIG_picnic_L3_FS_new() { return NULL; } sig->method_name = OQS_SIG_alg_picnic_L3_FS; - sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.0"; + sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1"; sig->claimed_nist_level = 3; sig->euf_cma = true; @@ -230,7 +230,7 @@ OQS_SIG *OQS_SIG_picnic_L3_UR_new() { return NULL; } sig->method_name = OQS_SIG_alg_picnic_L3_UR; - sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.0"; + sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1"; sig->claimed_nist_level = 3; sig->euf_cma = true; @@ -269,7 +269,7 @@ OQS_SIG *OQS_SIG_picnic_L5_FS_new() { return NULL; } sig->method_name = OQS_SIG_alg_picnic_L5_FS; - sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.0"; + sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1"; sig->claimed_nist_level = 5; sig->euf_cma = true; @@ -309,7 +309,7 @@ OQS_SIG *OQS_SIG_picnic_L5_UR_new() { } sig->method_name = OQS_SIG_alg_picnic_L5_UR; - sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.0"; + sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1"; sig->claimed_nist_level = 5; sig->euf_cma = true; @@ -346,7 +346,7 @@ OQS_SIG *OQS_SIG_picnic2_L1_FS_new() { return NULL; } sig->method_name = OQS_SIG_alg_picnic2_L1_FS; - sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.0"; + sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1"; sig->claimed_nist_level = 1; sig->euf_cma = true; @@ -384,7 +384,7 @@ OQS_SIG *OQS_SIG_picnic2_L3_FS_new() { return NULL; } sig->method_name = OQS_SIG_alg_picnic2_L3_FS; - sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.0"; + sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1"; sig->claimed_nist_level = 3; sig->euf_cma = true; @@ -422,7 +422,7 @@ OQS_SIG *OQS_SIG_picnic2_L5_FS_new() { return NULL; } sig->method_name = OQS_SIG_alg_picnic2_L5_FS; - sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.0"; + sig->alg_version = "https://github.com/IAIK/Picnic/tree/v2.1.1"; sig->claimed_nist_level = 5; sig->euf_cma = true; diff --git a/tests/KATs/sig/picnic2_L1_FS.kat b/tests/KATs/sig/picnic2_L1_FS.kat index 2bd7e89ac..b6f0f9419 100644 --- a/tests/KATs/sig/picnic2_L1_FS.kat +++ b/tests/KATs/sig/picnic2_L1_FS.kat @@ -1,8 +1,10 @@ +# picnic2l1fs + count = 0 seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 mlen = 33 msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 pk = 07515486E906D9D106E5976DE2740FD98291282214654CB55E7C2CACD53919604D sk = 077C9935A0B07694AA0C6D10E4DB6B1ADD515486E906D9D106E5976DE2740FD98291282214654CB55E7C2CACD53919604D -smlen = 12531 -sm = CE300000D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC836002E0004008C00A7002D004E01210123000D017600CF00440122004200FE006700490001004C016E0054001B0103013F01DA0064001400280036001E002600070019003200080036003A0009002E002B0002001E0023002100160038001A003100120033002F002300240065592F1BD53345611FF2A312C7BD2A7E76E865B9A0C2D86FB407B7A660BEA73D1580F8D0499A1C4643A809C6F084CA45BBAE9D63797ECE91CB9DB77C786E76BA6125C3223848213D780AA0046A607A45F96B6ABE51ED0CB7A91A30B727F2DE7B5E8FE6C5195A2AEF303ABEE2210D58E08CEE2EF1502780618A9514874C57E218022CCC9FA2612F1C7E8AB45B97A9EAC07EDA642518016D339D3A57D6015D0DE6C323C748CA73BAE9B4BA4FBB803815DD8566DCD6B19016B0DF9774329DCD6CBDD2E91DB6253279DF981215B469C3A93D25B21265794FDBD60F85FA2E37FF16E94D1866CAC233D8B98FBDDF084FC9EB02464349C19D225F5F1C13903564E627E42332DD5198A621B5B4ABDEF455E8D3A4071A0CD1511C57E82E0C67CF683FE770F738734D23DD4108F0D1A4567C9A8C45EDF682861AB575EE9F4EC665A59004F0B32E1F937C848CF869D50A448C2501E1DAA60B9B3E04511C41D871E277593198843A9FB22F47004126A7E9C06DF719C7913D4304EE078A387551E1191C6FFAA54AA6C133C8B55FBFF78DFEE526A3C9E6B4554EC65CEC1ADBD81F0DFD5E0007B022FCC9BFD279291C6D0BF2CC980E86B7FD22146487A49D60BDE2DF992F085F24205BA9A8C717770074F26813A6CF0B0C2EADA127C93BEA68197E18508E0BA2ABBAA1DE5DB55C44D64406626F20AFB9F8519FD4906746ED728CA80E17EDA3E6864D84D4C4BE1275D5F233C7ADD0184751F11D66F8A56C8F4F1D7233F08EDED5C20A13E094C36C530D18306F677F8A4652D0BBAAF41CE99ABEE29AF6520FE29A6EA9564558E777FB35F92DF9C18B7F068297FDEE8EFFFFE74745541170A2DD8BDC623D5B4BD3EF91647330A78CD401E2F7CFBC5BC544D5158676796D0315CEA74E8A7F0E5373BF3D26CE04BEA711D4CD67B5DFBE2C58AFEE2784BCEFCBD70B24370893A07F0257691AAD8BB04D2DCBE3F84768AD68982E084276F890B68BFCE33C463B0AB6E59A855AFCF175E64018E54EE460FBACC9A29C9FB9952F0857459C97FB2B0F41FA8BE4883195112D0EA5F8E9AF523A4F47FB5FE8137652E57341EB9176276078724DA39084EB0E99E17226D22B5449A7EB3A91C8823524B77BBC18F3234A8843BB7C69480D81265CA4BDAE5ABD94E5C0722756D2F30DC3B4745135B1A4A634CC03728D8CB0B4DF3F086FAF7C2BD4123DD42D603F741FA60119BF00FD33AACB681B1C573FE1648B9B9F1D783FF6A88EBCC1489A59633AFEDC6835B7613CDA740F24CAFA84DCEDD324E2EC5D48324AE33CEE2AC26EE877A87F9F64909B414BB56CE1C760B3909DBFBC4A6039A0BF782F56682845F1D16161AA1A0AEF25AB1211496950191CA5486FA41C4A397A02EB4545991F7FF37C396F9C5D307D3BD0B654F568C122E3E0F9C5B7AE5A6B05910EF45ECB2AA90349A2D04F6840747C7674ECBC5AC6E305343484172E228D151E9C4F721A1C6584972DC21A2760F18886754B0C848BB491680D034FABB734116318F799EBA1E61E0C38CB49DF2315EDB362C280CFB4CCCC02D1C44C8678C7403B781DC0C633D87A9FFFF3A50C9254BF80914AE759B51D595A2FEE1018A8018611AE2A67E978D15688C3C789950D3BCF71F0D81BA9B8A08492EE2A4772671BF1CDDDB558B180C71B9869C0E42C7F1D8ED2293F154D3A200CC09F51BEA8FA3AAF08378CEE530019A96E738C6844F81C1B814FDD0E3F9AB1BBFDE474EDCF6186474214ED0C12C8AF8D55A7E85A22A11C27FEB2B15571AFF96721F9784ACEC44B854E833B0C6960E07FAE8299C626560609C7F596C27B75625F947E3CC289DD7B18BABD10B5827A7F6E7C57455426B93BC87CE3CC1C14681FFDB14E69FAE3EF9B51D7A8A9E90A4F20D9AE3C591F2CA41FF263613577D7CACDD8F9B8D2BC18D6DECFDE7E381F2B895400CD24EB049934B2D9C6418359BB82B28D51E74EEC591C695FE96AB658996632E421F8A128536C397F91C58D11DDB05FF26E171772E56FB6CF86C1AB2A2E63B840189340441CE639B961B8CC78EF7D768C79445435CB215259BD47394D77C3DA4C41697C1B5F999FB49ADC1CD643AC442948E133F4E8DFE707CF446A9B13A1E59FBCEED69B87F6D81BCCF9FFDF1BEB24640152149354BD63F01006B558A61DE8DEEB44B1196FF51F3F85AC677207B1B90326AFC47585E3ADB9D13324E565D4C1AA84AC14116A6FCD5F094795526F40B3FFA87F96F4B50AF267591A098F4DF7EDD02B3D353529C5DF57BDA6F7C7EF36255BEDAB48B2494DB5FCA3DE37D0A0CCBAC2F06F5F965E17686016673EAB8E13FA9A51C3AA283D32EDE50F6D242683F54AA7060DDD6D7EE4448C38DCAFE2D4C358198E984B9D7B0A40AB8C7EBB66F0C5D862D277193231C7A9B4FB0F9070DCAD7D50C9AB6CEF6899350D6A326EF489D28F66076971228562D753BE459BFB145E2A527E759FF4FEFF48F56961D5E013E6E6648068D1611B954AAE174CB1E15EBE20251F371A8CC5A5136C14EBE4C2D12B731875E61126478DCB679FB263E188000E215B5DEC8BEC8B847D5F1BBDAA771B7393D7F036E5BBF9B35156564FD419D3ACB51BC54C78F7BFB11E2CBC30144A183462877BA75EC08D0CE3D6715D837CBE619F9084BF4B6062530B333B3148F2ED5A963577EE352BD8C33DE59C4B727F662593C5D37179475F61B61320A320EB106C83F46A5662D4D8F01477C042770F5D114B0840086624A9A7A8896E06BDE74CB5F9988905FE8E630180C63CCB3B62982C3B25DAF42FA1EA1CED99A91C12320F90BE48B4BD8E63F656914EAB8C42E6C0ACE4C6AD8E44171F3298C9BC2D6E451BA1922264E2739C00B50858D8882944DE9B829AD2715D9AF6BA40EEDEBD24BD604E94F7474AC961759C82FD5A8AFC1E91F7C0073CE462B97DDD69300A8051CD1071B4C3EAE4FD9369EFC13306C221B181B0AD829BBB03C31460765BBC58A434FBC4451D7E1315FD3070461A468B2258C24CE114FEA0C094B309FEE14743DB433A052623087B5B546C27A8C6FCF9064CD1E42D264FD9F1C2DF090BD89585CB552E35D159BDCD578F361CE69DBCDA19826299D650990C8FEEC5646B5A9FD04B04AA59386A1C40A76E093393B54F9C8C3E688E04AA8CD5C7BD5B402FC37424339AF1EF06D341D5C9EC4748DA55FB7173038A9D907A8720FEB893649101FE2F66ADF1A61EEB3F5551FB5E92527532F2EEC3D959A0BB402A03C6E7375B261506876ABF60311DEEF227714D1C031E4241177A312334F15FBABFCF161FD3A3EB68E66700F93C0AE7656691A9D3501C940BA8A518E377F100BBA165F01921C876216EB91E4F7FB1C6566E6E006F8C046E20E3245FE62F7A1EAC9FF340646335672EA9E4B01C255AC48161580EAA5812A507D1C880B7AAFE118DEA588F16762BD31741111234C7AC88C3FEE581437AFADEA6F045B29521C0048744A9285CBE900938EEC320108AD9833633F72333B47B9F8A2E88175073FCDF1235618D7C8ACC16FB2E8E9F500271B5364A4574A0AB4FF4C0A6100894A0A00C2A656C4385BD4D91AA5A7633810497769B8EBDD0875C69439862090B95B8B8463EBF7CAAFB6EC97D95C36D919ADFABD1A7D3277AAD233B0A1E77D2FB93CE6E32B6F931E7A990911AFA1625A33C5E45837E52D562EAD3E9E39B0140C7FD22B0672E92C028293588CE3B8E99C3EC2D04919AED7040AC07975AEE834F7072146D9097FD46D1EFC6F1A38D274E4C900F6ED9BB7FD7DB5FE18F25BFE6EEC84CC0CB68550AF43E2804D15F1617BF5D6A9150763648A6B07F946B09E6540F1038F9D1086991BC52F9FB23B42D8A9C0FB08840BF2F021118CF6617CD1F4A18803BFE1ACFA93092420646B94FEFB4817EBDFDA4ADB106F5866E00ABD413367C57BBDA4ED54C937A28A450A86833E5A9EC1E16FDFD45EF917D05182351A7FBEDE8D5E77B96961045985F739ACAEE19C48520362A8B58DC40913803FD0FF9764F94D552D58AE76C879FF81CC70CD1D1730AA32D10AB8DCC7CB56D9D71C4E4AD38BC93499B955B02099393EDFE640ECA8E97D348A7A418A6296BD012CA4B6625CBB686E3BC74094D8371863D94923BBE9DCE3678D4F97BD862AE96B2B96F30A14BDCB2647CAF9C385B1D7C1783F94DAC9517AFF8B82761EFF21BDB20CBA859C48541306D65EA509398103C11D7710CC7011287ACC064282CD6266C7CF1754AB1415E00CF768508E177FF4C469A5C0FC075888E6947F8611CB55EFCAB08DF029C8364CF6E2FB06CEDDFDDEC17BC6D7B61AE7FA927FB67D62B2694D8C63D0DB187023C6FF9D493C787A338F248BB2F911EBACE1DEFDE0B7FE4B18A4CF0878B5E3E0A06717DE951FDE1E096CBBD23A18163EE30CE1F287C26DFE35B2C8DD124475094E0AFF6B1639E01A07C98AA5AF76F99D1C5F39F78830DA4004F72A4E4FF7A82861420DDF0B00D89EA4B4369B5BE9AAB8DC98D768AEFA90BB332B6B564F271B48EF3A9AED932355C126494C6602317B1F9296698D583B9B549612A469C7F6095826A85C62C743E397FEF4594FEBFF49E0FACD70ECF8F2306127D01BDC67608951EFAB8F6729AB38C290043A65B00561908DC1C55E387448E0BE25467BBF1F03A48AFD501BA22AA862CB147F8A3A0F508647C17A7C59D359E51352D763D62AE0EA4AD9E571F2C7C8788E89FF070F03CBF01BF0819C9740E5135CBD2934797955201B5A12D26673ED9F31B25FB12E404D53FC61E49E8B92886E31C99B10B8621F9FE642DA68270975E8588353843361EE192B9A4AD2A80D515AA04DC7B331194C9A16486393B604BB42F6A8D256C0CAB84E4EEB1429C8AEA87E0F476D115BEBD1D8E8D2D543463D8F84FD18349F11C23DFA456449A6023E217BF26F2581E353D2D0D0ED75CF5100BF007691EA57F979F93C3172DAEA191F3128F1F36F227EAD4811A8EFCEBD636728BEB616E09AE110F93B1F0D057EAA1B74D84609DED4C0F52AE47106A1DCF8371BE091FD64741DA8ED41C55BCFD08D71F8C441A26BF8869994D3053EBB63F2A94D471BFF2181F1C00E4B9A3AE3764B376DFF5B8539BE8B1BBD5A1C9C66660643555D93D4C63FF1923590B12BCE9DD77181CFA80F35057EA7E3AE0E7278E62969D3941D4B6B80C6CDFDDD717DA1D0FC823137B9A1693AEA41D48E819AD523AE38127ABAD4B4C6624318655B8EFAB1A48DDE7578814489DB6FA60F7D8133513AF5455428CA2099804231E7F29801CD7BA32F63D7B3ED6F053A0268FF8A291F7A2C839B0B5FE49E3F38572F707B2D93886E7AA722EF5C55DFDCCF0787C345965AEDB83875F0C23FDEC46981174AA55AD75DE9966D336C05B6FB62EE9FA8CB09F43301CB18F4E300D3CB20BC31444E5A6F11375F6C90222AB5A2521DC1DDD1636CF95499925F5BA150639E425C8CB0A2AF00FD024F2978B4552A6EC463466AC4CB4616CCD40EFADC6953118B25FBCCB973B42E2A550F964514F89D5FF0D53DDDFD8E0285442BB6582D6DC14FD3C145DD3F8ED2C2F9D3BAE89DBB276A59D467BF2414FB39C50F20C46779A83DF40494385209B23C4BC5247BB4A6812437355DA125692B5FE99D5D8E2330CB3C161830702E200E798475B78FDF2A6608A14C1C4AD1900922CD7EAE8BDDE9C6BD783412BE303725D4F93B7D4637D5DABB263CC27FE386AEE2851B10547AA8451D8FCC786EDB6A34F4503DCC4BAAE668CFB3E583F080C5AE0101DA6CDA381EC1969A51F8DDE6E8B0F8B332DEA821B8F16E0005EB922EA76FF0DD40D2AEA9689276C7C4DFE21B9271C0854B48425956B7F438A844AB4233478E3CAED416055FF9B031AE557FC56FE671AD99170E8FF643B5D4B47B5A285C6A976A96A268BCA9D7BF81D3C6F1BC8FBD1CB4FF1969218DC171FF094642DA724716AF0AEE5294765F07EFF76BE443EC10E26E7A41326FBE1E0289BC794BEB0F7B281880D83E292E8AA46C7130C5DFD073DA1B1FA9165FD59C2A0457099BEE7799C0BD459819FC09BDFD44C4287BF7F110F09837512D575F30AF08A386E2CF70D0C696F8F2A993EA310AAE467CC05EDF1745D2A3090B000C38967C6139FA00EAA8D087FF531FFC0393F5B4FA97483C31CA19375B3CE48D10534AC6794261286B0E0F34B77CC5367F4140A90B86826FE739EB6C9B16C96FBEB9DB334D0B470C49887ACA5364D09BE8C5BC190711D6B041A25364AC5E90AB94FDDDD36531987CA79281A42F62C09BFA9740537F203313E293D30E2B80F20DA2CC226FFFCD84D9F56FE53A5FE37466B4EC6FC1218B44553A78F89813B4992FA622A3A2B60802D68D987A76D89DFF12E4B41A83E71C0615496B2A7C85C2E7F6E7B8F820B4231027E2FF68BBBE785809372A1DB3753205849FB21AA366F0BD901CD6D6A9801F906481B36BEA88E8D66D5E2A2944C0AB1DC0CD9BAB88531A64CAF03A8517D871DC36BA20BF98824D123381DCC7C65F5F150DA741FED64907549D9BC7B92994C104DCEEDDE34EFC0DE3545DE421C653344E7176F09E7457031E6F6C18C3DF7715E72846E60BDA36967A3572560F22880ED223A7F2F74CE38DDFCF3F16A7FEC25F1035155ED70BB574625C155BB80A67F9A2196C1E9D40F3C0E44DA7D6542A42E6D0A3CC51BDAD609829F452E59479B778CDCA1FEFB0EE28E0D8C995BB15DFD5E6F87B78B174638B2688F90BFA63EDF1700CBC552F26C7A77983AF56D382B77657F84A32659D9123BC492946E69F3F498C15B571BC5D0E285E2433D1B5A480C0D024C95582317E569F6EC39C1F504DC1485C486430D212C99E4755085BEC80FAF1ED202B676CB1C1F7F7DAD293AF49B13AAC82FD5EF5AEB3D7844E9DECEF6CA4B92310E5E839C3F98295ADA31FBEA705DBCC24B36796D6324CFD5C29B751CDC85F90A24E99A9EFC3DB10A7896BD8E5CFA984A1E9730486B6A6A20DA1D1797F10A2984EBE263B52C1978AD862924CC5C13C7BC6D4B1D91882457619D0D5C5E8597DB328D5B58F704F0129E0751FF22D05D9C49CC0DB9753B0742BADDC80D4D71A820CB3283E706F416631DD063CE5CE3AA2B1807188171A2F75B124B16DDBF8B5148178FA0CE082A4092BA98509D063B71C9D483E0905634B71044103F1F1DC8018D9F34AC6FAC5B6D98C4EEAEED9F3BF23610C6DCD6829978CE313ACAE483E2C173AA975712C71AB16970E806619CEF0565D9B13BCA1EDD48D1496B0C32DE2F67D4844F291BC9E859DACB64972066EDFB99DE61B3B7B6CDAC1515C00F68F73C20C4CC694F3E2940B9C84463CACBB0323FAFBC67C353A9936CEC51BD252FCC5C84FA588B148A750D8D0B01FD16035D9204C9BA10E87278765407C501A7502DD0FD22593DD1A104AAA7EEC5E44A23ED0FB13574237946BCCA64EFA700EABD018EA0CEA3BBE08E0F9BA5BE9B1BD386762093D2D251B58ECE0C481E80F858A7965E6B6B2116936636AAC9A9C49A78B909BFBD19460C56A9CB2F780390886889DB8B7AF196BF3843A3ABDDC9C782A5F656DAA6814C69120D87610D4976D0057E238EADFD5A57DD4A250D84CC4E3F405C44F754F4701237025DAD75B3A9C841275AA63C7C891BAFEEE5D9578AAB0CE28E583F9AAFDC868E1783905E193E0ACCAB4485436F3EF7A489B75BE50FC6C6A0354D1DA5C3D9F7AF306A710132A60B65E634837DFABA5803DD2E39FA6F1CCDB9D97586D2AE8E8FA8CB4A90E880AC8EEC16B4D4B2F8D7A09DA28AC362BD5D5765AF2B3749B51838AF28B0F9E6C511048D1E00DA7A783923F0F5F89D3441FDA6D8E9D27B523A35FEA4967FAA298C6B1304CFC857664EEAE5961AD85AEC7BC2C8FF66EAE468C8C911FDB52768240959F5421B7CD7E5ADF2EA2EAE65096317588493EFE2C755805DE6C6E9B1CE5A7F7296D5DFF9CBECCFE4984102DA70FD7DFB8938F6A58AB76C4B633E28B78B4721B0D58F6CE0D4936005304A362AEE27B2EF06F530B0EC651982AC8144DCCA6761A95CB95011E23642AF55D39D2DE00C6B2A1CCE9C549700F5FB464DE8D0C52864BDAA110A41CFC75BFA5979F50E5D476669EEF1A4CB3E0825F30905D51B11232371B96450E992CE4156CAF782CC78386EC5B924E47C99DB2C1FB4FC76BF8102750D495E0BD3D3BE778B57CBC676F3A0419048DE1B43C241F9DB99D9F6DFE31B8CF1E350E80D828AE1D701156D8E83B17BBAC1DBF6F91A56350F05833C5B981F8E90C659CCA44C60711B504C5C06BBD76DB409B5AEEE013417B49AB7EF02AEF30C3B8502EE438758CAEDACEC2F00C81CAB79A36802687C08C5A02781F6589CDB3C2461D1B60DA30D8E75BCF11FE609F806175F4DFD75E0B2C16AD17D837320D3F939BDE14FA0EDFBB855E0A984C6F3AA9032AC8C1E4F1510E1EE89AE3DB99D8367A0E5AD0C0F8A3C27D1E335F06135F5D9CFE277C50AEDE2D55AEC51804CB3C920B99295AF8F8F96648CC6866FA3DFA4666CA5B47D4F4B7B495495E017DE8A593AEA88AD2C04C47944A1DC0832CC9ACE67B2CF3860968686DA78B285599C12EF77D423B6396318BF863114993B5920BBDE3158539E6D6E1E6BEE9731BB916743764A29A0A91743E1D6FE38574B3EE5ABDF75540DDFD21FE4BDE592B4440F7B95CA8AFA1E400ED8B0A30119BD19FDDB791AE24DA560E8C57336A9BEF6D762BAA39D4CD276529B887D6A97A9794D35DA0506AF3EA0FF30532CADC3BA5189150B73F7E3CB9C3910E9C9D9442869743284DE8F6428BDEED8F5A52F89BDEB090412BDE724F28913F2DBE087ABEC236DF9934CBE32F83A231C4AF88B316C37895C6B6FED67F86C46E3076909BAB7785130DCF83C8F9D86B1CB23A93EBDDF9D4EC1F877AEFB0A03F2E0912847D35BA73822A28E4646E5A21CCBBCD2D5FA9FD328814B11998364C47BF90EF2CBCCFE767EFD26A7A54104CF6031CF76106E72FE9E6787D9A12C978A7055AA0548DA18E5E7B33A91F3B5B61E1A62618306E423E6FAB4F9D84289EE0CC1A47D45A692589C40C399DDA37FE54ED2B3D3A80F27D3302BF8358713A17A70F555A6E93DC8C41FA62ED0CA25D3A8604007649FA1A790FECD078D0729B8725D35FBD6C3D70FF506D2FFFF40B40554941F1C4FA036003A80F0798568EA15CA5CBA114C112F125E00BB03ACBBCFC6C9C5C8047ADF8450EC3E8ED862B71BA203A201ADF9B9A97CEC08DCCBBD75C1C42794D75C7252B09D2C7E5D4949436216C8429A18FEC69553ADB4EC1C76B387419BE48F0C5A55C3320A97057E5E5821419CF7C4A39DF85E51E7A943B7735278B838C1BBAA6CFAD174097BED8D9E31F9F5111F63144B42306A39309AD6D6664055707F2F506D15DB6EF138F3A02D9D2BB0AE160667032F3A1C6DC046B0003619E9DC6001C5BB4AA778FA2A137E417B3E5747DF5795C03CBCDCCC56A2C30880960B67D67D41545247B92F6BAB0D140AD950F9CF4D7F84DE979082A62890253F0BBADD5E654424A394C64A175598C77B91B898BEFBCA11125EE6738C98F753DA009D357421C7453B6D5FB414D4DC7992BB001575FE987E9CE796B0D5BC3BC7936F5C2EEE9FD1B19656C622DC35FF64CF23616BB9A8EF3FECE16938B3A15B642D58FB6EDE6989F8EAD16B52866531189765B09358C0F6713DD46C47EFE852E2FA0D26C07E9CD56FE7FC83D6F54C78A620678174B1F0E41ACEB7D4C28BD070F9F4B6E3B9558965AF26374C6D8304E6A3B5490168ED9EF0E813F591746F0F22CFCAE0AE8004875A14A764689609E979A84BDF1766A85EA0E9CF782FDD997A4E76C2CB408A4C30F159A46894BD0723D57F4F3F22952DB324276F1079111CCFCFB05B967C59428CFF51C31D2EB8930B0BCE59043F08DFC828CF11AB98FE90F33C933DD7F05A869A1F96DCE0ACC85CEE12636C55193D712EE7B743E2F9E73E30338610A8F53C21A3B9C3F5BFA0BEFBC7B73BF2CC912435820E5D3F34926ECC200CA0A5CCB81FD99A4F2F61FC26CBE130170FDEBA4E1410757FBA051082BD0DB8C7A338C62E108E2BCD0BEBAD73EAAB1B251E97A408EFECBA06ADF4A179C4272D1708B820CBD9D58AB20F41357377B1C805DFCCAF170714825366AA2488E193203BC824EF5EB2ECB08D69CB45FD0A46368BD5ED5615F5D6B1F9C648562929EE335BB077A439A7FC62A98C29B46841CEAD39F4CA33C2B30846760AF8696DA1576235A501A5DEED08DC00D444B11E8902EE4FC64385F985D63B35E0C5A023AD19C1C178C6C4A5D09E4DF8700AC6F6FD7C8165629809456259E578030B6621620CDB154E0E5E2F9589109A076DDC23BDAC25588494A46780E887FED53F225474C099EA81E6C95E3ACAACD5D75E5E657E3F72973BA2359C9A73E69B7D222FDDB56DD0CBE8BC1944AE9B80CFE66235014872003454F74CF406BC004BF1D57D0F9576D8DAF26EF4BDD4D9FDBB842B5C6089EAC70430C7382AD309C9B8686F234F23A22D940FFEA998CDEFC11FBF36BB0EDE16D5F9B619DE938E2F067022222A3CEA433703929B5CF2A24C1EF3C574841BA543E158F698011E7B761C660EE329D16E46A5DA57FDA392D49FB715D7299BE1BE9154529DFD1D972E22458D83CB241F4AABA3FBAF57D009936D08813118FFE93416F2C398893C99835930B2B663D3583CE2DED1B602D3DD295135E167B2B21F8A7E9E547746C832DFDEB84CB0468081E066F6BCDA7E5B037B90DA0B373E5D7A4E5982F7BE26C5E31446B7B6C2B2CE363C3E77589A41A2E99FA560CD7507310A58E15697E18314CA6CA7089B7D4924A1661E0B44D2F6F59319F9799763304940624A312DD59D7E61E3EA9C980B43A67268E64CF08456FAEE4917E443A5DFB63D0C33701BE75E54D6275ED724E20E9F088256BAB363DA4EC4CA3B64428AC2CFA929637B9FB1584083E0E511624A71018B7BC57FD1C310431E844CE1D057405B8E0EA33E44D31889F9BD9D8ED81C37389003B1A01ABAA812A5C1AD5D803F158964FF6DD0ED71BA867AB5F5F14B0B03BA2E3CFF2353288F62B8D6D9BCD251345EE0E9197760F9B3AC9E0D48A7B241856047F1EFB7119C7CFC572BA5874E435A4B93E96D786BBDCDD6308361D670D5499CA9193306A98E1B56FEFF0268EEBBD3D015393539A0C987F97B6FC142E5238571F8B5AFB0742317F4EC3CD7B107747AF600B337FD4CD21C2790CDDB3BDADAD19160B70AB8264BE2512781B78E0B2FA791538B45590EE01B6E13DA7F92E743FD14962F183F39E819FCDA04521D70955E1EB67ECFF76923BF11BA8D9CC04E92ADE0F2B9B78E8374A04DEFDEB119AEF47116EF934E77D19166DB164D4C3D67BA1461871DF6C49E679FAAC5D682698F51C677B515D5E14CF854D573BD9710973EB8DB202D12EFB733AA14D35D09A5170458306B759B2B36283DBB19487B4BE1CB07AA0774CF34CEAFC2F8C4127DFE07E9B21905D5F58D6CF6E5A9DAD90672AF3AF4D1263B723006BA91EF6AEBE22504D8CB2A544AC6AC42EEA8C3DEF63DC386C293097A5976F4ED1E180A49A6DA56082A1371A5F330CA6FB3883C4F151356A477ABF70837B46DE38465457F62BFC19E70CE05EDD312A325CFC015D3F29BE115D4324EB194F6163FE884F8FF2708AA97B6F24460968532478DAF18FA00906CA44E0B515587E2DA5FE6B26FF6438A27CCE00ABCC71C956C118D0B48A20F143C8BF192C7AEA9447EEBE549243D9CB8215B285154B25AF701828EBD3A428974C0D2AC5AC7D9A7B1629E38710EFAE527F0DE7016A7BD43538D17FB8637FE086BCBABFCD8E0DBD5B38ED0C63DACCC54AE7F01FBE444877E66AE408237A20E0B9EEB0D3DE758732225D42B283A28665300F177B8099676884FBF6B1FDBF00F2078A3160768AA231F2F702C2D932339C4687231FCFA6192A524039BFF37D4FBF073D1BFBE738C14148BB6C56AC25DF0D13865E3670FFDFB2183A9E5088D8EAA2D3C87A84817A02811553A67714AE34F82186ADA293F7F99856BC04C0769B8D8594FF5B2C95E531B236B084F87806957C1DC694375F0832E0F785D4D9DE8C8F3DA2356227F19846ABEFBF2589DD034BEB74BF193CD4EC27F9D2902D430497BE08D6B8C11C20F7A952FA58927C570257F5427650795022EE98F5D9C168F70D710E7B7EE2785073F3CB1C676C15DD991C9CBA9295567188E35ED414AF0C554ECF6558B5379B9599BB56BA05E5ED1A7D799E3EC551726EBCE8A74F8EDB3E7C70736FC1504C7AC02D7E61AB5765F176F166AC9DD6E99425C4D7921960B4CE4B1BB8A73E4260B58CB64C60A5E1A0B336B151524A8F40299904E0CD8421A2789755BC149F8D28A98E915C331962B5D9D8DF9B5D5B9FEE060FB83A96E46E078AB5BCCB90C2EA6BB4D67CE9F6A88102B48EFCE575B5E40C3FC7F2EDC939073CB1541791680F7B718776670605E6C27AC8B8A012CD6B411C55D7E162C1EA9051EEF9FAA9E2C94D0ED4DBD0B36E4A346A471F97E839D07F6EDF903217F3826E5210BD79A9E90A29C615D79308F401B2D132508C15651008BE011A92CCBEF735B715D2ADC37407E4F3E356620A0CB4BB35E791FFAD66D1DA74929DAB1996E419F528ACCF31DBB68EC7A9C2475DB76C67C66020D80B7AFEFCA044A55BEEB90015D27CE799C655F08C0A8D9836ABA879CC6B6A13048F9FB8B227A8D89424CBC500E14F28FD924327F4D1EC77A84402DA202872D5300A5557B50851497265FE24A8F68D7F330417F1DB537CE4E76A75B1CE851614DC7B8AAB957D47723F6FF9D43440160F86EC0541A950737F6E540117D29D14917D9DEE8A8427DD751786F2D4604B1FE494CCB23715FEEEED43C55A8961DAC9B059F64580F8C32DE400A3D23999CD9ECF598147F38A3072E7D7B2F7D43DBD97613406E8C5028D066936009127F51A61EB9A3C6039D0A1EE71E6163F892274AE3C2EB5ABE1B54D9BFCEE14B7AB9D16D6579985DECBC90C2EBE63A8220DAE32B9F5D5F127586685FEF32A4FAAF8D301F4F3CF0ECAD7C4DD54A42048CBF05DD02909869CB95316F62774DE731DECD724F46C1886CC02A833EA6937D31CBF76903ACB57676D70427E27BEC07886D1FB859A204396B4393626F401BA88C73FECDE8817BC3EA2FBCBDD9ADE68C5B72AE76668D309F1FD6AFC08A5327D16409349B42F65F79FE8E782FAEA862887C6C364421AB93AA7DC556B4EAF53D7C129634E385E771DD55975F25201D4D0A5841588F315C6E8EF23ACC394D16B2E78FCE21E7F22562DA3EF3C36282D12D11E03CB808BDDC443A10FF056E57666229B62C3FC276B40275695486C48AF3A544D6CA18269361554FFC3D286B1DABC8FE9958090BF97D364CE5DC2AEE6126B8193CEC2E269BE6A905D76B7A30C515C7DE3DB20686C21D23F9CA57EE6018CA86842F53737F29B6C8ED483FB4A00F092DFE04C8432A2E4B8FACD9484F0A61B248FA7DD5A3DC84A7FEA75DFC9BEA51F28FCC4E407CF34DAE64B16DA565980BB45B4C8859A36FFB27CC7D6E8CE2954EA037F2697DFFCE769BC3C4011231D8B686DD47EF318EF1D2BCF3BBF50E93FCBB143AF55A6E5064DBBF26FBF1AB5616E122424909C2DCE73D2685285D1F24A658DA0B060BC72BD76223BDB45484C2B36AA42FA644729F5457F21B08537C9104B8740A4E1D60548D3D0853334E5A39E3BA3FE4509A5EF45E8CC257B5A6F536516AEDD6F2F7BB717A520BC2074C651D970E14661C9AA104011311A8B4F3FDB1BC2002C9BD07C1D5C506DFA75F47D948A6C5047340B7AC65BA791A025AB8D54A4C6AF68CB7DADE40146C2B4A1613E41D229BB986B257AA3E7D5664511D5D16BC210D8018C906DF1081808C7C6BA0834B551879D1569557900EA5D979E087CE5FCB1205A2431D1CBC46ADFBDB79A8B06252CCB1C1908A739D262E2BE2D8B2C76118388814B501DD242795BC18D0BA6711B7B93CC8BD864BB4CF82209E2F84A8F80EC08D0030552BD9C3ACBF2A6C39711EEAB84A92BB6DD7DA007CABBC95A12EDFFBC44F5CC66CEA392C3D692D72A688F5039AFEB0ED622D4030B49A84C06A738CEFE3FBE6C5581F87180B581A25953FD5FA3523486DD3295BA1156331ED6CFA5E7D71570D2D15AAA2428AE7ED5CFAAF18AEECE16FC781ACCD5DF38FDD6EE63C2FCC78784427DB5866BE8B2E6AFCFFDE30C8FEE9C4EC4FDBE31EA112EA8DE47544DF177623A752D0ABF2BB86E99EE0CBE7BB4B3D80AC4EC219561AA5734AE0F523662043EAC2988AC6B00CFD67B0B8F5B02D2F9BEA73CEF360FF8290B500B1854B0B81AEDDD3B7502FF51B873594C1431E74318C4C8894284F326F95BA6B45709F61087E098718E46B072214025C3B11D80CAA0C1A8650A2C44F40F1405E9F1D5CFDE7F88F3F26E70EE4FA7A7B6E3E2FA13E7BEA119F24E5556B4B2B3C214EEABEA61A3AD938D73BFFC8F58CF97C55B55BA8C84133B55759CDB596D72B5B378512D2F08FA222657CDBCCFF9CD1342D970E248135DCE534FF1152A296F8E7325D65E5FEECAA5C55597F4AE5D59123183EFF3BD90E009CE30BE6CE96043B4CF8FB01EED12BC2FCC76093FCBD90397C30060EA92981630EC785B2EE265B945CFF7671C8CE4F884FB6B9C0D98852656160260007DDE727EB93BF801D6BEC1C67DE534255D739A4C382FECF1F1CEDF2590CEDBAEF321DD61AF42FFA71C4FB3FF8366BA992F31EE1F375386599F07830659E01BF97147A99666C054C0A42EA18ECAE973651CC61683686F37C45D6708037E8CDCFA076BB6BE0C008EC9D6BC0DD616676FA9EEE529B8412C8E9922826D39807D5B4FB58194A94EA348372C3394A7EE209028C23100CD20B20614D35609E8A1A2D6AA7B58A016E9E28F16511541FBE7BCD35126447FA4128D7265BBBE28B7E6B1311DA92BA816216ECE23A180F5546088372EB65FE2F3C4919296742D1DF82045DC4B6D542071C06CD1BE9ED841AC43DB9D0510CE1693681637A03BB3753269150FDA76F9304051A3BFCA3AEC5F0FD360F70F2302007DBD938C54E4493FA7718E537A75D67DB1863AB54CBB8CA25F1003D9A8FCF64687788A24343D34E011C192CADB1870461EAAE789176435F6A7705EA8D93864617BE0B8E4956F8F1D94C0B889AF0FD5B494336598603ACBEE860540B2DB38C6DB0C7876C701CD4CC86E1CBDC3344E0ED7AF60994A22AA41AA358BFE50664E24AD538C72EF107BAEDF736A5284A6088D035E0BC028079E1B97920FDA2A5F43E86BCDDC758EFE8662D0D19FC07F950AE10E03310696E8E32D0891F7ACCCC97CB34884F175B46473F9248BC80DA03A9FEED8CBC2D3DC3061092DF7EC0B1C3E3560146C95279F600C81A24E701F51A2EA395B5C4344859C0DD380B153E60703B67879100D3840CDD97C836BE5C3F55F2C19A8E8EB702B613CF93EB397CE3E3AAD8F03571C8FEEF18349EC96DF0BED698E99DB073D89B86400557303AA03FA37B7F7CDCDAD6FED3437ED0134F3F2ADB6055959CD58C4D50591D3329CDF6D78936C9A15F6CA6D452B3592D960275D4E0FCB19FBADB8C61ABF85A324B7D06A78F7A2B4D80164257E40DA883D473899D5482845DFD1BDB2C8270E0E3F12D527C9427ACDD47029C2FDA922E432F25E27C8B071CAAA70CD20DAC9AE76D5799C067FD6825B6F18C8315E94F5079FB75EA7889086EF1E5C8B7FC439F349E1AD4209DB517903E179B72693DC990D220090E0861900AC84A100A0F672E92D23A0E971D49D8D5083FEF7A76C521E0F13610DB9EB0C5E5BBD2B48A72C8D4269900AD35EF618669AD20D2170B9BF241A2ED8E5BD62DF7611C9AA98084ED2FB5B376BB7CA1C37FB45859E9D931CC2AA08FC87F2365546606BD56027F214332D5CD73D3917036218F037BA77D174D158848339F462D9E731463303B17B4AE0868D8B2F01741D1E86D81989D3B783EC1E86CF5A047E8ED81CFB6664200E3209D0FF6362700599E466FEDE7C657208F4F73A62FEAB0CB02DF775D9C6E1D0FA14A001145F31F18761F8C2E40B04EDFF7A27954EBC8E6E579B212858B9D45B618644B4CEAE4E9049AC0635176EE2A5A57D26FA09B26AACA1C94A423D3CD41C1FD2F12DFCB05C45735F281563112734478AFA34C338C2F7E5F9FB59C86483300277A61AEEC4A36DD9C72AEC0F8F61410157C37EDC94E76B34D24166BAE098C690E8ED826D7EABE50D8FCF6DD9F95592A8E005E37B387907DC980D5503FAEA02C3F4612C836F148349710EF3BD08381D5C53B81F10D19B097E12A7A600709CA74B4A4BBAF06EEC48DCA70337B08ACC6443C5B42C83F01CFF4304305A7EA283E1BCB1226C0483371A3519C54243B4EFB0A5E3561CEA480F537D2861707D820E3EAE318855546B6C84B885C6CDF19E6B931C5623F9FD449B697E226A95BED840AD46971DE45E259768AEE28E16D83BF62298261B7DEEC364716CF34D0C0CEB7C00A1CFF437594673236BCFC99647444B515D2359C1AA7C1D177580F0F54D4248C29B73537932255A5E014EAAA76988393DD798C4D08DDD9D4CABC3CC4579B1CCC2BEED51AF2FF885A1D4D904563EE09A15B6F084503BED773D65CEAAC01705E9992B46A9A4101E6C2D4036DC3D086598945BCC6BFCAAF45F5F5941D3C6C4366A83259D82A383D98E36E9047E1CA5B1B76FBC899C831C97D3FF1980ECB758C9CCB0102781CE3901E7711B96050CA9CFE0BE9BF28A6AB43B668253C83DD50FEFD30F9B82DF24F23B9FAF9B0AA3E490CFBD71D03BF957CFAB6B05E2DD07243B89A63C87B4265B052AD2903651628B559FC10395BA250989C275E950CF6A0079E1B2C3BBC0924FD36DDB7D74FD49926E4ACE8462FA9D5DB77E1966435A194B504808ED74B56E437E126D18ED98B262A4510A9E1D9F8C60BD1BB96E2B881CBB908A6F905C7E3DEEC0C6C1D7FBD26E1F9DAB6983486FEEC8FF42D4C184F6399C766ED673FF9C0491E2AD3715A81CC0E5D73F9EECD6F75A778E1B384C762B327187D7E8FF78096236C97AD59346784B6FA33A997FD272010CFBDECA0B4FED2BF56C5ECB90399E1F49D8F03D63EEAD3F8016281FBDBB1E70734402C50725146FFACA4D97397226CB28EB581593432BFF8022F15738FB76E479A555E41A81E33DD9DAA78D4296670E9D84183B9E156A9328F01533B58AAACC499789FA7A497B5F1AB302C7ABC723BEA2781E02CE606DF44D04A6C459A004CEA97D5613FD64529C2030653A94D935EAA15639450E9B4FBA34C4A08C5338A189E8284453630D9BD140BFD676D87439293FBDCD9EA28CFA907A25CA3E3F86DB5CF84D62265F605687C528CA35E126F7FF9BDE2FB0D3E69071386533B66B96BF5B24421936A64EC5E176FDEF40B18DC0D75ECA5F1E07188803F876D6A8D1FB11958CBC7210F9D99A22259438E71D8691B8C02C9FA6503EF5089CADE7EBF34C5505DFECFE9BFDEB2A99B14112BC2481D1636114F06A83A23D3A076E5C631DBDCD51F69ED98FEE842C2EA6A7CA532EB74CBE8A7D0BE5CF056096F652ECA0F25C3253E2BB181CA1887E10BB6AB208E595BA68B1AD85BB6DD32AD28E323D022F4DD6D9967F9F7A59334844CE7DE5CB5B2DCF3485E4D6FD2FD +smlen = 12243 +sm = AE2F0000D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC841006800F800A300A600DA00D10065002500BB00F9003C010C01CC00F7005100FC00490042014500C8003401CD00E40015016E00AC0018003C0009003D000400320036001900070019000B0016000C003D000100360015002B000E00280014003A0009000C001A0028003D0065592F1BD53345611FF2A312C7BD2A7E76E865B9A0C2D86FB407B7A660BEA73D25AA8A194FFDBC947323B466FB24807DC668DDDD54059BD53FD9C7E3A3947BA0F5BEC7AD0D68665C0051DAF485AFDE6C91AA1AF342AEDE23C9B757E0F0785CAAB4554EC65CEC1ADBD81F0DFD5E0007B0064F3E2CE6A3CBB6EC5254039FEE85736E92FAB0BBEE75D4A995885668910FF784833DD8C5987E73506A357B7276ACA623316DB590BD666CD6B4A65355A3F4C5B9E4EDBDBC61DF818457FFA8DFF99010663F3B4EE97283588B47ECEE000C17AEDF66EDA03CB5190CE44FD80E24D44287B6CE67BB179E17770E5160068B75CD3C1BDE191ABA653E2B117B7F7A43EED9E2071A0CD1511C57E82E0C67CF683FE770D4BBFC000703BDBF74C91E46FC1744B08C42FE5E8CE49C189AA6BD542413DCF1D55105E647FB2458F52B4E37116B1D228D5C671AA3593318A192FC9077E48BBA1A684AE8DDA25722EA84AA513887EABA950045293982783FD5FA28957D1A52EBB32E1F937C848CF869D50A448C2501E12EE615DAABA28E74315FA7CA5575532BE611F2268EFCAB3562D875F52FBF99E84CDE09E3A53E86D62553CDDC59E0ACD88F0234F2EFFBCF273DB0DF6DD81CCCACA977B60566BD48C9E77300418681A507BAA1DE5DB55C44D64406626F20AFB9F8FB2B0F41FA8BE4883195112D0EA5F8E9D2AC221CD86988DB42ED853CE0CEB0744B7CF39D12C01777E6E7DA68BAB7E1E380F78A4379BB05DADBBC864AB1DD48625C4D414CCAAD813D876261DE63DB96DB3F430B9792FA713065BCA2BA2EF08847F11D66F8A56C8F4F1D7233F08EDED5C23336FBB3128B5BA0B57F854DCAC77E505977C56650FAC0FCE6C0512F9BCDB244FEA6BBFB9AA502D3CEF84861B6A46336AAF6A8E8F35A1DB354CB6DD9B945A841CFBC5BC544D5158676796D0315CEA74EB6ED75160F24ED8CC2A6003A4259C3DFE06297C610729EE64CADAF11A27610362C00378402031B147E41B7B2A285361A9C4D85EE106A6BDF643C65DE3F6AC6FC358797D85DD65A41791D81CE93477478EDCDEBFDB31C6AFD966E10D7C95A102FB5DFBE2C58AFEE2784BCEFCBD70B2437E73859C594073BB8D6AC793D5C76686B6318F799EBA1E61E0C38CB49DF2315ED35F004F07AF0ADCFC4251CF3516CBAA5AB1211496950191CA5486FA41C4A397A918F291BB001159131BC57A0D50CEB6C17309B4E50127213AA80A99FAC109B8786754B0C848BB491680D034FABB7341133AACB681B1C573FE1648B9B9F1D783F4D535808B046B28A4C0E8860E6172C768BA5CBDC6EFB3546AE93AF7B45922DF402EB4545991F7FF37C396F9C5D307D3BE1CAF9846B964CF78D6B189B89C375C58EA5E94DFD34689F5300EC47CF99ACEDA64795CBEFEF517FAC7A77945CAC4537D6B61F536CD1F85D98F7CF65B6D69386AF8E56B45A4D80D8D7C14980D7C18BD297F24F33A7F025B813F8AC22962CACF6D2CF94A18C93F869865DE5F1492BA56BF89FF05E7D24777CE2B5E2AD3535AAFBD2293F154D3A200CC09F51BEA8FA3AAF814FDD0E3F9AB1BBFDE474EDCF61864704CDB0992A8002FFFB440B1EB44E50B60752ACC16AD4C73C194C7EED7DB0FAA275B8AE84B8FB7AD2EFDD489E5150CECBE2AF1643A4260F7845E9ADEFA7F644454DDFC74E46CFAB5E306082BC07A8CB5F87B7833FBBD8667F397AC5649C69A24CD7A8A9E90A4F20D9AE3C591F2CA41FF2FACF63BCF0C89F746BAB5A9C1CFED04E6BA626DCF5BC8B71FE2E5DE3CB6180D103470C2AF2AEC38BA5B69644FC45B4532A9BBE9ADE2D30ECFF4FB2BD133BE683599DC2C1895CFE48F2E75C31DC3A4D77589C14B649E55352622D4289366B71C8F31DB6C4D354ECB2F5A5A6CCCF822690DE1BBC9447D863534E03BBF42FDC3F11A6CB4B749BE4A2BC1C38D5E8B58ADF94DD5CFFEAC7C9F758E59BC54F6185CFD72E61436AC6F21756B55E8FCF28399634C98192E25431D85D6010AA058E1D1C627B7B6CB453835F0EDAD28CACC78092CB9E3B27763655FC20FC63DDC316D7D60765C550516E782F4D2722B5C6676FEE05F57AFBD5CF4D84E82616D6568FD61FDF7CC822C4570FEB8CB56D25C10D55C2A1F86FBFA30D657966FF83C9505F019DAC0DF90D7917D9F4466DC9A9E7FF3758CAAE14832641F53A25F6757710F8F219BBAC0E643E79866938C13E2E3A8D02BC6AC348F8DA750A82836C7B5A79E7F1010B896E06BDE74CB5F9988905FE8E630180C63CCB3B62982C3B25DAF42FA1EA1CED99A91C12320F90BE48B4BD8E63F656914EAB8C42E6C0ACE4C6AD8E44171F3298C9BC2D6E451BA1922264E2739C00B50858D8882944DE9B829AD2715D9AF6BA409ABE8FEFF8D25862E7F072F3BC3C0A71DF72BCCCBD319628D0679F449FC697DB179EDA1DFF90DF3AE1539A6C54EC77F39D68C38865BA913A0513277F1CF7671E6827AC71443CE5655A49D83FEE2B0956EB15F8BC4A8545D21BB16E4078E64540E14743DB433A052623087B5B546C27A8C6FCF9064CD1E42D264FD9F1C2DF090BD89585CB552E35D159BDCD578F361CE69DBCDA19826299D650990C8FEEC5646B321470B1199C4307EEBC950ED6D148CA05745E0136914992844E5310F4B23DE0727AB062EF27AFBED2AB1FEAC0EA9F453D1F1A1DC5A3B79200A0B105AFA51D4427088E84C1EB8264A08B7198DD5ED564AD5DE9ADA5FF51036698F4873FDFC6BEF712B9950C3C8C05A61B3D2E1333F4B97605E56295A10853D9B9CFB2BAC5D855261506876ABF60311DEEF227714D1C031E4241177A312334F15FBABFCF161FD3A3EB68E66700F93C0AE7656691A9D3501C940BA8A518E377F100BBA165F0192166581FC11AE0C09C746870FD78DB29BFFBCF05A63CA1D67134FB3260FA995AFC0C72C72DCC5D8DA2E33BB86B71AF4E10118E23AFD744462B4971BAC5A0CD47CAE13E93BC31B3BA4AD29FBB623B7CC87BDD33F11D2A23C1960834886E4FACFC3344E0A33D0D6809281254E629A14FBF25C5EE8F562F0AFC4699E65F59DFE8F3D9D15F1617BF5D6A9150763648A6B07F946B09E6540F1038F9D1086991BC52F9FBB03360A535C250AB919CD7CB18D088844408B91C817261E37C2F70383902D73892A9BF6A5075197104B04C8B18821B88A3E71F03FE2C60D8CD7609EBA053FC5FC03F04B7105DD23E78C36D4BE1B30E37CA7C78B596B27F43D8FBD621D1FF5ED36BAF883016F2B7688F41DB2BEC00F33C2E44E91F68A194F0E878BCF4145A890823EC292AE4927C07E573E046EEE8F387386028D7890B4FF255F584665044818D82E5F6464E825B55AAB3B5D7CDAE7B40507458FB43F69A7BAD934796D44D4A0E8B81AD0939C97CD1D258869B6F7343A7FBBEF21B5186B8EE05809B7BE6DF1481FAF1E5367D243A83A46B7090D8D85500FAA48A5DF8F7A309EF6AEB8C5CC4787E9ACAEE19C48520362A8B58DC40913803FD0FF9764F94D552D58AE76C879FF81C3B3FB5BDE7ABCFE7FCCCDAAFEF15EED6EE5EBE2EF87246DA17A64444608178CE33B091908615CD42275B82AEE0F77F8A314A046249F975E16D591101F6A8A5B3B3EC26CBA92DE2E452D4F704DC537915D36543CC75286CAAAE58E871FE1FD5A2AF872BD275946F000C49FD06044D58B519CAD98AA7DEB23FD1EFA1F6888D906CDB2A8D4250801776204AF7B4D9F20BF85222E1ED21C76D512355B842F886E2C9A489C0DAE0FDA95534657B9D0B89A1636DFD4D3537D035FB2033250A428EC817D7710CC7011287ACC064282CD6266C7CF1754AB1415E00CF768508E177FF4C469A5C0FC075888E6947F8611CB55EFCAB08DF029C8364CF6E2FB06CEDDFDDEC17BC6D7B61AE7FA927FB67D62B2694D8C63D0DB187023C6FF9D493C787A338F248BEE7A9478DA5EF9B249892D47E3EBDDBDB9AABF1F014816AC469A67996658945D42E5EC4A848AE4584AA1F2D121B9635C072C050E71B01CB8B6BAAA0AE005C8F12C3858E14F69161359FE9B75DAFE63D8611144B717CD92208C76F67111509972EF58322B994FA1F250C187B5CD5E2C89D51EE75B2911B917AA2A7CF9EACC36AE66D531BCE678540E49F9785CBEFB836BB90B69C269D6FC9FBB21436145C556174920590B287D3E2C802A7C533A9A9DDCBF1B6D8817CF2DB96FCFC6F34EB531075DC8AA99F6F18621CC29069C5F8F058CDA4AF07F556FC32A8FAE52D3506A4DA704CA6EDAF6944345F3617841BF5D3A1EEF079121629348221291EE6217648B10A9C5F121A4E554A19FDEA88FC3ABB317A7BD80F14B746E868446E1B4B8AB0A880D88D63AB91CAE6989C22EC86C10274CE83DFED0298BE79C47A4C0A1765F776516A2EC248BBCC28D742B29FAA4BD0496ABB6997E5BB06C7CBBD2AF08CE2E91870F03CBF01BF0819C9740E5135CBD2934797955201B5A12D26673ED9F31B25FBCBDA782FAE0D6543767CBA618485785A439FE053BEE0FA6DF7EFE7F6F522242943361EE192B9A4AD2A80D515AA04DC7B331194C9A16486393B604BB42F6A8D25AC04D37C45D8CFDBD4D5798E2AD70BDA9F7C207BA5D3AB9FF5A03D7DCCC1D4C7240983DCD7E803817D7815ADD205CBB24525F29A2C412AF117E73EF563A98365A5D79C284ABEED189B1053FE28B1EA36163305019FCE374065B194504617DFF78716F828D2C98CF38A93BE00AAD10C12DCA5D7D560B388162E406401080B41DE2B05F4C3BD7A92FE81DE96896BA8F3DAB79C6EA9DFC80406787F3D2523B03C3FFDDF1BC1BA073CB4CA4FA1919CDFF88B13034C6F5C8EAE5191FA0320CDBBD04102305E38EFC3A5CD83501623D49A8D4EB70DA726B3B2E6973E109639CC64D1D2D0F7C30E4424D52FFD761232F44DF73A82D68F3A4A642817E7803AFA7FB7355C9804231E7F29801CD7BA32F63D7B3ED6F053A0268FF8A291F7A2C839B0B5FE49FAE90C21D1A3F3293C5306FAF6B8B7EDEF7EEBDE574309C9AC6EFD4F50B697F99A27FAB09F70301A90078579C85C9E15A7276A109B5C5C425E45434130038DF67AF846629A2156437203E5B5639CC0FA79841D9AD35BD2DF6B5CEC214E61973D8DD86C9349AC2E1279F6485BE258961ED4417AD9E55E2A382A36752426105E765AF520D2643CB1664D51192E186981E06D498D5F2C76B5F20B3F2E55D2F36469493E7A690F5805043FFED44BEF6EAED88C91D580689111B2A164CE6AF6B26813BDDE9C6BD783412BE303725D4F93B7D4637D5DABB263CC27FE386AEE2851B105D72430CEB25D548226E6458AEAB8CE8AA7E90F4918D4F22613BE9F669CDFB2265030A5A4BD0C4FF9217329DCE1A63C9DB34919630E95C4047D1D32A8C7408D576D6E5A4A0B046DD578D98716C3CE127E145D982403811180E581BC0DA810062DCCDCDAF71E9C2C1298EC9456C54268B1DED172165CD02721E59F90A5E4110E7BAA2616D1E2BCF5E6CAAD3E81B1193C1DAE14EE97A109F87B701F155BB1E44C93B496B1651F635FEAB00EB65A973544DAE5EA37F22A54C62C8167CA7F8BBBDB2A86AB13E82FE76F413D349DAFD602095E92F11B370437388FC9562A8A5021B257389C248E708FA6C272F6B484BCF55C25F080C9E004EA920C40C6010BFDBD09157427FAB7C0EC820C93E0A9C9FDED0F7181B89A1D0C6F25F0786A893FE9D2D4AA00B8C269D4AE27D5EF7A035817409A0B883311653B9D2F32284FC6A014ED8EA83D7CE2B921D1E195489338558C42D54E1B1F93D6CADBEEAD0D856C5E7339BF5273D4D3250C3AFC263E8427F23EF0125871F835E3594C99A833A5F56F736C558D7C2D6AEB79C1F978B5D41BBB84DE1F3205D81164807AFDF380B388107F66118BEF9DE1337E84DD9177FEF837F367EDDD47BE48BF18E136E680DCC73CC5B6E7736A1E18E3D1FE1EA09A25A3288F59AF16C5267B731E043E0B2123A079AD33ABB2337E8B33071A7F4C4CE1532F536D58C5CB16482BF2CF29860D9A8C5BC54E28382B07F29B28E17DEEC12B2782EAC2D03183B24060FB242C810D9B000DDFE7173B046AA523C0AC684D815ADF52663F2AA91A7ACA7756A8F347CADA7076A19A0825DAF88056E28E7EE2CB9959ED2EAE41F71AA13D1FFB8097CAEC4168352DDA17E307FB699070E447427311C9FDD113BDA25DEC48CBDEC45BAB3F253F555BEA4B92B3072DCDAC2F0402634406CC6A01309A5C2D1CD4D5D967B464152A441F6C340CBE9989FEDFBD6BC8A31FB744FD584778F4AA67A94B2D43F5EB84CF73790F7224EED20D58FF8C2F914983E43C458CB2122FF793DDFE0A507A12324B88516F7138E9FF5B5677853C4BB0DC90C67EFE81F430F81FF70CEE3E80DD899652E6E4E32037DE953463D0FC533DF9A62C3AC17D0D8ABCA3A61C48D460266312441C1D80A993D86325D0C35B925D171F87775AE6813F0C1FEE78162AE7046F537C4983DD0A247AD8D1F190E45D0BCAD64D083CF16B0026759817D0FEE4237CF849D859BEBC29E99193C63BA6F03504539D8E102F2B08606AD9A6E82E2325E491DD6F59B6FDD4CAD268BBC97E4D4C8E5828B6EB1E70FA4A4D3B1E3C7E2B2593C0F81069ECD4E51B423721FC13CF740076B786F702A0666976D5156AD0507183E84161F5CBE476EC1DB4D1230160E8D6F01116770CDEFFDDEB0FDDE44F76277EF5461AFA0D9A8E91F5111F63144B42306A39309AD6D6664055707F2F506D15DB6EF138F3A02D9D2BB0AE160667032F3A1C6DC046B0003619E9DC6001C5BB4AA778FA2A137E417B3E5747DF5795C03CBCDCCC56A2C30880960B67D67D41545247B92F6BAB0D140AD950F9CF4D7F84DE979082A62890253F0BBADD5E654424A394C64A175EC5C16CD317A9420654996B22DC1A27E3A9653F858ED06758B911DFC49E7FBD5DDFDCB8B7B43228C21C7D54DF5F3A9EAAAFC3098415FA5A752F55144A81C30A1DD0E811C6F7A171852A044A0C64EE0179240C0CBD56B460CEBFD11F5D93017D3B230847A9C06FC9134B52AD50EB81D3FD9837EBFB62DFE5C0930BA135B0EC45A9601E862F2CE008D3C5332D32033DC1467DACC4EDAD6F841B9E144EFCE9877472C74A1B2FCD2F7EF9B48907BFA67627F17DEB270C41D0729BB690462BCBC49782F4A0DFF55FC0951D8D0657B8DE884F6DCC52941B76ED9620CE1FEF592280F1F15007D71C87D3148D2B2D9B0F967C94E9C0D8FA54AD8FE4D488FF4A8C125730CAD807D63DB117E8E95EF90F3DD929EB906D928F0303BCD3E298DD7836E27BF3F3C747CC9852F42BDC406C00CE50A619A95F2D13D418F3018CF03962643DF3D8F2AC7944B0996D3C8C44B63B50F9F8232E517B55ABC7B455EBA5D2722CEF4B3F9CB604F2A8645EFBA50D7EBB780F5795568E31FFAE62A7367E0DEB5220B84F71AEFC5BE402A9812449F9D858985FA5598CF1EF3988C21B0DB50D0ABDD131910FD4C64C27991F697DCBA34D7547DBB3D0F101DC7DFE785664707101C8B3485F1E7E726218D8DEBF483CF0B8FFD2C1CAE363DBAA6FA4A4D1E31D4E82F81982596765FCB050691E55EDF9925AA79DABB4CB1A69A0308F534A783788FAD9A2E73F9C0AC423D483D9BD238F71145D6C1954F8C5ED01C29A623B8D028F996BE6B38DF9ACF8F8D829B819AC30B1CB06E613ED9D4165729D4E2D585D73BF1DD3AB7B82D47C9FCD30C2A8DFDB98F50FC2320D44C4690BDE3F268C98C62B54A30D437AD781A78EBE4886FCBEFAF72110DD04BA6AB6A41E101BE33403198FEA5E5961767195CF32A23195E46A806D1637EE680AD73BAEB8A36F182E6FE11350F1884AA2A3F022FF1689AC827FE237043F28E30765EAA8AEFACE5A19BA6CE3D54ABC5279D92FD5F7A54E7813021F130F6E86161F0C766871360C8ECC42F340A58011347C135238F79746C53568C5B47CAAE727AB6C1A77E6479F3C5471236BA16DF515D1771CEFB4EBFC03DF50470914402FC6B51D79F0F2017117079EC3B645BE8503C1B7F563BB3A4506476E6D4EC9F40D4F776C04EF346370D6910FBCB891632658218C702D135E7FFD762B0B8A0119B0C444C8110FF25258C7A0CEF5020796F6BFF772921FC21E10B75B32E7BBF3D0B891BE4788C8D8EC38BD7F0CDEDDA08A34D26D0BDA4C53ADDCBA35FAF259FE5386BD7041A08A66EB60B6C1EE82600B93731CDEC664C69FD763E41C62932BC3512F4A1F0E67F99840C28F10695A76CC2B4CEC636ED86C18FA7C7D279C68DC6F304CB86523EA469E965B4B04E0B017B002B3F99E2CC1B557E784849234A2B66E015104C3E9C1B03495E4AB6C6402406FBC2D984ECA973E12B07B17AE9E460FCBC6EE6620DF389D7C6F3B55E840B71919302C39887DE63E34F0627332918C99FBA209BF49FCA464932E725E7F361AAC80B77A788C66538E1F426DAD451F524E25DC88E287D8CBEA2B05644B45544F7EFD546E9F502AD8575D6FDCFC54F7E86C6B86DA4B5AE7B7EA09F2629DD9DAD383250ADCD515393539A0C987F97B6FC142E5238571F8B5AFB0742317F4EC3CD7B107747AF600B337FD4CD21C2790CDDB3BDADAD19160B70AB8264BE2512781B78E0B2FA791538B45590EE01B6E13DA7F92E743FD14962F183F39E819FCDA0452880A77EB59BC1B63287E62A0A89C47034E11FF5D4554BC796667419CCD23FC5EF40769E031CABE21DAFA5C3A54FBACC81C700A97677CA25E81EB7F7D314C8AF3BC5E4DCF84B7FEEA4C3BE12CEFE558A0E5EBCC30E7421CFFE1F279CDDF3A6CC3F163D300D94EFF3529F9B62FC9FF270F70ABBAD44FF805C146098C4E88195C56A6613C335B78936F0D7F17B3913061D7F62F87B1CAD15E426B86D7D388BEE9DA68FFA82301E99278CB8B42A65BEFA09A5DAE9DAE00C5D26681AE18856DC3FD4B714D7AF67F82752F44EE605C23005D41F1D898DBE2FDDC6D2647D9127713B10D43B006FE58F4203CFFAC44B8299F645D2298F1CCC8905BF25D2EC920E12CDB6C39062F6F061D97AE38A02C9671CC09D268B552F2EAD2E87539B3958AE31835768CA9A0E62FEAE08596B48E56ED84F2FC8D3530F4ACE41D612CCDAE216D3A75EFF270B1F922D07CCBE6DCEE7CCF0D7ACDA044349F76835A05899AF2D440C6DC063203AA81C83CBA51574FF752A771ED329B0DC003AB4AD08823E68C83B2F752A9292AA957A6607A1EE4C6875B5ABEC175095B276851F43AE95A319719D240B634EEEC866E74D8BB3BBE57B477050C0DC5B4739F1E21E0B6E8E48A86657539A22BF2AFBEA5ECA440BCB529C102DA073422857FD2714A7D467CEEC9236B827B5BFD0DB6F9BBE440C76361D81028A98A6714BA8775368817759A9E9A00A7F770C266BABF2B1E427E8093324F7880917B9FDD3D0ED9486C288FC7F01EEF4651F2872BE9775FF46E2DBE94A556BF55D050BED58C29DF1209DD5F9FD4797D8F8F7FE2D50156526EB42B4B07EB8F0C4E86E6673CA6C4370B4A2FB6AF1B4292F0ABB13527F4CBBBB872DD8F1A9744A34CCE90DE05C18EFFEA8D17404AA89F329566FCEA4139BD19AD429ECF626F177003760A447B6171EEAE2F4F3D155F49223CBCC8BB41BBB01E0CEA0FE666DDCB4C3BF653B23F5C64CC7CE1DCA70A5D0AEA2920967823D1DD0AFFDA01377F13274A97687FB94E9866C805C0A479DC656F44970C5225930D86CB4A6C6B6E4B23DE8FC4D28AA65F2C93EB1B07EBD793983E964A9D98A33D0D9A18ACE9C22EED7DF2BA2DC2F419BC0A495AD72A70C6EF4FCA2FD145506E4D133D9C171985CA37156F7AE9C966ADC44C4AC514BDBC4B916E8345BF2582D04A0E852D214CA8B9A3A0AAD0E2294C24F9A660C3B277334703A4919687BEA0415EE002E5055E272E46FC04B1E390A29FF9B0E29F59CD9592CABCB395EF31EA8949710A7EC6042206202C87071DA8249092308D18DB7B676B94B56CA812997B7056EC49B0D65BA1CAA8BA676E484A23A98DDE27F272A26254019869D57A6ADF378303AABACA59B25AAB696A0F95357F60D4DF6D35CA4E24FF942CEB65D3F60FBD2FBD05E2FA5B614E49512579E515B7B4638B31A6B7C51E1C88E9BEA8C3C619058C4EC21D738F0461D88EBFF832BBA0CB26D8AE58B52D43B4B9F0C736CED9FA45F2C28273573E198863D000FDD3C06735A0138CAE651A345123284FBF0629AF2828FD7E2E07FA75119B88DD0F9C6A2452BD7B129C3518FEEAF1BAB204A24072BFE658BD8055E4EDE688397FD85AF18CBE511CBD23B85798618913DD32FA1E14CFBD6A296BD32955AB10F5475E4896F4F1EF288EA7AA5F23AC904720D799C0CEB986F434FE83C856E612C204A1AAB46F87EDFB5E20F4B6187C625DDECC6ACA02345165D5B45305658EF1F04C85F8372BC4185A81925BABE1B18D21750072640308F78DD6FAEB16EA53C4936850E21E410908171D65AB7BD70E0D1B10AA84A95BC48381B36CC76B51A14796324AA3FA934C794FE3C307E297F9FB22DB79B9F57DD56115636A2AF39AF5D6925FE4A6626F78AA85F304A9C8DA49A52D8A32123777196812D442073556D3D73F0A98389DAECA58BC555A9F5944343B714F28229672018F7E319AE3FC9DC41EC653A4A4C96800FFF7BAB19FC4ADBFF10808B7E62BE53B7B3E2A773674DD9F4CEC99EC71FDC513D2771D488032F9EDA4010428DC4E845284447F94DB4BB3AA427E9176C4368C8405F38AA0A36A3C89AAE181FD762753636AE1143D2AA2B3F9573C781ADDFE70166F78791C53DE4D649E441B5326250A30677AE1BD091A98464B59BF6F61D22E0D06D272CC85F81E274FF4B2EBE6EAE58CA513F7CC41E5CC42E6F5963740268191B9B06C2A26A5563FA7EAA4D792F0D174188824EF3A1AD5497FE59B76281CA82075EE8540F1ADC01F7CECBE7B4CF21FA32E30AAEA8A56D10E48BAAAC079A3ACFD535DD828C1C3BADF3D1FE039EDE07050C33BC42A94B525E1DD38277589879CA2017FCFB054E4420DF1FE70E7448439EBF66FC477F11A72DE2F122A711420449C11523DA7A125708DBC32D3CF8F8B9B46E2BD1017B6142C4E339F638710D4DEF9A708CB856ADC5B145585E9535A31B799948CAAFC10BBA88B0C6766261D164288C9BDA9DD6D703C48E95426F0303DC316D639CB16B826B2AB533B4624E9786440784BB9BA6EE8249A86AAC874D168D83179728CCDE862CBCBC6420AE42A2EA1F56EA6AD89345A5AA7C581DAE6A203A303CF96E3E6B98FA12AB83EEBFE2B02850D440272BE8A023B7C404D0C53631AFD84C16289B923BA2E852878F75C414A3B3B19CA07F668AF1E50C5C028D6D1C821FF7C81298D78784C4566AF0C93FD20BD025F056BFC2AABC60398FA88865CBD5DD8B638B287B762A74A95794095E5467087D541ECEC6CA23C6A62C892C9E14D487B96320605D61C06C55238C12AA754B54A78DF083F1C0493C497219525EFC9CFC25CFEBFB1418F9B71A9B36A0105FB39626130E72E2186AF63ADE695D344DAE26FCEA770BA6D3580088E5F5516C47D0A5622774BD64868180D1E1FD3C745E9BCF4A21F75C14D340D07B57D7381B11AEB4AEC93333490CA537E567CEF8F09222BE2FA09026A336E7C603445CDB750FB4A93D82AD2B154E270591414D74AFCC00918A4F6C1283A37CECEE657679C807118F917A6C8CC6F0212A87C7E7BF67A4220CC7E58F0EA3748CD9D5E5984D980094DA21346E45E7EA347546B3B83C80843E70102490451ACF06E3009AEFAED5EA7D339F348485EBF6FA8E12E44E6C8FEEF1FEAFB70C41A44C420AC9D02293D57D3B53D810F310B2358B8CC599DD1AC959ACE78B005A7330D230484F28077EF6EE1BA033A8A5470A1D4C61B694C8EB3D0F681660387DC5ADC85DA193C0099C369ED0F591E9DF48D7DBF88D971356824708793A3E221A1B29AC74155E490F42729DB196116EBAB5AC8945331087D5FFE00D335300860C3939934A924CC604476C8FC6385B9800BCEF9B6AE4476C583006192E24DA6FA578F496DF1D0BE3DF7C2F9CD6C6CE387FE8BE91248C7A25FF792A3099C89825AA43D5B0D1E19B390E8980218EA5710B0B12006932CDE19878C77AB969E79B671A06FC9F43E0A1BB122E1729B093029F938E4375358C5A9719CD74F51DDA8992B49413F2149E6780FBBCAD732BF398AE124E3110AD661872323D911E5837C731053C33F9F4E54D09ADFDCFDD3E76E2D2BA033E5D0164C4132881CB627AA61500196631B4778C3D29A4838D56AC0B2A745B47F38E622F451181A86D92EDB548035B46D6678C65DB1A1622B19587C71E251E963A4F3E3FEA38FA819CC50CD1304D77D0D3E1462EFA842A576AF78C0FF3085143D2AE0622D955360853E2FDB6EB4320111A8FF9965FC3A50481DA723ABF660793C108C961998C715543501DB3CF7538E38A0B398F54F843DA30B269880A020626E1AEB6AE3335E6472A544D6CA18269361554FFC3D286B1DABC8FE9958090BF97D364CE5DC2AEE6126B8193CEC2E269BE6A905D76B7A30C515C7DE3DB20686C21D23F9CA57EE6018CA86842F53737F29B6C8ED483FB4A00F092DFE04C8432A2E4B8FACD9484F0A61B248FA7DD5A3DC84A7FEA75DE8594C33E680E143D8816F5AFE47F07D8D5C846CB451ED37286C405E66723E1C0E6A29F6A7ACDA4AB2747A4124E8010651BA6CB43E9EFDE4109B67D348D1C3A93F61D13C33BEFC859D07869BA75F2173A149BC92703D6333B4C470BD3359F1D3391012EFFA1E4C47AA9D1B302F1D4FEFD7D5440F2E2BDBCCDE220568D88975FE64251FA9247EEF617020DF90FC9D62D47D5FCB95D56FFDB134B8F4B1DA260594C454A3AEE756E5F5470B2874277750522D14AB92D68465190E624314E7B834AB1043CDDA66F659F9EEB48E6395F0850B1884BB8F1B76B6DBA130AA4D198CFDB57F908690211D75DD89C870E74F6CC79EFB7C4ED629056DF04185B857469C7F90DD4B451447908027FF09F728472FEC9E553EB1CC5DB29AF136217A39F6E529128BC21001CCEB90ABBC9D78799BA0D44FDEE921008DAABD907A2E801DB2C58D5EACBBC66DE0522BC60AFC01653A222C5E442133E47B9B6E0E69FECD49C7B84F6A7875E49DDD794626E3777388432F3421B39901D16E759744ABC781E545BE84376C2F0F7F543C0A9B44D78D18FC1CC5FE8D3E54DDE481A20B04874C89AA5369EEE94BD14153D88C4894CF3DD3EE485850203EDC1FCE652FC649B1813663E34EB49487BABC4771DD37B11976637BA3D055A28563F6B4D36EC2059B6C79389F1F9B16C1BB084A8AA679DE55469C4F9ED44AB82EB707DC25A46C5E3CC70D6C2F2A815CEF2D2DDBD63C0BE63EE5E790F9C70B76CC6CA14E0D57EC216EB05B3B918E4FC95181288BFB5EA1A28C797D706A92AE3CCC4AA6CE7EA7EA39B3436785EBF28D4E3AE69DF3B2F17C0C6CDF2507178F244A58AB2C12837EFB922239B9814294341A0C8A554DFC55FBDFF21C9E554F15750C7552026FDAAA09CC9ED9FDBEF9FB031A9D6039505897D83CEBFA6F58307651AEB597791B36F8299884C5901B762873E5F2A228EEA1059E01C3F3C06C4EF31746828C4BB5DFBBCC2D65FFAC08282D7FB2CBC6F03EDE639D6361CBA5F6E259D6A7798DE84B4B7C82FA125532E7D7630FB0131B464E8A755EE174D28F93919BCC86AEFAA5A5B3C6E90665AF77E8F2C2463B9F945E1FC0CA1FFB83FE4FFBF792E80B63F8A74ACA90C42A7CAD85414A47612781BCC284A55507F69CFDA048EA95DC5B4C8D73D469E14FCD0CD671A9C9AB6B3F4730DF0CF40E7B50F105F2849319F553C41E466BDBBDDCD91EEBD4F512D465A0AA4D951CDCE62E201DCE8189522C84D67C8A06A13A971D367712CABF4247AA0A9C4A7BD6493F6501185371741FB1891372A85C3DED86A4054CE3B279FC79858A4CE1922A544CE7FC2AE5D9570C1F8F22C47FCF8190D46E753806860B7108F4D9A2491227001A3E0689D4BC45676A2BD6154C3F76627F18CC3DD9D7E2B09B0E3C37F91B413A648B6E2335C9802561B926E116E82E733881F474846029DCE2FC158FFCA537B110290093E8BA8A3A628D379DFD2C17C2063D159842CA7B3E629F72100FCFCA3829E524D7D31BBD8B655F51C6B43456584D52AC9923E88095F9E105B7AC508F22FD9E6AA47229E46932E61713738A6D364F8F5AC9740E40A7D1D83A2546BA8A8CA1FABBDE701205424498BDD0338187031718A2FD4B62051A4892505C14A3A54363E04E10DAAF492710B559A29A1955061D8B6C40CE1CE2657C5C760DF213ECC5E0B21A49119DD7DBDC2E60E0C15811E5422E67B48E3619B426412EB3FD973C07535C30FE265FA417E1250E901B1D08B88C12585386D06FAE4BB552C36FC6666DBCEB1E5822D7E23C2EC88FC54344229DFCC1A4BA2239C3B0329DC0FDA9E6ED63C12907CB0B79AB206A0D0E9326B070F9F860A43511542F5C1289A1C61EFBD6FDA6ECA99F3907F886C84D5131105DA36EC0B6B4C945B13B10DF6CC77769237BE2EB4FC4A1C54BA278821EE24969FC5612C9B46B7204085371D851E95D9BA42F31F136F499E21667CCFFC2322B65A979BEFD947249339C174C85E9D2A78CFA93931AB2E3AF54B4208F10D6AB5976E1094BDD70FEEB8FA1C907C806BE517196978889FAB751CBAF3D84985D3D3A5A74552F9626FFD68E556E04E27F466D723D6056D55C3DD16A06A48CF5356FA567BB1A1AB4F9379987B72C6EBC0D39A84E76D8C97785A91502B2A00BFC15A6E1663C2820C4C21AAD928403538DF96C4578307959CAAD6DBA1DC3D8EBE40E2E348B82E95486E9B822992DD039EC089BC9A7509CB6EE13FE36576EF44A61E01A4F452E07DC19BD1D3819EEB089877EE81618700F141ED9F509570CB00BC99D48C610256DCCA6FE588C80EC08B087EBC9CA5831C467E36D443DB29D0B5E569B3B5C4F3EAF0B65EBFDC41391B5285256DF8F8E03E98F181A6C5864D6A464CABD0C366448F20D36AE8CD54E5478B255436E05DE0B577523C5845C2664CD9D45057FEFE12BA7A6FF07E5018E0FF31EBCC510B77E7025D987C17EBCF266B2595CC157ECACCC11721A44FD390B848F3C43DEFD0AAE48195993FF994B36FA35478569F83ACD955EFA3627A18747318725AD45E3181A0BC3E5754118CB0639D0CDA5DDA06800F4AD0682B03381108FA3250DD116CA09E1EF4C28844228CD4F22FFFB88357E53371772436FB05D9A495579427C90D937F69F101BF783E5CADD9B3E1428E90FDEED7272F36FA3A0B82DB38D66D2BF2847F6B883FB5EE9FFA46C8AE4069CCF79ED5325C27AD54917D45A9F0DB0FE86BE3C62FA2B127C870B36CE38E49358E139B4B28A2DDCB23ED28BD9630D211A586A791A86F471B77570B71AC2B748C8C9FAAC0DC7E52328D2E8D10E0B08EA6390FF8F4CD86B423B040E40588F4936F909467CB337444AAB63FB206E0E57A09A24CF9106AC3E544A140F0C21A0FDBE93D1E16D2F1485969A6EE63EF7381DC9A9ADC587632693EB48E9D3A0AB280D0C7EA1AC39D70C5D31FE4206953BEE1B3C7E9FB8870D9F9042BC318A52359F8CA68737750BBF2E05E8B3933FF129A720C472561A5BB30B8E9FCA184B5590596E3050121F279A31692D7A8198580A99CF67A97A831B501D285CF8A78711A0D12DCFB2333BB08631D9A88F4EE9A11BC6FBE525BCAAD856859EC545DCB3AB7C4326EC9680717FB0DAAEBA0BE4CF121DE84763ACAA120EDF4AFFB92A68FCCD9A8A851498B76383509E926AE6353CD6C32ADB748522B1BA2078BB19C80F748B5D1B8BC673171CC8229FF2A339C74335E3A360352F392198A760D4F3E887CF0B62B1E3DEDADEBE98810E2B3F8C7DD58C5751DB22C2B8BE9D570E688219E91CA97EFA1CB85E296FB23A85BE45743977307CBCCCBA0FCC894AD8722A0DD499266C554B415214E8C27174F99548D935BC05D2CD0E8AD8A199534BFB8F66B6AC6835E6C4AFA3D0D86CA93B6EE4E5AAFDDD598556EA6CC1A8F460CACE8BA92D046C71B44F976DE27EA33BE0E598381225858A3810F3901885D0B38B4570C530479F684406DE1F0488C61DBFCB9212393B86A268B405DEF72484ADA9D4A8BB275EB9036690FC257D26A4BD199D9A1BEBD9FFF38DA7DBEDC9D2B95622A0A8C9C53D2056B5CBE1CFBE793C9A09A50B0CF9F076AF9A470B2F4AFD408E73E0FEBC31A754401C61E197AFD9040F40FAE7A537CCE815FDB5375C6FD7DC634AB973AD66D5688A746C2E02A30E050DB758EA8542CA4D3BE41DBCD2851D720A0E4431ADFB959831409CC052F6C60F99A5E4C79DF3001A0F9AFB706E7BC51B4FC40C10D9039AC9E8294FE5E0E9ECA7DFCF1DC73CF1581004A94F442BB3B29D17F9919AF88D603D96DB284269B6965F05CBAD176E63C3EA6832911B34A5F6AF1F90E17319EAA47C3B2037F8F61160EC3E354E23B84D28567B73C921AE27ED346DEA19A35565E25EFA5C1448A4CFD3F37DF1FD288D3788820941F9F09725261DE011B761572F74931BC275D37E70A4B024B24A309EBC650CA74ACE5E81A53DAEB2CD175E0E8D8C6BE4327BD57793A5EEA05B297765BC8FB06D893D3C1E256A6634D72A0801EF1B1CCBA0CE20BA9D4E6B0F6A31552FBE312FEF70AAC5A41C5A78A47FFBE6868F411A9EC0CEF36A7522F845F2CD6AB208C2342DC41B955C3FD6CEB5BAC194C3231BF251F6A7BADD11A9B6F7F3F3C0F33848CB2BCE00D91D2E79EC2AFF921F1320E939D7272FFF06483C1D577E71F4D6419889B810739824C961CAD1B4776B2464C7AE7EB4CCAE044701D165836714195D2FF210018A2BD61E50453F117D47DEADAFF61B8B7557724C90EDCB483FD5DA6C140CCA08AA7F82E7216F6CA505D81459E725B32E8AC6713799B342DD01303795DD4A94E08BC7A90D98FBA74EF4F90B766A7D4FE2AFD6310CE3E94A6799CC55ACE57097A8D1687029310B4A78F522993F6320D29C0FBAC6E622F81BBB38035D2A63A433C1AEBF42EF5862CD5DC6C3FFF9D55F52F2AB1533CEF99214772185E0DE1ED335FBDEFFEDACD0CA6C54A5EDB0B3266DDF4E79122FF87C582385130C1E42E7A413F73A7AD53BDA4FB882DF699850AFDFDE16B2A7EDD247E8626EF515658D85EC59B01ACE43C233B21DA3589306DE71796673D8A6A8FCBF22698F362A62 diff --git a/tests/KATs/sig/picnic2_L3_FS.kat b/tests/KATs/sig/picnic2_L3_FS.kat index 96d557008..0dcd72ef1 100644 --- a/tests/KATs/sig/picnic2_L3_FS.kat +++ b/tests/KATs/sig/picnic2_L3_FS.kat @@ -1,8 +1,10 @@ +# picnic2l3fs + count = 0 seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 mlen = 33 msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 pk = 083807C6BEAF6B2C7D181D41963467ED1B8424F3CAAE0AEA528626ED79D451140800E03B59B956F8210E556067407D13DC sk = 087C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148033807C6BEAF6B2C7D181D41963467ED1B8424F3CAAE0AEA528626ED79D451140800E03B59B956F8210E556067407D13DC -smlen = 27430 -sm = 016B0000D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC89C003502910151017000E901020075012A008C01ED01E301C601DE016701AE00F901EC01E700A9018E00FE001A024600980184002000CF0015000A02230109024E005001290032020B00B400A5012E0012002A00080038000A00080033002400270035003B00020038001D002A0032001F001100090020001300060014000200250020003700210028000B001F003F00180038000C00060038002200650933BE108BB0F48C0DBD00B167196085E6B8E76C821871F822D2C81F258A7E2E7D5CF7016D6BE62D1CB41EABBE5839194DF511D62351DAEBC3954B4DA7FF87DEFAA7C41946FE9C393AD36BD9E78F7AF49CA4D351B76F3A2F17D15E72AF7921BF4400B97F3BF3693BB6506FA42BB991FF4287EF06D790B20B1AC848B44066FE6FA11A3C160621EE25A019D5EB950A48EBE94C7597363CA41078A332D13E3EFA4CC3030A35B8D0E3A606E40F187F4BB40D90C56E488602A7EDDF7A1ABF991BD763E617552140CDDB936DDA17FE961B99747FAD34E38B10337E6C1AB6240CAC01C4577C7765F447D4D63C272F791097B030DFB2EF1DE7DA69A53C2A4CD6AA5828BDD8A231943E157273A70B33B839051DEB923673D2D23AC78B0A725D2BBA954411654E0D7FD3CC06016DB04BA8EE9142D4FAD52BB387AEC51A843716B879AA20778F95375EFEDE98BD680BDC707A814EE703DCFFF21F39822D048613B838C7EB8B0CB481509AEF39B95206C2D64890B5D988CB86E101BE6598FCE2AA2D6D3334E55C34473C10FA7D20BD68BA5E797AA609FE31C1D4E859CF53BCE2232B6B0B6AF0858DA94BF742D49A9100F4B9269C53C517C5A09C34414B41A5D485786AB6DBCAC05861492BF4CBFA2649985EF37F113A0A66A16FB6ADC1C60AF1E27D9F1690DFF71F0A2A7F7E58D7975AA461A11BE64ABC56F8804AF2DBA6DD6B5F62E29A8C13F7667D63B0AC81D97467ADCA34513E564D5EFC899EF3A93509892BD3C0B71B7A93DD85D8B9364064BC205CE5EF145B699E49D98C366699654B50BACA4ADF61097DB3408FC37A9A1E7961913714D8E65DE78E04D70E44746813AF1706D7B46C11BCF68B28ACFA7B917DF366BFCD304AEF4AFF5D2C84983A5844BDBCAA86F034D7B0793CC1FB7A9AEF623F5AE5D8BF0A88158198BC8B9CFBF46FC0964E4FBD30F8A3D282D975B83AC2F1A96160F8B16868AA1448450B6B7E10144038A293AE52E8CA1929D44D41A0D58E953003B62991203B66E34E055C9827C575596DD2C9F87FB657C4A1A5CBC9AD9D682E872A6DA8C7A9A1308FDF32C24EEE2C2C0E6912803CD10C24B2045DCA4AF8DBC481333224F503F840A9AC87B19ABBEA308545A7E886CEFBE9C73C9BE57B5DC0723848C9C61AD7208E34A23BCC588997101D9E8B3D68B7FDC847AC4E1FFBF296A4DAD698066A5634FA95F7E9A559DB0EAC57DE55FFEC77051089010D150790D53E4A9F94B7662FD4D7B609F02CBE24A310998BAB99647796CEC3DB82E9777B9D3B23923CFE26EA1790DB022E5F5D58EEED34DB80203F0DECABDFB46D03B1C7CC2FDD3D7BE8F702559FEBF92C1522D7EB0426B77D85ACE945BC5846887BF5EA57103F58E5AC48D6123935FD678BB52DF439AE301F31B27DBD17228A7801F837D8A44D32F6E4C2653958C4BAF627B71B00639157CE6B24402958B166248A14B489CB54B80000476D50F0CA261C2E708244B8A16E48048F7B0B967D70CA1DD11491D10E26A50A36E120BE08EE2274A2B0407CDE09F991449A6146248055A095DDE7590C6249650E20B6A28CC3F0BF75DFBB27A2C3DC56B5491C13110DFEC12FAE6871DE85A283CB3D037080373EBE21C7C0B41FC592A6C58BCA98337D1CCFEE60DEC338B746722A251FFE395AE565A3DA8B97542749C40CE91CC822B7FEBD6E6362E9034C86FDB4CEA91471DCEAD6B3877FFE5B774CF0097516C71C64A52A0F29BCCED8C28D1C6A56ED8765DA83126673EDC5B3E5530BC6A0A85EBAB9C1CF7D25452EC5F9E70B85B305FF56E59AF31C56D291A99AC9E831BE830E3D57726D0A80293E124E47C38EA8945259AD40D31A6DCBFAA336F3865B3CA1812EFCE74E7EDE88FEDF5A1F7929E3E84460C087CDD9BDBC1839362C43F0AC0D59B37B25448D4E457FDD07E9351FD1A4770CD3BA0AE6FE044CF052E989D2043B3CD984AAE6B4A8258295486CBB76E847AD54FDC5C69D5E3B0BD25D0A358A79EAF39C20448F6D6FFF745BEAB8DB69713A1703C5D1E5C01141EE2BA2F115C857BEDCCA8641440612D2D509AA8871E270DE84F3339A52DBDB300DF4AF9A35209C879D793E0CE533EF0D59AEC2BD2FD1506EFDCCF447CCC4E3C648755060BA75D08C9A2404DDBE9DFD6E3237900D472999C53728E693F38D20C32171324FD9EB95B86BD4DC75CBF62204F75A8058EA1ADB1B7EE801FBF3A1C2A5875289541FB05A05CA4766768B3BFB1C73A1C323C3AF5321A3FCC0F21425F1492CDDBFB55C9131FA1CA0008F8CE4F0DFBDE973A766A1311E6CBF40775F48AC88B453ABBFE1AFAF81E4F66A10CADE75439C248388DD29084F4F96998A3C8CAF2A383D319984FE50D2797F5B517A6767EB5D6A9FF59544F06464C3EDE86B8472ABFBFA622127D9C3A48DD2CA2FFC2632EB5CAAC81F9464DF74B9CBEFB9728B318374B51C32E2E3039329E0906470657F7DE23A051C536D16E2789F5A8CA4352F485FBE1E12FBA374CF6FF5A7190273E8951EDAFBE74C69AC9B7DBB8E0BD5F2DE76A1D041948B33926CDB3646BA78752DB865A8CC879196636DB105AB0E40240476BD4D5F42923BE5961BC50D8D3E7AB45CC384653A28DB3B29DCBB41033911CAE8ED5711AF3BAA0814C35D79A1544C13C38B548D701818F6D928D2691C4ADD22702B95BD506EB73EF5FDDA9DD1D6D29B6D86E3F19B4980641F83EE9E1F9F8465C4FE82A04A9DD6D64F4BB0947036C184B140E7CAC5BFCA61505F2F7899B87288D5F277950E2319418C8E6DECACAE7231BB4A1BFF6B8769A76B628ECE20CDC441A64330353BA3635972098D3416F46994205C38DDE95B5ABFB6E0EC00470FFDCACE71591486B1E0639509D10F23EF0DE6F9CFDEA3B8F2BFB65FC0D1079C48B54F2A171981672A63BC519864F26C1EF115D1C452F432FC562F7B5A2FC5D81A78ADCBAE019DD3148F0915CD2ABF28C9A41D0F19FBD63A8E8D14DF47C2465E24D5FDD9DCF38EDFD706DFC28DBB4F000E794547D2FFF80C6C34ABFC7DF5E8A3427CF841B9E5AAE8FA00E0735916729C04E484FBFB145EA8B04FE65B45D8572CF93549C471D7ACD6D664A50100A738A9FE926141B5F758042091B173B3796D3A9818882F34D608A329139B25443848020F2CBD3C5B5F808759FF7CD0486F9107690EC2A6966E20513E51AFB139973CD1B09BB6DF2EFE113586BD4F45B2E16117D20831859257C71293CDD777BCF5D2D6E1F9BF1209E6E3837A4E96D656AA465A6C2D1153DD5D7FD1C9C40273C11F43D96D6EAE06A4BAB5212880C9B2147EE8BFDB577EBEEF3B4367F7FEF5D1B43A02327B1D0AE291B4330469EE66A9D345107E4CE0311C338A057795B760E5EB0057A668B48858FB983A794DF54BA9C68C352F8C71265137E1380D2B48F5D159E687A89A4CC95735210FF1BAF47FD9B7D9EAB861E36BF319DBB105863ADB40DB49BA3CBF84632E9BE6155A9D76CCE146C58D45640A941CB396E4E421F9C2A393E84526EF1EC480B09686433C32AA216178E7F91A38AE793EF42B49C309D191142666B064822CBE9F742256CA51774D0FBF7B8E81D19FB96C73F6F20F0C38CC524037101A9E6F33AC18C407D23194469B43FF88B9540E8B36F94AA322470FA73E9937C21D37B389706A94605305D9B915734898DF15A4D9C6FF2F0CC5A0D0E9F1E594ADC1296451B28C931F4CD73BA17DA1295C6B548C8BAF25C31E38788DAC09CC4B776D438038B4F26F95F9204C5A556B0077004AD8EAC84CEBBA309F161905E50BA9219AFD7D52DA2E16CD80FBAACD4E1C082D9FBCECD3A5CC1C24C0D63B10DE04ACCDC63DB9927181BA298195FBF8B0BBC896FACE59AACA13B7961148D4F6F41719D89D7825DE4349A4EFE8D51357898216830292879C03DB8099F2CCB800FA0371658362EC18511B2D4C94BB47F395454C63F32AEA943570B35E195FE5E9C846E3A075E3B0335634EC4FAD2B3336160F393F080C86B46BBDC4B6E76929BB15046F2A673E61E1B3D5022192D2431553B2A761BBEAC5006F97B62BA1361264BDABD0ED1B49418A69F7F78CF7AD5B4DB3ED0ECF6E617BEDF3966DBF676556AC242720BFDB29EF17F71EF8C8571370DF8479612D71670CD83DC1372FE48ACE431AAC751F349D465F9002E7F5E65B78F93E24D2EFE6A0EABC6EDAF4C3B395602B19D7FF6A120C9E86D36522149C50CBFC54EB2D68BDAD9B3747C6C70DCAB90C3B7BBF6E7F4C0225D42141C557CBF909E92E74242AE0F7F976319A0F4136976F641D3DAEA982C1C7A0CC73CED63E746A55D2C2449D9CC876F705ACEF85812C5E1DC9E82C97AEA973D63547CBD2DC780185DEA1B1CB08CD0DA2680ED9E28EC5BF87B4164354ABC7721E47D9E41D8DD9110549A696351D86DBB0FD45C14FD626FE629EFCC0BEE28EEB4228669B4B186DA8DE692CEBA6ECAF2155EFD988D286CB266B0B35A63CCCA16579357181B8DDE9634E92EA31348B9CD8C727BFE91F74A0D8F28B1DD74B7E0B0F549090ACD0A763BD5BA71132E34393B315C0105E7095F5BBB7AB2A05C031D36D6C11AA2C06889A43957C8642413A62A865525E404C4F37C6FBFA3A0524F5C2CC57117EF3EA140E76F33C9FCEAAE5F63B63514A56862FE8645E1F0C936A58D980F01DB778F16A024AC9B3D422C739C33ED722CC901EE8CB89971C185AEF058CA028242A19CE0CC16717D4A2A756123739306022D0E56425E94F3BA4F560F2FE258710A0B4CD994C4D54D9F3CFBE76323D9C7769F354DAA7072DFCA69F08118E343FD1CFFC582DD9C2B892E039F9D3A2A84369C7721F1D78B87174F0019C0D6E421E555F0FB7AF63CDA935C75B77580F8A7C0D10A57AB7EB16460AAF32E4B2E7C07A6D4D8F1DD8443EB0C5821B133435E94862897C5E6424367AFDC1DA6A7245FEFBB88A3EDFEE4E6E4BE1683EB29652C675329E4EF5475D22717F06572C208ECE234D72F9FDA3F899A43A8DF211439D6303743C064F89A24B253280DD888E997DF14A8A709451CB8BE43BBC2CE7D69ECC98622C11C474FDE6D9E8EB8F665D1F3F837DD11D2D6E2936863027B25C69C5FB3808CCCB548A144450A1EA4CE50ADD8F4F5AC7E187B5ECC3B86AF744017BABE0C59899A929A7695E04732BECF6B1537A7FB6A3B61159F587B3BA505BE7BF55281CD2615E408BF40DC4FDAD6E72658CA67EFCB989A85F31D4F9065D55469C5D62185CE2CE952E7AF1E6C6BEFE2D1D691639B71575E00B6D02280AD42016E74F0878D979812A807879119E2C932CBA6BFDCF5DF9D93BEC47B21D94F9C57977422386F36169E6644D07FDC0452CF4AFF2F84B8809D5AEC0157DAFA4851BE16FACA506718A62A65518A0759E6B3F784B2B9A45D00B48BFC2B39861C9616A2ABD7CF75555D3BF2BF094B8F01E76DC076F1A8C951A3E6D95A90C5332E9E888EEEFCDE1299035AD0F6C41F7E82BC0E7EAFF8829CD701007FF0D8D8C99DA92CB89B298C3F180DA85AD59B475614577BC37C6CFB8B3450F8A7481F3BD064DA07F26787311E39684370759E37443090157889FAAF86FC6432934892B5A6B90459AB0E6CCA2CE6E644D62A846DD9B82A54D8F9A0322993A833B59F4914CA993AD6F7B2AD4145B36F6CD956F1BCAC8BC4968DF57972154D4AE63D933C836EEF45ACE8208B92303E9FF3011FC1BD414641DDA22CB2705F7DBF5C24EB9BCC9B4F092FE72F15F698591F1D7ED6A14333400C318F50B0DB6D50162F9639FAB9734697DF77BACDBFA201D842877393F1B96A55B3FE1A49740EA9FEC8541F52894EC31518384CD212FBC0CDAE37C2F0CB6A8391B6700622DA3B3301A67E4DE3479CB39FADB89BFE6BC479E34160A02C82666905C22626537B17B6D1E9AC632EE6318569440677E8833E976A0E417702A433E20074C96F17C19C553D7945FB1191392475A392554AA0830E4EA7DBD8B802F8C1BC4B36DA252703B53A9D5EF93333F04202492DE0496E2E1D8D54EBE09B258560A939DFA75602A52F638536DA49D62D0A60E2633304EC72E35C1C0FFF4EF5B433F91EE69D869B97E76916432788BA4D125DAAE1CC4E146BA19CB78A1AC68933A454F7F207076417365E8BF2BABFBC49A769551A8BA14951F23ACDF4FDB86B7B082539B43DE8349F3B896D6915EE4E32E088E860A878EF69867FCD374A789CC930BBC3776CEBBCFB2CC590C97A16FBA0D06AEE1AC09196BE3110CF7C47EF6492DB45E1B3D1C70A35DC8ECC841C3C573309AB763F4099B2DE0A17E47EBC53826FFC008B5CAF67097C3BFCB2892CAB53C7144E32EA089D646C40629DEC0F9E99F4186A66CD8E2CE0C0F229AFE22ED1C540DD9BD81296128D60DDE782FAD6B7429D547170FAA3318E838A8622F225FF36197675F032CDE07B30692F2C7F6D48419629A560FD39BFD040DCC04C4C447B1383D262AFF3FD0534E871033294A2E266D01A3DE2BACFA9D7EAD115B83BA7BD346222177D40D7B83DC6297FB84F732301EFA7FA5BAD59D1CB7A1023BA61919633BCD21F1705A45D0638A3E55CE9D6ABA6C7F486E90AE02274CB41C37B5408EA61825B9FB37C2FD22E7041879C494B39706DA928BEAB8BCFCDCEB0272BCE585B66FBB7C8CB9DF2AF73959CD31B80415CEA8FE3AF8E78DFD8F8DDDF550EDF187E7749EF219182DA5ED234766D9CE3A4108D06BC828689206C4DA2E08DB741EE3A45F1905E625DAA6527D2A688B913DDFAE558A802A52A790A4C7114838FF7F486108BC393A8873F816F6AC724DB948170FD73B8028A1CACA108FA634E0B73808DBD79E955120FBED13CD0C2F6445CD3807458EC9102F279720DCF8969939AD48206CC30A70979633AC11666FBE60F6B64BC33D2235206AE1C265D1B8311DBC79AABC661C5EA39EDC9F19BDC5DA0F10BF796267BF9466878C58A6DE6AFBB576884D996B9DB9EE7C4844A88EC73C1E72E9683AD40FE7272C4CC30BD10B23E46075B4DEEBF77076EC1204628416D15E8F91FBBE4B94627B211334CD49EAC179BF019CEED11FC12478645311BCA9918501BBAE0FBFEC4CA78223F7C4C398A82D8BDCEE99D60FAA0B581FBF31AD18458BBD13A84DD0957042E9B75E16C5239454609DE9AA844DAF07FD4AD673A93204341B338FB07D00DED6ACACEA1662C0679763B153D4AAF19C87DF907F09D2226F0E320F7F358FA291304D575CF0DA329E835417272DE930781987AAA2834EA4848899BA44A6DCC468EB3BF6F485D55DDEBFF34E3765F2FEA166C7C2EAAEC2AA0AA9EFAC2945148E6DC27B02DD4B1C5399B1C270A066A6FC5A1CD2B3539CF511EB5ADF73A0178BA63E7A000516DE66773289C9D02AF43A16133416C03C62EA06B7EA51D164E60E33287D3874D07649096E75194102E7BC13970AB4D3482A9FD31AD59275AA21519AC783712EC4AEBF80525C0869F3748517B1E3135678F112F449A6D96EFE3144D3685152D6EE88778E5C683D927AF324A88FFA6D3AED6BE89D3B2DCBA044E08D197B4AF184EEDE211E0621C0EDB3B06C6FD8C5C9638007DF74D54A0F92DFB2122DA80601F040D09620F0B5695A4DED013CF60B9B03DD005603CF731ED202CC99CA64E798067DE1E695E257C2C1F98A8074D42F4C80919FF2D6C42FCCD7F365932811D7A16B952B4C50C86D426B27EDC5E93803EAF1B0F21D89F80E422F16B2A81440AD72A33760769996565BE38CB1A26F9E3CA3381A313E08F7FCEE9717671371D1CCBE6644122EA0406994CB8405DB01E9450666631E36CF5BABB02F1264BC200E675602F74B549D6251F1D032168CAFB864ACC897B5344813AC9ACDE6685204C203C503946EDF56C5819BC19AB2921826B5A09F1F347FF464419D800D6D4E369B5FE153E7A884F38ED9B8D6847FA2BFE2FF2FDC7E09EA75B0D4E74512537EA5F86DFF3F033136F52D812D23218FEAD41C52DCD925AC245D9C98FC1A4659ED7F2974209D15FAFF4A7F581F2BBC792400E83A6E7B7BC20591CD6E10E26D0E78D15DFEA3F4BDA508D2E39B7EB8A23D820786455C3E9D079ECEE57983229D991E42672A15A77B45E3003BDAE0EB6687BAF63FB9092984F5E00F440F5CBD7AB5B12FCE9D7D2010B31AEA300CFA2B8D7D2F3E3C3674D9107DBFD9C07BD4B583AE1D85E917A9A70CD32AF566E2E684CCB76B222F59B1822FCA838C5E264CFA37A7DD9503B367869793800745A9183B1448137A099007FF944203DA92A4BF3CA8B0B4E4C1183281010A5ADB12101A977F2C12022242FF59E882D4F5D934CFDE3C6972B378EB418ED248B45A1EB55AFCEA410649476A22A7962594D805D9022C9FE8FFC0DC21253B7FFBC16E52FA1209A7C37366471F3880217D425B52633E929AB8BF01B2FF440A3ABD5C4450E14E94BDD81FA872250E5B7A513C015B34EF0F0C2884B3112DA5CA5A44362FAD40DA02D2383C254857E5B5F23A94FE8DA2D4873F67B29CBC53387E6632D18EE87CE2A7E8E3BB81EE6849425CA4980565598BF3E593DEA10AD3A01CD8436203C3A9EB9356B3D02D5AB37D953C76E1251C53331A3BD122F9403A5400067B73521D0324F9BD31FB0BE206EF26D0457ECD0E02F3F9D87D65D10105EE50665D1C79EBCA755ECE825E6F2B2B9666F8E93C955ABA24B46E9098D68435B441AC5F628CF41A624CD9D1DF1FC8880B47128BBC954C01128D09650CD102BD680CB4D5D9556FCFF69B8527A5802F9C5ECC04B8142949E87945D59AC33924ACE2F30CADABD4633196B8D1770EEFEB9D376B7FB5347FF1024E0C235DDD0DD870D2A5463B8EDC31C2FBCF213ED4746B6221E800D18CDCE3B4085961F63AA35B72F550356817268F33A17B11B741F52D21F1EDB56600C9A1F7BCB26C9BC3C9A35761A0256CE69F3B1FCCF20562AFDFA1D35F43EE4CD2AAC05D61593ACFDA4C34B36810C04A7D50C962B31173A8903564CD1B22ED54C8BF277E84ABB186F8095CB6FB1A04FE77EB6EEDDB49072C7A3F2F9FD0DB0822BF60DA36BAC10164BDC396411FE48B79DABA164159CA7EDC2C651BB0ED9CA80A8E011909B0D8CBFA6D0FD6D296DADC8C92E55D22E7AC84064C1AB3A7A71EB0EB6C0D88961013EF6DC381825C2EB6F0DE170AA88B7DE5BD646372EE58ACA04ECE33A3918529C14AF60F69E121D11D2D518D97585D511B87DD802295B987402F20D10CD6820E1BF27884214337E4E018E40DE1A2FE9E341D5B575D316352068833A53EE3F50526F9A798959C2A8ED93E58C8E98CEB611209BB9F6036D73A436E8DAB4694269A676EB7F25B94C31B019285675783604963A9F865CD072DD7897AC0C873D06503583E74D05973611743E181656C46E4AB53456521CF238B87343E418CF82A63C91C3ED3700F798A0FF2FB0B0511C18931994B0FA8BB6B0257C3717AB9A0151D9EA7E9764F430B4877F129357446A435DD6858A26532C3FB560EA69B004D23A355A2FA6056AB21DCC4FEB85690CC9E29414821F31D0A8241108213D8A3CCE631D2CA703AD8183A1624FCFD2FB6992C2EA9E0886227FB9F32B0411D6EE0B5075A0629B293BE5BA33DB2B174CCBD8E8ADE957774E3672158E693251E60A4AFC80C71B89DC75F2EDBD2A5ADD293045413CA135846CB54A79014510D873F593C8AE66B46D2574EC35DBA2B20D4A1AB8F1CCD6596B604ED8E8AEB88582E9DE55B202FD120E003AB81C145606EA25B95233AFF55E9CCA157FD5CBE7F39DD1C92D15F90157774C0CA670E9869C01B21397C68FAB214236DD1B3D31C202DF5D39D591A9CB1FDD50855675F16057E7CC30F002ABF46441F974B12B8021C8E15F5FFA21891A05C9954E1E9901BE5124235E9EE64AFA081254E3D981F1D9F1D8A2A29F9D9F74B67B54B3E2FCEED2D152F610B99379C4AC3A1D9CC9E09F24A6FED0B2A41905A5C59E74985A52DF309858D6AE54DBA08F4FDB4E2551B895EB20CE0F08A592ED1257ACE9FA40287EFB12611BE108E00926FB4917345356F761C72702FB620ECB1EAEE54789C52791C573C152E6540C438B5815A06248C0616EBDF83F75AD1B68C3B7B3B7B29892F9AE9EBEC40995E3DAF888F01E2FBFCC9FAFAD7394818B4BB11BDF1A1929F57FB990EEEE26F3F6C592BA973FE54B53FAC5CA224A30D168C18E7349165445782039B799941641EFF0648A7DAC2B485308530CF24CEABC8FBFC5E66E50D6722212584AD24EF3C5B29C4695DDF0FE884F9C90380847A94FDBD7CE0C119AADCC3AD78BBFFCBF5BA42DCC79D625F11AB93CAC21A48ACAB5FAA5C61BECAF103ACCD3A3719B5C00A7AC178E13237F26BC3B30D4D0C74DBE2055F30BFF75CE6E2570BD1E5006DE1A4ED651DE5B1FF68ED18FB14700FCF75F04C67E7DED6E7181CF7A77D8BFF918961A9FFD976E73C88EF5D759EB527972338C15D96E396B8BE5ACE335A31F1B29B0B6A8BBFBFEB1DF947D45FB3E0338CC39613A5B0F1FEB23431223BB089C424D3AADAAF24A6352D07DCAEFEEB579F48A679E166F9024CAD03EEE580C873A0BA26DD55C0F445E5A9539972F7FD44239C50582635A323E070DC3B223FA8052608E0CAC5155668D52CBB8BF05D9BDA8A31E1B677C268A750CD20724DE810102C2CFD9321F7237B2EDD2A1BB97BA498768D24CB9FC1FCE1787958DC727C2421A53CE8F08D408AE24E805D66DC420DBA7EC1BCA6457EB59C7755A8D0E05DF119A850894F365933D201CCA97FB13BB00FDD003205DB006FF3B8DBD18AD0AF082820AF6F6C05455927095956D4E16F4F153964314BADD3C2B4272267AC17279C0B5BA546BE47AF5611AD47B2AE7B78587BF7191C5F399F0608189EB1B90E8756EF7C15161FE0A9E1714C1DA04476FE9988405528AFCE2D7F182051A36B35C17DF00B47C183E70223B2B86D1FDFB3DA30B31B18D459E5DDCB13EE011BD59C837B77472398817F119F5D283A3A7B1D605D9A3A27B493A93AFB2166A57EE83D6CB74828052D4D3C05EEEDC64599F7E92CA80E986D2A3AA9DC9BD294B37E3FC2BDD15B4716BCC75135089FCC72EC5A6BC344E903A7C109A420120845C9D2CF3BC30C2FA5200319C3CE700372DA4BB0BF940171569D41E220C890A88F8984C1E74B98ECC6A2453D3CF2F61472483F146CB845D316EBCB29AB5AF0015AEBF43BCD222F35133922CB6BDCFCF28C2F6338DEA0A83A1D40A4730F1E1D9C8797489383B61BD48FDC3F2A982AE28450173393D6AF87D103100B854ABB6CA0D17A5F4F521DDE9B2E48FA47B4CCFDEDA5F58C73EE7D4A481FE57E19418DDBF5342F07797701E10F53905188DBFF83B228BA21D8DB1F88705CFAB40C8C77D8BACAD99111407F9AAC5D5AD3FEBE45B6EEB044614B615CFFA7B139B100FF25BC3F717AEEEDC9F347DF6BEA003023891E1F227BBA4DAFC016F1D37E97E8706AC8FEA1A18258205DC1D819608B432BF4E2BB5A921D3F92081DB8BE2A19B5C6517F6F33906DA5B002D463A28843954ECC3EE7592C56D3B61725EDFCC55B8FF5E5B4CD3675D6D673C1AA096E82928EC67D4D52DB8316D63831AB874F6CBC6AA14128235DEC520A74AA68CB0D7BD4D523BA8F6D3B556BD4E043874A8E08BC1CD561050D31892FAC685687C995FF9324DCF02F068C44808ED6A9D719EE42AFDC0F9D843DD3479853D54EAB25401F6F8F47E3F86390012B2A2ADF4DF34BA730BE99FDA2B2F7708EAB376B886966948DF444B952475674BB7F1A3EFF967BBB59E3B3A60C2FC2A94EF71E23CEECB2743CEE0B2548F0848E75262B114D32F29937C3AA96E93BFAD81FD264D2B36D7436F140864B04E738B80B42E50BF92E478D638D206839CCC603E72278F15535627FE94892A2E889828EB941EBE848D2006E2F1FF4CC03253D15544D9866297A4FBA618F6A83B136B2E5711F22C318ED5362CE4AB3CA97765F1CFA3C2310E3E19AD3B9D18A9562555E33C101A11F75034006BB180499E21119DBE827FFC78D284B0BBDF02E0C1D9E0ADAE63EA2DDD2F8EA05009265B283237428B0FDB2D0EDB7E00A22EFC7D753505F7DC49FF110D9714365D5437E32F69A16C1CD0130EFFF88A9AFE42D6044BF7C30F1ADBC867BB1BCEC3F71CE736D09931C22255FE766AC868A6C3CDE1EAEE37436D773C34BF92DB5D3731FA6B9B3AAC1D5A796D337CD90111BED6CB76D6A41569E34A0BA3E4BA7B8502991EB77A3051C69D11793042D35DCC576B4AC0CA9AFDFF8487481DC86B958E6BD785F659263F7E1E68AF1E328F747FBE9C0274499DA4D0068C88FA631400EEDA66A802C6A86A646BFA427D8A51D344838890DF0AD804D345644BA6E4278DE449E3C93D4A9D352C4A10EDAC0C68E22C168621EDBB5D729F04613AEA524E0C42AEF49DA70EB1167872055A58561F1C240749B58D7B24A113B460000AA2095DA2EC3C2222215B6922C640C334E19BD6AB4F0F56DA565021338B98DF998C96E0B92234B1126F557565C3F87BE4CACDD0FC7F2A5F45981A030CC488DC5AF276C21CDBB73A2106E53FA45D1D5151D1342442B84FB2CBE25189633483C96A0F1457940DC5A2E8035719FE75E83B162D759F98AD260C4A37B6A2F98376A593D680AB75041B1F04B896A80BEF0B9951A7FD3EB12126B33ED84ED1CB1C8CF3ABFF2E4C3A5F586A1300B763B6CDFB53E4EDCD0BDA7685D80D38824176DB62C5C7C35B1AC3B3E80332B888FBBB97BF49239EBA5B75999A4309B861B160D6ABBCFCCB35C6F530AA5027D135CD125DC5BD81A724DD126CAAEBC64F944AA5D03C81F9631211F5A3E76F09CD49DD8AE7B797BA5BC5F4C0E8DED9B2032E654C396A710300AC63769ABE64368665C015044B2DCBAF592B3F28BC394E51D60A78F97B6CCD9EDE85AE674B7CA0D57A9D4961302A341D1CF517D05B418EE1822E10A1F252222999FC8EF4237B5F8146ECF9116A71BD977E0C33A5DE047FAE5F13D1ED8C26A0A692A794BD23402D5936A8CAD013FD72DF61CD86AEC842CDC4C64C74B106BC8B9E63363B7CD5690021EC7F47CA488CB6F1608088231363A915E8E85522508D813F4B91081AEF01FECCE7CB1D1162A14DF47F279FA16F50C2965201496523BF6CC2B9C4D8A07CFB01DDB3787E1BF4555BD0C09BB2BC0D31F037E50381343181506C5F37FDF174F42C4F3020493C6E9C9047AF9C5B564EBDDBE53DF38042068A834DEB37BE3A3ED3E3BA22833033DA5111B639322038BA991D7108AF03BEB3994874C1C71AF9EE81A32B761292576240CC524979DCCC96C7CE6FD80167B0EACA647943D0A304BE6E93937C64A425A2E9C741477488C96178FD890FDC991DE653AFE9357642FF19E392AAAEEC680AC35D8EEFB065D280F7C642FB6BC057BF951CB7678E31873B57136B4A0651E6B1C51D482B8FBC3BB61EAB3D6522C15EE2BCF0E87CACC812D44407C2D289C40686BBE9625961E9CCA5791BAADEEC396660EE9CA1D677510C5E6365316EBE3DA06E8F941EE0D03577B68094C5F4BAA9B5D3ED41431373628A4B41E752985829C85594C94C1E24F0FF347C927217B3661F16F1C499A2F0B731C3B71D9D47E8E62267424CB56AF4AFD04332AC2AE841037D7485EECE94FEED3AC86AAC72F0D619E8B185B0AC7A8DC849B6570DF6FF11F3E3C0A32DFEB959D51BCCFAA60BB531A0B1F4DFDCBA0A961280F0D803D1FD43BE07BACFE335C77EC621DD41BF649E09BF6A6EFFA261D753C04DB09EDE86641268F4B2A5C4A43E5528697B58B39F4D183E2C8D92540C95F6D665FA73F7B43E032F5D76CB3D5DA40E8D161FF47D6ED4C152A415D5CC31AFEF17E4A4E27877D7ECB39D806837C72725BEE186F2530E5C6FF0DFFF4ECD54EE6A8778D569A74033FB20F8B384111E30BAC9B3AF53CA999A2BA978976FEF620016FAD570B05B2222458B6D7468D6071A0C8E518C3952DFF9ED6F079A7F7B29688E262EB8C8675A6129812556298AD52A8AD18B6567DAE38523BADC44CF0AF906C739DF44F4ABB7909C566466A8CD16940059D6C724DCF5A6C81FB79D62F58CE26E05810D368B0250CB11F6AB9986D53B4F9862813A0884D76AE37971D55C5F9D91847B31F3E15C021E4A722A337F2F602971062B5CE34C2DF6682575E2B73902531ADEAADB3BDC66055995D4AC41E6439C6417CE07D237B18E199D8D877EDBBBA1BDC9AF0793C2D392EA7D7ED1FD57CC5284E9DDBD9056E0D3E91BED1542AB4B754BCFB91F439916553A79A8808CC8FC1F4C13880694E3629AF004F1AE5BF18ED05A48EB122A47081BF42D892BE01116205CA9A729159CE84F60B07E318B583450BF1F21F3D67DCA0461CDEA71AACEB4E86E744A5526D455EDBBFC280D28A7358C60DF4317E1682643774153668D7DD1A384AA71A896902A45585031F4FFE98D1797E4E7323904035CF90FCEC65F6B8EAF4C21FBB846B3D3C63F49AECF458A9922351E5F4BB55E13B7089326CBA317CBDB595AD0BBC094F8E6344FD7957B374B22D4B0933FBCE3CFCFB2B894DB3B17C2E0D27B34E4B89706A30AC41F6D6BECA6229DCF27C88665C1A6C22A8768BBDB237917A624129A7F06EA49CF9244EC501414BC063157F43216E914AB806B977E9938386D5D798E2B3F1FC8A892283F50A5A58648405B4B7DABFBB5D4430DE689EEDED4BB65E20721D0DDA3D758165C1C5923B8CD5611456C8920F194B4B3DEFA9946CAFFD3CDDC04AB99E9641A2902851BD5EB88EDDC5B145ED40E1EC951338DDCB0C0ACA576553290A9059E1DED0C39C693BAAEB3BE610D26D49EA3BD411ADDE6F880A3D209D4EA188BBCA1976F65C57B015E8667F1F4CC7413007CDB46FC2B59C82FFB8F08C97A86B1ED1DEBC35E6F34F10970B2598B7E27AB823E974B6EFCBFAC2BF83D2792E6B929A42C82375C11F81E5BFE3990AAE1DA6068759395745ACA2F13E65CB51D353F8816794EC6402D4B2609094AFDA0CF9BA5662516814BA5848F83ED82A1B4CB05981B00B296E21EE8F6B9A51FDEE9352199DA41EFBD73483A0F32203BCE91F455EF75C3C9DF571A4BF4DA69273301D240B33F80FEA5AD8A891A378F9C6A45CA2A0CA23631A2B522F91E8C54EC90F84F2ADFFA8F45B8638448CD0CDFAD11E2BFA2FB6FBBDF41A40BD0626BFFC8134A518EE3EE337461FEC0B556C481203D961B98C8938D9F497515F2679AE62D5038717FC4B79B267B84362E6BD367DE0D44D55996BF78908AB04E0CBBF5703AE2B68F16B3281E236FF116A7FCF5085C9C4358DFC965ED5B067158769BC1F5591A4D497BAAA416E5F24A92AE0142C9CA5E144E6D4B28C7EE2BA1105D56BFF2F5C014EB6D63F79B9E30718B095683F830432D97CA729074B3A5EE1F900E2F63E2EEB4A774870B88CADC154A884BE33BC72471481218195B45E28B66D4B75203C9DF9D0F20CA02CF02DFA642B06C4B23BFE450BC07C6ED4F30251804ED74674ADA9190946495648D4F1280D034271EDFCCA4C9A09E0050CF049BDF14C6DD7A4EE700F583361461A1C4E1ECAD945CBAE64D1DA49E5A17177B24A6016780D24664C910E84E2C577A87DC2B514F314CE9158705A4E7835C28BEF7A1FA6FC16951B507FDE00A4924DC1FC8498F008AE3C1FAB8445C120CD802E4C992B15B8E2A2F1D78786FFFD9269398E50D4408A9CAE391872ACF0F46DB02DBA90250B148012348F24E54C513BB655C0F7FA3A41177770F0C29D38ED03D8A3A7DE317DD6B57223F2511CA9273D408EE7EF80D0F3E24F532FEC326487FB491375C7CDC085A500828E7063CB72727425C3478FA1A3E373B323C3EC976F4EA2C4F69CA662E2836E3EE7AF6401CE9F013D561ACEBACCA6365E671C528130A824E5BCFDACA89D3A83185B7A78FB783882E2A9AAA46336EE032C0C8012DC2D5BC4B00569F3B3602C7987744D9E83BB5840B10A8822DBDF4CBEE5150D865F3EFA6FAE887D98AF569B59104403E2A2887599FBEBB196172BEFAA491F0BE1A3EF4A3C4C2B415B375559FA92CBC1E49F60D03400C6288A68107BF6D9A971963BF025282D20E7F7875EEE6EB63851FF3EEB6A5CC7BA4170066185C6028BE09FEC5A9F3402260CC0B2E13032BAF04FEE128422ECB3D580D7F2FE623EF72D14B92FF43D48497736EAAFF8687EAD0B33A359A4C23E731B2E605D89C76FA9C2F620E34ABEB6A131FFC39D5E4DD249737CA81549CE4F80AFE30A337C45A3C9459D8D01B9D5712AB9F2D5212F69F806470C7B56D38EB8A89BCCD000142D9E570D91AF55216B9DBC568D36889C66ECA01F57E6AD6587D964898236DEBCF384AB0CCF3CBECD5924F523F96380D765C002E1C460DF89DF78D6C0F333105BFCABA633E6438585461C1EEC3612984F4DD7863A858FD74B54658F862901B53002773AEF55D5AE0DDDF3449F2A82568A88C3DA43CDA1D784C7266A5A1C547BDA85BB20BC0F2CD4B5B36A19AAFAF2ECFA09D348E5AE00FC7D0A4B4C2F45758BFF34673F1C781DB9206702A5FAA3964F7A99149FAE0755214CFCD113FA41CABD89A30825863A9C0C06436320B203B0E7F34306E1B33D9818A5810ABFAFD1287DD0841CA2C83003C35FF3D155B6546010592433AA60CCB96059E4BEB2711E52F691A66A3C14E366201D42A5E0955DBE3E8033E01FA995ACAC5DC82B5E3ED431A7DAC887AF37B49F741626544A39C43321335140CF9E581FE3A09BA7230D4C4CB27675D23614FB48F8626DBEF161AE867E2CD0AC38D32D3CCEEA06AC390689D8E32002A6926CCF4C8077BEE27C8D8DB016DA93C07481357BE50259C18981CC1A30CEBD7EA04123BAA99A5F231AF390D9C9FE03927A05608827B22D1CC63486E13688B9959178B7D844E6400E5547B3C3D63B25727904900C4B2EF3F4E1A84071389B7F08C419334D0A4DCA0CF0D5EB768D8839972B96BB9A5BA72EED61AFE3322A63EDE86A47C8E86E025EAB77F7A286E1CCBDA410CDCB77F0A5FAAF2893353904C5006E57EF031256228D8F5C834FADBF5EE3E027312816FC02B52D88106E52986C07BA5026F6453DD3E3B95D8E88DD3F3F12CB356BA83E86D90E61BD1593E76F91AD51D868651E11DC4FF9A552156D890C9F04B9BB9B0405C5DFA9C28794A7FB7D532D666620DEFD852483DC2D6F354791DDAF27E12152C44357EEF025851AD0A714E91ABCBCAAF07162484D2E83C996BC069A2908B0A6169B6441D0F9C1C06AABCB9BA07F49E98879AD8B16B4196266E73D791986A4264D2DEC4B67C844CA5ADF9B0252E6DE7DC3460504BC4AFAF0AF9EAC29B3ABFB0888B7611680991FB7B7C9DDDDE7CA028B5F199AC1212E79CF2B428C3BBFB155D3613D3989CDD3BE02D1953B4A0D701EECDA9959CFC682C849596F452199E7B874FE46D2E0F8168F273B4CCA758F5AEECA781ECE40C1AA9986E861C650C8C056B4A6070E93DE2FD0A18171FFC73EA08DDFC349E8F5B001E51C62B93C778DD5F5EEC5709BD09C4ADEDB1D3DA6CA12497AEE19271BE72F855828109852ED90F90E37EF7B703EB5B413AC60AF4571EAF5BB8BF77B7212AD928A01C05A3E8125F90864BE4FC40E8B84612108037D24BA50C091A2945A908FF13720FC136E207426E950E13CFF8EB1339C63F8710A2857DB2507024D220003441CD54EA4514F40F82DD7D8EC4033FBE6317916F6415C6BF87BA3B597FE9834477B6A1B2C12A29FF6C59187715BEA7384DED6DD57B9568C5F84145CFF887448756A7973AB760B4680998B6B7B9213CBBE07947BABFC281E8F85D1E8645EADC7C1D91CBA4093C9B356F4EB4F8CD12986A47EA249E9607FBA37A2B91288ACDC207EE52F7C9BF7DF780ED2BC276F8D8121E9A11AC57EF33FC3A289EE7599FF4E6D3789D4FD0DC53A292BFCCCEE6D89EB49703883855046F8C2332EFAFCDF6C0BEDD2A7286D5702C39C06E29A1E43F7CE5965075B2090C01043C911255233A8A245FA7B3AC270F5A3F6772FC43E0A460B9254E8E2DA0217E3998E1F1FCFF1C207C00F5B5B261902732341BEF6ADE643D76716143B2C14BB0079F80579D07EAE0134268DEC10260362B031E7CDD7C287375CB56303631FFC1B87639161ED78ECC0D2AD615D6FF06B853DB27238461B1982AE8F161FED2D88FE22D77FDAC89FE68A1FA6971103D3DF8BA960A456866AD89734DD769CC08166AAD26AD011B9853357B3465A5727DF4E95B045C0554961191F98BC88464B590D90D29221CCF4362227DFF6F3DB6AF2198BB8BC9A1C8345A8BFE18CF1C0E14F1E1DACCF5108428C41220392853B86DB647B6EB27520B843A7721B8509D90561E47FC3D000EB077CF7CD7425BFFB3D7C14B647C08D48E4D32DAC0694A823E1CD0E9B8D06EDEBE7B90DAD22C3B0C12609F7CFA581A94A63C155EF6E5D258C64AF5D627A42850855086473E3BAA901461575D848A531128CA1634ECC84AC24D495B93F63BD3F4F9240DD466E02E519B68F92D17A3F25F10F2811E54CF3BAE473D585EC6E601E3EC1CFCBA8467FA8D53D1D65F61A2FCD577EDB73CEC6DA6496DB49063A87A8ED8AAB7ACE90937E613B10247A8BC29186FF4CCB961AF9204D17E0C14E8003B720C018648895CC94920A1361226F208AAB6D3908500A1CDA6AA4C24528B794F35D2F316CA4E40A42436C343F3F8A0A950EE215148D2C2683C5D4F6EC2640E968C5D4D79CA3E94CE900AE50AD5A3B5AA9B18E6C41F1DBC04292AD4B24EAE07D37DC3C923F93C6435D71DB0B21904584233C3D9B08DB2ECA5CD546B8E7A6FCEAD7E43ED475AFD8752ADF7B4149CB39B2E99B0C97A9087052E79EDA18E3801A96009150A3D643F1DAACA8A6CC694C49E2B95467067A55B44B4BB22E23DF5BC1BC022AC06297A12769D9ADD1A703F7A8F85D9DBA9E763777D27F71EC08EE76D165288BEBFE90747D174D3ED9D597C42A7F2A7D19CB40E92226FB6260D83D8AF12E0E57BEBD7B188F91F4EC3131584C6FE1D28E211D600586541C5137951E0531383983F67ACC7A3096DB0BCC25191C5F1AD195E381C92C28FAA4D485567165A25493853A43276585ADC9E0ECF804C28F325895D09D46929640E0EDDE575F257CB857AAEC6BAD26116A6317BC7D93A7928F7D62C2FD8BAA7E9C7ADCBE0C80C8F0EA60203B503121749ACA1D2E8D587EC60E2C4E00183811C577AD9094D99F805DD12CA08EFE9B314A4D4CDD543AF84A21178467B1DEB83C457C1816414E88A56D3E63630A557DD2BFA3B75971A913FFBD81D921D250F4AF9A5E0D93579CEA61D8D04E9085AED26D05795C1F9C99C668C552F3BDF61574B4F161DA4D653D46137D4AFB2091B6DB47FF5C9C9718D809802C51AE6093AB405B58E93E186F307A12A38CEE5F858C66EB94C18EA01343A1F68BA27CD709914C92E20D9CD26E4BE070710E72D8DCE94ED365AC022B364BA9D8E14CA33DE570AD46FA11A8872CE6F3DB0A773617E76C5DCF3D03D5852F14E3A382D539338A341046165061BFCD923FB15A7C91998460872876D11F3D6DACCF11F16FEDEF368DEC08CA559A5891D1D1FADFEAA5A940FFA588857CF425AE0C8B92CBEBD858545DFF42CABFFFD121ED7BFD4325D90257EAD597D57875CDD0B92704A919F771C64DDD76A08C40B9A85DAB9726F5CCFD36EA8F1673BC578C766BF5224CE7AB3AA45B04307188BE924A8B0EA274545E4A57268782D79EA2BF0098B0ADF7DA2A289E779D9720A80600F4776A523E6387A273C7DDE44DD6999F5FB67D5355DB0DA881E5B8FC8A4909C4C17A89F634C0DDC297275423886905CF545469BE4ED79B0D50C210C5048AA83333823DDC826595901EDA72627014B6F3EB8FEABA33EA976A190EAB41E5C44F3BACB9D0369421AB73277FB97AFA39950335036C5D02344EB45A0F40E35BA1CBD429DF9D310C5131059564B740D4E2146C3985136252FC96CAA0FD9AD09EA148653694346262381D758A7689182262AEE26087ADB55CA7EFA2FE825BCC62A371BF7ECC9BF38D7AEA39E6521BAAFBEB6D4801DAB5D89A7D1BBDEFB894822648E92DBCF361F195DCA13A27F2C148EBED35772D3227C76FA43DA0151A432BCAF4E87BC85C2DC6963939A94D7FD0AEA7A5F169C0654B6F480C6BA2CB3DE5F2978D981849C3360039FFF2B21FFB0325C0E1C1E6D14A0587044E4A6C542A1D734AA8F915EBAB656FE7DEF31F7E880815BA218FA6D47C75BD4CA7730313996C5D61272EF17B08F6FC52C6247CF85575B9D58BB740CEE221EF084A81F17DB0626E543EB77A50DC7AF4C42DDDE9DEFE12CEE64ED12FEC87FAFB7347D24A7C9EAE20BD83844753FE0777C42EBD96C1C7A3AFADE832F3C6240D68BAE72CEBA33D6041809FD611096A2077EC2FCA16964CD45AAD6CEF04281922A793E9A336D7965A46156F2D9ED492753DB9E5EADAE99CDF869724EC060823E854F5B3D6D2A4AC827E9FFCC8D3855D3F7B3B8331FDCA0F6E5039F9D5E6931BEFD30528C47D17E46F87057E097231DFCDB410F02EC7275264A5A070DD436884DB7B6E070FBA748B28FEE081DEFAF70A8DAF1095A58DB1C6F442085A5AEF2AA077B0319EB703C76E21FFC0B0D222D7F20C8F377CAC2616459FCEA42BF82CA2E8015D5DC4ED045CD3B4B89DDD5E95770792D3F5F25B1A0FF312D6B356FFF64B28E03A8193DD4B186DBD3B1DB85C349E564A92D471BCB958805DB0D20C7420CC10E2140965FEE8D4EB790DBD4E88CEC4ECA016EA7F81E86B62DD5128F2604B645599C3ABCB5BB3EBDE8708DA2A6C137791832B39F80C36E7B7F69A5B385133FDABD37BD9BD9FF1D9685A0037EF904589B022EFB6F41D4E9FDB974033E13B83D2D0B2DCDBE994E5DD43F0B841BDFA45B02536C670FD52683A9B7D1EAF40ED1888C4438A6C2C5F2E3BE696D7DC281B5D9AD1D6EF49187E5E86CCB051F4CFB35DD01C4DD7F09604D3558F3D70AD1DDF2C75F1425F04A1AA79F643A1B8BCB1B8C47AEF3980F384C1EDD2EB8469D3A4526922A4971F0AC47775AD0FAC560DD7B5DBE83BF8294EB2726B13B8874FD745F9FC9BADA6FFE04FD834CA720B00AE44497F94A5A88DE79D4DC0DBC03E5C6A642A3F8FA56F75C0277976035562DED5C5E5D450C0CB63007083D1FDFC73C8CB763621680AD56DA5B4A3017124AD4D9692208476C7164408347E466A01A580B1AE14DD66E8D6C615F97ACC9644E58C6534EB690D4DCE6D4EE143D846029019CF7F3B2686A380E6B645A181E1E7BAE57F265E90FBD3156E28E75EE5182B8719C1347EA4C36753DA2504F169704B6A29771F5A8F325154CDCBD2081E797933EF904106117FAC3B3EFAB1880A2555220AA4CC6B99225FA305BF320850E276B12A02EC7F629D9E3F64540F219F5C6A1EA3B5D5A672A010B62F59125A54D64014EAEF7AE1C689C621449C64519CC35290EC8ED9B7B91878B4BD81B6A0524047BF3AD5B268D3FBA970ED8E5488486E1E843585D272A2E05908E6F97BE8CBF9B64CAD1CCEBB0D2EAAD52548CA50E2B1E6B9025D21E537F430A5D3DA2C4B25690688F30AE7D0AAB28907C347A49B905379EFABB529B9486ECA913624D24FE60D07082D3CF46E60CEA12199CDD2544D74AE86F03CEA32EB54AC9FFE5E23036A4583E44419857725DCBA4C032706C8D0E37486292DC1F7C4C3C1DAC7A096FC3EED554B33F5DB5200C2287F3D874CC9FF0043E72FD6E51C634F5D619D77C7B45BE27DD0745C2A56D0048B2C86E820149F81251FAE941D829AFF00CFB67AD64733B1C49956AB1BCE70DE7AD4E51827589DFA9BDC9BEB587A87CAB939EABC0487B348069005B25F6B4C5CE18CAF5BE34DA56DF9AFC04297DDA0511B0DA97001EE734606709112250816AB6870CD94F4851A189C0D50176A3FFA2FAC2D900A84CD429CEF8140D15E2C359B90D9B384C45442FA808D3608E45CE47B7BB4E7E0478CEF350C66977748635365BD7BB669D439E4FE442486A43F72DE1217232C303520E3035CA965FBD7C88EA09A47FD413AD658ACA88AB9115F8C74BC0A71C567D5DE0412D550210B1F98719F61209998604DB345712AEB240C050EF49A10C5EF51EBE4CA13FAD45A8D293E786F04C9D0666A40DCCFD2E5F38EAC18EA94A0ED5F5605436A4B1C37E76E4A94CBD1207A043504D97A40DE0356BAB40AF6F4C99A66A9149F38193A0B70815186CC9B8F6CB7789F53D1495EDA511B3B398E66A1867554886B75D58B5DCA211C4E49990ACD5646A685DD6945BAD215F28913F6B4E43A0F0CA0A6F52AF2C5E89CFEE7F967B00ECF8759EF02D321FCFD015CD28B636E45BB54882C82306A1FEEFBBFB73C38903C4AE5F338A3777059BAF8A944DD9459DA4272478700E9CE0A0511D0BB563970AAB5FFC705C6B9415CE81739F307FFC61AA65F087903FDDADF5D734E82BBE5580B91BC4BD71108BB9345A4D8B4B5957A72EE0A8D9551EE1398D4C088769A23B4D93969A8C875EA59A95BABE71397523215CB01A3D9F0B9A03B3E1D5E0D28FC39D21263FC74AC970308953D966060FC29F5F07AF65598532D5BBD7E2A0A170DD650F2DCA29EF849691B241F95D2D9C8F0DD760D16BA1DD032FEA6154EEA7A20105C2FB2ECD9790CC09982F99BDD61A0C1B78330152F608A1C5D38D45C002AC27F6AC292FD203D24137039C5D40AAA6F20425545E7CE0550EFD70E5D1A1DF71305454A822B25EC6BFCD398A748807F260E48BCCF2594CE08382F08A2C72B75AC5366BC3606F518FD10B65631EBB7F4AEBE68A5901BBB03C2E39F955AC5245F1AC713A4F9627301DBE0DA3BF087FA5B55D690145104A2EF0BC1ABD0AC63300064B9B480116CE599C73E32C5413FC45AAF4385BC8769C4DA5A5E80ECCFF0F1C55C7D258CB0CD0671564F36907C07A71023D44C1E8A7B2DA879820E5A0BB173BD196CEA5D958B7F104680A5D75BCF7B2E9EF18BA37A11A84821EB1D6C1FE77FB54983410DB7F80715A6A1D707B04B18204140A6D81B46981BDE75E41CEEBAE06F92CB172DCB7D20BB316BDDC07CEA970F47F5534A86A86D2F524833458E970CDD9A04B045EF23E80C682E803AD1C28192F159165AF901518AACD96F2FE6CD17CB6EEED0EDCC53E007CEA8E56AD84B1EF0E19F19822A8BBB927C457242419B58CEF1F468C753F256C473817A285271B859146C474DE732DFE54803509FCE225D3241AFA4DB820C3C47C54A66955DBECB1D1F7AD4048A69B3A1EC792E29C860492C60760D805E0E714ACE1EB3EF2590834D2F34C4E4ADCB987053C03DD378C400C6A62FD200DBE097E1CEDC2D2C90F8EE009B3DA55581735E791C2A1705D59302BBBE9B7EB9CBBC551A3FE03E1171D8CE7CB7EC0165E0F26273516BE94FE415DF4295B3F2A45A80DA879222C0BBC021199C3BE660C7DA6B11BF3FDBF1C18B3A82ECDE945066FAE2049FA8A5D168E27676B77A6CE4023EAEE7FFDE75D77104C27C2C4D9185ABE06226AD08E299A2CDAF4041149410AE05B4FD676C13125679D5AA5FE4CED384FDB722EADD313FF7B88B096590883D64231F99F074825E04B8A6FA3712F3AF2AEADCA5C79F24791685E90A6835BEA7DDDF80AD85550983C2754BF8701BB16A3F13C1AFB8302C372D82BF75FD10D8C43CA014F0AEB04FE4CE48EAE674243554D88F65042DB36964409E5CAEE4DE3EBC3E399B7B174BC059F0D6595F9B9FD5072B903DCF681E5643251CAF11F3A7318FDEB24A8EB86D1196777F5F4DD77FB8413CDF24E0427F8A297B4EA02BEB65EEA00744D83D1A5BD411211949A68E9DC821979A1F9D019120BA1F650002DF6C9FBE1B225D5571FCFC52427A18884EC1701521D10246F8A29199FDAADA2AD9E938B9B63B7346662912481C2452F9A04EDBCD4B2A04AD24B413F6F79C1EA4EFB49E22D514C03711D7696955AEF954496603B6BEA7EB35A7D29C24550A5A19D722CC710859DE6A47D1E5DA1737B37C6CF83A7ADBA3957F4790ADE8733FC6717E6B3BF648BD7FDA7D352FBAECE0DA37BC7B237DED4C9AE14F7DA85F57262A357BA787BC14038A054EA6C76566A4056E1B81502DD68DE76DA8A518A56BA67E0560C633B411558FDA58CA06A8E29122FD0C12F225B2963B8AE9E8E584129C12BCA7CF6E68DE943BE013B686253E2FFAC65C069ECAF93D09D522D183A98BD872B0F1746203F7FB4D87BD21CF2B9C46BC36578813101281E8686F0224EF8B9655E39C1D2251ED9F0227B68C5990A867946D3E5907CC1D56303DAF347BDF06A8282D270EB92BAFD961D27E8D74C5A3D79472CFAAA42C6E0F2A6DEFF0AF7F7196A961E106E17C47B20B5B8F88627A94E3146A8A318070B8C89149344AD63C15374AD4643C566F2DB1BC6E1DEE46D4F6EE355B17248E5B74611192F6C58C2F006D80A2FB93B8887393A4C55B218E20E9F8119A2F5BEA17ED465B556FA72B8B2FF809EB5C7C23917B8D0886D05764E3601BEC8381B4882913D25D6AED74353AA6EB0B8E68B34620361FC2B09DC4483B8015274CDF38D95DA90528C92E0001ACE853976900C61439CBF45F80C380B9DE7DC370321309C88FA2231B6770D7953B29F6199F71D7A9A02D841EEA082DC1BB289F7E02ADF4AA05394CBAC19F82616D4C365CE3C04307131EF2046A8E7B75D4D926BC09FA78D8DEFC4D347AB617B07A275D215EF98581D36C295232650048DA4D6C395EFB078E3B845CA75D8AE9AD4DC93DA4D375E313347C16C5EFEE845B06837EA0C9A85CBAF791D3EDE54D58FFD2DB81614809C43AA743D7665A0C0ABA2BA0D52C0DB7DA4F0B0844F7B4FA702B6E482D510A1456D5C52241365755FE67916AD04B719F646A78F70C1FAE05B10E875E7724108BAA87A78A02579D849BDD08CE2E48C1503D932C22D3AA45D3429321C60A6EE3820B34BD18D558D9F514C9BB70534D50AA88D7CE8FC6478D133461D11DCC3FC8C00168C9BEFF6EE15C651B498605ACA60E4B1C14F591B9633C079780E97318152B3C4D9AC3B11CBFD2C880641350CB39D9B8FF34ACE71924AEA70004577CF43038D65AD84A50E37CAE40D5B0E20FD6CC287A32C5E9BF12E0F0EE6A2495350011841997B4BE0FC021B9452554DE8AB588F4B3678D1A52B18D7F0702E8CC8C71D306090060410E6757F2633160434DC7D99CCE825814AB7BA626E13D494AA686AA975AA56C9E00373C4FEC2A0D3DCB7F203C9BD785B068792FB83B244374AFC67B5069A4279D167B89E556409DA3C9D1EF390BB49B519A973473784A0EDC0CE420BAC0CAFF7BBD1F9AD56909B8B822DE8DC2EA0109BB528C7E77954F49D1653EB7FDE374E29964B70142AA41D209EC5029CB81331073DFF4C4CCE1C8A7F8C6C128B6B483174A2254593893B4189B83C3E6C644A49AB3F2ADB02891464DB41A82A148E0548DFDA6C5F2A1757C8D08FEA8F3A83074B7524AF01BEC00B59007CAAD2F37B61090C31CBA56873FD3306C574AF843A716C8D9170E998EA6183D6C5D5708CEBFCED759BAD044BA8CBA98413492CA3033CF807346C2731F38922B14B2B5AE5A43D882E0BB86B6ABE3F9722DF2EE99A3E5FC364E4CDD9710F77F84F0DAAAD6BEF5D9E2745AEBA1B755087A75820187248FE2AF18A121250EF0A5CF683B9795C62E8CD0685B784985090F558491472A332640B5945B8D2A35798709E66370221C4605DAB483C1C0E0F1F44183D2585CF3E300F9BCD9644AD5D80BF93386C534DAA72FC102708BFBED892FFC9EE7177635848107EF206EFBE5ECF21A5859C26CF87C3889957936B8B2EE7E3C20076F332CF322141F2376E57D9AA1F6446D8ABF0A1A6608B5788F0ABECBF0883C5A2869C7AE8F2223496A2E592B6E746FF8633E9586F4F4D8202BF75213D12127C3D2CAB560FE86B4FF6F0717A65340C0B17B400FB2B4062FFBE6F5E02834F52A3F5B18D53C6D47993C35BF79F28C680A453552021003C26C2FBFFDDBEDD1BE79ECC3E347EE81EE20D1A2655B1412444398BE252BE412A7444834F78AE257989BF703B7AA0E48E6CCD560CAC28E55B7CBF6D1F2653CA06F55FC2538A27CBE5C84F0BF0873F889C0749BBFE2F2C1EACF06F979A809C0630B573EB52FF3CB5D4281DE7C7CA1AFBF8F1D9949269A50357B653056FBB55BD4B25C1E79CF444ED54992FD31BD00D92AEF124EC8D9B22D81D773C399ED603FADBCC0606EDE33B1E7D5D88073AD287D548A9123E6F8A3505CDEADDFB62537372199770070D4B79436126431052E5E476AA105F659803DB0A46EDCCC235AFB04E0C13B06A3345DF7741344C95B2E10B8F37402A05F8AEE0A539E004E40B7E139077338F7623147EE48EC1246832B7A9A819C89E653B7640BA8D285E83270E0143C31C4AA20040186283C7A60F2879C3793AB00CFE2A14AB775D4B5A448A7AD10D84ED1073F91820865927602E4AC19A20045C13A77DE65E68B1AC60A2C64851C02C0BAF2613956217913116AAE82806592FEC9A51D2A13C29D82328D681A7712F03796D40C233E6886FFB78CA1FF5767E8C6723DD9708EE8DFE826D8B3FA653AD6E8A2CE90540640B635219810998CA69C49CCA87CE7A0735254E156CF70CAD93B7DC42DEC3D767D8DBC0F07DCD986C557557D6BCE83CFD1CC75C6CBAF3102D0A388A7D87FE235F69FE779983E88ADA1C83EB01B0BB4CD4958BE51CCE02344964EA71F1C7AA6069232B2569C8C3F9A8FA8430773F320238880A5BFA4BADF9AE2D7B39067138B9A46FEC967506B6D65C1169EBE02179C536C25C97604F3D9C5C415D0B2F46B13599FD40CB6E3C450D4812FCF5B236018A93932FB0B8FC049452FE08A71A4C2BBC4D7FC5A865C807740B436A5A9DAF51B01BDC2635341A46B4501EEAD677316A7530B2AAFE110986BA00BA8BC6835264F52691745377F09B5CA8446D8BC6EE249D10AE3720B242AC7B7E0329958CDA9BD5C19EF194DD3824F011069C5BEC438C7970B6E1316A0BED118AC3331E58D774E592F07C8E810FD27E2136AC8640BD8BF6EE2DF3ED6E349D5EDB0BBE06ED539D60B41659BE3D4859509481598D2566047D4F6FDB00CD5747B018443F24C137DD1A1F59B3070BF9A8F5A86D810077135139D666F3FA4ADABD77CE33D7CEEED1D931D1221D347B185E5ABDD2C186E9B8830C66F1D8C93620B9A4CCAF65E43D53D5CF33ADB286587A40986367314B0C917484273892F1AD0266A8AC8C62AF95C74A23A56B096D702D047301806F786F94EE91E9DE61DA307FB37DADF118A3C23122D81F036F6490340A030DE594A311BACA72DD9F2DA66DBDC5FCE714408992C6756FC7E1ABA22BB44F4DCC6AA8871C13AC0CF43FE8C07B38F4E62F49B2E9D56DACFF33D62F9502A1440D9ECD3871DD15199A752FC9F4F0EB94DFE70E08129C96368D60C2A209ACC8B74DB69D4FF64B4241290AF125F97439E8526086764484E8CB632CE301383790D6870E09FDBE295D7E73A3A4A45E3429CFCBF171EEEDAE3FE9E87BFD02F9D2056F96BD88FF529454B360240B427C59DEF274902E4202BD146109F9076EF86C23A203DD027D65F6A7C045033554336CF06AE39EFD81629A56923B3A63690C4B7198980FB9946A856A97E02EC92AC7A522B80788DB19D224B3E2DBD5D62848597072B455F4BD3D5DA683BB05FCA499592275EDACEF5B1E91CD14852D320F2989E1817B656D7E3C0E8B189252E6C0C754D6C0F861BF475368EEF57EDE1C79A50C6DEF5159680A73E01D3159AE704B25C809AF3582CF1B200340E53644CED1A6166B2229ED0CBAC187CF28107CE95855B5A37D1D39061770147A40BC47ADF8F6AF2F44689E39DD118FD1EBAB7929E310B0EE26CD57A96ABD069CF21171DCBBD1070446C794A36860E5FAD89316A9E87781368BFD99FD0DD15DFD0A37906923B4B5633E43A6377F737F57E0A6C1BA0852295AC9277847FFAFDAF30081A923B502052C49BAC689205D2695844D20B29D411FFD1CB0B5B3C481F509C027093979A92602758D48E896E2B8067D14CDA78E9933F24DADDB3A73ABCFD35DB4A6727F150A344DED37E9EE7E37F332D938430344CB3D315C560C15B9733D74D056EC7324611CE79589F86A0B7A3176223AFF22F25A2C8DAF21CED201AB58AC70154588A14C671363E37A3D4C13D9FAB37CFBD54974D392089A14A7E63341FE4DA0D05C1C08D12917B85F1CD59EA2E41E5813DCF038232B427B686BB22C1438B9DCE39A1C95B3232710E1C40A1F6C5BE709B5AC42540389821C9721059C9BBF6182B7181064F5BBE8A9D8303EBF32E853ABF10FEF273505DBFE5E5DA56514E090D7BADFB225A69E0D9B05EF62799121CC347C534C0558416B2B70E658DA2B1D2C948AED4CFABD5478A84801FC844303539AAF472F75EF3474C537704A076A30EBA7E3AFD1888468CEA9B4284AE7C377DDA780197319C6351EB07E7A1F1010029ED500423778CBEAB5FA1140D958FA9365909303D1D077C792A6C0F466F24633A400F490C1B915156EDBAC029A9097DE02D76B39E0F5AB8FCCDAB828BADD7FA0A13253D72DDA7D7B2ABD6BD80F0D8C47A853659485BF6F83823A266947FCDFA205A9B5D50EF924B567D9EAE95DCE7F39F8FA06B424821988A31B2A2E2E356284126B0FC4D876808B4ACB6313A5EECA3E798C711E59D5A2EBC5E066B1459283344671F56DE0FB23CBA190173EA0FE98E7581B9AC4D1E9CD729889EAB2411A1BED53A6A2A2C0D616EEBFD3079939C88899925358F399C89F2E7FBF1EAB0AFD799B194402E5D8D7E457EABF338C038A0DC579B452F24A9ED3EA145F0C83700A418903951B3B656D96F40631694DB18C17E96292D4D1D513B6D216742DEA974B3E0C0EEE16A4C4E337C2E0A052BDCD43F7032BFD072816E48AEFE8EAAD7E5A6110F0861E862D66A516A6E1B75522EEA4D130D80073436F1399EE96F58E96EE4A3605402B436A1572EC368F9A33FB07C9EA5505010F0F86152A6FC7D551AED4224BC1F552BF9B5CD76F1D32DA97FE3CFF109C012BF6C3B1D8225A87B6CD361F859FB5FF25ABBB7FAD4E87336F3DAB6850D67F37C1D135D9E0A0BCEC3E5CF53EA05DAAEFAEBAEC3C50CFD96D86D98298D58C595C02CB5569D53636D583F149C7D4A419A55BF0BA075C9938161C092C427BAD8A67272053D7257CDDE6898986F30DFEDB874E225AF6E146F52E5D05068AA6198AC664B1A2A266A0078724C14E18BCB2073455281BCBD8C4BF67F97486C914BA98F5C9061F0C0ACCAFEDD7D06E05A93BE8AF14B9250C7CBF161E404B9AA5B76FD809A7105A1107AA51317CADF38481CE89C1C06561C07D446CE91B2E64754A690EF55A6E9D89E1B1C053062142B37E869971EB54ADCE609D4C0E50756C926462984E68789C2136173E2619CA9D2BD8E5392916E630EEAB691759AF0A6B9F518CBE65B589F8BBEA8300DADC854FC7D3F4870C97ED1C4F6491276A712536B04A590587C5312FADD2A9BA21BEC8B38859B3E64449AB8CA82C6896870B7EF4D313DB6C4556E670580013C7D97F36C3AEA036E63F62B69E031249A0E855ECA8E8A64161BE595BAAC443EA76114BE7C0EF8B9BD6907BF6D245C0E35297F273CCCD5A8C6A31DC280086486F607467764EE95F92747775BD9D6CA898A4A80522714128FFBB0091C43E473AAC070BF81B46FC699D9B2EF554F344938071F57CF2A69461C1E1942CBBFDCC97B1189BB0B1F6D9AEAACD708E62BC5BD176B83A0F9679F9004B0E276FE1B094B95A1836A1A9A1893492AC19D5436CCD0E1C4F24212EAFB636DE9E77E4DA6975AA367DED6D7EE8BDA1917873DE36372B1FAD160BF800F4B63FEC1DF1A1975D04716273B65B7C6134A58442D17734A9A12566DE64691F99F3EB1352DE0B1DD5843F0A420FF9B799653294FF3078E92BEB5ACB11E2CDD511D134BA19A667A9B70AF35740BFEAD86AB4420065910AB3D8D6AAF7628DC6EAB941316DC799DB202DC6731779F455ED2D8D7C6FA298E89813C7B472D9F63EB7A3ABF1A7BFAD2ADBDF1169231296609DD7CEABD058FE85D5EC8B2D311B99CB771A55DABCD142451E9D497D43EC28A44EEE14F91CB2CF24006941A1C2F2433C94FF54197F3017D808349541BCF81F74E6B8544D400C01CE276C5C8AFD3AD6822C5FE95AC8B9E273631294E12B67F551A1117EC1536C1F09E6D102772BB9AE6867CDFC4F14DBE4E2E360F8C78A3C6C755F7771EFC28FB1CBF79C13AFEEBD94EFBEF1A07B60A1C884CE6DBBF561DFEB3B5FC56F94196C951CC143BD6596C33EC2A3997F1CA5F3379FB3DCB4BFDE24C18480303FC2E6ED9D2AFD420F4AEDCD6B8CD37E12BA862C61FA3E947CC1545BE53D62260B02359BCF9396041BE47D96D3F79F599EF3049C6A6CA1A3C5D7E2284E730E2769C5852E750EC0296AD73444D2E212E359C405759ABAA722F36871E9BFEDB2C7D18B11306DC5719062077360E018075E2190CE7CC6144FAAA1366478E0587DCA01C9F23AEEDFD3D9CEE64943C9DBFF6DE744DBA2AA89AB0E60313DB15BA84AF9233599074FE87907EFD120D8D7178C62315D41F5EDB7787BB05D0E73F3F69E2BEB02C29854A69A67FEBB3A85F81CC71F61C7350705BBD71DAA77ED4B05FFED57392C48612EF66956729AFDE2CF113EFAC0BB61E1D542343BEB68993E339F483301138771A96849E81687E8A5709912283F9B57475667F62966196FA3FCF2629B5D1A0ECB439C1440977A4502B353531E0E1B3C44EC9C25607B1C66F41820BE5CB3D10061FADEA1760BE7AFBD73674D460892684AC816B0925FC1527C81FF7A9B9769362E82B8405003392A700083D5D7365C865C1BB727F7C0C0B619928D547C7FC30E35A6B3D5229B4ACAFC92485FA0327591E43B906948FD4E7D34A042561275E56DC330C8EE732F39BAD43BBC49B4D4D6DDF99C48154D5054CE7F6D40A20A91EF959ED7164FE8B0AA823B056F27DC702394A686B88117EB01F827FF5B314C553E70F48A73213FCBACB6864FD4E7AD8206A679029361571101E3AE85F5B89AE100001EF474C8146BF5A50436F07E4B9D7FC51CD85A3210E0E9154F4CE270060E0DFF9EC8F50DF140A9F0899D98D42A88D651054327616124B679FD82C4BB14E624BF7F56148906C74ECDD683953DE3E751BE4AFA94068900A585F91695E60B3DBA0D5E5B2F6CCF64585E75FB2F4F59FD38EA07C4C21B42EA0E5D978FA4F1C9FF36790C88522211AE5A6B068593589AC7DBA15F39A45D4D49E6D181CFBCAF93C72B2323DB79BDE727267134E9BA08EE0A9AA740FD17C30876F94CCF94F1C83187CCE21E8D455A0E67746C52B8B8B79C4D850BFE84EAE569D6EDB3FDFFE36F58F9BF385B487939E23A300101795BAFA4B222A18C3CEE73D5E30889ED2E0EC10C2AE4723DE9E3264BCE7783D8B00F519AAC8E179403B2C2590DEB066A51409D4AB34F168A259F8BA7C9144DC6C60B8CE86FFED547F3BF1592FE4171B185EEA92138296ADF54609969FAADC975B08A71E97BFD44A77D45F4F0FAE20A92DFC6E5999B5BE860C7EC4D8A1C28343CDF465FE224DB8D7F3A87DDECA49F880A3691C9331DF274F713C0399560DE27B782C00A06806DD331E3FC7FD6BB25A1213F11CE7BB5B9487E3C49DEE07F9FD3A9FF129D64677A311078C8F8A07500F24A63A40B816D11B6DBA938C7AA719D1246D0398ED0B2CA5A6175C965F35C9E388E875B7C29A71773990AC9AE55F2233EDCE3D14CB3ED1E87ED87BBECBA04A441ACF48C82C8522BDBB7555DDC53FC38EECBC3A7856E429973AA6D739DFC1DDB1A796934FBE5E654AEB478E0671E8BAD8AE454502676337667AE48BC38F209380415CDA8967C3666E21A11C32E644A80BE0D854F2D7184AF773CEAAE30AD664161697918E630D45C733FF1C7F6D3476865D87302D2E710C3E59BB2D8F81AE3FA91AB9B46C6612921AD55AD5EAB826A739CB315EE7C8A87F26146B99E9A29974A8645F4D0098F54B8C323206572A929228CBF8B89267EE90AFE2F5E3E152864AAD6DA201A79EFAA90252F646A98F3277B36D3943DFE5C4722D140928589030017EDE6454CF0337F53A48B43158E9CD83528FC07BF4323B6BCCCF6CCB30551B970447EFCB8C1FB3FB156AEEAAC2C993E0FD250046E19DB249726BBE7009A77D3B9CA08823F5A848A336B7F8B64EDEE7A621D8D4F1928A24CAD5A21AFB28C42A9DDBA8657DD7C7496541F38B982F7F1D34279AAF400139DE13D3D38D4675AF368778391AD3D7659A053BA9DE5D3FC3CAC746A847345FB4F278E6EDDCF8C762DC7086723F0BB026856FE9EA14E09BD907B0D3860B5B4798B8662274968D614F27CD58971C98626E6B4012489E151F580728AC92A548F361E6447DC8171DF8B40B57307957A768F8D1515D7F069150DE4AC676ACA524B02DFCD63C5B26AA1222E12C920F53739D7581403983BD0C11E6671D2FE160DBE33441544C4573EAC23906961A78B291377EE0A8E10AE2ED4C6342B16662E3E92F814CF8B2F79EEFFF75E356685DA2B08153A315E13683E2D299955A8813ECA9C06221329CC3976AEB43454C51349652BC9B3370E93DA7F7873DC1BD2FF88C86297E9058C0D827914BE38A9AAB845FF2CA3F626F280E3289AF470039BC237AE85318984934E28A94DF84AEF3F2814AA1BDACCEB05D28287E26B5C95E6CEBB914F7ADF6B555525316E672F593E02659468A271282224AAC3A50B2567FFD8482E7B8F764DA0996853216B26DB012A8D997C03C8EE86E776B31E1C5E94546C77A378B6C20FD3B78E77BDF57F798C8D5ED404B11C3E24CB2349E33B7608D79B7318F9B2970A7288D226F3AD4E4DC1E936601983EDA59CCF04FD5F4E64EA94D4EB852677F07947BEA2091D5B503D235277D9DECF8B366ABE332B89437039B0D400E2C9DDD40140AE51D6F5700EBB33257C12320FC1094F56DC55BCDED84074DE67B48CB5BCAC46EFFB5BEAD5C9C058007EAA99B2CA20873B40BE629579B510723BD910112D1A54CC0DB9D55921D5E9F942F268542173411C7A8BDE9C3301AF3CB081682F5299A72BAF026303D82538D37FED762020CA6FE49DD2AA9C755ABA96F65878A550F7CF3E410F4667DBF39C51A255A695E33F60A3B20C5C9F7866099444965911DE47253FADE380ED4BA58B38C66DFBFC68E5ECE2372BBF65D9848A140822BECB049B2E3AAF7F6C525CAE6ED26BF9F219507B0B1FD9F6589D750B85C62DFEB638039E8E8778B5DE1A6BA01AFAC38728930693927441B737207AB57D68BFA8D496064AF006515A219C382A29A5C6F38FDE04BCDB511055CF74A08AB242BCE10B82EFC01D6051898BBD9EEDF26FEE977907E72864550EC1D48130B6712CF2D12DA1AE068599F28BAF749EDED0F993D070F1A227A33420DDCF1EE99356DFBBFEBF7C2605F15EF42FCA0A5479BC3CB6A85B5A4F68A40D80EB0D8FBFCE8F58D081EE01B6A6CAABB89E8F961FA7A38CF20068E240C349CED451E7DBECF9247C77211FBEA9E5CA1ED19930BBF535A28F38980D9362EC839F2BD29BD370EA3FA42D1340AFCC9B8624A618AEBE8BBFA65B5C77F48C67361B8990F85983C147ECC4B9CECE364CBD1584A8B1FA7CBDF740409E1106E526DB2C86D0F49C76534FBCDB936F4B5B7F884BDB44CC4BC841D6177910FEBC2B96FDE572D0A7BE92705A7EE0A270D405D4AB3ABABD3839A876A2155616351C7F0DCD9DF2381300F1DE1DFCCD01A566304FEB685C82D77C16F53311B727518946105B73F1889C22554E90E8AF1AA4DC367E793CE3C1849D00F06B533434B34FDA6D9034BE2FA13820C25ECC9416CF2F7423893AA49F9FEA5E6CB597050923BB6A8A650DDB32A07E866F702A14554DA8669F74317A59A88232B96C1286A8821907628ACB21B6B7CAF0B73E3C8036F4379F8D57BC47FC75D01713659D7D502B1A43B67C31AA9A69CBECB0F00CB9A7FD43392D41C331D2162290A9A1F8166A5CADE9F4DED3D82F9152EF8D65C3E5180FD52DB03E1B93EF949AA7883BD3A1BD3C83A8D63F0423AB3915BF00BB71F6FE1FBA50FB8A52B973B22AF028DBB943DBEF50CFED0D3D0C8E4505AD5BE3F11DAF9920DFB1B6C4AE04EA5BBA1ACB405383E66848D8C040FFDD029E5C2EC14E3CA261FC658A4CE6C9EDF1FC5B987978BF8F8839C23C68BC50565ACD25A829D33490813995B3E9F657E144E528FC282A96F15D339A9A29D1CB29459245C1ECD7AEF7FC33522984281DAB02E438F552A29228E0E433F079CCA7CF7760332861C4A48EEF09636E8CDF93A83D3C504B73B529558D53DED7A0ECF09AD1073CD897EA9237F520ACC94988497B93E4C244EC7A2F72F5E961A2D2938CFAD100E0954858515081222EE8863AA7B91C5CD170B0B663F959B58F88B2C5962456C5857D13216C573248E5BF5F26AB55008FD51AE273885215770791AE7A8C4E5CCFD9BF9D9E6D2882EADA558E04B4109B0D6956001F8EAFB6D4BEE61D02CB79BFB0A14EC21ED4B16C6B13F80657940949A1318207F7F96C5D1FE32500386E317EF1E50565F83E7382ECCD44BA2E66563C9C41AB4A745B2F21319B7408C4D95D1DFA0878921695682897FED033B230A5001221110203DA970F3B86406A4D3CEF3883D4D81921DBCC9ABF022090D46A4FC5B0CC6CEABC67BA584BE0839FA47169C4D86264B7F065FECD9FFEAF6EC6031F9AFC700FD96EC108F56EC9260C779113ED422888C7CD11DDFB2DF0144765DF5A0F6F53C4FC7069CE1987960E41D494E7B743F60D8E141F02736168492D7EC8054D3781B0B9520D6101679AE0C0E60BB04A9919327746FB933E4EF0C5ED493ED165945164DD37BCC41DC4B77073F3700F41D4886202C6B216473E5DA83DCA01A08D55E05D27D4720E7CD51EBA695E5821E274471EA52B0373B7C9FF65052869C92DB91E8177863A1C5970622B8C4A87A05EF12AD799CAACBB6ACF8C9847341A4F825B9F5A265B9955581C626063F68EA6288D7537B4CC5E706A62931125849E4B1F3FCBE22FE1EADD83DB0109C3B47EBE66D1B2F392D1B7252BB46177EEEDB6F64E9DC340DD6E125C15D699F3A81D0E79B02A864985616C1A06131B10D88E0324F67E5FBDA05A1C8F7A022C1677FDBD1FD74203E66B5B0E0503018CD9E0A7EA494355E14C7F99A3602471652ADC9D7245A101F6029159248453893AD86B3DCED04A2477B62B3AC17EE88D7214242D7514C56E99E8211A3CE739C99FF7B19435F49F8898E4C4FF52D9EC9FD6EAF5744C5D88987E767E5C92A4B0A3462117DD984B047E989798AADE3D8446E4BDA960EE61E252C5249EF8FBC9446120C1DF8531C9CA9B29605C31B85B657ECE87BAA323375888BF1F889BB264FC18DA5D02E81AD245C768057E4BD861F0C86D8475A717CD3D5C0EFBDB96F9AEA5C9C83CD83D1DF352FF012A612C57AC1C88ABDD80A7364E3EC37ADB25105EC9FE18F7CBDB994B03032FD53B6A72D3E3F79ACF92977952C4CD94733FC63F82C73D6DA973D49C48486A63BD502442D79927DEC7F8EFFDD824E38B86A14F91FF0B80B755AC943978588E77AD3830658F69BF869C4E3CBEC8698598C9AEC5FFD5C904C4E5EA7DBB3D5E65D82234CC8F6A740EA210FC06DD0799BB727B0A3824A02C0D8ACC06A8827FD61576EA893B3F190245DA14105DC110F46FF4979410516A45EA56221F656DEABA472330DBDF24F5D0B9D946878164600F1F4A53B2847AD3B31BBA5D6E9B3D48CDA294B3FB652EBC10AF5F7A10EE503CF0983DAB946AB1A8B3447DFD74240F85FA0D425275D3665D4FDBAE75661EDA17F3613BCFDB740D6818CF687D6154D98A5D4EE9F50E211BB06C5FC30479EF3815CE2CDF24AA8971663D4D3246E1AD61EDAC6448AA31F3020E14048A60FB60DD5BB775C1B975D2664591F5F44382B207F1DF3E05BBC2C3E6A7DF88796B0900914B52EB7F26DA9C4A6F82C72FDF782F1C89446A71780D1EC12B9D30C338779079288EA49EC4D6C5AA4D8950721845AB50F1CF1AEB7641D7E9CD110B6701B7E15BF434D8862B87E22C27E2FA6A27A6A3C7756E145F0C3601B234564E134AFC38381EF4A2AF656306923C2B913675A8535909228BB6FD14BA04CBA738475D4363A2222C40B51E43DFD55DDC79EC7E9004484513C960F3914347E25273756C556A745F7AB00B5C469F982EB308590B49662C85E8A63206186D623F359C700665DD4EFBC07B25A22C730C4E85CE391DFA3EB48200DF83D0875228939D600096A8033BDF0B8F2149D33B7B1C792A3DF0DC09508F2BDAAC239DD12BDAEA2980EF50F481487C160EA59495B25AA52D7DB3E4BF445BAB2B05FE32CB42A3B1EEC136FC79C14E629D2633EF46384CCB47D1246221C1AEFD6BE891F6AED92D2693E7FBDCE2AD694871B696B22E1C576214EA5582E5B0AC2468A376923583A90BDCF11276F8250D44200C1819777CC8EF7017913D60F094332FF42996D169B00C1C5A08F0ACE502FFCE6907024304D4C26A5134CE8EF3055A1CF3340EB3FEA5C03FA71DFD572315660D961C69E5FBAAAAA90EBF2D65B4938F90E6DA2B9A14A33573E690AE800A5F2493A9629C4766E2D767390D04FDF345607A5C4FDA9A1F634954CAA81FB9DAA81B36F9CF6B88D5C285C1E04C3857BFC68D2F98FE62AF1241BC718FB6978D82BE26655066E71B6D5EC8FFDD48C9B6A5CB796CBAB49AAB21A0EEED0D9304EE60724032CAD909D07B0C12CBEFD6EB19AA813467F75FC04184C1AB874B050A22799CB3742486C7F1E64540AF2A87E1C2D45B781383006F6D3D1F6C9286455371BF6E28BF425B450BA2A7493D3F692AB917BEEB1BD2EBC9DB077F4D7DBF9DAF9BE7E28DDEA53D80BD5F58800654FBCBFC4D33328FEC4F9B2E46355C9BCB0C6D267356DFFA9C843F6C4E55DD26AB0BA720525894FBD74D1FB4409651C93687580C3ACE12FF2C1221762BBDB90CE13F5E0035492FF89926232E984E6CD33BA3E104B55A56F826EF32DD5BE8468E45A0A7BF4E5BC0A8A9562E0D48F922CA42416FD1AB446D292DF46259FD5FCFB02876E9D8EC30BA4177BA6B7374E2E0801F0FD60CE84B4FDF84A6C1640536030B168E5054FE3B87C1E419C1A250BB888AFF7E915C7529DF034F2A27F6B0572D616BA65446AF06BF08C6222395A351023DA6C7C6449383E14D2E2C53957352EBB543188B3A7D468B3AE365773938A7E58D875CC33FDB911DDF62D4513E21E398C0F0BDFB24690D748293FFE5117D8846F4114811CE5D66D5DCFAE3C42278DA039B319007280938B747123459BF81EF2C084B3FA64335A2BFABA6F472A7C205C89B8DE345C9C22FA7E13003E9BB248FC708CBF62805FC5BD01BBC0CF9B242046C31DA4FE9C987C51138FD5860C3A2EB340F8930AB6397F6781CA969D60ADFAD5B184CA0C336D44B2EFF5DA8F1CD1B64A471A3684A07E840496CF45916C560949D438D713A91A4866984EE7FD5DF1B145035E0B0AF35B559EF065F1AB74F842111CDAC9ECDDB93BEA2E31C8E2C333A677C1B7FD47C91713D1486B049539457A539B836E0B18368EC418FE8324DFAFA01648239C9788CC87096CCE7E556E58DF7BFB67D6ED75D44D60C2F5DC2384E1DECF2997DF77EB56CBBDE19B8421725DB0624C47C1C95BDC985911B4136B752DC3A9929B3B2526936B0A359D14912637501E9AF98DC00DDFE16856E72489C2E3963CD92CF2FDD5A659EF888A4F5EE62014A79A7EA8D5647CEA72CDFB23F7E62C6F95BD79599BAEE379ECAEE16D2FC25D492A4387CD24DE409F6CDBAF8C5794C40E452CB5C98AA45F9C47900C2460F09E2AB53520B2D2C73F92D2F52CB0D3E27AE60849AFB99A8C7C132966A2DF603485465A2E9A5E644294F49E4422CCC673137E8F28C011727BB26807C467D6B84B709A7D5C26C5444A4AD1A7BD6DDA8CF86C961E96E36D462D58907D86BCA98F5A3775AA757A4EE317F058B738C3AEF3BBD375B571A8D8C6D93EA8652993D8DF219C1AE825E47D84203B6D3A79E9E9107D15CE752161155661FD3E155B2AB5825C4A48D611DD20A805C812FD8599A166F57B742D8A9678D6955AB9B8C429BB0A586CA671AFE3910C6C1E6C4E36CE0090E0B958C6561550043B0BAE309E21064D028AE15EF3B39FA5FFB7E1D2D9D8BFF4F3850DF727A6599A33792FCA158FC15AFB4A2A2C69082DD64B22228F5F836CD719A71D141967997B332F790B524E6255C655D3E6CD687CC36CD15F78756588A0DA31D00B6C248D129A01EC2116355345FD23BCC459BA8BE915038DCC0E9BCEA134F446709B02EEFC8E8134539F790F5AA7772D5F4710C0DBC5CFB32F39008AE9373F378DEB3C08579F5E5D88FAF2E57CC3C8E5C27632A744A3B994798B6CB1217ED776E27C0DD2E01843ADC97CFEF0524664E05A623DB5B38E2AF24714AF841127DC12322B6E20446D95F605F1A39D1C8DA471FE03A9235D4766286DCAB55AC2CA8491627B9647C025B7379C84C68C31FA08EC30704B30E01E3111011142F39A480094BAC06B4E35F2D7F689A52035BD0C083198AA9CF83A2EA7A1B4523C6AD3B945171FBE4E61B274678018BAECCCBB5F1057FD68FB648997703D20729F84EA69A97AF9BE7FBFB5990A2B07B9BE503AD9152797BD251A0415D515250CC44D8693AA1079E21D5748832DBF5E65DE04800D4EFD140E92FF4F9154750A35A649A8723E3D48C02C7969B0B22D19187F357834B87366F61FD6834BDD7022F89F2FAB2610100EBC921CC71DDFCE551A235D09D26D7B6E7A48BD4FF1 +smlen = 27111 +sm = C2690000D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC82702BE012B000D012B01D1016E01A4013D01EB00BC00BF00EE01AC017401F9017A01760015026901C7004B015901F4012400FA019C017B01EF0056005C00B200E1015A0018014A01F800E701650127003C0008000300040007002300060007000D00180014002F000A000B003E000D001C00130001002B003C001F002A001B000A000A0009001B00180007003E00290027003E003E00230001001D00650933BE108BB0F48C0DBD00B167196085E6B8E76C821871F822D2C81F258A7EEE885A4CC2F4F965E592FFA6A31899802B56B4606899C8E4AF978EBE38A57E302C7ADBA78B292E9AA101580421C829700472A691884C6FD13485F6EDA75A44FD02E3A4E06B246560BF77DF741F225BDBE7E8101DA28C5B62797BE2119F767CDD7FE655766956E2897296F30764C6B6EE69AACBC03B32F9782B7C10FD076461B4A81AFAF0010CDCC21061C16E96ACEE66FD6C9F57EC1B45C9D4E0E9D8C8823310A6949B4F0EA641364F9536C06BB6983D2B1CAEC80F323BF8E5A89358B2CD0747C22C28FD32DADAA758482BE44A00C373850777B473696B831B6199E327C65D983869A791C187F335CF43E1F59620146F51635B62B1D8689605000E0C407087E595DF30321461D7120BAF029D88A4E319AD3791F0ACB4159BF6341891830122528CB89F87F46D81E5A6A1D59057F99CEA915290C5B93B0C0E0CFD885AF4D47099DC21D2D48D28D1544FEC4282984D2BDEA3706BCF7CF5E33435C18D7474663A834272EDD8438F5C3CD988CB86E101BE6598FCE2AA2D6D3334E55C34473C10FA7D5730BA0CE4C405437E17E668B446F551BDCF1D7B8EC34B3973B301933F78286BED308BCBECEC5244127CB847A201C89CFAF30DA26B3A2944278885FD6EE7564BC1D8244B911A94CB4877D7681EFE14BC87BD53C220B67BC6C6B4A12B2068CF89086CF1765F1ABF45D3E1E3C5E815A3E05382484452EC4EA1C0B0AB496AC804A184537E8C1ED4A8B7409FEEBFCFBBF9EEEC119A4CE16CD60E3B5E1C3506773B4C5733BC7774FBCB1E979244EA2FEC710AA1C180B9D06D3828F4C35139467C160243C19EC443E1612C1419321A99302DE31A3DEB60F5EE77AFC19E9EA77F7588198C5ED25477290F8DC095870908C397631990FE47C63DD55481446DBFE332DBCF739632D09CB2FA9621D6B4ED84C2DB364AF38A3C9062AEBC24FD6C3AC1814AF57BA2849F058EEC550A13B3361633326BB01DD15254BA5CA5C789D1F8C4F3E1581921EF8BEF99955297B31B8D4BCF0AADF1D5D87780D859FA4D818BE0A78F5FA81D1020880272B0855309C4927CF7776C196164207094CCA76ADAB03C0FCE7380E9D429586189509F3F96604B3626411E62190292C2E778558B54C48FE4488238D3CCA7309A53310A1BF4FEF6A02F60D27C118F2C9C756542597F0920110BD9455FCE8364DD7F0E9A2280008014A5E1F2D5FB57CF9FCB0278766B90BD8C2382019B729D3747626C38802277A8199EC5DBBCFB420B317026126AE997ED8A9799A5807A60EA61D05360D06F204DE43FD406FC2312A0BFAD3CEB14D7ABD746D9297E679180BBF522486899426A7554547B7FDC7AF4CF5EEE4CC67549BE3D77C461EDFEDAB2704C59AC4B14ABFC12328ED6E8970FE054944ACD336A46F04DB691CF6C3AA45B0A82599241DB5C03465DB707F0DE75439C248388DD29084F4F96998A3C8CAF2A383D319984C76D38493807FFBF4E5E21D63A77889D024D810FA4E2C5F43FE286ADE87FBA5EE95C2CEF4435E7988DA9426808232C6364D24843F226C6757F365A87E9F9AD230B00299E408098B0757B48071DE5C317DEC854FDDB7F1B309538B8EED73784FF476D50F0CA261C2E708244B8A16E48048F7B0B967D70CA1D7927D8733108EFDE0A00335E4758F98C474732C08A0B8247997D88EB626255123E8266A0115527E76819234CE1B744E06D67D4E5798138B45EC4CE50908B7EBDB4F5F690501E42E67406E80947F8D3A2834CF6B13678A8F802D1EED978E82F2EB276280B4EA25E1C7C2F8EE5B5488FAE711517AFFE8AA227C83D70624C9AE59C6563A62EF022635FE4AD68D53216FE57C136CB7C0587636D8E8D71E78B1263882147CA5C0974AE2BB0BCF4D9E61A797B18C8F42C7C62983243AB841A0A4D6365BE3CA3BBC0C0D21AD3D6EBFDF1453DD7B3D853225A2AAD62CDCE44110DA4340A93A4EEEFAFDB6F1A208B5EE71105AF72C426BB32B12B6F08629885E32B493CD0139733209CC9FC7467EDA0DE75CCD747053251427F6D1D68FFD88A63D8CE9F1F3DA90C6BFA3FCBEDEAED6D1A04C7042AF50B4F34C679D64B1D8ACC47FDE6523757BA672335848C8499AA4FC9ECD89332D71165FA4D93A6884B72E6AB6E1E14A8C126BCA5B6B080A71065975B5EAFF08B0E7F66FA10101380C2B3A4AC14FBED9017F8BF579F3EFF2098B6FC509CE1F2196D24F70F8E099577F3906823D9A81C3A6FBA606653CB11EE72C1EFE04BF4A99425E742D392D7BB6E5E3084A761EE2065F4D71FE95ABB070816DFE809134EF5F7A2DD7292B0822BF6AD21B4319E6273E5DE636257554ADFB5AECD2C882EE6669C70A8C6E470979AD6D7E4C7926FE0E6D00340A63B17E2D45D7A886F8DC4D737DB96636DB105AB0E40240476BD4D5F42923BE5961BC50D8D3EDFF9C389532CDE99D5D7B81B288F9D279C381E4046347C95527EFF10C0E6EEAB241060A87AC3561B03BA7F1C095D763FDBAC2FD4F79D3361F329DE9603B77A7CA9A9090D82F44612F54BA9C68C352F8C71265137E1380D2B48F5D159E687A89AF4741B20FDCE7E3E8D1A53CDDD926C3E9641FC8A536B10B386482AEC79DCAF14E9CEFB06F7ACDE419003B63071BF4DC458556D81DE5FC4B1FB1EB6C8B84934F34F6A0D4720702C4DB247DA6E1890691A0E0D096FB9E3CDA6D9792F857B23E123F2DE76A1D041948B33926CDB3646BA78752DB865A8CC8791C441A64330353BA3635972098D3416F46994205C38DDE95B62913706E2187BEF565C53C45D9EC9460D0279775AC212E598547B139D039D964D70A460757A3FB5741FE8202BA7F0DAC4C738DB04964406C7ADEA516E1687EABF68A17E887FDFBC1D3E8275839B2BCF7AF3CAA59003FBA88C8434BF18BF74D3E72C077B5D6B89241E49A2C3003D3D8C89C3F123F85206DF7A9C2CADAB92EBA8F2E4B88767FDAB9045B54268E0A61C881EF98DE2AC8629E151E892BFC336B98ADA1AC07A8C8BF947C8FF56E22603B22511C99E23339E2E5831B0E75C4683FA14F7AFCD43F49A772276F1606E4DD2ED95317006B92F2F72375C90A1CAD058BEEB1822ABC470535162C54D79C4857FF20434D2F9CFDFB96E7A58A4002DA42F8D8920AFDAEC411B68E4D2883732F2586111FABA26D7D8F16D469564173562AF82DC86E9E9B0B3160CB1921ABFA0387E9B0329D69CC644B3C840C184B140E7CAC5BFCA61505F2F7899B87288D5F277950E23E8A32FFFA3A1B8747F895E36879F020ABA432BD98965C0E7C4064E6837445F7CD4BC8772413E760EC4E15A8123C8868D1FF221F624A5A722AD449AAADE18523CA5A5395D371660C04A20D8EFFE17B916A62DFB40CDFF5777BBAAB5FDA53DBCC4DDB871150AD9963B28B0646E527F1C69CAABEAEA7FD1D950D517DD914A74F45D0274F21429801F34033087D083DC840E8FE90DD01F5DAF23C6ABEBBA0ED4A9D57D86B1CE9A18779232AA216178E7F91A38AE793EF42B49C309D191142666B0643C94E81C73FB41D2B9E844115AD16071B806C3EA1DA1887DA6E7D24F6E417613F59D9AD520E20FC7264AB27A3D937B58F51128E4E1EE7B252AF74B76FB1C8B7B3393331CD4AD0CD69EA3F602777B676AB0FA828DA2D17655BBC7E720F3369901A9F7DAFF2C92EB98F7DCA783D31D3CC3A001626DD4864A1FB680A9BB83A4C55978A433396F75E2342E570A5D1706DC09C63DB9927181BA298195FBF8B0BBC896FACE59AACA13B79613E76456DF788347A49A815A54C27055D4FA27AEDACFAD6DE6A0EABC6EDAF4C3B395602B19D7FF6A120C9E86D3652214FC333016D3C7B0F532C6FD3C8A2ECE36B372B73E0AA161636A123ECA6034A42C7C5B5C1B42E31085AB084BB20B8CE55EE48ACE431AAC751F349D465F9002E7F5E65B78F93E24D2EF578AA48A70A1521F66F3E1E30528037C093A3EBCE403756436976F641D3DAEA982C1C7A0CC73CED63E746A55D2C2449D92A04F044F257AA2520B95D85D8C516269BBCAEEB62B478B87FD58D4763C29AA497E1ECF2248225613286FA1329E8BEBA73B452B7206E9AE67F408472DB2351A8826B295217F990CA53E1345700CBB17CF51819CE331DD3503186387C132836EC4BF020A5D11D0F9BBD68D3EE3773BC0C419D941B80776C2DA7BF62563B2CD27AF4FE4C57430EB407564121485CE6D516C2134D23868327CE7830CF61851F4E8352293E83CD4F7D1F7D6B6234A8AD7105AA30D8FDDAE3C02037526CDCD139E48FDB3C9590630A990A4AA72227F1609444A2E78F07D1B256BBFE687F133A0B44CD02012761F5DDD74758BA55C4C005AC18D92DBD8628D2F2BC12B697D6ED56113C5B5AE9319353E97ADC07BF4B5B48B5F03C9801D3B62C3B686F155CF3F3667661E6A65AE97AC127AED4552A539869546FB69E1C67921F12ED0A563BA3E233363DD7EC029E44FCF7A82D110ECB0B93FCE3E9AC09FCF6D5FF6949D953ED825B50C37882C7A0FDE189B4863082CC9ED6A45E631A5860B2AFC2B5712F8934F922BF8BD7CF75555D3BF2BF094B8F01E76DC076F1A8C951A3E6D95A90C5332E9E888EEEFCDE1299035AD0F6C41F7E82BC0E7EAFF8829CD701007FF0D8D8C99DA92CB89B298C3F180DA85AD59B475614577BC37C6CFB8B3450F8A7481F3BD064DA07F26E3464DDF1FAA770BB7D2699F8009403935413E059A20CA10437EE586EDD9BA488CC2136525A79851FDD2FA372B3C59E2AC763657685F4EFAED982C04292D233E87A0BF62D1122A32E393569690099BCD4AC267E04668C1063BF08CC6283C6E5CB8792DF2666C51A11A3D6E523647C7B12AE1387C46F5CD2A1E4F54DE7F3EB972D8800DAC806652D0C9D13EFA45AF5D4EA5F4653D9F56BAC384D0F34FDB2326DE5ED9941CA3D8CD3522EE087390F1787A20EBDA66FE60DD6D66F93944F393C06C699FE641102BDB45A171C6B543274E715F7FF6846D0D09DCEEF9E854257730CD53A389770876AF711EA39D5CD430DA8C13C0ECD0B91556CEAE884421B165D8611AC6F8E9D5BC6FEC810B84F59912785686C7212DF6A11D1EE2334B66A0AD53D4701AB3E8A50089C43E0E2BA85FC88082D6B2549BB58EF1F9C9DB04CEBE982E3548B4E91EAA27CB2D0BD6A81B373EF87BA9345D55EEF98C0DF9D83A26D27791E0B537DFF95357B320F452091E8B843D4627155E1A8CACBD4E3D42A6ECFDE73DC675602A52F638536DA49D62D0A60E2633304EC72E35C1C0FFF4EF5B433F91EE69D869B97E76916432788BA4D125DAAE1CAFABF036425129978CD6E1D45D7454CA3D703DB64B8D41A3CE7336011F0C354BE87A4C0B5F6049A31761C2523B53AA9930F7E81ED661DFFC2CAD1982171020A4F417A6E8A1C97E828D1FE92D5441683B9EA245DE050315666A010B58F963224FB61E48DF1DE354CFEC7D361172E8CCA44043E0948E484049949152D76C7347B7694420DFEE5EFE87FC1FC6C4870A0B50F67097C3BFCB2892CAB53C7144E32EA089D646C40629DEC0F9E99F4186A66CD8E2CE0C0F229AFE22ED1C540DD9BD8129140EB433E9622A156B9C7848CAA5B47203152C2C71A417C59C51F9C55D7640E96887A605212932856FB35BEEC516C3D324F1CC5F2BBC9B3B27C899F54E6780CFCA5B08D64C9080CD059BCCE4ADFBB31D4BA008046CFBC18F3BBA8772EE494C210ED60CC6321FAADABB86B2F5D48654BC643CC43007879969F83413B63794FAF8157F73B8199E3CD7DE355C8A89F3B866A1956CA507E7B0E3956780B1B10D57BCCFED774A56DDDC43B621B13BCFA202AA78EF46793C7AD4DC47A5D9B902FC384FBB28B08F58D51C8F4CBD5AB0A8716DDA61E4BD623BC0F9C687B1B740C5D26038DD1962681FCB56471A6E158697F74C46DA0A6F854FE7E73AFB68DA48C947CFD4FAB16163781CE204D7375B5E35D7FEDB3C7FFB976CEE284DAEA6E4503E00A157A1429CA224A998A81CED075E17FBF1CF454BEBDDF74F86E56118B32B54431AD535612E0202C691408CA956EA8541523E92ADB663CD29CE265DF22821E542C2486B23E38CCF91C6EE33C7ED4D02CACBA97032728F14DDE7318B664DC39E176EE8A17311C398E22A69ED90D14DD82C41C61E05395C0D441F8618B5C8C710ADDA9FC0DDA6A2022FB5208E16EE1E8F7C8673BF0A6389953F862911D8EF91897D5D8C0EB36F505DEDFFB1E42BA53FC76741E5E14BC39CF176BA72D3D1F22952260E7833E11F6083A4E2038CD84661726CB766A38896540F5B6445EE8F9ED58464F9771283A52F12AFAA0AC47430F8DEF4FBC6493714B40ADD4F0AAD2EC48D43BE4FD1C3CF17A11A857F01E57620AA207AAAA374C1DC4A6D1E2FD6AD17F4F79B355ED09F1F347FF464419D800D6D4E369B5FE153E7A884F38ED9B8D6847FA2BFE2FF2FDC7E09EA75B0D4E74512537EA5F86DFFE71CD4781F7285E62BBC4AFB0DCDF44B2DCCC445A6B4B3EDB5C0D205ADF99015DC4D7A15388EFBBFC59D7F79935164C2170F9E8459AE48D18794DB2BB172F692C5CEA128937B02B92F2F4C5106A618876DF9F521A25617E9C1E647BF3966C0609BA7AE557B84A08650CD9C4C651636B03EE9850D3D86EB3A678D7C99670F4C133D2A4C78DFEDB7C6FB5ECC5AD887A322EBE000414392A11251DAAFFF4B21D68A21353972D00C4446FC6C3D5ED226E46D8780169F0310D046279DCBE228E9E78C5A5C905467DF27F0D1FF158F8A872FA51A562563DE29B1C2015BD7FAB2EC25C27C0F0D7A711738605A8811211B2D3A7B869793800745A9183B1448137A099007FF944203DA92A4BF3CA8B0B4E4C1183281010A5ADB12101A977F2C12022242FFEB4C03F142D1335D23677847263CC9A522D6C0F3F367E083872DEECF85F396CF129AF2BAB164CEC26B94C4C61354CD5B8C0FA756912824DEF3696BE2A82B8BD2E4DB2BB5884931559C53AA7BD3385E1595ADC6480F9783CC547E26F8CBD6A3537A3CA453CFF024D83C64ECF7839C2315AEFCB7949CFDEFB1E9403BD085F741AF5A92AC17EF1CFE270CF56BF38E19CD512C3B1FDC163BFADFFD56878FB4225D81ABB7CCAFFE7BBF46A646D7297E09A2BFBBA3A29E2AB3964DEBC14A6104725EBDEE019DEC9C0FF6960AEC19122A363AAB754DB04DDED17B2B4F79973BA7FF4C43EA09F9FDC63985B68D7EEC0ABB80B900A9A9E6BE91CAD4F88472D4A07B7320D7F55B81DD4AAC9FDE0013C3A47998D9CDCA674B26726D47D20EB2CF458A5A6D04DEB21F52B86AF9BE69DE9AFF8CA75660FED452CB614D6A921747A261590D3CD8CCE1191A4FE71295A4FCE73571BB4900BC887309034027607A8A470DC695C0F9CBE324E289F6C1A423BA6050918D7D33E3DC311E14F057987EE270363F69FDECAF38F6C93AAE77F7A7C6FE97D53F68562546B2E6C32D521EC4698A01D62C65C9D0C8EDEC4331C8CBC700D63BBA48616791B70339C022C25A3CC715B98D49CB2043C69B83CA732319905FDE678E754643E6F1F63FAF3C43E0A66E6546B4B156618B1F3D69381B738EC9C77163AD0E7802280DA659563473D56F6423DA656331BE1B533CEF18DAEECB38CF4EDF494776363BBF4B8DFFD3A2F374C361E99C536E284F4F9D7DC000F5EE7460983CE1DD918A90D504E2923CAEC148DEFC5ED825B7B1790CF86E3FE7C946A3FC95C080F57D4B75962593093DF2780FA6438312E0B3FFE0766DE2E709027DC9D0E11553A8CDC0613D0DB1A5185E029AF8D5B7EC484773AEFED876736333410EBBF3573AFADCA2A5CDC9E1268C2E42E3EB26C3265003F20BBA73BA774E654F92822FE50B38A46075D36D69FBEAA7967C89856490EF55CCD10EB7D8BA8ACECF077F857B1B9FEC44AC59BB6C38F239F3B74CD8EB13276EB78B82F1680D970B6628A9F447E3ACAB4435E4A73CD0F7277180160D6ED6017DA6055949FB1822D1EF1D6F845F2E14D51267218044F16E95552C7CA06DAFC836CEB01890B474F7169110E2C84DC7C50342682EFB8462EC2924D6C847086D2D5FED3DC73FDBCD56D5916C93B880584FEEC5737F8DF3BAE4062187DEE95D2A2C5ED877995554F7CA8BA87B93D46976B48A4EC1E24B5665F4B50968E4D4885863BCEE2E90DC946D4FFC72C1DDCD16792CB0C3CB7ECD7B5428AD7754F4F45BCB6635753868EC010FA1C826E88883E218F7D953E1550612215FE4BFC306C18FE6364B9C4EA855588267C85569654FEEE731CD1CC9BD336C11FECBC603F588DB7B01091820EB435139CCD29A07981FCCFA963C39191650B57CA853323EC742526D662BEB1803E4F0B81CF22EAF9D9E915F853DE3B4A480C1C5EF2A7B96A62D9135D71CAD19CE4F6A612ABDF6681EF956ABD01166ED9D65ADE8371A0816397455BA389AD501F3C7479F0FA2DE906F7D18B18B12553622FF67DC42D28479889BA22F482F04C63743720075C155D0EBA1ECF0609BC651B9BDCED35F11F32B70D79D68635F4882256C34D73DCDE1D0DC692304AF37C392664B23F28B9AD980CC771AC5B20DD500F783A3ED6D09C6DF48960BEEE1DC06FCDC9AB6BAB331A369A6BDC0D9D2C9007D761DD5ADD8A8821E4660C38FA6C6EB48B41159E7259F71C131F80382AD0E5A1D2D518D97585D511B87DD802295B987402F20D10CD6820E1BF27884214337E4E018E40DE1A2FE9E341D5B575D31635260943B4C10B5581AD4A5FE46347EE1CC60BD304A511E7381941358E078AFCCF943EEE124B72D67BD446104E34110E570D3E1128B6A273B07B8D8F24A61FF5770440A34FCB4F7B17F21AF94C99046FDFC2107C6B50EEF53D635543FD13CDD85B59CF083C545DD56B671E9E0C12F0460EBA2F25E61EB72CC09597867A388816407A20C9BCCF133C5B7D051F90337BF4152FBF567C944BA8DE5A570F2149F7C9B5019A4B660004D2886568571C2935F212A4E2FE15D550A394E32E2245306854DB113AE40279518CFA6E45CD8E66F66E1E70DC7C9F4F8617CDF2C00A2727BA59F695414859B745E23E01ECA9290F8E04336C99035694A66138668E66697163B02664E358F9F071F8FBC9FC3D5E3246F298BD57B9C93FB03EE218A45209856030A51F129357446A435DD6858A26532C3FB560EA69B004D23A355A2FA6056AB21DCC4FEB85690CC9E29414821F31D0A824110465BEE80EDC0F706B696DB9A57A383EAE3A3232BA2E41E7CD2A9EFEC84232A3424A370316E9F99D1D4344E746ACAD449B174CCBD8E8ADE957774E3672158E693251E60A4AFC80C71B89DC75F2EDBD2A5ADD293045413CA135846CB54A79014516B5527E497F7B1273F0FE3248F398E36519C66A084A5D59334AD639FB21F67F13C30E5857C0502A4132D14126F48AECCE2DB0C7343FF796C8C0471876EFAA8174B6E6195B6A14557193DFB390BA806C42F35551E4D5A1773CFA1176064AEA9CD84830917DAA633FD4F511C4B5CC1AE80AF743802A9F712C778CCE4BAE926DFE0115E3C1CE60CD77BC2C81C99DFFB0FD5A660AD5954FB41F48F2E8EACFAC0BA22270A90FA835FB90284476D9A9F3A94209F96E3C0FA5559FDCADB6EA3CDF53931853C0DC6379AE18A143FF5E66A700201723C4169B84FEA2E3043FCAF389E90189F4D0A25BA6000441DD99CC3CA40968A7C0C1D47ADD7A1FE5D06D738E7D03B64C576124264C9C23E4BEA40734DE626D0E192C2134502840A88C7B8149F2E7D97FA277A2DEEBD717C3D8F7C3A920175036E83E05E11B2ACC74F255A5386C4CAB807904F10267D0F7F6C6E6DD848F83C768961A9FFD976E73C88EF5D759EB527972338C15D96E396B8BE5ACE335A31F1B29B0B6A8BBFBFEB1DF947D45FB3E0338C0A4B3B1BDF58518A48CE6D09FF1408C93A6768EE37ACFB549695C293E8FD22DA2D2D44168F8120F3EE87DA1F45DB89FF26DD55C0F445E5A9539972F7FD44239C50582635A323E070DC3B223FA8052608E0CAC5155668D52CBB8BF05D9BDA8A31BC6E0430AACE7625B0C15A63DCF092AD5975DDCB8F51440056989089C1410E13A0A78FE94BFB74AC79CB814B85AA22D4B6AA7D2D1CA51AB62A3D5A0BAEB87BF3EE2FDF722502B1C1D068909DDBEE7010A0B3C7714DACF5619651139D1EA9EFD39D290D1CD84FB93A7E94C5D05B58D6A7D7BA77D29F8160C28F31458D916860500CC5B848EC1791192974190E355E07D4A3E380190799D2B69625254E51F226099482B3C1F1D580350E1402C119FF08E816367836C1A5D00CB4B11372F1C594C0030FE3F05D2A592B155E3A83465A3357CC0CA3EDD05E8D447588C99E26DE3871F14AB47A378B47F86FE1182F1A8111D5402F431B0373D982C7FC76A54E0BD7A1536EF8F4FB90D63A116A1CDF1A6B2EB229C65A0020827097D8602E8A33C46FF9C90E0E3B920F699379722F57CD46D5E07284129FA51C12CCE3A0AB954A2234333D2FCE640FE2AD83C08C8AF902DFA87C486D9FD15D4611331D31D95E9E7D4EFAC962FC080282FDF1094D9257B5C4D771E29F578F00AD1A21278DB2C9814C32B5151E6238A3E6BCEB7C8169D7170A804D2AACB21929C9299372E8757E64BA067957FE1D0CA7C6A1C66BE077F1C7A375D13ED85C4408F84BEC00CED04BBA162F70D82B7F1C7C13375D7060C14772CF0040639D076DFA41A7510A65CE108A492DDA50BCC27E4F488E2E16A01F5F9F1D7C7238D272AF7D65B941E8825E5598FCA7EF50C85A46D123073556997FBCE8D12A5B9958F15BE468EA928DC3DBA312B7BDED1420D9E8EAC66EF63A147D1E5FF394903158DBB17FCF81C7E1121D35F88F5B91A336EE54C150B6E5BF84A1CCF40440CA38FB173E879B0EE056B3A09FADAFCFDE16C9230F078215E7B9397424252303E69297A33398500E39F78FBE5B8FA42B98C0B62562ADC089FB5BA910CC5961334642C2569C2EB72D94F1D3ED9E0AE1FEF556F3102746026F037B1781EF4C13F9191EF942A61DA034D370B89DA3966627BA526B77FBCA3E7EB38AA3738009C05421A536B8545E392ED0A50300AD123E0F36CC8D087964A3A3CE0D9D6B095D71AC4B4F1C3C9AC019D996AED246436FD1F4D793017F5828910E06B0BCC4001206ED17E6F4BDC948226FCAEA4FA01EF8093840E85184099A04EAFABF761E720ADE092FE97F7413608E05B4A4350ABCA8F62AB87057B931208A25DD75DA9B4837FF0C2EED9DE2002D202582D375639B690875B101BCC413E06C33873C414CE883513CE3B83960FD3AE3084FF464675AF46CD918A8A38BE19AC232A50361D7A8DC0C568947DAF5D00EE2C43A2E734D01B520B1E520094729B335891AD01CBD65193A99CB0BD124755FC2E5C9156581B42125E24C010E1160B965AC6CCD049E8751233F66EA8F82E134A1B3C4F9256D8CF06CDA858E4F20B22F39A5E83EB5608600513FBA773EAF5C6882EA20880FD112BB62D7FF2BCE67FA2B4D3FD17D381C3EA163466AF618F2CCF909B0B82835B2CF322082F7618F6A83B136B2E5711F22C318ED5362CE4AB3CA97765F1CFA3C2310E3E19AD3B9D18A9562555E33C101A11F75034006C584C7A56FCEA49F5BDE465C77AC082B201A239F4F1C3A40368C70303E10D6C959E21DFA20131765BFE7A1321E0D500722EFC7D753505F7DC49FF110D9714365D5437E32F69A16C1CD0130EFFF88A9AFE42D6044BF7C30F1ADBC867BB1BCEC3F86800ACD439D293437BB96471F8E4E60B2E71D8F18BB173458C942E8BDE1DC1349A4C3106635CB122E9A3AE7FEC0136172C3AF1B1FA2ACD5A670E7C6E33ECD9D3662CB5296307548D0050BECA603022125445AB2A46E39C65CF1DF0249AF32E16E6B224F3ADEE7F6F088D8260BD6E66289421DF6A95CAA24A8936078F803927E40BB57AFBB820954B81958EB470718F3017D3C54ED47D4B468818706A404B0A67A43F0001F1BAAB2B411567E0F1BB0D7814FBC6504CAA3A0A2C725A397CC00A77D5FB372D8B7CCE22D0037730667C542DFD0E1217769871BCCF38FF6198D63E45E3695740E36BAB26C624E57AA98B1806C44AC34E66EAB8271C23A54411B8D9D9B86557A9A0812732282E6D76ADCD719F5E36D125B65396572959A3DE31808F36C8E58746571F1FB623FE71852E97B29D555E6CFED9E77E5D1113B84B6532D8D835D22D78894C3FC9BD029EC7A061ED1C0B98F89577C146D972DB48BA4A8FF1A708B24F59A379E348694CF91A23D77EBC67FD9D0B35836A8C56187EF8C4DEDECB82F43DC71F1944A2CAF39848E2EABCB7EBD5C213631FC357A46FBE6B7BC87BEDC236D1984299BBA4E2BB70437D2C1D8635FE70B4A91BD3AC9CEDD9600126F0FEB77241E349AC045284D8A4B4C0CADF3F4A252A28DDDC3DEABB94DE388023E2B9672C7BD67CD0B6ED3E8A7477AE8FE35F009BFBE7443C4BC40D70E8E3CA2108463C4EBB65824AC7D7903A23DA72D5BD21944796BE98AC07E77E386774DC00A45BF5E9369F28281A9EA7C4FCF19B41B8B57236219760F5D7C41E6613072A98B3462A728BA96063CDC410A3D0356EC29D563E4EB7D876AECD740F678D0BBED2A59DD6EF5845A6F583E3D6ED565265A4DB1ABE4F4D3ECC3A67735F5862B1A1D317D603140C3B113B6202DEF4CE033E76901C97B68CC03724AEF95F0F83B15C86D8880EA7BD409B1343931CD1BF6772F3C0A8131D0439585083BC9E02DD04BB36482BEC8CF4BC8449DCE48BE9967AF6F69EEBBDB3553F4B6B8EF4A7262C6E1348BCA8024F3706EBEA6D0B16C31CD6378B042FB46290A594C69C497E4AC2E5FB10E65B0E50C50C1A59357AC47AA8305F87E5BB9E0522B774080C707B3824B3CE9E67AD9D06D2D3772C75A5B3A76ED54B8E2D689EB10A2957A93CF0841DC9E4772B9E8050F1FD996CE216052935D4AA361D4D82FA51D38555263ED18893912436C735173AA06325347907BC0414F4CD8A9AF55EB1630C3008491685F6357CB2788D951FC3083D746CF88E00DB05DBDC3A027D568B3ED23F3AC0169AA58E71CDB9C3FEB24F2F966BF426B39F5016EEFFED453D6910EFE682C39DD50792749A3F163D0AA5CE7351F54AB7D8C2CE190F9D6AB3804F0026104CA6F8ED4154342FA02C69E236BAFE9F21EFACF9C3B13D78A0F5565C23D609BC2966DA187CF5E37A6CD4A5072BE60367D0118D08FF9709978AEF0223C0DEADCC581046165E99AFF3A7F82567CBD0F7A5920B7A78670B3649528C7878919BED3CFB0F37E439F01749FD9A553AD86BE584AFB8E424C443116A6B35374E6A79643A7DE0BC7B7757BBA1C6E76670546361450BCA58287C66F0D213376C602E83D4E0BCDB93DCBEB265353A50844468BA0496FAF9F3325CE6F02F1A316B8C54453882B9064958FDB7F7119CE841A6541A7CC406514B833271AE1EB1CC7AD2A990A908EEBD39C10794F5AA8404A75C427CE05D91A0B188CB7ED20B416402FDB699BB9DAAEEB08A1854E3A84599CA74C51705C61D4E8A4B168F346F57C086540379618F8400BBBD988CE2E10EAD2B7BE0740711D0510F38A4593BE2C102EA98912BBC65DE1CF4B0458A75DEE032EE2825693BC8B33B62DFA6E9AFD1F1108E6B1E2C91CC4ED9C1F726B0CBCC94DDC06BCB9A58573590ECC5208B600C28EC4B92F509F6640D631B6E3274B4D0C83C5767B974C16808549F43EAF0740C7B9632630E00BC46BEE32E009228FE77C7A3DD47618DB4F09A6E68CD083A9D44B0BD595969601215F77CAFCE966CD3BD50A0E9C31C11BE73EC8E91F8816DA3D32439EB2E91A73584CA1039B4382A02FF9721D58F26CFB9B9BE8E8603CFC28362D4925F0C168BE542749D4C1B2ED2FC0CDF13B212C17AE41D20B302DB31DE88FBAAFAE987B9A4BCB1D45F31DB787AE4BED9596FEBC0A9A574E05533F2F98EAECE8B7B5C2B45BA3738F7054EFCA3195016A2C416986D2B029353E5AF9315355F58D299EAC46A5BE102FA3567A45141C9D08E4BFF3147BEF57390109E14EC74C2E9FD6DE66F277349D2FF7C469FF332C3DC74BF36DB2D74FA01859AE319384DD846551B15E1AB12545089D0608DEEBBFC839726059CCD5681CA1E0ABAA67A78E2469880726732275F2210D186FA005BD8354D339628E29D0C5732676A4BE6CE0F9D7BD83EE78A842BC2C0ABFDE1A847F49DA9030B5ECC051AF4786AFB341F1BDDF699A65BA12334C890335811151592B7AA5C47AAEA5B570A16B17A872A4EEC464C4CFC9E5575357BFCF6641D7058099C0C4815A2DAA5665BAC094070A7A43BAC5275904F77F316FDC3F3D63F1BF715559720BD86A202F917B8D8040D08092D962F65F5A5CDA884229781625311CF226E41F7D8ECB999874B1D010F195C09696D1060CE6755D88691EAC274BFDC3251926C9ABB00A979D84DFA64FCDD6F768F89E469528921D9D9D11B08AE185C36BDF90BFE0E459103FBE53D2FDEE02FDCEA01506480A1B18AA86E31FDAE5FA6D70E1673E3FFD285DDADEF31BFB622C734F9AB8F763796DADFC7A602760C662202AF2713C00875A3F1C83779F4F12F343D777405D9BC32A9EA740C686F969A3E1B8E244EF6934CF3ECD56B2F2F5FF35BA8489EA2D2B3E894E56AED0922D85F066107876AF7A1AC269EC51B448EE73D513EDA7F7EB569B57DC53ADC14F52CFB12FE89CB762B50D1D2ACDDC0C040E2DF9F3061661F32D46A48A43C234F8247130DC7AD5ACF64AEF499DE5C90CF9E15363EB285C2637BCCC59B06C9732BB42745004C1D23248CB036C4E2850FACEDCCEBAD2B0692D9F44EDC27C0FFC57D59A664B5EFDA65AF87450AB49D4840D891F94E123470823EA195A35CAB8973091F52C8D5F4BDF81084A356D421E003E531CD19DD07244A058F5FC82A987CC5F4B9D15385220BB0EA5C032C0180FFA60986E3D8007A8999B035F421175F74C872F9FD64B5B1D8C3401184C3217839966AE441114BC57FE64F1CE143EC338A3168C79F6DDC0BA4F4CD9F9D7FCE57450912C556BA00040CB1DA7E790B218BA11D15691C0FFD4ABEDBE59E31857F3AE1F5883022B18F01B387C1ED29CC60B3BD3B4879134DFAF79DAF89C8AF3F1350161F38EB57028221ED51D1A06561296EF6DC4A86845745B3F0C2E4BBFDCF96CAE8BD639EEC581047523A0DDDE1DEB9F6A839E73D7288F20E70039B21EE183820771C222A1547282813C14E92F4F4B5B2263EBC321B7AAB1327BE0DC7488CF3BFDD3E75B20B331E61F7F921A88984BD3891534ACC3AE7AAD5B7BA76A4A55BCE593DE7E2D34FA4A6323E4357225ACDB7B34AD6BAA26394FABE9E771822B81DE4A5846D43060E62D0AAB9DE669665370AB0C98C761F689AC0CEF72F6AA87363A3AD8B9D699254D9F1DBEF8C07127A1D9B28CE799C5C39019DEBE29D469F8AA8A4A08BFE5350F5A661720183B4203B3641BFB41CD110155973B4BE242DAB29DF780AC60FCBD8D1A6547A951F16A1B894EC4ECCCE8BFF5E1F032EEFEC3227D93ED0C34948FF471DF669ED5FD838843576FF09A288420CBCE87FF28700D984DD68BCE7BD5FCD3A21209405DA77DF45BCD7B8B9BCE831CCD6F90BA6EAE9E4D07A9EB34206129D89010750F1B5FC503047E0DE358AAA441FC246210848DD4201C72AEB8882E633898546D8A6A6057E977A55DEA5A4E996B9EA5D700E8CF774CAC11BE253F7853FCBCF9D890D521E9B9B3619DCC575A0747CE0181B9A4D26DE05B98234F98FAEB68FA9E4CFD360885AA858AAEFF9E5F9C5814899BFD9AFB507952E3FBE74ADC4C238A979D5CC89ADCAAC003F14327B2DA8DE015CAC987F74C841B3E20C0B028B9CB1169FDEA3828CE8DAC92FC4C5D4FCB6210D47EB6BEE52BD8ABC39021E0D5CACF4A852570667B1E9DCAD0886713AE3D4216DD2F7391505017059DE50FD7A6100699E4091024C5BDC2DB27F378DC2B11B0935BCCC9867BD519BF259559C14E296F8E675056FD2E557F3FABF1EDA44EF96AD4AEDA1D50D45F11503CF084ED93E1773C8EE5B50020D390E5BAF509FCEFCF03A769544EAC9D66912313467685AD33AD6F32DB3580FF70C4055A9D4F39036895A7371D9EA598D0DA735142AB1B7AE469B959A83295739815613D384B902C631A845E99D8775883F8DCFF291BF97247C29DD19A710932A079E9AFF4548AA7FB43C857DF24F7A5651A034FD23582726F19677A4E6CF7BF24C523DE0BE0BFE48A48DF48ED17FE7D374957C5252C5FB3210DED7438C92D9D62A92CADB0E66AD4B95A2472CDC51A1ED8299884D50D0279B005C50BBF5D071F6722822CE02E3CFEDC753999250492885D60349C5ECA014752C8F0FECEB495D2D63E9B6230414DC1F21ADB08807DCBCF7168C5BFD931DFCBC3C86880007D5CEEF0C359A6A8B7CAB4419DC663CF6F1AEFDF69D18564E6386D9ACDB9B5AA9378FA340032F46329BF64DEAEEA0BD4E5D76EA01887E4BC4456EFCAF3DFD3F034E266C3AC0C56E92330C5DC70E06F6ADE0E27D0BAEF32D4B113C41E069386E0BD8F7F0FACB223A80070CC20EDD2A7A8542754C1C6A1676C306DD013A8A16E2C7C0BA1C10E9EB08F32AEEBC2F958D470430F4C10FE318078F7027066B9BE087B49DC55809FAFDE15DDBBA87B398C5AB7B16A32469F7B6B9171EE0D084D74FFA5B024C0171C033F6431A95B9A60FFDE61333C96CDDD699AFD927EC1792D926FFD40F20E69CDFBB659E047D97ED800AF25B10ACD6CE0C13D6527FD3329A471667AD05D05CF8DD020E2850E7F3CEED2EE68FBA41AFA12F33A54663E9A89A3FBF167BFB87680F940C8E3B1EEC85311AB354B0319A5DE4CD4BABD1A7074BD7C3EF2CC689AFE1ACEEE90DD14E02769BAFDC814D4156A26E321A3DA7DDC49FF88129DFC27593416CD4DB311AEF7DCC5C9EED0C0BD593E8541B3CEB0ABD7F1DE79C5E8D80E3966047593018E4614642698996D45B28E9B438C5FD2769416623D6C7BAD60448658BB4D3F20120713416FAA777DD6E58A76E125A9715C36B7C9762106E0F1A5C622D5895E7C3753B6CD960EBE1CA3B36E0175ED6849AF90F841A86A0D0FDEE9CB557503CDF0532759B80482D941B7E13F23F57B40F908DFF2A82707BCCF7180FB483E2A9D1EE45868BC7871CEAFBE58458C676442576A7373C950DA27E254455BBA25281B36BA38E513E81E7E3A266F857EC5BAAB87C3F5BE838CB4AC1F4BCBDF02F62B251311A7985F06C32F0972882DC783119EC087F3404C4BCEC64FCEBCA9AC4F36D0B46F3C75CCD2180B9F5CB36B83D730EA8E9874B2DF6A925E0400E22D18193877E79F0A2D7ABFC192B9326F4B502D0F439FC7E14AB5BF7097FFAD1476B6CD85809B653B1EA2EA25DBF9EADD3312E4E0DB294F082651746B1D97E51030F4741652DF677C4A1B6DB73B9BCB08A82B8FB8FC11C09CC4265B28444BE1F4B3613700B2CBCA271647CFB4EFE564ADA8D8749A331D5075F18A5070A656899B0B981A43681ACF67B449C19628E279CD04EE65825A720A67BD10FE8069497D7CD29588826D1FA54E8717717215E71AC765754742FA86213D6D4A8A44B6C1B06E8B3A20BCB2D0D58C4B07BEE7E84027B47BA31304DFD3EB9F0284D9DA34D0B0B93CB67D35E0A60F1903BF2CF39156093F51F963761D4CF80064280DB30DBFF1EB7B7FAFD45EE58F44A1444699268EBF4E86D0211813C395DC48E8FD88C3318754DBDED9B8A90985849A2EEA13EE818ACB389A7214818FA3558B0D420C5A46BE963EAE166D2A4617B88955DC79845DD7AD10032B1A0D42EA8C6CC0858273800EED42763645368DEC466B7617E5BD8C9D7B363A5101A66DF042CE31B3F31500DF27AE7023E6502DC584BCA63BF407FF0BE2C90491AAE7F95CE857BF09C3CB49A8035DD2D083BB9651F4E04B269608A63A1DFFC2D3DD006504AA9CC7DA74488EE515984205DE81829E4B33037547E8081537641FA1011FB60A6C9A3C521CDEA6846027B863C97551B6E64E7E4D6A42C9F7FBCA487C2C2F09DB6F01BCC0CB1F07BDF1CBA3D84D7AC6A735C386CD10B9771BA690D1BFC8A2B63F76375CFD74D41BD9763B4B5E27F2C821B720739C271C03CFE8122D974151164DFE248B82B0B14395237DC4978FC7FE678D136FA67F3CDE4C493B298691101D96C8F9F8CD8D20DC00A4FCD5B8C572F3D1659817D90B1B8B74D0371980BDA9F399BA1BA077DE960D1542F65E1106F09F8C3F7982A60B4FC2D4366C096BD966AAE76797CCDEE30817529B89181833EC93F05E636697F2CFF236D1EBDF3D2CC0761098BF2D5E195841BC9526727F63F20B72A90F001259A79264699F24AA3BA3D1E24579A37994CAF620BDEAA55FA3AFEABCA4C216B006F0E6A6BB927DE95BA32346E1065BAEE66AA8F94B22512A5D34DF2A8FD3EF52CD34CA06F2FFF5ADDC453817FC7A9035EA7CBE16AD9563581402E478435FE84D4220EB2DDF0B5C459B283526A38468B5FBF08E3837A466EF8BF6BC95BE0A4BCEE1A85049580788A8FC50B1C09A28FC3CEA7E1FA9A4AF679853A959113D8DB9A4091E0E4E6E9F5381E236D9BFD52F57A98FCF88CBA1C177CDA44F8B9071D80BA2C6935F159965B6FB2495F8C1B4754B56898755B41DFAE3ABD78B19B106DAC323D55244B48AC58DCA7F58F48AA1200FC6CBB1D4B187C0082AD1135750397C40FF8228032BFB973758EC0DA038D237680DC9A271C82FC9287EB327F84B325262549D95311341F32362C3C2AC0C682B83A03DCE4F1FAE92996DD3F9D080AB5923E569ED7979FAB29B4B62E566E74FF09A1990DD40FB37E83AA2996C35D3D3848459B1873F8BF2FE204DEB3CAFE576085F1E2D334820DC50CA561CE08BFED6ADDF8DA82BA130D60D972B870A5DA13150B1818579929E03D28B0B6DD37C17FA15681015B901345E3AF5019FBC0AF9407843CD8507E33E349FC541D072A994B102367683937F0BA8F867B7CB465EB010A38414D034F8385D832EFDB523F2C0A7AEBFCF1E93AD9F3DCAE6B0A37C0CBE23EB3867A939D0DA657685C17DC2F3037470C18A8A37A80BC87DA39C47FA11BE8245A612A6BCFF16D3B69DC7030620FE37DC9824B5A76A070D9C4B61BE7C87EE773F7478CA66755AF95E20B30C113291C6B30E991DF0E39FCB97C9BFB0DD89BB2A5EAC8BE532B76164A504A2E819A4FD3BEC1792E89E53F57BBE51EC0827157F1298BF2782484FC37389381B8CA7567C0A518ABE4F1818BC4C1C7921024EBDAA774EA1AC050BC78A81C4129E2DF3A576D539C05589C088F6AF5F9DD209E2D9B42A6E28576E641D6FFDB4C2BC4961F7502844A3F55506CA4A5FB2C5B9FEBCFD20C7B14263EA8EACA7D5BE34BB7A4323B6FBFC96B051B489C0754FE849BBDA75403C032F59DF0A07782EF9AF29B38BEB1ED0A43EEE5290BB985841B808E1CCF1228520199BBC3757A62F30DB807C7561F39EDDD775810CD62184E14482DBAAE1376D2DDD64840EDD83FFD7B99CE193F402BDF63819FB60879815B7B513DF0FE5C58EBDAB60B71E2761974E1D5B197D9C12F287349485124A6CDFE8F22759F6936180A2C10579E0B033C3AF40ED50301B512CE03B78BFA018B4AF4A050A5EBDBC8D843D84EE494F731C1B91FEA44B8499D47AB460BB9E66A0C392AB9D0FDABC9055D2AE9173951CE865D62F33E888440DCBDB8B0C501A5C33B71406C16C52F19F5A97A009B97BBC51D615CD18A5CA030A6DEB61C3293F36690CC2A293B78609DCCAE69B5F3BFE734963EA9CA1431B352E4D62E08F0A5F8EE97B64191702BCF45D90C3580A9F866575B58BBBE583024B6BC95F504292100E93D23520F0C979C49BE63AFA0BDE78589D07927C771F01D4B83A55636E2EB4946EC283A27B2E88AB715438885725FA3E10E92E0777F86F423659197A0FC94A4EAB0B855F03C4FEA217C2F55A7ED4A4A0D063DB1310E4075478F64398A1E170CC47F4BD95C2813CAC257762B3B3244FD19DC4067B495064501BA02E3488D6AF51A3C4A0259E90C61F6BEBC1D0BF954874D5F7553958241B8C557B8DD614C096A0D4C8A22D956FC1437455F017174CEF79B1F034CD29007D839E2DF53C0D8626F9D7ED25F77B2043A001C9F0F0EA0A8D8D488D76616011454E44A705A22A5A293B427917B290218287795D2610785CE4CE108B4041EB9676678D32784187A431B87EB4B1801FDB5B020DE134C1E6052B2266F5EFF5F908247AE82B222FF891E5F8111A4D8273945BD03C4C6453018993B7F6353F4537DE3F27244D4C25F738F75ABE46CD11D77F7FBCA85A5133A9FCEB979A3120D68B927C0C617085CA3C6F3CA404598BCAB5ED48916368BC6454134EEDA3CEE8BC91C09E21A054F8140329CD6C4CF372122CE2111DAE66EC7062030566769307BF7614CDE68CBFBF1768FDE2A44C9F14B22D4EF7812B5035343E4AAB6986F06246B91DB66282082F01519DB917AFB605A962D30C02592F22E64E9B871903A61363FEB8FA21BCA686F8C9BDF48B099DC6EA1DB88538E0EB05F54D8FAD819B72E69CEC126EC8C8510929BE278AD3FA3EAC4C61DE06D8E7146A167F5AFA77131E65B542E0ED2C74039671F6F5F137CDCF029F41D7C3219255BB32CCFB408DF681FBB0BA081B444F4B59E3B752D1ABF35218EEAE66EBA4DB152E9A3EEBBABFFEB32E951C6C151E6823694FCDCA318A9B5F17A0F19720FADB81E16A680C9FF6AB6359425848CDCA903904253E99ABB9503A6C2072F8AA657AD3C6010BB63910502884B79EF52D1F8CA9A58E1F89ECAF97C157807E4D5F71D76CA4494541462EF30CED6885B5101DE7673C66D87F75606ECA56B7C2AAB19ADBD7C65CF412F2BE23A15FC0D74DE8F431734BB600C9992824C27BF2C28AE6902ACD320AA323422A58CFDE9506733F820CA9D901208E5B71712381B2B0E01463E69E405EC40995A5567A98A17C7FE4A0DD92F5F8CDF9F18CAF34E81250E6A6E36A26D58F2A2276FFAB625EFE63A1B1D0433C540CD6C1069F7E8201676C4D3899F81A495EFCD575C79E47BF1FCE02EC32B606A46B824DB96458AA1497077CDB68EA7B72A28100F894D4828A4DE5E295770FEA41174F80806BC382136E01C622BEB93AD4E2CD46B5D55E697BFCC28A7A61960D6E8D8ABF4A4967B3F7069E8A05B0DE2AED6C67553050D11930B56887932B18E910BB3758EDB70FA4DDB0FF8DECACE9867383D004ABFC834142810C99BB16D3366F0A2E65BBF85307838002D1EDF4ADAC26590644A5F3CFEA5CE76020E0C51EE5B21AFC6A22562E0431B46BDB1C38D901F5246F9D4F48921BB9998352FE821D5830E9FA8D7DCE17C8BC29CB5BC8A2F17BA418FE794BDBCDA2B75F297088A9D49CA69EADB87EB6646E2781E295EEEC38605395FE758C283C2A156F6BF0C9E5931D2EE052B20A0BACFAC708168BF0540A1B94C2DC680E246B3EDB6BBDEDB991F349FCCDB167B02A3D8AFF4A9B648A99C6CFFB21115BCB5B0DBB32D90B368DFD6F6FC688EEE6EB7EA11C9332B83B0886EF8A304B71A7376D8899FCA2E25CFC8D70E20FBBB4920D779ED5407FFC3451D1221D02780CF7D329FFD585AB0EB999AB9BDC623BE764F5C109605DBBE74EAB7D34A311412F8C899C37DBDDEF882900C2BDDCE60E1EAC426528B8BBC53CEBFB48A12440BAF4FCC10FBE0A33DA55C5A49C89E86E7B7DABEE256D8DC20FB49F7EBB9C35265D0E9822E4864C48EF0CE357208517EC9C23156F68326D58EAAB85173084AD279AA8109AE90AFC97CD0FFA4426BE7AF14FD74BBBFD70BFB2D739CE115C4416CC444306F1430F1659F189F8D404C3A31721C4FC7E75965FC260788B593825FA61A1FEFA61F2B560788BE645CD57527BFD0C33C57B0C1B3785F3B07A48BF1874C8AB32DB6CD02269AC125A8B4B934D5A034DC747A4939C3767E73BD2530AE2535DDD4028CB634E1614804716935302A2091214357D2D539B6597F03E10C364597D3A581D73A56E9F6CCFC3A5C9FFCD20C9C091B204B1AD2BA0F08C63FB26A7EF21D096220ABFABCF7374C0DEF76A30600ACFB1B83B7795E49A3B2E10EC50008475B5F3DA0420BF27D6BCBE96B325AB946EACC1AE7ABFA431661B94C864C58F1604FDC4BEA6516BBED018D935F2B47278DC5F65333404F8BC9A86202AC8F9229B4BF7F8717FC274742734DDD73F25EADD2427A88FD70602E8BEC4FE713C5BF770C39CDDEABFF870E4F6836DB5FDD40BF7A2CA5BE4A4C7EA4319FD272D773E71C29ABCF432225B77E7DA05E5B7D7B968B186AC3F8296639C176CEDB86E624590CC564DA2742B10FA33A50CCF40AA38F91FE5239B39B4B353DCE89A323058280FC2136464682389418056E83B3CEF19987BB9C55A59A7801578DDBB7FEE06F4AD2BFC0F7F0A5F16C177D61D08FECD6FED32043E3D58DAAFDFAC36BC08901BF2ADD3F1D99A1097E03E2FDCEE3BF929BD029A4FFA06623D7C5820D2A35CEE28B7C26568A97627CBA3C7FC27585AC6BF72A42DD75C8538BDCC9233C39E5F1588F4CD90E9D6E72CA047AD8E018564F63D2D3F235B1BB7BCE6B8E99164A91FE2AEB3475CDA366A3C10D3A9883B2684562C39D836CA5C4F426D6B965937B106B9A1668F3B4C6A2B8AEFB3CD3CB12C51C826501C16FA08ADA1E5B4F2E772F365400E909E52C8EFA35E133DF2516FE3382CEB7FBD89AABCD2C3C257DEF3B45A7DA690D730DFCC2F916BD5C5CBE5EEB7C805A702C00012A94C6087D210BEF1078CA8162B5853195CEBF36201F67A850B30D43DED5559F31DB217B03482E6D6192FCBD10B6C68D6B123C835A48F0C740EEDBD12D05F2986A34D992EEB201992E7E769B31B09DA01F2A37C2B0CBA245039DF223D2EDAEFFBFD68281C5880FB3F1428102C779FB4CF83ABBDA9D083344007255ECB0C523D5F61864CF2776A21FCC59C9588E10A0610CEBA933F143E01E7E8CFA5789741E1A014AD15B565D3EE85E327E7D0F51A6A3B0F3653AE75647D13F9BEDE85B910F53016F41B7CD131302B06D8F04189F4AE1AE93A3B95864523F55767259F7270E4C5011CF99AFCF78F4F627EDF56A4AC7FE767687D5A3679384582759947B101A7AD038F557AF3F6B25690987745FBCDCEBD3F53250CA867E1E3ED8FB927BDC807DEFFD0151E4887CFD67094F25582248D7CC4E91044C49FD6B5E0773127308331AB2F9E69945DA42D0B0F010F0DFE709CE910385314CEAF481808941FA2003904496A62A23ED96807B14EB60BFD99CA6FFF28B2F0B49A14EC65D60B038E24FF566409E0FFDF7BD2B35646A77A82C83AFA027071107EE75EDAECAAF51BE9298A4E22B77AA054BF82CB8F6B72961A73B9B79B8AF7DB4B6FE38E61321CA40A0AD26FEFDB3FBA1B6E35F9767FDD2352A86CC8C38041FB860DF8D93BAB5C4F270E385DF20B77CC2FBC9E77A7A023FBD76AC9EA40F21A1CB03325481C327AA958C1BB3983DEF613C0729C6168A7E2B49D3765FC769B2D2F3A8872D93478E78944869629FF96B5ADC01F0C0006A2BE3C700C34107F91BF93C562971635A8F6268B0703E100C342DC73475468CCB9A873A4E72854D14D089F146E5C375A6E0E6076C69A519D3829FB431B4509BE543002B80442F76F30F05B4CA3FF0C9E24E44843931F53277FB03BF800F487CCDFDDD5EEE6F0CAF3D477D964FB44E00B9934F71F40FF453F06A022D9A2A5A7CA1215ACE7336B0C652EA3CF637EE6EA4740EBC14CEEF0EC1C7F02C152735DCE9F273E1A3BA040345344BE2F12FF1573B207B36C606B58B81F666C66A71E9AE7F65038543B4CE8F6D5B1DD63A38AF8B9E5644F2E42F2F1A353C54BDC575FAD9906102044CE0416EBEE7FB37CB0105EBF3326157A16706429F0EC19413CE3A78F7B286655F6377D0F1B0DAB512824C97BE406A347143EFAB7B9B2AC9EEA5ED2020232DA49F577DEEFBC00051375B8689FC3B3B8D6046A61ABC82FB6A7841AF79729DF30E959F94967C78591BBEBE429AFA2EDBF6079684A725EC50E311EC5D12B102C718E340D8991247941ECFB7753DFFA2107E8BA903838F95327A0A00E9AD793BBFE378409EB4A98CC96B2BA1CBE8279D0DBDB82EBC0C95EB3988E6F4627584E2D80A50825B8253606C7F57B4704117F96A0A9142FE8E4666C6E0CCBA3128F88B8EF4C0642865CF9E4A34FADB25DC7B701ACF41558ADBE795596EB963952031CB48F2519BD7C81C69ABD7EE2999B9FA6A7E4DC3A6E1276CE23DD25FBE5CFDF69ECEAECAAA0B2AA099089075746DC068C7C633BD614ECDBA4F56766C0370E74B97F40148605B673CB6F032C30FBDD34D4E576273369B26B8570D460BD128E0602CD8A59EF6F5109C434A47D88CCC9888F32D97E729E11B7C5699F2C697E4A01D08164AC1E7F91C87DECEAE9460D46E5D618D6BDB354A656BCDD59BDA9E64BC6CDFD941BF49265F1B8F5FBDFACB3C5A77769C7129DB447CC4204F8D5750D325596CA92DCB970389B8795604ACF591F2857A42F10C814963052F06D08AE930AF5D7A6EABADF7D5E82BD080C50E2AABBEA3ABF50184935FC1A9919AB56A7C36665A15C81596E98EB4F62CCB8A8DDFB0B034810359F207DAA4F43121F805B9A3A1D2B532CCB796149C556C9D1BB8B836A1DF285FACA13B760A065560BD1F09EFEB21C32E30BD881C01D890A7C67BD69A947FDCDA89A8C0D7D0DBA8897AF42984F39AC7B10066D84CB4CF2F7345B2630FCE8BC3A507171C577EF06C0E74894A5B74B0D68723DDFB88EBC6822FDF7A38DD634FFCAD185313B3784F92B65964A113878C193769E1887514C9E47D57CC1A996863C1CF35607224FD56ACCCF0F59A63C5A770732C4CA642B4FEC34519221D26CDED82F9728BB639B435E148B6897E5B35757EAD4FFEBECE43F672DA6B1AAAB222763C7282FD4048FE3E0C97BF100087331912A57310451BB124E4532A89D45B041DD1EC026C697BA0CC84041CC1FD51348050A2FBA3372F08457A301388C6B4B6E36AAE94FF40F3F30149141D6D31736D6977D90B183C5BABCD46352D7DC12919A30504AA324981F71279925BA7B7356A323640B5779B10421AD9909AA9FAB2A6B6046B8B6FCFB3D0D9F90DBF411E696D86FBEBBA7B849ACFFB17EC33CA3ADCADE22D99197055536B7B7DB3C33278EF36802A4955E402F22AD7BAEAB09A2005ACC26DF053D2E00A3B880696BC6F73B39D93B4D1DC950542C24156154B7B9F2D1E40E9848E7BE7F5EBDD8BF941C75E7B4F51E5D179A7BAE4E7F95D4B62059BE9737CF8C5FE6067EAB16A18EF0689E46FB972C61A890D1709024E74D66E6B3EFACD37AE289AB3A3FDDE374A13024B2F12615070B5D451CD816EBE73D4947F8B4B6A6DF5FB3A1F4BAEEE3574FB4B25EF54840BF9DBADEF0DE70A03B56D1F8F6E373F303B9F79F8BAE04C69C6CADD34A0EAAF5BF667461919B20F7914D3BBFC9B713ECBFADF7A432DA98DB2CDCD527C57F9FEFF75989583FAF712F4825EDD6B7722CC15E213ED9E2D50E30F92E34CEB876400D4C385C4F150D9A5C9FCFB561F2D72D58E4FEFDDB53AC67FFBCDBE91BB6CAA1AFAD03C230A9FF5137256EE21B97C30F3C44787E5C3FB5C6C793CD896A8F381DAFF083B87E817141C855C607B7A921F8090AEC4D0CB070279B929721A4265767AE9A53EFFF90E7E4A922A568E8BBE2EFCBEA6B44A8EDD9C4F71C7800259A6389424122584EBF22ED9E690B83E96EF98AA994F19CD44ACCA3E9A025EE22595609F0F0D2A82AE74460D47B881F5CF011D8830D01BF393E405A2E3D8BC7829FB82E486127AF0EC7E4A9168D5E0DDE547CF7E2A8679D4B55E65AD7082CEE839852C3F3F4E3281C529761E43113476EF34A41564257FF4860870B99199872A87DB6629A170F0FB4A9B7B0DDEDDA007E8CA977B9ACBB248FAAFD71438BA76B61A0223630F3AF7937BB5ABE99F36A7CA1A416B6CBE8068A5EF7544671E008566BEFF1FE6425D9BE20E6E1CD36ED902FC9FAB0A8F92CA01040A22F4A3159FA2F632F93DAB86F9B2659048DF001563DC50B6C6687A285803C2894E0FBCDD0AA383711EE83FB59807E783D821DBCD0887F6672B68A5C6D8F6282E6779E0D36549A6C593B3F7F0D91FAD7DBC506E04F8402224249869A503CEB6E5231D9D95D8B76F3F47F6A4480A7D8C5257ADED416D2101D4507E1CB42B5600999DFC51D9F455C47AC6B787B1CEF78133B600C5E20572CEEAB803143E6827415C37FF02D553D1E359739B89B968152BDCD0AB2D765C6D5A3E12AFED6D33B4051F7A7D8C1A792AFED0A8FD431F535486D0D5DA2629643692A0AA9E8ACC9B6230FFBEA7E7130809BC247D5C85B5B2A2EFB320E1C4A1254FF77AEB5D9C3A472043675E3D02AA8C26C1D31FF3BE6FAB4FBDE00BD0C73AFD8264EEF7472401AF32A2371265843AB734D317C17425BCFCE3AE125CCC7EBBD5CC81B5A8C5BB18009FCBEF12AE3FF071E38565115DB6D49A0F24A0F510127A80100FBE65780EDFD542BF174729C8BF41B6F42A057115D92F9A6ED3A813615E2D2C31AC3845030D6F3FB7602861C818B40EA3B18444F9148FDA18539F3972F395550FB185E9E259FC036F9A5D46AF583693DF97327AC88E512FE65E42F102BF3791A1DE83DE89855E5ED81688211ED7864F0F4C39B6F2D6A4603134DA4529189158DC41D7B4F2414256D0876BAD26392816A5C5FDFB33A875033B099E37AE5DE50EDABDAEFFA1B0ABAF4C1375C09E3FFC1FEF83BB0EA6C1A50C1B807AA0112E66FBD52FF588DB89C686FD25BA778142D1EF39B0FA4712A2B2C799453F4BE7F5BE224B302306A7EB0BD8A0570CEBEA9DB5D293581B7D1398B5C487BCD6B8209995106B9646413954F97951486E991F7BA9F3119B661C041C90180750509787895F86E70BE053F6F7F65CE39786FF80A6574675F8F03C92BB941055860133306AAC0DBBE0A7545EFBE26DECE81E692144A6686F8E0F575569E5BA8D757018A3CAA69443A6F388B84D3E4CC3DA650B3B1B6021DAB5ECB3112CA0E30B130AEA7AA92720B15A4F99B93F38F6D9B9038956F2EBA41D3FB9F8EBFC94304541A4AA10BBCE7F72CEE29386B535B1482CB1E9C1ABB23F7D111F47F65551A75AC34ED21230C31466D6F9FFC343204257BC366257786226BD35116D8CFC6A0C84542D28035FE879C6C05E0D59CCE83DD5EFEB56F595A06424119A289AAEEFB2FD68031126411C25AC065A2217E7E636C87FC4EEB8A16E63F269E0AA4C7A42A2969C97FCB18E2B72C101024590D8FA54FD00A01066643DCA5974FE87293F99B438F30F3AA2B9F66753EC90B9B62FCEFA5E783B81ACEDC4C9A34AFA382D836A3C2970A99E54346598D29323E3C4594DC2FDDD680BC75E1ED1B15BC1070ABD9E90F33E451ACF46B503F6E4E984EA42A21E5EE81672AC77D1474C9A313945D5804025E7F5336C4D755A4D1994E064308C6A22D98153ABDDDB20CBFD8EEFDBE4E958DD0F7CFA677678FBA2CDD4B90CA65A20C391E84D8F24ECD1AF9E957EF31CA5526837F9C17143B8060F45AEDFE8F7F12F68E977158D66E95E29CD89139F73B4A4B508A41229C559EE772BDCF6F5F44985D645358C034ED8FD1AC5612E784D5FC767551885FCB8044F43971CE0A3CA0A41F8425F60E582D55495B9F91999B7BA0D5C04569FE934F25B599583177F93DE6CF41974BA805526D8B2B8E0387ECE87BB5B50CB4CE4009EE632AA158C9D815EB63CF80296A22DBCA32F1AC240D19BD370FD92F7DFACED73F0E0DE8B2467C1676FDAA5B01FDBBE0A6540D25C8DCB34F0F01338AE380E4E6128EC925ACD8E9474F3DEED7FBBBC2DD0C398B712F2B1B1A4A115BA948E0B16578039CD00C9B49EEC57F789F253DEBA4B5E25AAFEBA87B13BA3DD60CE5269340136CA6388D91FCE6BC7400DE3CD697F8935FE11B7F512EDEF2E41658312883E15304811D44157F7DEEAF5D7D1D9091ED4CFCDE41CC475A01F88D1876A167DED6FD5A197EF61519695E6990EDBB1C787F2A3603AAD47F219F1A8AC2BB855DE08F624A63AA5988711DB27503EDAC30831DF2D70A5737AA700406FF4496159BECFF7F4DB216EB0C28CBAD7563A1ACAE6B8C0426B481925D580F5330AB9749AFF25E774778DC2AC7D7AA3D46D0DE57213548A9AB933E5652B97936BC206F00DFF81A71A8FEF9E63A5E92E1DDCFEC1EC7957002C9CAA06B3770288DA19DF87B7EDBD5F7C882F6FBEBD5CF60905DEB726AA61B02972824732CAA3C9F5BFB884B802D009F798FF838685E927BF0109C8C228D78906DAF6E5931A078C5EC038E0599E2E45D6831DD5EB9D4AD74E9D3727FC62B034859D2EC6D1565CF86EE63B22B5FEAE57A1FF3281BC101FC85F70259D29B1009FF84DDB866796DFF231F126408D24AA3025396945EA5353086785D7B3B4420C0C1FF3EDD52AAACD33138A6E4348A8753111321057BCB806B1746F4867D9C31BCD1F651938D60EF8CCCCA861CA22EF8A58F6DB644146705A1579E25C9B13798479CDE7ABD8730B68AE5D54792F65838D17598DBCA2C9149B6D383FE97E99D445DB295725C4B02EA4FD656F961167AA32DEE3369E4CE43E1269319CD2249665ACEB524AF43707EB6ADE38C1388C15F9AE5FB36FB8ECB88B5DE655B109E67715B5D08C0AFE433EEF347DBEC4D6E5FE8F020B2FE6B4E6F44B5029DB5AFAE5DF5F4F1F01671C050926AFC1929D75CE1C3455885C465893A063BF6849BEE8FCF5DBF7824DC7F3D6C6FFB4C5C1C8F64F8B4DBF43FAEB52909A69FF0C3221FAFBF81FAF3F549A5B2C4EE64CD5C4DA911C50EC233E6979FC7A5A552BCCD8E89493E940D95280AA3949506CBF01182DA36F4B6966123EA09706F295D8D5EBB5F5F890F33AF8317A7D287292D26B6B5643CFC6524466CD226E6B9C018FDBD72B39952481085A9209F9913F1B0A94246FE0A63E789FC8C32568CCA4C8BF2A217054C5B608ECE589459F6D614C1858CB2B252E947CA353644D92F244D53E1192E59347533D7B820D62E7F85FD22DFB088B230F1884515874D08A26356575A55C417546162757EB322138EFF1147142C983B36623ACE6D6D2FD5F62AFF9FCA914940A04A43ADEA82C25AEE2B25424E557821664756965FBB289AA4F8BCE08475EA8B53DD73AC533B5545DDDB7F1A83CB6CE43EE33F79602AA3A4237259689C0AA4121FCAC0E1CD75E0E9BD01CE94BE12CAF3ED3540C13E862A0ADAACF0C84A9FB1E1AC546902257DD5D2DC714D7A65519B3782C85D1A48CB6E300DA9F8F615F13C8DF521D155CA1B2EED20C396A5FD165FD3226574A09DA33722A55656B0343FFEAEE6FC5680D95F4DB0FB8967D9AAFF2299EE5AF5C6CB851720E0052F951DEF0995C9F2CC4BB416BF16D317478F3EA2533D7A7009626CB32A80D8C6FDC0E59463DBA6EF5B596A000A5A37ABD14A46480AEF39A93541AF7294927DA25CCC68BFA1E762F6F8C9EB62995D7A4A95B8FAF1335735B5447155145971A05FD4FF7AB4FF26E1EA973810AFB05E0BD93055879AD5DA2914CB5B5422254618309DB8826CDBC32F5889FA535E1F86F3264E6286C9E91BB9411204DF26A0CA3061B0EBAADA0ED15899735BE740341D1613BA73D019C8B88CB8152A34BAE939C0E78DEC3DA987B1BE765906D884F1DFD99FB64906AD6F66B51CF7F962C8FB794A9D7D519558CB051A2774F6E68F94DF84F7E94298AA225D910298F85D210D3EADBC76AD4EA9CDD527B8DF98B71F7CDF127C5FBEC2F7D755A8CF74C9E1A2F4B704DF47D4C6132DA6727A55E471995C27EB58B767C30068C03C8D38F73C201451BB57ADD2EC287423AB68781F1DDC87C10D48F86C077895C0678CDA59F877E7FCB7D47B438843AB4423FEE38E04901DF6FCEA3C68C65E2DDD65F3712FF9ADA3E1B197DEA5F20D0892A43F0C358DD0BC83565F5C4D61C0B36822D9D4297C5F7E0E8783A1BD0AB24FC6D3F2E527A182549C5874FD1B78582CD8405DECB6F59C72029A25726699C9E69BADFA9ABF218CDF54F5F0827288709098D2565A9F69B950EE5D71774E36C7646A4EC7321124D5D86D465D1808715A25A266838413C7B69976AA510C5097003968C4B0EB8598D4CA5FD213C4E7FC374AE62B5DBBAE6A824F837EDAEACEFF5F0CF49DB853DBA33D3521954C92E176F229D6D8E3998BA96BEE4E83E5E75CDD59941B56BB768B211A8757F497D5F27FC339C1E492D2BF47B59A68B83B37B9E98C7A07B3587E43EFDE87589F2E80E6DCF0ADCC3D1E2AEB1B8A1B87C29A2C58222EBF45F64BD6C06132A47210BDB43AB1CF11AFA7326D0294C688E6C3940BBECC7A4291D40AABE9BBDB7F161C11F536A9060C675E027C465F4362BE00EAC4B32FE548FE02ACDB377E92756A8C0562741A75A2C97484D184E4C62CCA9DBF699AEFAEB0AF91995C7E8B2FE0D67CFE635779A54BB8DB03BECD52C2A4DA317CF60B22AC0C21E0D7B40309C260646E8EF82CCEADF6C403A84BA88FD0A08A19A32FE529A888E959CCA2171830CFBBD660593ECEF2C80266433CBA7A3D7955B7726532488D9B765857E62110B9872F1238EF4EDE1BEBFBE444D5C5ABBFDB3B251EEECB59C923063850EA73EAF2BDC28C4C257F2E2203848A7FF643780CAD83D8244F49B3FDA7733E947E242B5DF71BEA6A6219808E2BE607C5D768F98B273ABC99D780042883149025DE8DD781668564930F5FB367A7308FABC77C35E792F4A1C7AC3AC94324F60E4BBCDA81DB0026C00810826CE6131950AC0E9F22D6F591BF50ED28EA197A3FC4C5A8D1593E25DFF1A598CEAB583A8E2632A5F29A0177AB162C3FE04756108729577AB8FBF78F82C94BBD72FFD68DD8AAD0D0D331FC1989AFB750271BE1197CDEB82D58C508598D82948EC26D1061CA0178DCF87DF284E62D48059AD0641EC365F6FCE3574BE57DD66774DA38A3B8317D0464FAB43611DF268EC81D284894776D4749363A69B118F78D5AA5DF15D83A1822E5554AE65B55A959E2CD3E2BA9B77008B476BF0B747D91C762892EF2F7B702DD5F38571EF83E586A0DC55364C2BCDCDD4F73B42C513BAC412766DA6F8E32533595CA73EF934EBDDD9F9AF03744A641D7DBA432C7A45EA883E66126C2E43F5D38FA5B857156A0130581C96677141A9F74F1D8F5D5F58EB956D3ED476B02989D0DC7FE04099A3326F4CB584AAEB266EFE2B4EAFCC8240AFF337DFA1CAD9B2AD3536A8FA274957BD3DB419BD268007B3F42F2C96FAAB5E4501E242B90336B1BAC6D22D25BF95B8F802393B8B6C46B5297A1A054B8E3AC5EE4E41268BA55787C4D0C21171F8D36955888A8C473E783217CB33519323933785D589B52FA90915363E76A0DC45BD45278A07A071D8CC39E41D8B1DC3DA229BAA5BA3C5E702BF7B738A72BC0FBC53865407AD7D9672201E40EAC3BBFC62A95110570BE8D5DA5288C29313AD726BC74EB8AC1C4380D4479D7BF99BD6054B6CB692AAC9ED68EB6D898F781DE8FB4AACE92763F9F1DA5519318518B52801EA42BEC902AC4A8D8383B31C46C722E44CAA7000520D719A855A573DD1684564030665FFC056F9470B760A7620229AC94300789F8D17CEA9C2C9726217385C9AA85E9BEE4516B4F914B1686EFD29B3630C7CA61AA9F5C8C578F551BA09A0FC2ADA5936BBC0230C51FC35D1BBC5C5DB675CFBE609F352FA3102E394333A980845F50BF138D138F56776B502DCCEC3C306457A80D5A23150341E25C175BC6DEF61642C3490617D8EC29CEE0D53BCD38BA5122B26B856D32D46A792763EB0AD2CE5464DFECC4A51293511FADBC53923BCA03D144B4301B8171F3B48255C9DEFF2743E6509F741A23174B7BCB8A429FC80ADBC3472902E3E17C787903235F9BD6BFB5EF7AD6E1CAD8AD6DCA00477A9C2FDB9DE005DD9487CED2F319011A6BF1A928129BCD239F9F04E094DBE5A508DB5CD1EE6536CEE128EB1F42B2FBB0AE54A925064B92605357E9E2188BF48D605DB76FD7A405C995234787C23F513066EDD18BC468A0F7D9607CAC8722043FE9D6C4FEB894A19EDE90706163E22063F4BA1C0803162BC47B855938A45CF8F0D4215958B07B98B41AAB5259998FB61CF5659294CC938BAE3BB8DB779A77FB6A6AE03B7DAA0F34EFBBDDE15C72BB4205F2A8ECD6C4C4211D0326E2D44CB1CB63BDAB1F74FEEB7719D8A25C2768CF837C70E4604DC1E6D14AB90C47401074E3E7B9A1846A2EDAF0A8F161D11A7F3BF0DE00FDE7E25F5E75C7157D8C9CA3CBD6659F512E73580DFE4C9400D28D11A9AC93317E978FFB5F4689DE50534CEDB21D96D047FA4BCAE9D30C591473FD230AAFB73C6799215E4C044A4F9510B1EE494E64E724A6ED903D93911F99B230825169BDFE57DE5B08418634547982D6F428093A9648879F2EF5A312C4F611C1B39D9AE503DD3250DF72A8DB5C16D675CCF4AA352536C9BCD7A30DAC6011925254A164912172B966251A28E56F8976D6E4D46733B9AA8533C6039D5A4F9312E358168F1636B7B548479EB56588A6A3DF120E2352367BBFE9F6A3384C9B4E1081C3E2D21A5F910E70F5606BC80686AC46757479D31E9DE3B08FA90A46B05CC80147A3BA406F5E7EEDBADCBFB9D2025743F0D496151C737D5BCDA3E03045270AACD61881FEE0E1F5D83F667FD3A4A3FF079382F19E17C0FCC18BAB048B734197F02050689CA88D9DFD5174629FAE25F00C840A3893E1C71A38BC9A91ED709C346DB051C346865EA919D7AAEA310848610234BE1D54723EB55C46B6B4197E9B85835558A190D67603CD60F271D52398A951AC91182EC5B2F35CBC41A0E8014C99372DEE21B362E1D89E7991EF82CFB3BF47D2E83D4AAFA9112112DC7A9D19C114C9DCFA54D0A8C023A24950D0FA9C9414B567BE51AB781400EC91A0C4818B477A2A7FCD2FD6522243CB6E767A3862DB977A2EC09211BB01BC27B65FC38F0F4B88CE52FCBC6659E662CCF525DC3F0F9C64664DC7B4D65E5288F76FCC13A52C370585D28DD1FB1627FD4681D8B886BBCA01DFDC6E41574B763CD7718B82D9CAEC05E01BACA487BED8F00EFA5CC7CDC81B442FF6B1B8008A5C948514A6CC6C21E27901A7DBA456DFFFE92CD4C64F2ED31171728C87F90E0E1719D9288D3C20E85297B5C9849C27E4D1781161FC838412B32FDFAEF0812D54BD4DB05C96EF0ADC998B6BD0896C98F283C2D06E1D455D2489E52019913883AB3858F9FA3AD34228A61C84C1EC46C81F2A99779FD8A46D41BBF0CE9718286392B3A78241902F0F18FE6606672E02F0A53CCCC331521D51F4894901CD11770F081F29FA5122C81EB69258BE9C7C331820DF2470B031A370A3EDA34E2F6E33FBDF508D65F8CD39E956D1373EF47391C4DDAD1A5FD8A3D945DF312BA3693FBCB61F324EB773ADB61F851D675302553982EAA71564EB651914A0820A4D0AEB074CC4161D1DF0F0290EFF22F7ED04181F585232468D9D3751C6771FA0D2215779758290B78047DA4089CC5760847C56A8A1858707E2DE2880310ABDD13A0E7E8AC7F844DD90FD5FE463257A53CE0C5821535D09B97780F5D4687313747774FB923E29F1AC5032749875D6AA11ABF8C58579CBF1CDD5969D7F7497FE5EDE990D96E27C9545E2161807E7F27CA93FFAA29541ED4D07153589D4595F9B3AFA85AC8FC1EDC23E28129CAC134575F595F92A1154F0EF3F9A27505EE3274E28B82456BE3B98D77E3928D88B80F97F8395F5EC4F6A807220517E14ACCA5EF865BA88E1DB3081CCD81FAE932256102A845CB171BC08C71BA5601DC06585776452D8BDC51D497206BC9605382130FF15460268293ADC69BB4B335D8987323E4401B6834B638E9ABE5F8E52007683B3CC5C36452C50685E03D9FDA56FB04132DB46A608D5485D2FFE45054FA5CBF052E328567702E93DD5B4507D59A77BEC2706E6ED12B54CDC21A7A5635CA0FC436EBDC4C265E16F4C3132AF8AFC183F270301DA8755AF1CFB41100360BC30DDDE0F86AF290A6ABA93D12CDF0B467DA398E570DBFF20A7A7FDB216D54F5AE9695EA5D204A3D3937540B17C6A49294B9F408B838ED59CA56B3E0DAC3C383CD18B3C5A1FB76AFF0A8207A493248A085EF18D8D232479502A5C8E8775E01A0C56C3A7E3BBDFB817B679E7AB9C4025940F30C34C426C092AD5B352D4BB3060F186FE42C0193FC731503FB5798A195C4E1AEBA53E22C89107E11E5E5AF2CA065DE5706FBB303FFEDFA9F1EA16E2DDAE4C4ACD729466F45A7A628E90B566AEA6CC01D46E6627E10A74604DA9EBF5C48C3D01F7E0291C17FFE8870459DCD114ED4C0A7EAEBAEF6BE8AC3B526055BB66A63169FF1DD7BDE39812C7B9FC94D67EFFEF35D8B3E974C0CAEFE7472DEB72BB56D372888B907FA41EE0F1F1F2CFC7C44530C002BF1B29FB76FF299CCC7B321546DBB09DEECB88C9E35E6CAE4C52B8375DBF38C30F473A66952AA22FC1C46016DF1B40CC7AF6C68148C662770A95DA8C033A6CC429465BDFE519373B9EE8C6365CC36FCDE4179C06BB8318AF11BAA0AD0F4CE4A3BDBD49C1475A374005070FFE4FA1C45272A934CFB8BB6124C2C46583306CF15D9619C3132BBF01B63C2459CE3020E690110E5DDCF0CBE966ED84963B41C1B6F2D5717AA0AD38C77AFF5A6E59AAF27C0AD0E63452ABE646C16B5EFF6844EE2869093FD59898E31C122B94C8B86710AF1190069B56D1C1FE7D884331FB664E9614C38C11CA38BD9844C5F7335A5B7B3FF87E0BCEDFD883D7BC3235400818448341EC0C9A2F24EC871F717E0A2B39F8D4BFCF5A579B8495F600EB39BBDE706480F7F285943FD9D236D60D190DC50256F7C8BAF3BAA14E745E0AFF090A9864F2043E48E50F439F17DCD92DC0C988BEB7EE04B910B9BA52B99B7601694DCA10D1F91A339FA128EEE098CCBBA29E9E9E837EC3F86B19CAC8FF34815731EDC626B67524AE3F6FAA1B52F265114FB10E86F6AC6853416013C59CA484CD15BB028238F14C17702F9C019A34EE862471F59766D1DA202922068F38844EEF79821555C4133BBFF8170DC2659727AAB83ED4AB37F45D459E3E68FDA8243A88F9FA32C967C31AD54B7E61FE80D6BB04998BF95914CA4ACCC318D16022AF9620F1714F0E29C6C540424F991702A8889D26D630F183EB81264755BB4E030BD553B6293DCF5BFD76915156354E8339815416D3A0BEBF7FBECD0D614E32640F969825EF0DBCC2A10741FEC5D9C7200C8E296DB8D50A374504D3B245FCB7E1B716E433F15259539910BC4D84F99D7CD3507A087BCE0FAD295ECAD07D73D3770B17F8FE6C3C061700CBC4B5E0C4B5E00A17BE4883A2D224125085F9E3A47FA8BC291ABE4EEF5DBB318B5A579CF208D36672F8818F7EBFEEDCFDED4D3BFE9E122ED6BB0BF1CE6120273EBEBB1A49D6F93E9362BD5EA57C7F29E7B38A065AD582D062397E5B1574394E50011E5C20DA9C47373AF1D89556D3CBAF93C55CCE76A7C6703BE54AC83FFA6B93236E5F5B6A07C157BCE8F2DCB9BC774341CC5864835183AFFDF1BC6C2A8E5A4B6FA940A073813B871145AAE7CE05DAF80798723949BF3F8C3BF39531DCA1766FEB79767EFCC3E1AF6EE0404B7937034A5234BFABCDFC2253DA970F02ABC485841F46A50E7F60F59358DAF3C6B7726AF53B2EF628ADE0DB93E9B64E58DDD4B46A5382C46B3456C64EC3AF37F09C0B2F6D232D2EFBC0CA1F59FCDABB12C28BE83EBA9B58115DABA5609C6350193045920F0311F3CDEF12AD799CAACBB6ACF8C9847341A4F825B9F5A265B9955581C626063F68EA6288D7537B4CC5E706A62931125849E4B1F3FCBE22FE1EADD83DB0109C3B47EBE66D1B2F392D1B7252BB46177EEEDB6F64E9DC340DD6E125C15D699F3A81D0E79B02A864985616C1A06131B10D88E0324F67E5FBDA05A1C8F7A022C1677FDBD1FD74203E66B5B0E0503018CD9E0A7EA494355E14C7F99A3602471652ADC9D7245A101F6029159248453893AD86B3DCED04A2477B62B3AC17EE88B5A76BFF0A1DA66BE84EF11A7F244D33C3EBAB6AE8C61EEFA8C2E934AAF1771FDD88547A6C5FB06011F09A37BABF83BF51EB7452ADEC12DA6A737DC0612CC51329C982FC41F15BFFDAF3C550902E03E079A82C107F7BBC4ACD3854C0EC78BEACFAB3CB9378740058BA9EBC3D1213242A9907E76498799590A69E3338B4A6D93317938FA14D3A9C61F0CC3ECA0F9DD7AC708F3B002160414BD422699B88A27D68F076E1885AE8A2B696D104B26F8BD8D7DD934CD454B40C7278730056BB224A3057C5ED0A0F799C589957014BA6628ECCF3FFA55FE3C6C42A3D9861B7A89524E37BE0E02158112B819E27A435699DC592F0529148170F23D565036388F16E739A62763BFF521B0EFFAA2A6A98AE28695F51122EF267CDC3317602E1ED22E7554D6C832B21F10CF02F6A32246066249732B815E975B40422FF7AF1A539F06E0BE0F8593E453D97CFF50F5922D5BF12E5A6D2350D8009A2EF26B46ADCC7E20D2D31B478B43ED8DB539B6B4DDEA9822BADE1C4676FBF62700E22DA6F25B8BEFFBA0524E248E10AA0CF04805FDB9AE8A55C81B82E62600536F2F8369988E3BB938323492B67CDC41F23CDFBDCA55B03B3B6BD3784F03A87366FAD67B014D0723CEDE34CAB7E3907B08B3AF4AF64276F831CBFDAD2497E0FE564204F7F6EC2A7D93CF52900C3691A1FC83E3929520386846C7D7DD0CD5EA5B090EFDD7D949260523C16996A01FC2A618C4F9A59517F6CDD7544D96A10FC75815649507AE9D425C37AE848056AB5476CF87B378EB6F6DA83969689453E8566402260195398FFBF2BD6D4BCEAABD9015EE7FE7B07A7B7329E1851C46EF4D320681181D4BC90173D9A73AB89CFF6D9EAC84FD2C4CC16CEF4A6C395743BDC3AF866B2D645E4CEA6E387CDE2DC2266AFAE38E4CE26594D31307795AD6CCCD51DC055A7D2323A8153086C654B998E08AB7A3903724DEE525D281E421421F3B9C342DF600B9E802C7ABD0F9933425BFE3A2DA51A8793A0DC0B75DD8D94EB7DA82C27A62001307B386C4B0917C6435360066BA1A26919EEF6D2B402F4D6D7134DFF952A1D5311332801B95BFAAAB4F7D4C845F7D8ED7A0D23541B75033C6FFB421EFDCD18FBBA2809AE29FCDCFB7CAE4576C7FFB0EEEBA281214F4656F1B11221B8084D44920FBF3675D8F60102E554317BD3AF970EB95CD317F5019182932C30F5710CE4CDB3645DD5B97E35EA388559D70788A7B6447518BCA2741BB5284BFBE226CB1D3D1545277E6BD9E113B64D9A86329549F64A8F79902E6386E0A121B781A5C7EBEA77A54F426D5DB64633AF4B4EFD86576B403A654B783A3EC4A4466A258F6846F38B4C1F1EE0F8B52083786187308FC9FC0591B5D6AE2808803435AD7A446F004F71EEA0D0C1EC2D1A00028E0B147BF717C6420B6DC3AE78835BF29CA5D9C55521FE095FB53C8B0C8E87F0C6A0CB047EEA06A679DB11BBE6C1EABECC7B04F816A921AB7CB576A8608081E5B3CC7E0128F7FE191636E01CC07ADD11682F8782CDD2361A1423FF0BE2E33133C0E73B0990A8D92C10144504760A48BFECC878BA6108C7F9CF9DF297C0F0826FC52779188E1F36E8A89078821D5C0D35A5E71EA55EE2697E975D5616EF549711C0E34D30F30EA0D15D7AFF2E8AC03795BE1323A7C1715726DB5CFCDEA48601C003E5DAA9CDC33B2B825360B9788F23CBD98F1A46719D980E31ABC1BE2D3D433394C005E7431FEE102CD1565C62046C84DF5BAB47C38181773CC7313D8A6C358E277265DF16CB81B69CC54DB61EFA2ECACC2C3A4427675727DCD4FBA09BED1E721FDDF89F945F4E2FDCAF8B9A4B49A4A1393194F8DF63F1644981221FE60F0FCD6B53DFD6B11B67C8AC7AA83C96463DCB52E51CE46B27F12C30E2F0426C639B4E57EAB6133B5FE17AF732D50014B28D0E263B7B8D6FC67B588E49CC10C4D7696A76762A73D6C80C864756668890DFE3B9D7EAF87E16626930C39EBF1C1D3692F36859A81891674639321CA3CEB112A05BC3FD7D5252A4E2F55AD6E0F78A0C08ABCC67F3C5F2BB78A6F2D673A4CF4FAAFD5BC30B86D14E3183E51495DEBAB34DBC6903E750F3255648561284A079A667E00E706954998FCA9A35E1E1BBF9F50F4891BAD733941F0F70924CF467C0AD3D49AAD7E298C17B45EF934963B4804272822C92240A17CE8C115FCA3F6F5ABEC8EB94E41DB670A843DF0BF6326C642CD12FCA23393C9C027187DC1977A511 diff --git a/tests/KATs/sig/picnic2_L5_FS.kat b/tests/KATs/sig/picnic2_L5_FS.kat index f7e2639a9..7f6cbc457 100644 --- a/tests/KATs/sig/picnic2_L5_FS.kat +++ b/tests/KATs/sig/picnic2_L5_FS.kat @@ -1,8 +1,10 @@ +# picnic2l5fs + count = 0 seed = 061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1 mlen = 33 msg = D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8 pk = 09498A8AC9D2F9F39574AF9F1D6C57900369CE5B542C7E53F1014540042E162B3C8626ED79D451140800E03B59B956F8210E556067407D13DC90FA9E8B872BFB8F sk = 097C9935A0B07694AA0C6D10E4DB6B1ADD2FD81A25CCB148032DCD739936737F2D498A8AC9D2F9F39574AF9F1D6C57900369CE5B542C7E53F1014540042E162B3C8626ED79D451140800E03B59B956F8210E556067407D13DC90FA9E8B872BFB8F -smlen = 45404 -sm = 37B10000D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC86D007E021A01850052023D009300970121003700C10051013F00F80016002400A40230009F010D0150026700F1024F00C8025201EE01EE023500AB01860131020B02CF00A300BF012501FF0141003401E500B7018A00E00013001700C2028F0071000E012400020027001000340013003B003E001F00390029003F0008001F00310014001E002B001A0003000B0015003F000A0017000F002F002300180007000D0019001000200036001D003F0009000C001D0032003A000B00310001003900330015002C001900240C36882645E624DB471BFBB1CA6BD900F057079C4CB20AC5DF683AE40047FD457F4A71599A85DB10D4AA4C9F0BADA2B09C207B6B9B26332905CC2C4FAEDF376D00103DE402FCD15DF82EE213203E611E9CC1AF9C7230B1BF07AE9A1D2B998AF0C8F15BB640B7B0C9CC7C6056B6A718F22EE43F8430C0721A00C01376EA71C5003B3EE0477EAAEF06E1BFCD60401B6F6EAD6B7AE41F4E701C660A010E957DF07491A582F2D69092CF9A4BDEB5BA354B999149E69E4B7BA79F9B3B42720AF58D3688317C9A9099B7800970C2FFCFBEAE53C474717E291BA8A9C748F590C1F6E6F1E8D040681ED7152CC78BF6549FAD45EB4EA5B0E339CBFE7F9521A5F5B82E6462CB0DB4361E7ACF877EFD6A32328BDC6D46681AF03D36A202278B83148E9B712A0052F189E9A7052B22CD52820AF583EAA098421563C5A956AF044FFA72DE93469D191ECD55A5E9A73EE983B075061F6C6EBCEE1FBB3205AEE5338D449CC43B21BAD553406D939805D880872DCDF8F280F0BE3608D2DB76CE7D61C32052CB1CC6FD5AB7BEA4874CF8EBB07B4FBA809328BD999EA6215F189504B34F9233BF4BEEA6B0EB1CB77675919EC3CDDE1AE3928A2C19F28895207678BCB2A645E906A8CDB62C2411BF562170780AED99ABA71714423769E42A5DB0D95B2E59AAD7D1AE3AF47C42790A013BE052FF1D42C6A936BB3D54CF67D7F375C21B29A3C5E906A75EADBE812CECF282D94172B487F76336D3E3AD904437516493B13592F5619E49B67F8ECF86B5B34F48AE2BA9518F82095CF784D4AC3A655E484DD64A01EC57A656A78956F85602A648E9C83C84E6A7F7B04891601963283E70877618D2BC81E5B13747191EC12D790CECAA5F7431687BCA250AA216F34D7F4729DE7DEBBFDEBE93E00DC355FFE55DD213F56ACB21DB7B8B0F5A554FB10AB2CE2C1E9540DD4E202A118D5C8463E0C08DE25973DA0F99F5E9011B01ED480F8961A3A44ED850CC1C46674BE7AB594DB0735CD44E52762B41A208D38F2E515A4CFCB5163CD4C70B24C064135F037CF382A58F97238E40AAA30FEA0A2419EC3D57A012BC362152EF4C0DA0FDC517A96DC8C602D7733F7D5822AD4668B043AC91107419651DA5AD0F1C0E7401A5A2EBD8086E0441571EE5300760460355C56F194C5A42BC71089D931F0FBF9D6439B56A7D712E201FEFA42F19CB53A6812234B0C5CA12BD831BF261FBB677B4606A9E605EB86B374913808D87D569C514997C673B3BA4FE20A69CBCA15CA9581AD79387343FF8B2714072C868A43C7192FF2E3AB0BF7526A805AEB4FAE2EFD6963BDD0E4468F58383667BD28C5C7801399F1ED88A04BE21F58A5B665B32139F1ED96CF2D858EE4A1B3528B47C5D465B76855A4039367EAF18B676A4E7E30DECB84A727F9ACED815FAC35C5CCBB504CF9338CED82B33486075B0391A8C3E480D006D5D2409E9E28DE5586FD90CA4968BDD13B25F6F037229AAA6D2CC5BA65F6760F9C0CD7A903C36DCB1D98764799F7C2B872942E0024B1600CF4A80F407135650010B925A516A889C204919BBA34D8EFBBEBD08D693C9F2E9C20A1DF9D98A604DBCE01D93FBD9BBF1A61434293313A651D765B83C41E6032F2BA4626FB03072829EFFC6E817B2D75589EE0FBB26ED9371662D3DF825465667AE51030108BE4AC742CA34565F853E4BB99D052B4C8B0D5E99C21DCF4F22D342DD7D5B7303822176A9D3CFE003ABE428102F5D8F2C8901E1A8B2CB8E3AB7A187E681FEA4CC54D9D881325FA625C3879C9AD071EB7B4A9C1C0CA2AA3CF4CC90F89FAEF00405C467B9F3C4C2D78B22F5D29F8228BCD060CF31D38F4378B7315BAA987E2FBDD027B453A5D6EA3C4DFC2124B847A9C725363F493A295F2E8D1A8374B49033F10DDA9BE671317FBCCAD3BD4F690C8067B3F931F5E884E399FC01BB735F72F476EC2C11B0EA52AFAF9BEFAAAF55530A9CD10A62E5FC75CF1DB6D58D5D8EE59D650C03B2510985EEDBA2186E6A584025A8A98A5065774730B38A99ED81928A01732F07A41807EA61A3EBAE400BB098A352A151B0F3F550BC31CEA22A2EFFF9B506685E9C9389BD94A1FA598FCA36C0DAC1BB8FEDD158315AE6EAA8A816D9E1CAE998FFC3B08F521C2D946CAE6C162D0CB20D47204E1387BB36B7AE6855782BCD3DFFF70D91534B4E6A975AFD498F23B7DFC1A578FF72A5041F35D924BA8B86BC74929582974B05DA90D243D1A31220384C65C700458217AF2A3DA3CFBA49166C6B272220D0AA86F0CAA5DBA7A8C34C285180057C7DC8BEC276C21BDF5A97AA760274E266FE51617BCB38AB577002076582F2E1EFFBB654317F7BB91E9E01A7AA7F11A13875844A4DDF67E401B1E2C14A3334888BE773769316F27EE8782638A6CAACEB30293DD1ED69F7F2ECD3325BF3134E2EEB89E3362549121DE78D89687F342902581FD11FB3B1FEC7A5685CB6E021367DF7E56EE675826B14E19F65EF07AFC77C09BDDCE3DB5334D145759A7FAD01F0DBF898873F3C86DC96DF3A55CC5761125E0185FDABEA022972B02DF2C6FC71521D637803B2BD049930A5D6A08BBE433A229A1DAD66EE87E5DBE2D886BD25A2C4784B593A65129779BBBE59EA12B98EE24738514C00C74BFA79AF710D0D37D3A6A32B15D13209464BF91482F85585933A1ADF4E544E4B97A60D4E0F25640CE568436B77C689CB8F3DF245B518A7D715EEC908CB05C0673D1AA8160893C30EBD431888A914AABA1F54971484F17F12CA5F3D85971E0EE3CB02D34582772B2290668D1849EEB085835590DE1FE36BA755E368993CF86C4A330DCEFB66CFB1907E313ED8763E144FEE7EF7586F246A4D8B2E8183C5C445EADE3C2E3AEB7DBD715C61AA0F3610E49EB080CA5755C92D4B010061A8936B7A2895770211E7E601CB9D3C5FD591B604C9F0F34471698C04DC2AE7AF89D6FBA96F7AFBE8336E706F5F0722498343E5D43AC00070B1530873AA2CFFB25CCE604EBA6ADE6713BE9257A08D81541E9D5A82FF85A64A1E7C49D4C146C0539C430A1E46BED571B88FD8186F765DAFD86E00543C4AB89C66B623B3388B77B55FF9255928AB891D0098F5308638967E5CEFB911EFCBDF5BE9CB429C6B7D52F5450D6AF4362766B6333E7592528A0D9BE08EA60A14C5138362E852C9F04272FF3180C96D961164864B721840291C9854BAE2073E9088A03061F92094E6FE974BBE98288A5BBF3C931C93812B44A01CB8CD766394AAFE2AAAF4FF7A682692F646092900B164B3A2365F7CAEC9332B433FDFE5128C1AA2F5FA88F41DA5189C3D787AA1E2CB14CA9CD5B0C35486492271855052B7595BB96D0EA7A38D79B12CF91C4C6BF7453764748E1CDABC371C55126AD54A73722553390A862C70106425A0953B9D64534CB3522071ECB6B68E9A631B2D291B30C9530318BDFFA5252C36A7A5679CB94D83B75BF7B12959372EA8683C280D5F1CD04EB270EEB93FC3DBDD4C330D78EB27FBD40DB4CCE8150DF0F1AE73E632DA51A0C3D6619E6AC02E81C9F5BD4DEC07652A3BBCC0525A0B673046D5FC9E1976CCA3092C460A9BBB9BB38D9B3F761340826AD2346E506E19E2394CCB1594C3CEB2C5499E12F00D3E8BB353FBC31824BE773867D82ABBF150F7C61F14C86F3689E97A5C353B960CBADE6C3C266640EE1A3BD8D75CFBFF1700A6D38C404B0819B6F0770142D00BD727860A3C58458E8DCEFD245D5CBE1C98AF2D3A684B304770E65BA180E8C7809959912CFEC124DD6172D2F2BA821E85C2DE1CF610A18470D28D4D3C5B2370E1C0C19B8319CFE336F3B88A480AC245660A0DE209B4FAA47079CD646802C610169279977A79C7D579691BAFBE214DA68572FFD593F0A3B602479EEBA3D7BF64EE8A1EFBB8D4166982B51268C5D1DECFB002A11A9ACB707E7566423659212C4B4311065F2799DFF6A67421077C4D346FBE75740B7FBEC738CBD7670D9DBE77AEF83AE6A0008099B1FDE7C39CE81C6EA009EBD376CA51824AF45502ACCA3B5705AED0AB30FD4BB2C90C07FAC6598C99FA17617D40CCC82AA96F2BD6261CFED08E8CBEED032F64170913D98067FF03EF00338657537D182B4F9FADF303D277572B0000475C53D129D1089E5E9D7239051480700A7F7684B2BEF2936B85D263BAECDB70A9CA2029BE17EBBA5FE4010E9072B578038B063BD07450A27AF89B1901159C92BE8BC677DCBF4B6E6F7FBBBCABA5CF7543CFF54C4721DD2A305AFC0E1B6871436633B755BBEBFF081E7593F2A102F8F4C7A3FE8AE93FBA7331593C981C8CA3C1DB3A3F287D79C7A2EA8197A93A061221FA3A7F2C36517D3487A18BCA33C55D16EE524BC0BAAFE659D166DBC045799070B9B7C164E1947C8C080F3E2DF8950DEBDC7EFC994C78B21761A7FA5C5535AB1C3767F348AD8C0B26F3556F35392008D365A74549F09A1F74C5187D0ED35DC2494887517D22D78652170DF25CC067F50E9E45D2A1B989AD1615FBAC33ADC0CB0359BD3D375997C95C07B614C1275C7F427E81229CC102F72DF6DB2D46900EDD51E400041C2F81808C10FE7F387DB27998BDB630DE9B475FC8C14BFDBC0A839BC0F7FE5A9DB7E272E3B5BBA9A40A74D39185243A566BD7A88B604BD92D45014CEDA42159B970CE71BF82C79C618C84FA6E64141583374C9437C3EE68C3017D8998768C38C17A09F1E1FF6E8EFFFE811E77ED1299AE3EF27ECA548063BE2AA6C5A7462D69FED452946D02C5CED5CBEA533E259B0C67F7F0E77868F831FAE01AC005EC530EC1C63365CE282CA796CCBFFECAF4101133FDCD77DE10AE83C3077AE265A90B91974DD16DC72929D425DFC91F225CEA22F865E907280E5D338D3E556BCCE70BEAF59A2AB1B0A59608F283CBE932EE3C3E7FF0D3F0472B3AA253CBE52AD78431E012CA6976239F77D3072B1417BB0B5362C4550D04032C5E208BC26BC40176344EA4249A029D785825FFAD7BF3B68AB057E30DDDD5C2A0934AD394AA2156E3C1A28AB902C6402D8C4E9CE6F9999307541944AA5EDE64EECFA7FFC14C8B2773EE097204A7079418554C2655D68E37E87717268F049E509ABA4C86171D1D0AC161DB38CFBBF1475E70E04140416D75B96BBE2832E4FC42A15067D0C2725772E6BA37A234EBEAD9DD975F1B51F63113E0010ABBB12F9205DFBDF05D49EBAE53682AEFB0A1D0F6904D67DA7DC8F637DF7E3414EDDA5DFA521D91A322C8364F57E58CCC5AE6699A68E27DD6C419F4C2B94A084893C0226C825164EC1133F48C05FF1C93FCEE1C4BD77B62C842E8692E9C0EFBE8AB8CE708EDE860D3E7ED64FFC8E06ABF77132E957D7513ECB6A053024406B16016B495899BACFF27CC8B8EDB8614A80EF148D31D8A6112B99363E06F38FC23EE399B91D4632A529C21F5C36D94F87D97424BB94195DD4906AA0AE0B3944F4DC86A94C694C2D531B49F548128AC5E05E496204FBD72714597FBF93EFB97E03F98014AC7E4093D024935EA31945BA44CCF6A450AFDB9DE5BDE995C812CAEB14AFB78B7ED7CBF95407E73C7EC2CBEBE03DE2A73666791B5CECD1051FD2F44978B088C2A1F401B72DECA77962FFCF92FD0541E42CEA77BF552B054640FBD915265BA9D50AD7A16EECDDE2AC09BC3108275529F8C72EABD8054CD2456B84A6A4E7F67D2D51DF0C33EE7BBB00B7AAFB8341E7D980F94F740BF81415B633E31AB6FFF4141ABF466B0DA27E45337D2AC473845F0F0A42E0DCF172354E9A9E4EB647C23E5280ABA10F1641D7E8B04ED5A8BD6DC821B99097263DFFC13947488F712E47D49BF76BC944928EFD726585A7D9A426E1B763C63C8BEA1F53A793421E50E4612D19DB96093CC1E2618004440660267B3328ED13DE705B55F1B2A54F88140DB5EFB4445DA7422F3D9553A3D6C3B4ECE7B41386367ADF37712F85DEABAD0D411CA932E51294CED82F638A4C72343FE9608470979D921EC34DA85D539D24D5B7AA63825C73C1B8DF2DC558D998C74851376343550816246BC7DFA245FF0C551DDFF23612C49F83DC6FA093E547A540D6D209B5529575C19C47A3606E6B557E10F90D96E6AA1C66420D864942A877E0BA4FE0CAFC892418E1751E44712B8C6EA9B8524C4DCB86A69A3D84BD7C1CB9D672E8D9EBB101A949C5D16462891D7E92CB9EF4B84D927E4C583D160B56DA64EFD818A41318FD4B4D077504D79EC1987BCEA20CAEA504DE5B0DD879F628965804E08A9AD5432811A1DBF5AD40110B3C9AD1B7C43B98394A616A39872839F7F79CD84E84436D498CB278E6F737487DD8DB8B021C9A3304A9C791C5ADF66124A4724D09A0D4F162876C84D3DE0D004179BA322C7A9EC1167D6F890C39507893DD9491AA26B1D9CEFD86BDDC8015260630A1F94B10EED260C69EE1B6AF9F9BD5A9B444424E9F5326FAD50073AC06640CCAF8ECBFEF1AF47FBBC6F90012170C342EB482D34D43FC359571B7409FA968A4724DBF3EBC8EA256B9ECDFA19641C9CBAF70A892354DC526170682A92320902388AA18CD0A2E04F9188AEA83944E3733976DD9F368F0A0CD9278F0C6A4B9E5414C79D7F3DBA355895CC0AB88148DDE0CD42B461315696F278C43E065EC6AD7F2CC01F79AC4D35BB156395CC4D5DEDE662B9212F5558CB2FBF047B12B21E122E977BD8F9B0B319ADB64516190E7E33D26CCFAAD3B718FB50EC7C60AA7216BD2F1D773C14A32761ED2CBCA13C75C6145D775295986A7F277D8A102987E5ED46A48E6093A959D5AC103CF06FCBEF2A8B1CFF5D418189E2E344E5A0EC875D56C2F0337C93106E3C588FA404C88185BDDF4F040822807D4B72286821FBD5DD6F3BE6622602C107A958D64291405037781DF680A3CA897EF529F2688513EC94C3C77DA7446F51D70A0D6F65183085FD3D02CF4780B20F557BF48FFB250D98F58FDDC47E91C916DCABFFA04F47C796B109504E11CBFA7F6A90808F97F2C2504F4188B8F1D0B3627593038E6A763880719225E0CF769ADE044474F815948C61A285A5FD87E4169E6797F4BB0D81D6FE0989F0055A06CB8EE9633C637F3B8E5DBE37F27C934368915D02693D7FCA660DC03A11D7C90379FB6D722F7CA11875F223590004D3049A9331BF0C0AB836C6DB69C595063F01E4664AD68C7E532CA82B1C96CE1E316F87C84DABAD94AF2296AA998D3D7D96D1FABBE0C66B4332A3B0310DF1823F400E5BB9972CD5783087D4FAEFB663F6031A0DED3CEB9D5FC72F65983D57274486CB525AA7190212BD81378E2E9F4B5E12E5723A8BB6270E5B2EB996526543A05C1DEB98DB86EB4D1279087EB03C18E1CDC29A9DE63FDAD2E2193316B66D7EB8A3DD9F290C1A79CE1ADCE1429335C1F29D1CB7B08B34BE956CC7F18FDEA4A1F0BE522D9BAE516A688FFB3AD02B31FF187656893EA08281108C02E8FDCDAABD11C7B09EF4E2A10D4BD725D3A172C7DDF5A71233136D89CB653793E45F63F5F7C7727676EEAF2DF8F175FBE95B7C9CC1F434A8A9563BA544A0E7B395E516FE850879A35610C861DD84E82E99099FC0051EF6843E6576E0799B014322B394687D64B8EA87FDC660A77A65157480F81D7A91C21BE5EC6FFE1B7D844332D1D212FFB09962B7427404E967FE83BD0317D19E2049BA84ED7C51AB9833CE8A29EDB3EE6E2D80788A975DC8C2EA7779CFFA72EA174F5FF38FD6C91FEC4A8F37A64E97C25D430B633E408495A075F97D14C2F0043EF69B511DD108262BDC76C0863837BD434E72EC082A6833435C875BFBE740FFB678EC763B91E8F136AEF368568AFA4B3C5AB9CF13DF0873424080CD8585C93BA60D3E91975A3EB80F182F125D98CF828B11293E6BFE408B86EDFF1B058CA0C3C387D8EAB64AFE13C75E8CF0DB593DCC161FF1D59D1DD9F25765AAD852459382F83306836F2FFA7AEB0C235A97FB018EB1DB76CB9ABC4619FD3795EE0F88F64B2EF44EE80D1870364B5D2514F7ADD66D654DE64CFC03E3DB1F0864394CA18727E4C4BA2D7D25E3376B1AC8395F885C376EA26E0BA62A3CA5923EC0087EA5CE535F7E06AF0123532737CCAF1F8D88452473BB92B3AF78C77E1F5F67B413FDD961F38F77766F5F6303C411DFF62B828819277DD66E8E247CA64F8C56913DF8292BF5AEB41E086E40169B6B3E43382BC52C7FB4A253550D60806048316FC2991136402114820BA07C2508A558C5689E136BE55C3C5D40226751918A091A3E4FDDE9B044394A27D27716F539ED9C82F52E285CACE6EDCA897203FFCD4F8D30375667D5625F6F31BB4724EE7749279E30B208D3C5CFD4FAC651450E12628CC3ECCC10AA3712D224162BD256AE04FB1BE68D407EEC0C89040DA58E6A5CB96774965580BFE6332E289547FCBF2F24FE838568698AC1F4DC26D92EDCAAF1E0294E5778AC4639301A774B7C42647B050E0DA4EFFA073DB6D118D2E7D8378C8C21B9FD03DA3E943A105E4A09C6C1D19F125D3EBA13F43A38509DD039028041674791080253EC123DFD9DEADA8DF7454610CCB4F0C60513FA09D598BAE9381A8D8B9BC54EABD3A676F414870DCDC8467644A194132B08B0DCE914EEC323A85C375DF40EFC440300C7FEBA4A970AB30E57E8E62A19BAF5472EF66A892DF03BCA639A548924477D6E6CA5262B357B638FD04DC10CA0109D510861D2B39A2A77F3FDCF29CC20CD36EBA26C34E2CF47A7780F4EF36CB62955F26CDCEC13CD5948F258463DA77F4F7957D44A928AE0FA006202FECFDA8FDCEC8D7C2EC8CEB96DD698C199D74E6D978C505E3C9130E1DC442722513BFABC7A2B9D1C253D374F8066253C10DB9F3B967DA44FBFA3A37618BEEC8F383C63A6E1BF4143B7358DA2651E6C52F542E0AB5ABD17F386936C318C353026448E3C8228B23E10160F74EAEBD070D18E0D153BEF3C573433B73DB45938051A57376F9CA64A1618300C8DA785D8ACF852FA4C56C661211C5C63D08D63323AE2402C43EEA3225D4B807C15D885036B2A97417EFA1D5EDFEF2C35EB26A88E99E85967D472B174C25029C3A29C617954B9D806329B04A599B25ADAA3DB3B62EA59791FA237690FEF69B74BE8D2EED88EC494EC520AF5AF8F2BCFF08FFDE74AA2B94182EEDCAF1E7292C1BA4E77CA9E69EDE9C76E65A72B51148819442DF04AA230C581498A7F544E81A111DF5C1F434659BC1693DB1CA95974AA35D6CA99D56C4DA6FE19158787317038B84B65E0D81BB9AF1ADE5BC53CFCB68092929A2A240E058E7BFA4B052EECEC4F5F73816F47D0A6CB4B44DD6627489FF86245EAC1E5704E0CE20B53F3227142E787B5FB49AC9D7CFE4E51AD41D6158AFF900D4FA99716EEE0AF19D7C5C7545394D56260D5E2537171E785F588D299D96DB9A15D9E26061890CB7A8310E8D8B0063C1AF888C8C0F01D17BF396C32D6CEC54C0124B8FAD130B1F7A034E753A4A12AF37245B56C8102E169899E09A42382DDBBCA7BE1CF27577AC6B44A55A75FCD0E79106952EC32084ACB6DFFA3ADD6FF0AD46B60AE67C55FA78C02B14CCABE7DE36D575E26F7275B5F1E7E06EB2DE9F339F22B8590CBE7F4AEBE81443C30E881EC32E50472181D3CB969DB80E1E50094366C6175C7E32126B11C21F8E1C00BEC1B0DB283D7D4C89A3704FE2ECDB0AAD060F2BA22A347AD0321DFE525E7A115A340B582A2973EF539E308E8E17F6C7294FE12F033783CD5460776E3A9C85F8B4F18FDCE43266BD2593EB23842D9CE8DEB8C2E6B6C16B31393BD878C9BF40BA786A41323BA83E4B9C53CEFECC977769CE83AA916EB04E1D00BAADD120856EE93468D0050116FA82B399DA01881804C316230C4EAB0573AC491CF43B43DFBE9C157A01F63CFD7231E9E1986562161858D64B1924EF07B2A58E30A3FDB907F9DDA20BEEE195155162FEAFF363C9C5ED5C992085412DE8576B6463F11977FF7371E8721633D2D8515C9355F2D0AD3B82596462BC40477D948632AE56C86572521DD02E57EEC4640DA99887D60293F65582818CAD77B66CC8FDA3B3F972609218019153B2DCF0DB16370C9F11EC73A7A86793EECBD11341A9F54B8832B552DA6EA225E43B4082C8D7E22D137CBE925298C790F5195A411DB0EDABD21DFAFD08EECD2F6C82E183F36576FC70AE84960BE7F465C11D6B58E0625A74FC432095332C0F3ADEB35928FE8D50211725DA619B2B1B710ECC3DAC284879F6EEB77E2061BB56C0DEF06C9451A224CCD01376A24EDFAB9C1661C8423276F74ABCEECE66ECE6C6C302D8F89B9F22F5A0796F8C280E308E9B00C7C4CF7A0D35753494E60FA7CF4F2719AA1674A6809E5D281CA9BFAB82961226056F1267C7EC709B2AE91B9F3EC103D50EDBEB7D963413856CBC8F14C52EB8596F7C58618F099C4A5E09F100DCCC4EC488F48AE900EC1ED73776365EB752A28BCDC4F6162A567A4D6A62C2CAF20C5E95EEE3C1CF1F90B639BC43A1EBFB400F5396F8181CADA4C03FED89B61CE4A8E1031910F33688C8364FC8738D3F80C812412E2E84C5FC1E51551EB9C7C253B8EBC94BA478160CC284A099825C76F600A7D9A42791F768F61066019846FBB9D856EDBE74E03272CC015A16C09EC761B0DD7980B15094F636F497B84EFE6F74ED45645BDA7520667689D282E4BDC8370BF71C76715CA4D7B0347ABAC50B562A6EE78422CA1DB2EB2F823AFF99B8544A7D886FB4720D4F4E5F35772E71DC7556FDB193A33A812E554730DEFF19FDD0E279613B8A639B22C64E1100DA2C62F8D734F9B036079F166D89BED74278BDFA0206363F4AF05582962B82F63EDF03906101CE4673B64D99DC09061B327315327F94018EF663E97E05AD7848832781CB16EF4FF87C7ABDF3B9F815C9EEE33D762C581B64F4CC163BEEFFB8C2D634EABDDBBCCC42E86F0DAFCBD420AC38FCD0924761E5428A892E7679E6253F17D2E2A7739C84D31070430BA43F51F331698865B223503FF79AAC3F97ACA2F3755BE237C172FE1340447D26BB5417899A9449519A2FE2C0905FBFE1058B5B54AFE9D13A4DEB8A1C3ECE97C1BBE1DF888D8A0249C7633C40D34260CAF3A539BD2FC3B0E00588DE00FD0DB1539D6FACD891C4AC81468800D3DE4C150D53E3208B0FA4E6C2981ED2C174F122EAC8B66E0A7DADD8A37037B7027B6064C05844C51C782CAD1BC2EA328CF63485943CF638DCF51B92F6D6062CF8220D9BCF94BFCBFC10D139C1243878ED36B3067E501128CAF07F593D3B7C8F85BA462907E5DE67494DCB12F6CFEFBC059A925E1F07A7AFB36C28C7EBB9F5F736393B3EF36225E2AD2B6C0249B4B3B844D9843E04F2E148240DFA734B9154FB9BF4A4F80160F7B5B59102CB7F327E4CCCAECE6D0BC82C1EFC7868C7BDD867F0E5F44C21E856763F1F9862A40996863F8FAB8AD6B71A6963916055633534E8FD48E91D964AE3446EEED3F9D41F3CC410DCE90CF0A70ED17501FB39F43F69C4FB586CECCBB78A192907DCCE98E7540119159616F4FB7C9A17954DA7AF18B338446AE36C6C53FC2E9A478F971420E23C8FC1CA5DF19A7CD3E1CAB783E296012F95382A68C27B7F39BDDD664811D531AD1D6649AAD861F45436311D05F428150365E26320B50FA974923A153DEDE975E33EBA32B86A455A58212A3B202FA6D5E2A4EAA55F2A4C677C5C9E3F606C547FD6D89C457FD76DD95B703C969512254E223104E75CB716EA513A0C7B7672B017CB8AF88D4B9AF3E6BA2C553A15B227712CF7CFEBFBC8CDA674F0C83748245CC515FCFFA6C6D89141D9D71CDEAFF8056A24C9E3A5F8271F6557A8393B56E04C035B4F44AD696F7B38136600ADAE1AF2BFB56CABF152B7E19771E506485DFFE59E5BE929F25F2DB9103A0D6ED15FC2A4812868C8E2A0A97E5CE284A7CEFE3B824497EDE93E0F15B6E0EA84140717C7B45256FA11333E6E404C9DD533979649F9F1F5ECF2906A72F1D3122D2843BB0CC27E1CA45B831E832401A4567CB2FC45B15D80D58C0B642968B0F7C0D9F35ABDB1172D81E97AF84B7738A85BD9D25459BD76758404BE672CFA21CCD4AF726C8AFD50C5AC82C43C6EAD913A9B666C2964E35FB0B0271B27907DD190B803F564809C131A66124DC55E0528DCEE03BB0D75A2056D2FD734B5C9CCE0EEEF758E880BBF47E7200006E696E961C8776E9D921D235EFE7A661ABAF024A32CB8A88FBCC074E71F07844D8D82AA94249D76EF86987409ED88B98E2293BB5637F03F8229B0D286148E3524FEC540C27A9F2C2D98898048CB57077DA1C22CEBEB1878F0C0299754B87F847CE9A4D4A49EF31719F6490092E31F54445BC85AFF7D5C5C4A8549F2636D8247D039011F12D083AE141C6F9C458B886170C38D475EC6B6F29775AE70EDD8596FEAAFAA14AFD3BC8BF45CC3A0253ECC8AD4E2651EFBD79DF9C24543F32AEE5B198DDF72BCC082E159FEB3F9EB27BAFBC18C2D51E9A2939590C0B18A4ECBB1973782AD1E0196FAB25CB11C916273FCD05FE9CC714969A612D46C4E85D21AB7598F48AD7B3CF2550F49BDD75C4CD1A2F1FD8473F2AE27EEFBF9AAE10182ADF9AA5EBC0F145F805642154F9A891BA537C786767BD8C74A5E73B58D9BE23D681C81EBB39887DCA34DF265277FF5603B569C529BCC13854D153A9A06F83627E14F9F9BC4C816310E089A11FEE88BF1AFD6F4289074E678668D2A27391CF33CD9EB85F1F25F868EF974085F2D0EC30AE30E0AA4DDC5C7A0E98B71DC0395AB69F4A3A6810626AD2C284BFB8099471ABA8F145F516CAC04BA897A7BB4558CB9FE00ED3C878AE0F06E1AD414C851B2EE51BEADEE67595949707F4360C6DA36895836583149EE3977D0028800537FE5D75017C27A9DBD62ACC1415B9F7F10F72580DF81F461E14AF4806BA76FBD768ED9C8404215C761AD78CA53281E46F24CBD88E84F4F6AA8E707748047FBFBEC2831CF404F180ACA4C0C436E262BECEA3B1F84689B27C169C4E1DFD7223255F05DE6F54B7440A747974FDC1BF968C6958D537E11AD9EE07647BB50A7A6F16D93F860ABFC978C86DB7D1E8C260EDB5E07FD27004B25FFCE9B8E1D1EAB79F41B6264E80B662985B92D26C4DE0C2F6BA71A2A2FEEF39E17236F6482E97FCE0193675972D177C54A044A3323B6B043EBD3C083503045BB3F7834E6F67C990B70DB4864AAE27983E204A9730D68080EC9573B878C87F04C6EB704B5E8C4E7EB58C6DEE112E2B5610721A3AE2BCC3C32D972458471982E9F2E80F9EEDD7D5D5DE42094719B0EB16DAA3FD06D4A0FF30A3000B17F0A791EE43972A47FFE5DCD9B6DC6833393146537E24D3941988DF5715F29C61A1111AFA7C587443DF7C392A5907131B7848B1B577B4497538B1505DF495D268919767BDA7BFBA9CB79BD5A21DFA7DF7BA470EA94DD6EC5841E2543A6134C226D648FBF9D5B5CC6FE9513930638204250AAB90F3D82150AA43F163E8E1A1620CA743821D69B112D6C7709B1EBC8C98C1FCD8925F30EBAD49E81A7C006D8ACDA133EA284E83FC86B919497D8681BDAC0B772CB861A4AF1BE57EA34FDB00782C2DAC97585526EA1E7F853C9C2CE6F789D4CDBFDDBF61A119889527FA962AC04A3C662B45864C771DA5B526D41C8DCB3DC22C010223B3135D4A3C1C2396DC3BC081041730FD4668139F0033E448DBD7E9CECC53F6153F794E9D9EB01C558F2B85ADEAEC2C93136B9DF82D93BA6A0101954E23A49F4CCDE6776F8CC625937B13EF8E847CA499F5AF1FF51C57693B8FD973B90D7E0579A7DB2B2B957358CA94BD1372435C7FB743F33FDF1DF85D37C944631890E5A27EE23C8F475086483D089C7A131B6936B46686161227FE54E34EFD8D901D42212E02544ED564880742FA08DD6C9BA9FEA90431200A2BD9E5CDEFD049754BFD134F4FE32BF40176B7B7BF67EF1728ACA44CC55C1F631F422322226A7F474786D840CFFA15C00AD51A8F3D6384E392547618DFE6D11CCB8116341312D0DAB67EE6F8390D87D0D93DFF2EBA6C747DBF8F7B6396DCD824DD064D87C000E5AAE97BB84E645BAA559A8EE990573F08ED1AEE34989F39513214739C88134CA2FAA527A1FC0ACE5ED4BFCD8C8E1FEBB964178A7E3B777FFD5AEC36956AFF0C576A720C6BA30EF055249DC4ED2C6AC4556B93EB4E783B34C0471EDBB8C1779434F0194D9DDD072FE583EB5B0EA579D69271769066947F5966BDBAA8B6BCC43261738623C469D1F4ECEE67EE671502F9BAF747D613907272CAC654FB491799C3FE783A61587500081670EDE57B6687FE735BE19A28340DE66D54BC28371F1D223493088D776CE63558B77B8BD4F6D87C17D910B9F42392CAD90E4CF0D3D9BB61BD58EA24E916861B461627A8550F60295D54777CA7A3F0374EEA52472B9E8C92D1F894402E1DF0C58EAFB914722657E095B5E4E95694BDE9A0F0943F32603F76D7DB672A31DBA842E5D469A0648457B8CE53FD7552989A9D5EC78CF765270FDE240FB50B7ED382E2A23BAFDE87C2CA2817910EA17B07FECF20BDA0A57F933A552BC238EED76DFB28320A933F96797BF6D056313225A50E89A22B2526A5F215EAB0092D0321EBEE6BE7AC32B0D21EF1EA5ED7DE4726B3606056E770FF3C9E2171FEAF447EF6930D32CC067326F784E17A9528357705500BE07BD0AD82087B18860C60F286019793F2ADF77072E1300FD956C2B5E3FD10C30B9597C14BA63D3A28F8762BFAF1AC9FCF9ACAD3555F5BF4A3F576AB940618CB1C42EFB7A298CB6F000E49367AB8325E542F3770FE991FF8997896E9A1BF6EC50906116263DE219298B4646F534107D57B1185726DCF9E3AE7F44C5641853D64BD81D06B1F97A380A5EC7F1B2B64B86D9CA5523E21249B206A30D3DEDEBE620F295214A0DB15AC412B55A2C16CB51D1D3388FCB32BB7A71D454A0D3BAA6F7B5C24C0793DE59A8CA3947247A9FBD68981F9CBCC29B903B484848B1B261747A29D0A1B7B98830B83CCFBE60E0C21D980B915497ACA87F912061A0417538CDC567570D7F154DABF6D66197A655D55DDAB0655B128A7B41730D4759D2D2E9B104213EAEB849B89574CDA32A9D0D3D24DE052FB7C74B28E84C5BF00A4EDB2D14FB5FF1D818DBE120E26E0EA7001517085D5AE4FFBA959AE11BBA0484DBB35D9F9CDFA9DA11A4479B243789002A880305A2FDACB8F93D761ACE1E456F07341041692CC23B7D65B523D37AECD2080DE37CCBB82DBBBFF94CAA7A5C95FAB923432CE746A25F751AF7AF7CD5944814C323610AD609B80045B45EB01D74A28F43E412DCE76C543FB74D73F87D43A48CA5B4AAB5B2A7A563BDF0C38CDAE4A8B6D74614E48ABF43ACB7EFF1C3C113F2E684342FF0AD4E669DDEA0CC4D1C16E5E0CCB061040F63262B31955B624B891F31C93B28FAF617BCC1532A0D6459ECD759398722652688B45CE3084E1075F91636D4075AF4D3961A8B291A06EF05FD7F356AA8B69281C71FFE28CF1CF31E36D383470394BF42491FD10A89F28124E18217261C51A3492149260E48F6851FF5DC7B5964E823306DD083DF4990E7985A0B083B5DDC84B24345210889B418A8E658FE917805FCA205AFBD5A750A9B0F5778C0A756F00798CBD1C1DA5018C3AFDB73C1795FD15E77734597C79C24153D4F8DBB5C7D86A3586C4DB269465C7F419F771092389AA5FF9B2A4D9ADA7B3C7BD030D0EFDD142541B9B032034D9574F444704F603112523B8FA02F0F8AFEEB8E5E1C9CC0492F761F6D888771CA6931E447CC7DB3006919C3DDB0109125AFA4D184053A23FE3F0AC695B3B59689DDCDB67174B25FA031BA74EEB75173FC6249025E983B545BCCE3CF2376F3E1A2B3F6BD5BD400C6DB1F79CA13EF809D908B289D2BFB51AB6F302485CC805FC0CA378209637768A10682106BB81064E718E743FFB0EFC8545E008648C48C54B725859401C00F702C262AF9B71A8F68BB3D0080F1E79704B9FADB424541A0113CB6C886F2011D3AC6E80ECACBB7801E20458B67AE4D93F795F71291D78DCD37DF09512D7160A5FF5575FBE9A54BF102183477BA6B6A364F8629755506318723F5BD226B45485F2FEEE74B67ACC31E8F026912FC8363435056AC8E3E0CC703E9B3387947DD566C21C6CCBEF6118BEC34C4709C7CF47C5D239B30D6AB7C9B5D8304712AE1257F515C2B1DAB6660831F972D66346F60936BCB0AFFA1865EEBD940CFE3F391D9BE182DA7B605544C18E148F0FA231391630171E6A2B20AD3091134845897E5B4BD34C4F0C43B07F19B19D4F1751CA20A43C1E2A61BE4AEC57F2888C1FFAF9C1C78BD87EEF9A883B9018B1BF05E31A8718191B96CAB5DCAE57D1AF96C5B58DEF9FE1C8025B5CEA6E386B9EDEA55F90383787FC44DD7A4A2CD9E495AD58CC2881139FE75F2C6C49FF01C2934E6487DCC59618EFDD1BFA715EF4E3E6424A68D8648E80584F68D2E7A66E9C47CE0EA660A535F458BE75083D878B641533C2A39A042D366E120F22D3694AC1C463D3EA3A14DDF0A83B2023F6F52A412E2D9BBFFF806463E135D78AEBB8992283275F214CB30184FD6BFAFA048C5601B3DC057D80284838576B89DA1589C5B1647896D7B1EFB12BD387BFB77FC6E5F3CC2A83E9075B9B0135B94CD23A2F8F52E5E4E6EDF332EECB8F24D4279F4C8CF37BD979FC8C8427A6EEF39123393615DA4D4D4D384351DCCC89A35206CA1C0BFF0F6AC7267BAD8A852278FC1918B072666A834C406C0C010D16F401B85A4045CB50E190A03C3D4603629F1F1361B8865120FAA921B7545986866341307756D8CC18848BB100F6D1FE6C90808003E323A3C489447DC620049C5D9E6F5578E0E508DADC54B20D1DE51DF57F07F2D5F353CCE0541A1B739CC92C98CA8662CF5DC6CFB7A2D25BB5434C30187C9932C3AB1034069DC39333FD15CA4E37EF8E3112C4D3706E7D5928931E7013107E44D155B25CDA7BE6001166A28571254C3CCAD82C8043085EAF05AABC9EEE3705A2A12C4A08A5DB360035B78E308CFE613ECF796521527C0BF08A02DBD101C4744B6595BF2361793EB8F42DA84E91D87C0731420297690DD6183CC239BDD0848D1A165EC140709582FBDE23335BDCD2EB681547ADEC8BE8D8227067E2FFF707048F1401416AE0839E609F5638BFA775002D88155982B9BE3BB24EB1F2B8EEEB16DD9083C4566759D9A269E7FF885AA2D0DBBAACC943D4AE56ECFBF938B486BCB0F5C12D20A60592EF961E3D6F658DFEF15E27D498299E6F340515FAF29A2232823B13489EDFA022330160B9468825A617913C298BE3268AC95A9C4198A206244F7176746331570ACA38B79F29DB4AAE58792DDAB2BAE38291BA44D309D114B8AB77DB3357648B79A99F1D758EE074B4006F964CA179F9A320E912E53D6911DABB30461E2950CE9B4F113AB3120121D2493E290A9C0AA203871F4F6C84E21AEA1533653ECC2FC8D8C21040167A8796203F6F04BBCE936D31A507D43D89BCF5D76828C2901D8DB4D3AD681A6F05FA95557C3CC8AB331214A3386E42AFABA89DBC12D3624FC4EC8D21984D098451D5B8B30223C68C8347921AEC68C92F8E3E51075CE9CAB88861B6BE01F4769CDC889B87E44E940E0B5BC9FED4C35A3B0E5A8BAFB184EE9C7C854A6CF7A32E8F0A24E0D5828A8F294BD2AAB85DCBCF892DB8AD5717C651CAF9EBE0A9B5098EA1344241F9898D7AF0B07BAEA11CC95BB463714A4D2BA714B830394C1BF48B86D6C13EA59D27EAA8B61A4C0D8BE881779F403E713B4FBE91CD26ED3C79D6E04D1515B00BB26A9F264C5BD99E3F1A3F6CD96DA702B6F54B7C33EA9097319C301D80323EEAE1791661A4640778C6151A4D609490E5380B34423C300441968C134A12E5F0FC50B32ABA0F52D184E39A32F1C58BD22D0FB3798ACAF43199F574A3B289323EFF9023A06D7872D06B6B63B3F3B7CF88349A28AD1E9166BA3158DB38FAAF51B4761BBD207CFBEE63014AE88D9CC3099EC581209C61B804E4138F0ACB2C24C6BD807CBDC4EF5272D4B0D7DC8DAB7A973543595D96F67E3302B0D4C3605CB546FDF939CD53409CE46BF527565709EC550A4A7F05056DD3537018E8BFF5D6B80CFE8C3503F5617EF4ACE98284C37722140AAA013B6A04B908305D441F8390C63CAC98ED6AA40BA77BF9C438D0B1C34C565E61DE743A5978D77BDB597304E3DBD40410A0106C0DB45E29D2EE3B2A04B43BA1FF10074F604F1E1ECA3D3269FF8475684EF779CA4CE32900D0F0FC41268FDC8368F8A81E48849CA33A5EEAEA2EE5E175962CACA35241636F54232E4802A699A6BF4C8D40D965AEBF3F4908146B00E1F2CE8AF5DC353CD6D71B1A675E8710E1D52A7A54EB4E5AF2D8E5E4215854F720D914C24EEEF9A18716E1638C9436371982BE15E7639A4F3E6D0EC6B0EF0705E6C7366AF58BF309911835F3A6DE2CDBC98F4B25E8B37980A3320DEC3F3BCF90461A9BA02A4D868593EF1F8ED5177B29DE09236262403A15B8A531009583B692937C2ECF8F6ECC4751CF5E74AF9F67907D36C08742905E86A2E6BF25F067AC672CA9C6BB5A46C6D129EC0F99D136028E2DCCDA75821C58F83B0E921D03F452BDE3C4DF847DCE6344CAAD3F223433EFEEC01BA27A2FACD9AEFDD4E042193299BF3D507B9E40DB5720A5D5EA6839ACB359ECCD4EE97B6159A1F2BCD1F5EA9986F8CAC72EE7F9BABA0399315BBD6FB5926E306D37572117698AE3DC479C89FAAB0CB62A87383A6AA0A05865C67C1F7A0EDBADD0B7A02DCD46CF95E2DD7A1C01306571512E55662809728B2492C1F2F1D7A3C3E2E95FB0572B1906931F5AADD80DC60C555A7AA0E546833DB91DE9817D676ED0BAEF9B9D2D887E732090CDF12170B3F6E69B4E358B3E865B7B69A5524D865D04CAD21EBE8AB6D2E611AB65427F0781CCDDF7F312DFEE0DE8C1CB66EA9220BA8408EA9DCC71AB2BA4BC2FB3F2257183EED8E6A0CB62DBA49E5DB4F5500DF63E10E0E0EC5BCE510004027BA87060DB0C68F5A92A8592E23F3ACC3393D1D0E7CBC5447FB436853864544A36149BC292D29D0236898590B58620B792DC773AE2337C9135B58484ADA2F9AC3EF2115686E9F39AAD5EC415CE46751FA0127745C831C9823854F08FF14E4A0ABC13D19D2617AF10EF53509BA4BA79A5A0F18CDAB6F73EA85C0A39D3B534A474B427DF64449A8D0DBC1410D9D32567DE6CC0E143007C625D067C760B46A0216DDB3F9FF51202A47221E84E64C18965026DAA13FFCFC0F7E8DF4039D74CF8D1F371C48EA43499572F7A04DEA7FCFC9989825DE55473E5C129F3B5927C59F038CDB68C83501F5F44D402E186C5C98EEA30C028A491AB4DAC3831360D11CEA1F4D7CFAA9ABD4953A85D1FDB966EACA5FA6AE840E804D70EBC1B9732DE3DCA5C4D7B01A4D95C063BD4F2600252ACCF0B6A6FE337D78466F0CC7169C55BD574014206D8EFB081561EFE549E072D83C67E0644F62B92DCAED581CC72AD1D4F11BD8BCF42A37D0CC307DB98FF177E454DC6367F573EB0652E92168960244CC352817A38DDDF68C3B659C5F33BAF3B1025C110ED27246A0319B943AA2C12543E992BA435B63B2AD4594C6176296833AE0528BAFBDA713B47E5A4FFF886311352DF6508D93DAA608281953B518E568ECBE38DA0266EAB979090A0F9A15BEEF9A612E0DB38751BFEAA153529D865E54D8832C2E7C8F83346CE092B67949BC7126E3AC2DA55047C7B2069F8ED9C7D252BD7D70D891C047E3BD795532DE6911A1CD52BAFAB94565ECF894DA39AB48D1866C05E464C8ED107A0EA5A839092FF8D315BCC91B9E22EF66438281E6891AE3853237BC11433BB483FB6FB914C1C479D270E20AE5CAFAC90F0335F7080B0024F3BA27D7B860EE18CB8B0602A2AB5D65734F2CB7A03F5DAB725B7D7ADE4F243238C289D64ABF5E4E6CDCC6B1176A7DB0CD0FB52AFD7B67BDEE95E04883B40DD2082B228DA0A2AF6CAE46490B93984D83F6B3D2E23F4848E3C5D527943080B4AF0605CA09E523223B0A0CFCA052267FC16A7FCBE00AD9731927F87A0374AD38C537FD1DD9CDA53DE2C91A45C4E253492A2427B8C4517F1533C435E00CE75F47F503FBEB571E9145EC1E5BDBF36B471360614159B5DBC6F7D978F8F1C2089052C8B9DFE79B6BF44BE2552D5ED95A165397CC5DF3FC051236C09DF0B9D316E0567FA3BA79BA7F73C9B3E6DCF2332068B071223D315006DB4BE5E95B99653770A8DDBF8639BF5DAEB9FA1A5DE0599F0551DDC07345F4D4C5FA79C1041FD4F0D93D5DFACA7C79846A348E9F49E9842CDFC78CF63C734BB7597B36EF515E83F93FAA42F1505C382A28AE65195F1F092FFDBC8C1177BEE7A376FA36A0C8D156FAC5C0E0F00286FCAF50B816142632B11A76FF7CEF72DF58AAF449E72DD2FF2CE015BCE8FD99DA0B3E7CF11A908E637A10E638F84BFD976ECCF9E8CD58A32C0905B48DC07074AAFC45DFBD01DE0CE2D3913DF9C2FC6C11C3523D893785F1AAE7091F260357450A96331565790214BE5FCB0C4E0CD83A702692E6FDE1E6F1EF481314948B1FC74A74DDCBA485306C60789DFFBD694892AD2F5C45203BCCAC5683BAE9651A7769675B0BA321FD2CC5E85207BB05D99845AF00646D81CFED2F160EFE36979CF6A281D2E9D056AA45A8328FDE5759DF8A0DAA7444FB53131CDD8018064332FA8F114B6E4CFAB08E383E3B19F6E42759C66411AFDF05AF81CD0244E76BCF975CF1E4EB07E6E348B670F84DB6C06D031357CE1E1F457CE870D635F64DD66A53763ED116EE4D14DE5566785AD6F9C47C64F584A5DA59CBA59782E593D7DE1B9953E15ED918B49969DCBEABDC9EB293A78C78F9C47BABD7FFA80D9B453C55BF10D9BBDE0B7D0FF2A59E2C2305C553579CD61D1E777A422FBCADC358BF5E2E2BB327ECB4B8E3BBCD5F0D0DB3F9F55C2BF585250B24DC13BB2BDE6270605F094FEE9245550F85276E2FDB37094C50D6EC0B15B805BC31CC8D5E7A35E6377ECB647C95BA2FB703A7A12A384C083C80B72E1AD2D5381B578FBBE63F3160516323329B9FE38CF6458C4371C2ED64E5C7752A793250C76BFBB1670D55D1073596EA8FB678D145094D93BC820B13E9338D3931F1C3752597B035016D87C24975B7F90233A411569CE3EAF77867EFEE38BA7F8AF56A64629B0D0C848D2C0F42E59AF2DFB6EB9B6CFEFD341B812C30EB43AC8A3E89B191B219FE98203051573439C2F71F2941770F6B993808CB362C842A665AEBAD1DDA976CF42301FC51D360C90720C4C4D37E189A92D1CB6A21FBE6B827D93042A3C7210059DA540A6FC9FEBCEC50CDCC672AC02BC7EBF4E15590B1D369E6707A22259BDB11DA2179F456A0B32E692C67666E39BA445CEA290D71A457F05F8FCE67A14D7E7213071860E078D3E7C393457C6E685AACEF1DFD12877AAB4A682203BBC2EA04EAA7EAFA562E3DF9581F63EC52AF8138E64C16F4D86B01371555031EAA8A6A33622A62FE9E2B857584111C67EAF53CC73860E7C74773446AB0058ADB4B2B8DCFB6049B48C68E190A3AF037A5D07C2D788E2020AF7BAB9DA76ECA8996D71027C84082BB2A4336C4B86934B6CB26CCADFD845420125DDA10F4E1D687D1EBD12139F46C7FF1FE2FAD4186AF939400972B9CB4604D7E0F16C5BD5D9B38057D7FBFA219483F94824487DD380CFA4FF6B8EA410C1714BA188D28F9ED252B8127786B46F50FB72B848FDF27850ADA07153775D6647474AA0DE549C50381F3C6BDFD5F5261F6755035A8A212201D33E6FAD491FAA5D03903C72EE27686D77F2C77CCCC7721834CF0A7D984DAEAACA3B0AAD8F2D9F93E9292BF979A8B07EA3BC0CC1286146A56381C8C7EC73BC2B0BB4FFDBC288CCC70DDBFF5366C456AFAFF57780E65A933B9FF5BA46942873A618189201C14F832C859A17ED6843BE10086B67BA30C617FA1841997E322329CA6198CA4DCFD833E1949180D692BC54C9B5272B4BD643DCD5755A6D069A0099B2B3D90AEDE3B8F1748A6209BEFFC85F5B02E046A92642B88FF30E420011769970C9BA5158AADF4EA19F627FB2203C54D866BD2396B748112B507CD14F667F2448F04E0F274A2C347CEB7DFC96EA4F0883CE1E47BE6C6A9C0C4F65F02917FD548D101C3AC8123F033E9A8ACE8B476010BDF1F9701EB5A9FF3C3BE997103DA327A48F9418CD2627B359A52595CBC820447F641B1A2623D7CC67FC699D3B666783F4EC1D16923EFED43E423B614DDA20CC66E9B3A2AA94525A4B74902194DD7D6CCA1ADC3FEC236455A7629893AD87BCB9E6CE307D2684819A38B88932853E5FAE4067E45D324B41D67D95EE0872A99B9658F105CEB071716D05EE298CCD85F5F4540558714E3F3DA3BBE825BD9FD1369ECEE5D3E75C18E5D108DB43AE90509BD90D59FEB11D693EB3C468300636007E030301E4C7F376641FE056C38D003D4D1AD8060F55B32B9C2A65ECC0E75C7B382783577F8AB2D785BCAC52DB9A20403B1DFB4154C7540862B7F55DAF189DDF30B11EC7033A38B9343D4059F125D85329355BF6F446919A8E563BC88C9437A321A4EB7FD7134F5A203651104C52DFE398723B49FECC9301EF15C440844AF9E30DE13B0DF97627F4996D28F0994FAC822484054CBC722E93ABC5B0ACE9F175F5093D0C08E4106448D444F5E6FC7294C3B11AE69B8D116AE3E5CB55B42F523F7B678DA629387A2D554018CEEB5F05370A6011F6D243C718E6594BDBED9A7CBE1FBC885B07D61C8BF95909E90D116B4F180C4D122CFB2B6CBD3CEA3F2C543F69B7DED6ECE593F7025746B8CE0EFF033BE13B899C51B01B0B5DB0E65CB94315F57E5A97FBEBBF2317F3B30AA8B35391392C10FF38CD75883905552CDDD0EE81494ED24A73F595152E177919814A164EEACFEA3C270E77CA74882E5F8360701A1BE8C3C321ABE5B1CBF9E1A09DED8539D456F2FADCB9998BF972B005ECD43EC8F51D8ECECE6643D266B1A9F19BB0652EA663CAD4C1125AE8C0EDA30DC50E8AEE75D08DAD31062B2338359726A33181F7B8C5D0DC1C3CD7F30F5F27BE09447019C08B17897A0F88EE23F7C909456E3D3E93A83B732667AE9B5535017124ACF15A480BDD7D9860DE0F9FB4A69CD4F1D382124B30CA85FA2AB98092C3205A4C339C5C44051E728D0CEC56D5371027EAF7152C9D4ED080F102AE36FCA18DC354E315BF1CF277289D9A8244511566455D1C93EC5F2A261FB6FC4A81050B6833F4C1B6A2A0553913A1D0AC9B1CD726810039AF9541AE8EC5670DA692B576DF5BE4DAA9B2A5EEF6ADAC8CF2C731205E1598E12609AA85BC3E38A2AFC0773B40116A4B9EF4598C9B162D30E28E1ADB3E97CE12A000E2B401A2454DB8B60CDE43801D58B0D64617C1DA1B56E509F56C6EF79A875ECB4030C185923D7442EA6311945BFEB415D7C72B9F80ABC8C44AD062440B36C37F4FF543DA8CDE7D3E356430E9D54DB63580700CF87502029EDB0A02E4D427222D109BD536C235F9FE9217CC9559E480AAEB1958D240B3E86AB858D522EE4D98A9F62E6A7AAE97B1EC7426B6FA40841AF06B93A9D16A4A417BCE11265C2A3882C46B62033565358A9FA7D55910AE2AACF59A4B1261489A7AE3E20DF4AB0DF3B32B693EA5B426D5822BFF0BD90D2A78F41C3E7671771BD9CB4BD6D71824D827FCCC3FBD95C1D913192233EE5C7108728D23049A42CCF05C65B3260C5A89C09DE1226D9E2C74D76F750F2B45666AF95759D5B13E4291D4E88C9969DAF16AF84600C95515DA5055AF0CFC635F627B1E7583AD2D9FE44368D50AD1108CD9FD7C7704A7C918CC6704C76A7F41DF61801F6DE289B52B9C1F2287D436CDADF6D2E1990283549BFE8EDC5F54A8262B0650B45F33253367912240EA9FEB11CF7C2566BA25770B59ACBCACB9ECA24FC0B124A3E0FBFED0CDC15F34DA004DEF2FE9CD66DDE8893A4CB5ABF12A5A0B3F549523D7D1AB9BEBE45E91427D15BC2ED5703407194DFA0D37D20D39398789563C84464A32F2CAC8181AE581894592FB2AFF7DD7CA3BC7DBE8E78B09C3ED24B42CD27B79834B62EF9323950F63AB1319E558E09F8BF00CB1973FA4CCC71C0F3529181F57EA133A949C19F9111CE5764A65ED95D57E1175F2083FD33959B0FED58A24D38BDCDB4CB301C406136816FF187F6A8EFC2F9494E29000453EE645A6F3A639D924C69367D1ADB45BD1AC331880338D5A30C58EDC48C62E69802077600722C0C9F8F9148C83632764D2EAED7CF8C467729250F59AFDFCDE801CDD4340B1DCF3D691062F2CAFF1C929AAE5DF16DC44AA5C1D3DD0FB436D1649D62A808DFE2E54D571442A7C076A1B25EAD130CB73B1063081704126ED25A4F731F3ED648E306FC03F3BCAD2873A96DB6AB02D69B3AF7C639C16FCB8C12089B69A03F4D085764BAA94ACA58A6B33B989009C5CCC661AADEFFA174E2BDF5BEAB3E45118D355CC353C6482FF9C360DA30691BA640C00DFDC63900F7AAE50B18039A1E358465A25388762C54BAECD8B570063ADEBEB4D0A3920C5DA4776FD2D05567D3125CB8D251626270D86D7571C1FE7DA9BB940F37BEEC6908C03A69C90B0C1A1FBF3083C3E22C337F54DA13871210BF1849545CF40480F2DFC31A41B0E3A6061C778483B9EFE2F1CFD14118B54EC337B5E9A49042EFF545907FA1D2A44CC8ACF3031F24BD748607C17691313BC893BE24A8028A9C18D4B35F628E0346EFA9EA8EC78EE3F8B9E73A29F5672B94E1B2E4F6E862F1860A0ACF0CA2E97626C3E4DEDEF08A956044BF0734DEF422030D493CC59A865354BE65FE3C3F8222421A496843C4A37B5BDDDBD43A94E2AECC3C25DCC8C1051B1B3C45562F3AEA4503D95907DDCA81923463118D458300347408563367B0B8EE5FE222A00C5F11BF61D61A782FBA8D83206356A61B61AEDA042E6910CB29CC3701011D2EE6A2BD1E140336BC0E7537A69056ADF31C8E1D48D909B1F5DD98CD18EB8143D4DBC5F8E15D7F57FC52292E683F470F6DC18B00168D6579254DE37D0ACBDFEC33F2604D7EA84924C0C5B4A7D93A662C67AD506BBFE9117376C13F196F027007489BED1FB1361A5164E315C10A88AAD57C09BE0E131BBD0CF08D8B835A609E0CBF55B71D554B38B394269466F274961B2ED3237EEA31278459019AA98C4D1DCFFF1A3B8B2B7B01E605F149AFB307FF757A515E02C43861283CA913DDDE871A901F09BBFB4A40AF118F41E703A4EEFBE395CAB206223D052300AB030F567AC7605B742A434602133A20548B403320E8E4DB4DC7D6393DCB1BA84B665796D0B55781909D22082537985B6BC935DFC43B5CCFEF374602F770A006F4CC14124675B570E570D73E72F799D9869C0EA6E2AF6042CE5645E9E2375E72ABBCAC8431D4B4406F2F7BC736C39107377A7F5AE00A9387FF8A6A537548B9104F03A34DEF0BC5A11E93E13985C614B1F65FF0914A431D4B49BE9D099EA6B639578E0A81FD7D6DEB7AB398138756C185D244F6543C6B924DCBA26FA7B42952C2C69C290EEAC752EF080C5381497573A9920206174CCE45CFE3E60F1652619D6A74B5B77DCEC6B211ADB0FE2DA125436EEE22824000540666EA6D34904B5390C616699932F86D380017D6C334CC3FAD3CDCA766167201B0299250A5A9F97D3F11B3ED8C4CF639282B15898EE7306D5D6503BCD3EB59456A32DD9CB03E95847EAC8EAA82CAE5D6DCFC883770FF9B91777B97DC7482D9FF5D6249893206D2CB7662D2C65C4C7FC775DE31EDB6D61DAE3CC20EBD9C96142A81B8A4DE77ECA814C887527BFCD9060B7359F07A844D1F80004C8E7F83EA420E93ADB414A66212B7B732C582F5F671F37124930D1A77649B02E90870D05374C31469421BAF8563B4B63BC06AF07F1324A0375444CB7B3EC9DB586959F5CD8C573878E26782BADE1D0D8365246158084FB386D2F6F43269C735DFF2ED912D2B22E1CF9A46D5BBE6768030BBE5C54991EE5A7C94CA51A1E60569213A818D9BCF0D9A84BD31854BB87BCC7ACB464F9A299EE02F94069FA43EC644E0B8ABAE5F01D21C93177DDCD88F68E6C577445755E55A0B69E27824681E5F26EC3B26B2A393697AE61C53B1B8D393480CFC8B3494449BDE86495DF56BB8475E4452243B2743ECBA18211E4F3DC5C106A456C1B22BF941901A031B7EC73A80FA5DDAC3F6E4A4C0E4A8E691605285F440B0761EF3A5F808451464479B1C4F4EB7BC66CD8D484B2F2EC3F44722BB7B1D22244B7977058F8B2F1D1125E5978FE03F807004CFAD879F34466575510DD7CA24DD0CC06622F90E0D9A0299D42F33A216B2F8C9918788DA67310C6F0F113908F35F983BBE0C89F34EC7FFD3B7510CCD08CBC154C050494A41FC06E716702D2614A520CFE162DAED1FDA5D1A8936857EC3380252BB33ABB40D5A6ADC0255DC9A33A5892B5689A99EAA4BF02E31FE0687F9C6F76DB3FA862729E2C686173FFE526C3EB042282C2CC73C4886A637DC7A63A970DF075004226A3479E643A3D8128CB7BFB5F9DAAEAF539DB8F1C038A1842FBC418322CE1E34319FBEAB6784940CEB9FC1CD6FBFE0898736D10CE496877925C58653E4F15D598A8A11418B907BD48DDA57F2FFE8E9EE840569E2EF222FDD0392CA18F7BD9A6F9AF3EF79392CA6CB2F247AC19888284CDD66F45DBAE32EC084AB4FD09520C5F68205E3C1C4D46474DA36C2ECEDBA6F432BAA046B5F81B1A02BC75C248F5517789C79CEF555120639FDDB51A9705B603BEBB3F55CAAA601CA2818DFFB2A4AF69829A61CB43CF3421BC2723315DF0E447FE7994ED1C07B076DCCB4D4662538888ED35E86CE3F0A2722EE3692B364959A9054D03D57CB119B4F1EE5D43209F3B60D2E288F19650F9A1B4795972F7ED2FC4275773A38E1959585792331DE5EEF4F2E540D8FDC2A6B514A350640A9A3D80CE6090C9C0A45B159CC0090F5FD71E52DA5D3E78764E0374D3AA522DA29427CCB3BD5AB80F8A85411D66FA2C56288D6AED168F7F73CAD49EFE7BB0BBAD5FD76230F474BA7E7D1885CD60788B20FC28265FDA8D459D8A426B0DC5ACF9DACEB33AE1C8927A761C8AAE4A363B16C2137B25534D6C2C2A9864C3FEE3FF037A45DC6EF4EB81E389A0C963FB3FDB66B248AC975ECE2C9EEC309C47BCEFE1614B93E7928B198730A77CE293F6618C0D0A67BC48AA07EEEBB22DC34C68DCEF2F968D6A09BE331F460F0583F7345B04E53A27F53D0D2D275C6D0ABF14BC72B080B6C234D981249BEA965AE8F1DF9E5E902F4DB9EBFD7368D40941A27E09127C16F3C946529E3E39F4970E8B0A47047E07C54539E3BFA6117224DFB8473C6B80A5C3BA47B82EB8421FDEF71B3E309F9BE70290C4ED2E5D2FCE29DD795AA6D1DC8EEEEFF5AA8A70C84CB17F2C78EB7AF397E7B8C02140EE5E9341D18729281555FFAB8CADC06DA430D8D18B6F1FEFA15E54A874B8E5A5BE68719BA7DE59A1B1EB6A78968012E2DBD12AE3CA4D7C0C473D9126FD11B8E29997B78E64A01622A92C8C7D43BAA6CCB7A3DB7C14B8954617CD2C294444CFEB54DFD399C6412DE2DBAAEC5D5C2E2776FEE067C33CA718BA78436A0B249B374169E37D659549A945E416BAF3CCADE950AC73C15D3A39C396DFC7A566110F8C22FEC608E20C96499C607AA360A1540BF7B850616FB7EBB8F81FB58BFD8239A6A1C398CC8446DF7613EB1D8A90ACAD366AD5D447594F4CF4A1AF04020E7CC26D71AF83C0980E4EE16974FF45207AB1250FC987683223A6DA05A7F7C45669767C8A3FF1E74920C08A14C04138DEB45675B1BD70175E5798C2BD45CAD288D3A59FD82F7ED1B07CDDD3DAC33C900746FEC0588E7CA0144B47C4C8D294DADA67DF533A52F53D315976BBFE63D985E37BDB92BC9701B44DA29F169BA00D512EA08FFE437CD74E06E7CF39914B948DCC1CF4089A0DCCFCD0594DEC74EB5C5623C2D23777AA37E01693637F0B0F3EB203F6FED3761D05BDAB21C95F8A0B6130D878A008A32F00FC3AAF4826EA65968532B4664FED6E9F8F9EBDFA3F1C7E9495004AA6917C2D914585B23EED8471C07ADD0B3F2373891E20C443C51B3774A6C40E71BA4A24D3C3D415F63ECE5B3C33056D5997B764CE5A1564B2AE315D95DB6B8E14B2FEDDD212B7BB0A50F4C03FC98A2943123A1FDAFF1BCEAAE1908EB152C78E7F28EF600BB684CC366A19FB8D73EA0FA0D8F8CDC709656D2F82C75B31AF60DA953B37AF0E2A2CE3703C042716EC69C4A6BAF84010E689C3A0989C8200D3875C3673B703DF77BB1FC06A678EB3F967BC765F534A5553185E9253EAF3D3B9914E157FB766699B60F5566B8E71566949685701FCFA6B4438B3D4CDFD62F88ABA114D819E10A23AF2E9F28001B6B28E4EBEF171B83A389471991B104218DD87BFAF9631E123EDE3EDC66FC3F0EB2BDB71556F4028DC8F1731911515B737AC05F5730AA183AFF5A68F4C563C5E24A4B43F468AF02C7589A6371F1F48E3DC45AEC889280A3C701EC1D2ABAED877E94CA0FB7BBEA7B7D49D130029314B37CE213385A993C629F5A1D649AA5CC7128BF98F26E1E5A3C9A59E152AA571562A458D398E59AF22E181F20814AB681B57DA5B1E56AEA12C9A7C5D7E71A87E9C1ADE1944FC0A2E6539DCD1812B76A49B338F48BF7F95056FE31100B881DEE2763ACA208B237DC6D838775AC53685794B5A523E8B104F41D62191B505DDBA2FF73036926CDFD0D218FAAD7BC3F9A3A88ACE1E1198F212B5C0F886070E029054FCC18A5CFA3D1A200211325414FC0F1B3135A0823AE514CB91219FD78B2D0B1707EA26ECF9279B6321A42E20E99174197966DB5E7BE63446C75112C0AA39123778165EBC7D2C9E85ACF80512D5469AE4EF9D228A4C00CF46708FC08928F2F2C6BD20CF8B628A194949AE9CD1A6F900ECEEB2369DF65701CCEE1BBF4EF10625870205FBCC37E0A705895649478DE329F3D8C022BF62B1B59E8F1EAF7A5BAEC5A678B5B9528C44843239C47AF2865A7E022BDDB403AE1ECC75088B63D5F4044FA282846470FF0B8C1C1D87F597E525CC452058CFDF689BAF9D8AB7F76CCC85D94602CEB2C05A0550DDD82003CF05A9383661BA6FAC6E500F86FFA5F8A6391F0444DC6A8806C7B8D51A4DCBD6D38F5F69DD11E2F4E5D1A62711F854F586FA62061837F8AF4451529E541AE1CB4D185A65AFA72A53C6E82BC127182058BBE25306D50375C998567FF3AA8D6732B6CC03FB524A5252ED8405D71AC9E09FBFECDC727C712ECB8C23017B957AF56CEDDD64D36201E834713A294F2F5D79B365A9781DA42373287858DC77774416350DA85EAA228C2F0ADB6F287BEE92B35FDC3484441E0BC85CA847FF62581DC2CF833C55E49F9D6740C7EF1D7A7CF836BCAF8F46ABE1AB3B91BF6E3EF77EF304000DF48911B58D866063B588BF1BD2EE84F981A332D6DB5FA6A6682E9A36873C203C617A226B934677D4B1719A01019F97A874F72AD4DF8779A5BE6D22328FE3F8D62748A128D4A17D6DB52F47C6DEC5A6A3EA79EB6F1A6BDB206486782725EAF5B0258C1338E5164A3870E7BC5B19A8875C55CBD01945329C6D1145D854AD9CE4DC89B87B8598EC2B60E09EC202EEEFC15C18BF4C75C835C61A8EC7BD09DFBA9509BC05322F793166D1810FB65EBDB6C577EFFB880C19F8B03D4A21A7106A9F5AC275F9766413E82986D739B04D344374EABBBB886B88B54E7CB612A9E38D7C32454997B2532518DAB3DD1474BB6715EEBAA410FB62E24FBF5027BCB63A545F7E90782A4F2AB15E7C6877B5FFF1F2DF07846326C824BA5010B864300094E4DEBED121BFA6D3CCB5CCFBD20E1ED6FC6F2CF8DA370A69D2C05B8655DB2792AD00ADE9AA76A30A12F899A955E00FC45FF1004CCBE3D67C671C402C11896F250AC29243045E6D79E8DB73655A945C4CBD2337E13A884C8161B06E3FE70C3885A2733714B90FF0803D24FB150701F6A5058FA7B6FB7C2755FDA6137958E498273D6C9DC085F6BD047F051102AC136783D22038438CB745B0DF6656493B02E0D6270A0E122242A8E749EA9C21ECF56007A3A86E0AA22FEB57DE718D24087831C438920B60BEFE0A4428C46C85BB8097BE28F9D422AC7860848F589DF9F8EF509980A6482F81980F39DF23771F901BE7BA511AD849D78CF27F505B3F70D2CD33A9FD8C91C1EA5B11D1C7870F87344A830874A897CE0FF830E458F506EFFEAE27C16B3336EAE12469BF9082A7AF1FF40C6986D67D0BBFDC00B2011D7FC146D9E4817A129DD29A9615CFF8E58AE5281EA373603E1C87DE2C0CA8903E9DA4F0601EA9AE79960F61B8660068D1E4F3A0110B7BE03BABD8446A413342BEF5D56ADD4E2014500FC117DC720969EFEFF65AE41BE308EAE0A155F4617D5153BE853C456D1061544193482DB2E94F5FA8F20DB4AFDB4A7C1F9A87B536D1AD9C852291D83942E57AA83085452BD7849A5773DF5DA4D65BE3C59B8CD42DDE4FA55392446B8B4A940B045F63273B04A24B480B5756F4A11BBC875B10DE59CAF23A0ADB925F736193BA23F0B0E40E62B7CF6E1A7AF8527166D900C32E4B592087D934F64663961BE9F92E0E6B75F73E59B699AABE05D35CBB03A6BB278D4034D55C8D007CFFDB297D18F44A037D084B0CF1BC4536AC4CAE212247BAA5365E989E0BDEE3DCFF134098EA93C04B35E14678E4E61D02300CE305401AD0E976977A1618919B3C611328C5F5F56D6EC2F82CC79D98880A00D03C4646B907760C75CEB42EF595CC610625C65ECA9A957472C7DD0768B56BA6810880C4712406528050805237922AA7B6F0796ADFBD3054DC8DE467A2B9A480B4421FA0A9913BBB328A95F1E4E98686AEDB447FB90C613FA4CD0CA4E615C5257EE4922461788EE6F1E5B58F8E953CA85C98910BD61357F68D215B0E477BDA8F73E6A9466D3161241F14A235816D405E98AD72C181704A9852AFBAB3DC0A17405E5D5D18FCECF43B55CE803B8127F506EE56D8F3ACE8EE1B55D96BF63F3BF7FF0764E0D43BD473DA018291CD41B6CE69CCECC145B59050C4775CCD8443C7770E907D2665C6261ED851ED0C4910C6D6CC24F5EA0506AEF287F081E19E33D5379501754C919FEF3F9F66B977C5D1572E846DE30FF695755E3B998FC29A30649C99A13C2A41A478A28383ACBC1412CEDAC9EAE61AB4CAB5454CFE9F56049CA286AE4A7CCE76BA877AA08199DAB45BEE32A4084A14D54FD94D8A7747F5D8274D6238CA6230DD29E6B163A43AAC55CF825A08BBC362917B96B4011515C8B913E2B5706CE110901DF7E1F3B0AAC2932AD5AE8EDB46EEC9B425E4A82B99351568014B4296EBC5AF904289B09B3DAA896CA23D3CCEFD3E77BCC64C6257E1B22991BAFA3ADAB6AEE64E0EB2D0B14C158DC4AEFE24C77FA9E0262CB5F3312F4F771D939A1547E3689C3BBF922882E60E1D7B223653473D02FACF07DD94CAE92C0556C8FE9BA6E99D61E0A02031BC0B6D303E46A91B775A8DEF3F9F1E4712F38069AD511D0483103F2A491D58A4F95D5E3DA66E8B9CE3238A372E319E3D74C6B95D6B75BC8A2D642EBB2C7388056C48A719FB9B1C484BD5DB997FF4277AC06EEAD01EAC614591C9C23BFDCD34FA88B972273A87FBF9F198E55FAEC5616872AF1E19F3A3764C3819C5248657B40043F4CB784DE70E2A725AA71E98D55D0B65C628CAF661F488BBB91FBC4E440D3649707746F77C7C2F056C2B66E86422D6AF5CEEF2ABB67BF09A1A5CB028D9011E69DDCB199B6FC00916AD6E235E117021D975C5C95667268416318CC7FC18E0BC79FDE8F1F1ED7192E39A10BBF9AC223FED6612EF91C68EF018806AB262D0C142CD4786093C058F0353DB306BE41ADBB173CA5F8A340B14860FC8850B5A959E0D132D02C8256FDFA70E3B2A87E078255418A27FAE993D2A08FB05EEE144A7AA14509CEB9C4E8BE28311D99F0617392091C345E299E4AE92B1FB518721C41EFAB908D4A7777B1F1F72AC311C1E4F6D33B6651AD3F5D9AC88A971CA678FEF1CD470EB22E7FC5ADA27FE24E4BC3E4872D43884383AE94AEFA597D9194BF216E01AC474BB49735D0A3F98E9863253961E8BDCAE055EF705BD0B82488E207DC3C8932768E419B519E61FDFB5F97C25CCAA50438107F9BD67D497340D1AD696288C6A6E95C87B99FF8D627DFCDFE7AD9DB4491A267D98D110318880859F91C912DD9D5FB3BB132917237990683B55064A10B69E1CB6A88182BA2869B325A11C479FB76ACCD2687974523574C717E1F6E83894909A325CA8FF39C5EF0F65A8EC5F16569975A81DF9686E91888758249930A8B4617BBB14AC7A6FC4965E8D53128D8F2839BCA1DA9E166529CA6E1ECF5DD7F4F36FA223A781F3A1873F54855E12CB5C856011F40DFBB816BCE4F530B03DDD5486479BE4FC83D4665DEBF7E867630EBDB80D21E71DEE79A834CB7819ED86B55BECFE35095A832EF9748DE69543BD7A4D9AC8F2BAA35F836E2DFD7A58CAB1AC3CF06FB06431BAE8B1C6C8B33A01797440246F7B3D1126BDB2E2B1F6A5B7DF78D8B924D1E12F3A3E69785C950BD462EF8099C8C2A462267FC19A203760D22FA6F146A6E86057197656C70A1EE44580CB42946A1B739B8E21D964C6BC18926E2679562DD0423AF1956318ADBDBFEDD76C410DEF1F94A8AA92C5765AE5B924B23B68835CF71C612E06617719ED0326055B4B1896FBCE036E1FCFE26AB6D993CF0ADBA4EDE6283EAB3193ED2BBB232F72E08BA5049FED1A1EFE4858F0608A1328CF969F9368ADE08902C77CFE93E56D10ED8F82ACC4403E86465F501E512B8E0C4005A5B6D7846CF6686B0E313AACE0872DA2E6E9CE21EC1979B5F4F601AF9F3BE512217F2F6C6F2CE3DFF2FD2E663AA022E271AB3479D6D8887151CB2A42379A0162E294C602253F1E9BEBC319EBDB5AD95E45C4B4A0E6AF50EF6A724FDEA51AA60EB9E8B9BF48269BDE9E92BF08291107DBBAED52FD6ADCE5A6D326504ACFF43BEC4BB68B5849FC59EB3B6BF770A2E57400C61EA23AAECB4C0417B1F7CFEF8CE5B0E32C612C596F5DA89D9632CBD123E1A932200BB4F2F7447DD29BD32171CE6DB80FD565B9C7086F72D4E0BFAB3F76E30C0114575297CC39341F06C9B505FE57E15EE606DDF56E3AB8A4B205B94031BF547D0FCE312D20DC9F1C64FC1FFC1B0575ECCAE38CF368CA10F3E1B8E5247E76B3DEE85F07B66DDD03C440DCD53BF6064B9A5B2119C19192EA9584BB2449B4EC8F07548361865B7A2459BA2E4574B57E49308EC409A65B433FBA4995D97B611ADDFCF654F95651A7F514A4506B9441BB2D4DE861ECC67E08E65C86AF012DECD8D01AAFF4944747719EE663657DC177571AB4ACF67E39F6A714F34156A07EE0DCAC665CACAE8BD59C6906168077946D7BB8A1727213F85EE1C0318A426E2AEC962F2EE3BEBE9DF250E5455A5601824A4DCE416521AA71F6BE5B115B4FE822E346C05BF3A54F2D12108FFA138E52345B92BBF8FF96E033756EE0A1D841F8FCFBA2CB400B9FF3C30325B05D9EBE3DAE60DE537C34A058BF6ACA814F9AB64950736430E53DFD4085EA7F457911D8BDBC8F829DFD4E6BC6607A14ACE89CFF61D0A88D205FD534F822A7003393ED67DABC5706B260352292D043011CB0C2DC192C4AEDD0E6F7479D7A7B51542C18699D607E7C670E69D50DA33CB6A1F434CC8988E0E4BF505682EEEADF7F028E508B464281A4F75F9B696B1CFB1D46671906ED3454B7A5F118234D37DFEF10FF80F8908F46292AEC2A8798C8C04C92737B2AB946392731B86A1CB7B6E87DE1995CE7E17DD42F08A3BB01BD61C31EC006D3A57A2A598FFC5F72C66BEE845E54A3245772453A42F342CF624F2D2363C9BC3ED983B441CA848D1B360E05A511BC247DD9002EC1F24CB43DC1E1DEADD8072996CAA7E1B209545113E21D03996F47400979DAD71E40CB41DADFCBAABEE8B5C68523A1D16CAB886A8DC2EDAF356E29F07A59A12EA40F7C25BD459DAA3E888376AEB1EDD23F8EAF6C5FA9312BDE12C69CE80CA52210A990E1BEAFF3F2B4F66349D8D930303F67556A34C1A6705820802B120C8A7EC9A736A29AEE3179C642796550788019F50D49083ECC24F0ADBA61ACA63FE460EA3F4FC9781936D5EFB19EC0C8A698547C56840FC8DE8515B42A05B42593306F43853C5C4469953C44F33C1A73708BD6A8638E10D3D1EC7710A623D3A164D25C6E041A1B4041AAE6E36AC1A7260DC0320FCFA425A6EB80CA73BB0ED30FAAAD59C1F171F5C0DF53AFC5E21F856DC7945C9EF44F0ECD790D2BDD740C137217EE805F3FC8B984FAD3BC2DDA6BFD673B5ECE02D869123E92CE7AA3BD8EF33ACD313AB06D9355F53A60EC1A863B09A3F992A7EFB426E54903C0B8DB58624914C6FBC7B7ED33E5EFE999987F71FEE04A4FA939B0819D9EC25245CC1A723C0F1123F0E1400C3E5D9E7B42AA63F2FC08CF2242DF67F62093954202B83989F026FCC35DB46C7604EDCAFED797074BD0A846B9F4CCC4753CC1C0846014B4FD3A021D201BCD84657B9064C81D11F5FDDE6D62D7034601094B4E2CD4F72075F484DD075FCCFFC91E37F02CAFD46A8892E454CC1D378C5D5715E327E34E0BE61345D12068B07D529C61070B63900206508D98C3ECB85C71EE4DB0D3DC9B1B0EE1B0BD6D8D0FC774A5EABC4220CEFE79FBA206C9A0456952CF29009D03A31FA69AC52E93906540E2C11602BF57B48ACCB3C73FDB0CE6532B2FF5F83EFF32ABD40E9E87F7105493C190FBBCD19D483EDF7A1146BACB15DB1474362E477780A77E374C0F13EF637C4C18599D97450287CE46E777C350E3750042DA06605BD830EE952B39F2692D6BCB5017F70381D914A80735A80E491970A433A71255B73F22A22A870FBB0C7B2514445BAE0215728328AF8E9440A47656E3B17E15373B865537E0E979AF5D0A3A794ED9B9DA008AE3DF6C4A6C9E608CC49701B87E3CF4F2D36F29916C11D0A09803955B6DE66CA25455E860E1D54429BF36E3486671981973DA5518C76F415E6AC3106921F683BF97DAFDCC5BA02878678B3789223242099BA6F95F09F988D051858820F3A37127EB6A9260934088F117A8C2625438450850E5084AC4907C695CD8D55BAC18051D40B3E8F62D69094A004FC9C9849277DFE398CB6ABC0DCFF68DAA3109A4361C4AC963C06B4C63FE42F25AA75D1DC9DF64D4D3618EA0D48894467E2D16413B2B888DE6AED60A54595E821EB00530C4D953693C5623D13D6FB13B964F025D5DA6019A0B87BD1FD1183C697E98EEF8097770E2288E776DDB47A800A85656A80E882A508E19DDD9FF45CCC3D16377A3ED84F0AE9B43A032AE89EFB6E014378C008E43DADC5CBABF33D5EE641E20180BD500CA1DA6A193F097F3B2EB138858B27ED49CDDE25EC652A06C31A8C1EA011B239B0593CA89558DAF48034C0034045D5EB1F7BDCC97F12B1AE5DE56845B2E6934779E38BA531BCA3E5B93396F567054C2BF000C8E9D1B73A478C524E7733CA7579EBED9A1DD2410626DA5D38E4C5A67A336EBEDA39B690C97D38E08CB97B7026112FCCBB13288A35440128EF3C146F1CCA77014388AF2210A1989D0673465E4FED7F4910D00118E6AD0E173BB3CCF6468710357D6F27B89825D8B67B825376EC8848571DCB1DE411F9310B06A98216574EA586787E441D22B04584279D46EF833795942F342A2F9647DA51EA49FCF5D0CDB2D3C86EA04A99B57F4AD9041F7512CCBFEA2D0E18BA2D7157F559A6E2D4452C84F8E376D3C3CD110D4BB9D1D0907E1311F2F1F8F60492D8281EE8197CFB92DD8F430D9413E64F18002A011A1B1AB203E10A1741A2511B268F168A79AB23F2240FC93F540CE47AFFFEF2D77742225A9FD767F727FEDEEC797FCC931F4478DB242D7CB32D206F85CF86A594A3643EC71AE8526FB9B739FFCD79EE400B24D95DC735EE445D6C07D1167E0FB1B48B125752E697D902733C8ED76571F0EBAC4056877B203EBDFE1D51B0A5BC34D5FA18CF714798FD8E07827ACD531658E9225C9538ADDCF75261601548021907E57F965FDD307E4538C2EC7ABAA9DBFACC4A6D5ED4EBDFA41F1F4735F15BCB16C76855E0397B6C47487CF1DAC14336A0A687050B8502D38E596935EB256AAFE5AC6C22708134CE4877FA35703022EE56EFB0CF38F7E3D811675104AAB5773E37FE6AE9DED7DDF22D03F90A4847EDB0E085E033D72AE25E2CF4EFBFA19964181944DF108A228E2345D509F6266DFA35CE1D1FD568C59BBFE4B337EBF5FC41DEEC70AD0B174023DFACDEA561842E9382656E851FE108177875CB8A42F15EE8501D5BA679A4840D6C0BAC6D141108DEB4E9A90286BB2596E87D0A974D71C26CA93DC0000D8EC4DA94431F4DEF624AAEF42D761CF329A2EA6366C39B6F76D036185636EEDAB0992EF56809495F63E6AC7B611B285FF0F284B899523C4FB5A9703F41046909E344731C4ABA88B716BC5FDCE9C1F8AB371FFED752604A7F02DFCF679409DCB830FBDAA71B7E93A4F3FECE05CC4492426D9B497058F18314AEA92A2DD50903429AC99E7B8F8E7302D935427681A922AD82855DC21856E38AF4317776AF387429AB25B364C8D93EA770E735C61CDAE127418D78EB07380947A9871F3ABCAA18F03B63488A320FECBDE63886EE3A4F401A313811C732621B17C4565C07C4B9E33F7D4FDDF7096BDBA41711AE297191BAFEF34A895BB22554CF55A7AF4C7E33E85EF85395D98028B44922F30265B1DAD9ED2E0D42B04C09ECA3E43E783182C86A200AAA3186AC53248548BF2EF584BB9AB02351FFB40B071FE8AAE512AA8B17A3B45CC3AB706D229E8588E97CAC94E336D902C94135CD0C039C40B641438011D4BC83C0D14B0E318C4993D0CBC0F79A5BEB67185DBE28B52B1E564B9AD8DD4CBEE49DEBE490BBFECE34A48C88EB94EED0BE334C58E9510E74BB02EBB21733955B25A9EC57C3CB84811D1593D91510E4689946A94A2003AC87AC35998205791054742063E1C29A4AC42FE14CAD47FCC405D622C60BD4C0EB5B1D0ADDB52C6D1A252610F8D7F98D64E25FB5C5C8F2AC1EBE5020793E05773E474FA9CD5C21D5C2C298CE11CD910914E7B18ED80EEFF9C00AF20267446499D2FB3EA69834F662B9BD8D91CE5CFAA7F332A7D9011010B73DD2540041618268B008BC3B49CFDE1B3AFC2134B83130F4F4DD94BC22CA2E3CB9CEE3DD698A84B669D57E32A8C72D916B7B50F5C1E7BB6A93BF065C49AFC4A163F0E1C0A585B81A04AF0C6FA8D4F1F6DAE45557331A1C125CE476080A16FC9C1BB8AC64CA30D5C988EE16CBD2E464A0ABF0D78EB3686A9001CDA1B7F53B70189AC0161503337F48044F0B4FBB227B398B2E18624AA4CCAD20FBC4E6A67111AAFA549A43BD12E483BCAE4B724C7E9816CFEBBC6A96F38A44C1804AE9272DD8D97DDD38D80CBED1650A8EB438A6EC5874026E3B12B2C7A24EBD8777BF00DBCE9EC1B10B496A633B1AEE24A236CAE28C998C4FD593741258E05AA0EBC051FDF32E70C62E8181E8B651C05CEDA40AD6BEA7AA9F6708C2F1CD2A0B47A921EC28C85DC865DBACF90ECD9DEEAFB6A9C159A19031F669129FF092D0369D7E7AA1E3E906DFDBF2AE4A44A1C77EBB14632570A76D3101431526414E09C57B36F29A74FE77163172EC98B90497077642C5B63A905D628F10DCDB1BFB42C639AA801E586C78F91D486309B7AC45EE43AD0C783D46F02A7B9F51D2DF2439D596C69982ABC2CAC505CD74BE514E2D44F1CC12FA406E82B7A44491B363C14D289F9F02C97BCBD0DFB2C9972021B0A634D63CD0888DBDE0DBA22E56F7E2B9FCDDDC2741DA4EB4C0B028F9FF97DBB93208975AC4005342C94F462C40FE8D1391FB0B7A3AA97B4DA4D5268018766B7CB002983F3E031B992D0C2176D6F474882A5804142C0D509FDA637AF9EE320EEBC55A8F8CEF2878E03AF96B2994380EA81E44DEC102249EB29314366452C1715F5159395EC5996507B133258B9B4ECFC173F74A8EE8D8B8C01EC0764FA302266C6C0733C6B47FE4FC80DAFA20BC9380DAB64DF613350587C20FB0EE0D40FBDEF48612B3A7A21E09D46498012477C66ADD36AECDDDEB8C75DF196B41A7EB350F7D1929DE86EF449447D1D3770D4A6096A65589ECDC6FA99898047C16869E1387AFA8731AA5C7C7202DB2F6E79C31DF298E2C2390C1D018D7F9EF145DFC5C0B5C558E797BF62808B99AB35DF24DF224F44C7C48BE6BBD7830145418C411D9158A0B2A2E7B4D6299D8B7C619DA86BA9FC80B3F5E3C251E1B67F92BBA64C3A776234CC373C392CAD21B8082DD82CB569943CB1024147EEF201A0235294B5970674A35D4A365C366D8F719901DBECA22F3C7E50FCDE797106C5DDF6AFE12FFF2B21BA3A1006F42715CB9EAC27DA176519FA98B42F2A240450537018C03A25AE4B01B159BBBB9709E83E5760A45C0131EBC5B72773FAB142023ED88D531C6418E349F2FCAA294CD446DAA17D58985B1CD5239BE3B01CAEDB4F6E9B32BD95A909E0BD357FFD605EC3781C31EFC2A509D4891F7EAA9A5DF116A808C599B4E6900E1F727CAE4C5DEEDDE94644E728647EADF6D2877A64504BED973029B0B1914FEC289A23F45EDF7A1ABC7D7B32472B3BF743FF7AE235C44FBEC51B14A101728D16E8BFACA692672354E289983688C645DD9B1C24355C64E3513D21DAE5A72D8E0D8ADFC0DCE0A43B459E0012DF6AC841A8BAC58B35901BC660146F86B34F9E62CBCDB15C4690A72B9FA6C3A2C1AAA7BCEA88304BCC342B08078E02815FA520B2E87AAEDDC6737DEC2488C4FA426FA14250C7C21BD0C602B96CCCF3584E7E5D75AD2D836096503D6343ADC1BBCBFA26617D0197D59E67137FA65DE814DF9EF3688D1D711FE4391C297FE5CCE0FE1852A46D094FAC334D25B25E7A15C61EC9CD27D7262660D94848B3951400FEA4D3A3976D5E256211FDB4317152E071B2A90D047D5869A637ABC64767F8F69C570FAB40B019820BAA84F8D71215B318F7AE4D14B1C4AAC7D8561FE84136AECCD4C2EFCC8EA56304722CD2E8C8C756F6A42EA6FF587FEDF4A4F8593693DD419EEB8201ABA14994E3716D0D976C17350CA8D86A0F2D76C22AD667E9D37A5547C4B5887140B87D7270D68B09A9894F06F1925362FB93F3D17D53376A33AA3C283CAA8ADA392A682534ABBA51B8395B63A16A77E22192EB9B276D7B42C81A6510A7ED049048E0417589702BCA6FD6414F4BEAFF4DCE79234BC5A7058BB575281241B0A4FF0F9B9E141040D956A2A29FA8CA6A8CC9FB330F2092BE01D344F6980E0C6B7B2AE896CE68EE362DE3716CBFBA03A0BEAF5FDF12F9240121E7B284438DC5845D74A832E246C26B2563D0B65F3FB9B43057F0731EC59F4A266A34E8AD4128201B8EA3679BDA091436363DFFAFAD6F66B5F945B1791C89895C567AEFB7412674991AC4EEDADEEA3DFB93DC748EB27C513BF60B2AE53B62E15F8BFD175EF6BD8F65FC68FE103013C5E03318F8569B64228AAB84257FE8431629A109A110528ABDBC76B7A847EBD773869651BEEE2DED053F5ABC3AB0D9D862F63B95BE5AA4577E0ACE99D35325883EC9E9C59267DEDC35F70E369CAEE222CC816F40ACEE0857C6864BA87C8B14B83D069D652D70354E66CFF030F0C0B54B71CED61200711A6680EA10FFDD3697CA8A1969AE931D77EDEE1CDDB27F28244321EA9C02BB92FC2C67C9E8844A964FF8C833328C12D57435D429B8264C4195D0FEEACCA3680CEFB57887AD0E91714DA2A6A2C6667A892A8C96C5DF64E1FBDBD190C4140EC17D4954711408F2EF1A6805790A67F17303E6DAD652636EB9AF3452E1D079ACAF7522CA08DB96531E08E1F924B6DC749013C9C791CA834EF551E3D5EB19856D4B2D51A4938463A98FA9D2AA18278F1BE512EE1CD8D2F5E13108CC112F8768A0A3CABB7D0401ABC20A28D24821937E934E719DCB713D33AFF9D09369C3190FC1A29F57177A94DD155F7DFDF8202D9004C4E8DCFE2E707952397BDC06A83A11EFD02F858BDCA20339CFE2A3C259DD0F64581786086B25064E51181D0B4B1BE017397C7BC56F784B06F4654853837D87BE8B4842B92228FEEC798F6E8C38E9B2279361FDFCA56EAE6D4C48A90C7683BB3D273E94253E30811CA4A5D2346F827BBD9CCDC77651DB70BE0283DAA40D582B2CCD4E1800718ED9829504F3CE779FF2434020E932D47FC2CD68C86C301627526EBC752924C4301645D6CE5515CF55C1CF7255D559C6184B4A59CC1F78E618F749B9EF86628E713123452599083C04AB8FA77317A570BA4ED9051E176D21E924F2B4E164AE7F3D3B62FDF2BA32DBB2F814A35F1C020D104A7735090297AA795E1D2E2F07EDA213F62B331121EB5C179C2591846716912E59FD8AD847E869E00840E41117D4C1CF6E8435071DE1802AAAE1594E3808D8C60178E1CD64CC12251120243BC7F9AD5FBE4C6EFF1836DC01A3AE6B309FA74871D993B4B05BAC3434EB462F97A16731CC5ED82DD9EFF17C8BB16623730BB9005D114B750DCB22AF29EDFE9D58E516FC050828B50A5FBE6C416BEE215157897B606E33031A22363D554DFE45D090D887AD44EC2A66C2EA1764C67DEEE3ABD282472EE8D93B11F6120624F7E6DDDF3D031121BC3465AB6BEDCF2A79D3BA449B412BA3E746D0308D27BC0E1205DFAC0DF3B8B2D99FABABFDB4E4556312C0122991E3BFA0DA6902042C0FBD4651F26CA126E6643AA9087EE47BCC749AEDE36693EC807B95498AE6AA0F1D2CD60FE29B30CFAD129E6E1D78E1C1FFA9BE9DA1D0BF5B93E0D425A8C9EDE1B94330CC93AD2893C1DB1BBF80D2EA2AECE3605E8D5685EC5896C8EE42143BDCEAF13142027EB48F819CD822999D5F803DC826BF866606914684C2D599C4098263D509DA819FD040ADE399D42301BBB2E10D2B8EF872F3A84B694B3E9E69BD9BC3E5127084D4FDDAC0BDBC5803F36D551CD2DC7D3C7B5399E83DE10E9F31F6270D3EB199B176473A417608BA008187C30348FE3E86770FA9347718369DE9CDAA7B53B2A27F5792014E412F7FDF7FC3293533A8D5BBBAD0748304584D46F415C6BA1EC13941C35066FCC26BB2C27E2A7D6630199B5C466FD3719841FA5D961AF1B6942B111073BFE49DBF636AEB201A83D687E135510CC3A2545F0AC62E739AEC5E2CEC27FBA180D051981504080C76D4654CA3C8AEA964D8F52BC80E424ADD84105B7DBF00AE774795B23158889DDA7BECCC1CF47BAEA721897345D58EA4F1F77877589EAE66D9C67149146F3407DA9DEA52F4E601E3DF8FA63C44650658B4D3B0C3EB28137F38ABB18DE8FCF9823BA18AA4CCE122F4782E38C0979C89F2E20F3B55034A300BD01F4951BFC97B40D7935C47082E843086FB5E80C0364055DDDAA26E12F143F058F3D7D5A93876F749348E4DCDE6BFE498D2A5BE37A314B6D39F54FAB930F410D00F36F943C277BCF92FF9D20BD0140D0BF3190898569CBE2354CD05DECFAA316697298467241E0DE5FA17376E0DCD6DD117A9F6C1F983814950A13F7783FF3A14639C3F9D5F289C6EC5EFF76740689C69BF6486BA9B3ED20DF5D1BC3D4D92E13726712E6E7AEC92F6DDE516F087A925508CA6F0FC2B33FB7413BE5B81F6C2EC8817079A1ECA39356183ABCD59CE156500619434189A5895282DF1C1C870F66E3B7D4FE1781AE9414CE137CDBDF594C62D4445247A4C632CF7CA43A2920B32991C1C4CAF4D47657002DDCA78156E6FD20EDEA43A39D48C791A8ACDF96B40C59FD1D00F0AB6255967A46DBF0C83F44633F55BEA55C1E1E96AAA63A4EAEBD520C6A9AE90172E29679DA31C2A19E9B2D600DE9ED99F3CA36FFC7CE716D586B2389BD19A7D81123B0DED2659F1EAD727D2A06207F73BE61CAA25418E4C2DEC5EA5412D610DCD863E519535F53C37AF8059DA77E7550FADCD15D2340FFFFF8740509923C0BF68720F4FD6C96D49B9305B3716956DDA07BBE28B25B097A1BBFD450DE7257E5494E10AA4F1C53BF57294EB71E0871FB39149D8843328D168CA3C9683C135BAD55695194D319FB875F7D281B7F4AEE0C7A8AABE5649C5F79AFB396E9E5DB8C56D8CEE4D529E06A547B574CA4AEA10541BDB8B57C6C6571ABC76E0EE1D9ACCC2136260711C29FAE752EDA3D52AEFDB9030D9A5EDDB679FB8A08D8D024445B5607F3FB4FB55C0F2A0DB19FB26861E5BE48BBF286C113C6453E2192D8FEDE04DADDF5CA7452239DEFD8BAD0EA0C9FD8DF048236AC56A13AADEDC6D846250A5BFECBA6796D94EFBD31A9BE3A82998E384218DAF3AD0CEA7CC9EC2FB7F12378EC0CD34FA6BB9BDD4B2D6997CD531F3DC92ED600F929B718642F4B3FED4AD6E67D8BC28B8DA4201931CDC04A5EF7EE4A11CC4E32545EF990EF438B99751680BD2D1F2BBF5DD6325AC37D4E96F1B4F4AB6E9E0C96510D9C0F458C4E4E7BAC75A6FCC701D360FE8CDC8A37F5E98CC3F8B4B5CA6D786F96BDDF7BA4EEE6DCB6833A13B57DE2F9956587D581E8AE8D50B344A046F13F277441A057CC0E1A4761AB6556DED7803432ED4A1837649D66B69C7B3D4EA9B1A8AA228A78EA01C566EA36A980F8CF9BA685E416FBCF6D8172AD379BA3A2608E32AF8FDE81C77A45F71A0A4B1CF72EA002CE030EF565C3A796911A87473DE56A72D80F92481B4386092FFED1F7D831826C8748C88917642AEAC7D838433C6E2B4C0887045930AF829FB3795E4E8F33971A4B1E96A9CA388C1160B68BBB8C37646AD9E391C24C1B3B9E728C13307586DDE9E456BC861A5543230A6037FEE25B2D9D77F2DE7451E3B7F5039A9850E7423A277AE8376AC97A13F3CDB986AC0368BA41F3995D7410DCC74052AC9689CF6919327F0793C21373EB0E72BE234BAD121CBA44A265FF64776739A3BED6041BAB33F8015285E00EA03F7C9196851DB1863799A9151196524FBBFB1791125320124FDD49C5B6B788671377F1703E3E59F5BAD4C95762A03FFE66175133CB92C08E03E1BA037E26938BC61865B12ED9E09510FFF92B957B82D48D98C8874F660D09550BF18B1F1FE46BB45432F05E13C1BB3561BE354A56622606AFCEE4474CB2B1B5CD96E42B31E863630694CAE404C667A9143FEC028D7084DA00D132127E81096ABF4BE4FD4327ECB109AB8BA91176845BF656A4A71530F35EBCC998B136F8EB80D7C965FFAE51C9EEB674C7292B407CB4EFE71F4CFCFB0F12BA6B3F7AE8DF9B2E6CCABDB8DD160C29AFBAA042BF0E844CC0A7FEA5E662500C4BF0ED3CAA55F3C7711FC95A6D97E177B131BAB8F5A737DB9CAF2CA92FCE17B7680EE68609B19624CA85C92D18EDC9D5BC0F64EA502FCD22DDB5DD74C339ADC418526204046834B1E7582524BFBD893D4F224460A8E06F325495E86345555A7E8C9F80745D659636B8474FBB15A2C863865F288840B5C468C414D8F8FA5DE4CA330BA12E458FFAAD8539218FBF941C8BEB52EE059CED91ACD78296DCD286042381C3DE3C9ECE78CC7D7713E8F31DBEB18DE3C5FAC7329241AF7B4BB6CF60BF33C6F0D0D899D7625592DDB9F768CA7088FC3E3CE3C37AB2D8DCC30479D91EE88033B3A75522236F1AC587E883C37025C602548FC068FE7DF85F61680AB98F9417ADBD9EFFBA7360CF418F7C04270AF438E049012C2D80F012C2F7B021638C83079BFE00D45DDDAFF376A6A7C359D0449F4280F8F63BD7ECAAB2B038BCD1A76CF3B92E602B8340D4D064CEFE4A882E4ADB673D32ADCE2206FEAB05F98836F5E302DB21901FADF2ABB106158670BACE685D0044D4B2DA13E6BA35A8B145BF71AB06A6F7335F621B9B4527CC9F8C784DA43C464278816C290E15078C0B4D476C78EAB1B7F1E1F1E450534E065377109705F6184AA9133160F518DFAB7283C7675BDFF86F5D25215BA7D2665E9E9942F8D37D0418B22D11BEF83B0145DD9DE184AB074C4B0DD9B3CCE768851822664398099AD5C9FD21B785CF055CA214071EB11023C7A88958BDBF4DC7B0DFE9C60E707F2140237A1794C30865AC91FC85F17138BF54555BDC71EDC46AC4B850BD1BB6CCCFEE77ACB97F6F4284C55ACD6BED057C2E5972E71F357389F87C614E59E8EBEB5707E496FF4F0C958B399750E54262CA065C71509671B2D5A87C52FDDD125AB8745CDC76281B52851525196A67ADBC10C392C8DF473972FE43DFA95FFA6051381F33D9863AD9E0716F556456721CB3087064378D527D20D14236C1966961B0AB82EB0455820DA73509691BDA17701C6E64C83413451860FE802B9844B512DA1B3EBC25CC077FDB23BFC6B86CCB7984AF688D4DB4D9EB79A3B86A287975A4041C76D2FBBC04581673BBD0A61E3C3DA32FA436ECF30EF4792A5CA44A01DF1CB0AF006A6F54924C457FBB10DAA81524758450C732B7A66844066CBBC0DC3B88A804571810359EC1BB844C92E84CFB32EE6AB6E8E1480F08C5884F76559B8238EE51CD05EBD8CD0981683D37AE7182FD625090170B68FDEA12857A3DF8C3B914B656C4D337CF409AFC41D1889FC6BA410232502CB0B6D29BFC1AE0F6A04FA8517EC06EC1CCB66FED7BBBE6155F6DF39D8958DA00CE8CE7469A4405EDF4EDB2A891962C63235678DCD0E003805DF0E7B1885A42A035383252228B98BF9DF274B85493DD0BC010E8AD9DAF0B52CBB2463728B95A7976B528862FA255D21EDAD4185987F6F6C75C1E7AE9B0D65A51E6F3EC9F21EE62A335C3880974DCFCC4D755782C7B2F97998A137958A04143D1841FD1043D7CB96E15FAD6A526F241C7393D657B184125513B0AE3697EB88C68C385700306FF6A172F9A391B5690445B49ED011AF82F04FD382E60E3D528DF34BE5D20DB864208A9200A67B64F20DAB379CEFBE6FF454783A6AB6AEC4ADD35C0AF9AF2263FD803782CE645494CF805E0C4FE011572F17DC7EB9D10A07B7F150A25C2417A4B78B98423707B3477629AC4BEB652B14C53DD70C9F3CCAC05A68E833C15AC0270C6AB5AD936CB08920BA7A6DD48ADE22086B1A5F42522F677657ED7EE078C7370DC09D00940EAF595F73FEBC0FD18A492CE9B57E8CE51250EA38308AF764188600037F7F28A6A17404002860593B5C8816DA3C5A129291C893C80F52815FBC2172AB36A8916DC4918847257A9520375FFDC60BDF06DEA2ACB5543902C087C93006F8F980008BA19B4D73EF33C0643A409C115D32FEDBF3E2F4F6586FA8EE024AE7E46AE0EBF75129454B3F7810A8F8DA5021DEDDB5DB2B00FE7A77DEAC0D4B21C5E6B8D0AD12E729DC5546ED1BC7963A769353C4662E1F39F2278112D95549D85A220D0796B15B0FE7EE16E254DB1CFC12FB99130C210E1F679F6E43A985D1D986ADD365152E9FA76CB67C955D93CAFFE32211ABFA14C228570043EBE0EBD9B1B0FC7A52E63B874EFCAB942AEDFE7AE32481BFB6EE8E5CCE5279C745891F9136B0F228F23B4E53724F6B292F7F0004720CCEFFF218C41DE09BB675F680F341899E5348E8259A5CB87DCD3D01D9B8308D4DD69EA16CF18CDF5FED04FCF042B61E23279C98C1CE9360494ED99FB09D9D1A8298425B0CB96A1DCE63AAF4C6602F731EE7F8134D9137153E4B336351D4A483BD458624C195DC1170AF6A0B3BE1D9238BA970F550DFA60739D48C49680DAA020F69E6CB0A48BFFA6E9C179F83D501AF85E4875215200145077772C0E95BD6A0065A0703BFA50758391F209B9FAC14BC29D75EBC6F9BF931DC548DAF06D33D86CDE2870625C575B06FBB3BC354112A01C8092C25EA85CBF1D9955CEA87F6BD13CE819AE33DF2C5951074405798105F769E11C1C72D671E07D53A0F605EDF7F9F384BA0558EF25986ED9F87524DC57511B9B1E8E72FDCF2C14870B7CD0C4E8054A875229790EED8780C3066AD7B057C82899B7F3E85F51ECCAC206C2EEC1F56BADC280EA2DBAC153C555F28D3A97BD9DDA974216BE06DAC24AF37A6AB9D714C5E42EEF96A047A45B7F4D4BF7F704FFC90F717DDF620654C893AEA17E30F13334257D9A9CEEAB434EBFD42C1A0026A4FE7E8544F4C02F716F108549522D695C9CDEAB19DD606C6D9952AEFC51188E925C7E4A8E3FA8F21B886C9BA53ED3937AA5514D687A9B5A3B6EA4676AFECED6FC2C463D8256C36797ADE9932EBBA53C4C27502F11D60687D9E0D1721B2C4DE3D048A1CCAF17EEE1E719A7EA44FE84435BE5ADF007CC3B01A31425B9790B6BE67898CAEFE4B647FCCC06D9053ED367CD0D5A7F9E4C0A79ECC0A7C86400B660C8D022ACBE1464FCAE3C14D7C2CB691F62320284F4A21A2CA4B040DAA187D94C0D89F653B09B9E592B54A97A62232F17FEC083156CFA5B3C1E2F1785EB2E06B2832A4ACB1BA2E5FA5362403EDE2700080DB8F5B9335467DAE54B9F651E5728E6F33D788C140E6314321EBC48EA26DCC1B1F1E9D588E4FE0848DF99A1B7697E9BBCD5DB8109C599345294C1B875DF6FA0E1B9D733A92DB3DCC5F427231EA430D56A515B5D4AEEA7AB59117B826F22500DD43D1F8A6A4D3AF48BA079B4DD22B577EB18AFE8470357821D63CA9AE5436CE5E09F8B336DE57395931626DE1246FC6238536BD684EC8526B6E6B9161F78AFAF137300A0CF535EABAC1B7AD00AC9EEFD0127925948D227505525F993C7D0AA65DACAD41458A4B1FC1E58B29691668443CD9C36F94698AF67F88D2B591D5EA8BBFF3DD253616DDB07923E99EE66F2F12661D2DAE432D9E9ECB70273CC06361613017F214D978F9C09B0A9E0211051EE172C11C9BAF3580751BC5EF0ABD28AC903FDA47EBD351C7A022A9F4077D3E7ED290E3E6593B850A419DAA493586F9ED4EE4CD7D153EC09A628B2B2C87A694ADDC9062C49B35745FEC57E2D0841C1D944F23D314D846EBF048A632B1519E5EB13AA056884F8D44D2B925E0061CD2307B17FBA291DC047F23C4D19B92F184F309715EB22DE9DA8C6E4101643F5BFE1B0A888053682023C9E114CE0C6A211CFC3D5BEF04D3BDA32E4456CCCCBA044206564C149A1F3ABB0390826B5781C959EEF92CD98812921FDE3A1080F3459BF5DD1A48FEACCA6418678E4904294A8E88A411F0D0890F765E162DFA9E902AD6E57A86CF8752A0491260E68A018A444A289C12D955F5B42DA19B76A69BD814DA864C93F2612D01B90FEFA78EE4D50BD33188A73981F68F9D09DAA4A7383AB6204147A133E2C29B12C9F138652A205D078040BAE303D8912459158CD90C06B0B48836A4174B817ADEA57FD684A76BB89ED02C885240BFD0F3F0DB0D12D9D4B57691B8825DD2139BFFDC58E811C23E8164CE7C73750233084AEE6E4A64A45268C8A11DD8416ACFC3A346F2DB4EAE45C0F093B5D81DEE72FD53FF5E815028BECBEA750DB4DC788DAC9A9153E80B76B60E0A5E22BE8AE04D6F2B0BF7A5AE905877AF3833CBE9220AEFE18FE9ABC40ECB61C6CD8AFE1361B1EFDCBE042D07761906C67D222A5C780CC5D8B2D31EFD5B69B6241B36F8C08789287752A8F5EA203929AEFA53237B5BE6FA5220C625CE16B56FA445660BBA4D05EE652E0735DC6C85D3833104C84F46F417950B182220C6908B67EDC672B5FDDAA23A839FB78DBA37F81DA55C51B8825554665FAC2563E4417AECA8437EB6FB412DEDB8518713CA22D77120B0634C747C8C624E2F3DDA91EB7691FF685D771E7F4597627BE8131861FD42E485E118E9551636467E2A6C232F35DCF26D89B5C02CE348A968D4AEFA48267891C6E76546154B3CAA990422187D433DFF86895C3C5115796393F5C2AF388530B7586D75E7C0875B7E6A687CAAE4ACF4697EA8D2C8EAD4DDF9795FC47BF49E26607A911470F9BC0F7F09B39FC0E153BECC62DB25843140B936E2FF5E1E3FFA302B2EA4652F0C4A218521FD76FDA0D6FF95B85963E96A2091200FE128B901ECDE5877D898BB8D9BD0E5A2955E6D6F93E2B529E55B502CAFE77C5C1C6DD0DA061C4391EACD1150EA76FF3CFB7565E2890EB1B156597EF606151B4B132865FCF282FEA0FAB41D09C2FF13560B8CF85FBFD74D39AEC3B3384B72E7A98CA1B724363DED4D7A464E62E10C08D6A3FB66E3E84EE7C6A75533BB3A0DEBE7895FC8D010933BE7197319123F757C07918E85D5E7E1737912B6CA0FF86E4B47D07069278D667F1AD2CA2B93BC130DAA3862428FA784B121D4806016286CAA11F146120631D580986CDCDAB90B94C27DE6AE015EA7732C6605D952FD6BF5AA8D1B4B1E2AFE2BBB1F5B38E5DC7BCAD6F22C5DF57FB4BD70EC6B55E43F466DD2AB2CD7BB80F98323ED064D6FD57B1C83E3EB9EAE333813D5B9BE307A3376AE58115787F8F7E28A2B075212CC52C509D78EF764F65C2361E5353046FEDC7F7E110805EEC73B38D1D976D77D3314C471ED41364BD1BB26A2EE052B5DBDDBAE5036BDA1587DA4B326BED3A68CFD53C0BBE1EE03621A66E04498741E421963F4AB4CFA75727A0E70159638E10A3A3BE375302D1E1FEBD6FBCE69CE66F939AF49408C4546E3259A29FE756539D1BCB7F56BA0214BDCD42C22BD8DC8575D8A0BE7386E26A46F3CE81AC86E66D4A21C795F0F8425102ABD76344A3F2C37A704EDAEA5C8BCD78BE0C0519435D333BFB1941A0DA6321A72E107D4B0311F8689AECE9364F6760C173CD1A8EBDA74F5B72BC51680452513522CA210CF9DB7AA61A8D22BB9285B4A834942E5E6D41BCED624D74569FCEA6674C03503DB204342D78C78451B9B6D46F7A8F0687E44B5BE32D863F957FE289F2C79EF806A634E7C450BAA48751B41B4A91448A05051E5EA46940CE0B1FBD177C77565DF138FA767D281921868BB1F8E8B9072307482CC84FCF7F3EEAD67A6B6F350DA0FE284324554E9A312002DCE02D48FCB61C1D1CBA3110F5F9809362D9767BAB4FECED9EEBEA316431ABC930AE46A61C2A39AAFF12EE76A5230BB57E517116918385B796D9642B8FC072BC8BFACE3623E4451EEE7694F63640A73BA5C1F4D348665234785413EA520E7634C813F8AD93D11D0CEF0C5DB4496D8E4BB7F616A9169B7AD7049C3DF2093BC39665F318CDBC623C6706FCF6A9ECD7E0DECCFEEE59CFD0418E3257C531F1FE7F32BF0E0273A467241A08DEF89498A83F2C68023C5A52D51C391925FEE202B6A17884064A70A5B70DA020A8AD22675EDD08F925492B5996B8E5A5F155D53B9E585A25BDCA3CE67ADD8A700C086A1C7EC621FED0318ADF3532625C2CCFEB4AB29C31A168D2AC4D5486E5F518B35FC22C567E318B48601970C606CE68BB9D9C2296ABB081A81E9926E1B8C44048F74EECEF63D3F0CF40014249FA2C0E4ADE7CEFF5399551BD2B16DBCE021710FE09AF1001BEF9EBEA2FE1C4C2ABDF14FAB8AAB28140F858EB10913A618BC94EF45879E5DBE528911E0F5D75340B2F423AA9D1C3688FEF466CF0FF83A4CDC22DFC8DC25F3AD7C9A546A3A17D917ADA1E86DFCE41ED8A45B6803C86EC4DB72A641FDFA56CB35DAF74ACB825132F0D993F27F8577248655E2BD5E02344ABA2AA513571C3B473B3D5800E1D720D556DF89750250184DD0CF05E7B48B9C80920F2E34E98F67354280DBA91C7C686494E305947F9BD25DB105AA55609B19405FA283814C7033E04E8BAE2D1ABC6093F237E78EA17141A39F0946AFA69EE139D07C2B85E9A65EE8AAF84BF2FC207607FD0AF1B21C7FB4D6A87847D9FE861C7EB8311E6AACE27F58826D1B2B25AA16EDD8D83658B9C434FCC3D180027865F2978C35B5EC9E6B61DB9364E4FCCB3FC436C1B791B0E101CA1A0CDE1DAB25C585697554A90894B78DC91CBD4259DB441FE72F56CD75AF38FA6219F8E01DA30D04065812FA5DD96CCD78139787BC9DBB280D90F53DBA70100D0B77CDC04578C970C728D83FC948E375F013DE41FD62047C994555B32D48DF4895DD05D2DDE115D4823862856F7D42DA619E3630FFDB1B896FEA170BF14B836BB5A115CF9A3D3F9713F9AD7AF84F09323E9B55C277C7EE251840731D0F07E15CD9C91482AF2A965CE78A612CDE8317EAB11D40AD0E160DAA87E78028F458CBDA450D95698D29D1D1785DA0C5E7DDB30B3951D42901E8267D85590D8B0F58420687352188C6DA1FC0992D8EE37382EA6B60A44FDA6A5D2C00E25130F1ED118F41D97C6B0B885A2F483DCA464B34976F60A5E11991D06DDD2DF884AA2FCD46BBE0C75A2A73D152716D9688EA6DFDC62AE4DE085C7256B555977B4B47208DF5A02DEA1ADC5F1E084CA9710DCAE46F21ACD9B100CD043E9A13796CC796A80AF3E69130CC87372D2808D6FAD08AD5593A5F2C6FA7D1006782251F2AD463F71121D9238EE977C81102F78F244BC42547B58E757A4B6247C7F0F81F904D1F799B710E977C576F603F74C2FDC59C5ACC2164B93C4BDFFA995701AB2FC56F7FDA84C208C6429927821480CFE3896EDBD1604EB077885128BCF92ABDFF7C1059B9E2B9E291C80D4E708143E89EC8D42F10FEE4EFFAB6E15131B36CCCAE0BE9F67B0BFE1E46685DBA45591D11EE8520BC61838F09C43A5F46EA169E31D0F7530F4A9BE8B8F0ADB4894CD1780925BCA34ABC780056F733673A6479DF67FEB67B98336ABF681C4FA0F0E7AC877FD8DC1FDD64680F61B2455C023E5470DE18D8F0F900FCB2E593D94E9E807DAF82898177D86FCC0D011C47DEC95B270AE4872692C5913F7020AB30818ADFAD57B9F85D44EC61BE13885849874C930881FAE15C46897C834846F1E1F027D3129620BA0EB38A7186F849453AB87894AC2F6FE8499BDEA9BB9BC0A01D9709E8C0B9069E6DE309C0847DFB92D787F5FE48C46FAF63FA37FE01C55CD697CB7F31DFDFAFFECAAF2C9CAC86CBD28DDB57977006AC4B2A50D5CACD82F4711180B34EB45D6D71C9AB76F7D537C997581624E78F2362F8B7A9728BB2646731B3B58FCA4C3B37162E9DD7E5A7E163ADE7418415C38242A427B84803A570D57747EFAE70702DE4456D015A43C8FE828B997D31E6DEE49843DB01969F160A7508227B1F64FFD7159428D740175695312759E9A0426146E24C515B9632E64588FD19CA148EEED9CF2602E7C9DF9EE780ED231201A63AA2FB172B09F31CDB6709B03B2A7D2D0268F29333FC4011DE29984E456A4DD8D89BBF17E4F9A31F0466EFFEAFFC3577F20E1E9A9E800CD683DA7FB77873AA4CC3188495B6BC573766BCB6291769C67588FDA010D151E0EACBF1B196C8075AFF2CC4E310E6D301B49A0FA2B71F9B21A6517F73DCA3A86E50EE610E509DEB99426ECFEF985C1DF1BA8DA922FA3AA0D531D2CFDB11F8081B21820BA0D48713CE6593AFC8738CDA94B4BB7B909CE540516C80F2F040120EF29E5254FB0BBCD5F896964897B1BBC596CA3A3A0F2F787C2370784518185CCA2E1E6757D7788D369E8F60C9D8181C196D0CBAE20844B7AE83E2136F447A35D1572AEA8076401B7DAA60423A3C0F4361FEE8652389260866312D687139A5ABF0BE4CD67BC4D0A10FE2A60E2DEE4FD26AB0933081B33BF35E62BCB376370A24FE2F1060AEFF91FEA1501FA1C44606FC1D0781607B5E484003B548E79EC87CA186F883ED87FFE3B939106980AE28143CCB8DE81340D4498536A36ECA80724083B3BC54AFF025CCFBB5323A35EBE2513414D41C6C7DDFD4529FE814654FEA7CA8B87CD41614EF3E0589E02B449D831E2B6674CEF59797A56C9019BDA600CC4817328E42525E31915C3AB4E757179A9646333BBC570EDB09CE0035E4046C5733A700534EF638968CE0054EE60ED31508A311C985E115AEB34EE8D6231E96BABE707E797E1FEB8B4DB03F982DF57CE8F309685748CDF23A4341BD2FE912A8E5CF9C4BD42F0038BD753AA16F4FAB6F20572F466081E313F733DD6A8AC08F9E5FF54AD5E0942FA56D25F0DB33CBBBE4344429E0171545F81444BFADE34E9C6B8676922B5F0F106703527076CB76CA859FF56F5E4078B2605E880D8FC7E8B3F5A5D4ED04B5D6AC1EFD34BD57F99ADAEF78AECECA4398717C92E4CF4F0AE7BAA3C8D1A8E8775BE25D1D2A2C274929E4E8CC77DE3114FAE381C63B874865905D2AA0F213CB6BEBC4C2131760B8E40FDA35DF961C0FC937A801293D3A8A5C921AF9D1A0329636FF4683FB5472D0D562E08C9CEE51B6AB6C6497F57DC9AEE7AE5C23807B2B0854FC49AAD058660E401805D37F3E549B0B8BA2D524A0A09521C82660DCA23AE536DD1C0FF10E725D688636040F9E73D77BBD6EA53589E25093022AE44F394C56A80399DE295A5F52AF26927DAF7BEDBD5E9A75E13D1D592CEC509DA33C5B6AC223C6A6CD0BDFB5B8D434156D74001E8E0DD37C79A8863ADE185459A72871FBF513971ECD88FAC7A4C90063752F74E25EEDD6127F8DAFDF96656E5DAA5A4C28BA8E53691F0B90FC63811DE2106033E26C6D622314A7782D1A5C394F3257763320CFDC65F97DD8350A254B4A8452CA73F1CC56FA063DDA2F975196EDE078252744232255008C56809F0FFB081140E88949B3E476A3110C8A8EABBD79913C9A9EBCDDA191AD2D2E4B5E8315142A309C8F7536C4757D4E2F8D3133D1DC84D00478AAB595E6A61EA907020AFF692CFBC5141DBB1575D321564DAA0077CE9746B2980FFD9D9E0CEA02AE262B4A5C8B9F7464020D83D8C7F771B52E330B947037225B2F8B4612FCCC1F7C47C9E2AB7BCDAEF01C3942FEEA61688B019418BA0E7A3020679AE8DD79136F76B2744D026456C03229E2973AD798053BCE338F7DD218BAFEFB3B6806C7A02CA482BE1B3167217F6417309275D4A2E833C13F4DF2E290A381035294C83887C7E99BF8594C928E78DC2B91AF17CDEB5FBDAD89188BDF5A40C4CBBEDC21E3FED26C53058FA272CE0E7E629E3CE8F7B142DC6AE74B5044A056842C809F05C3F956F070883BFAC7731F23063396EF7ED5710C7032C7D47F1A4CAF82A275494E9A95A29874C8CE9F812D7F8D743974930ADCE277EA884A2D762143E9028D4D5902166D9A35AE8028C39AB8075F0F2FBA05D03366F541C1E7D4139F67CB5CEA1E82F2164EBAB779B88A8EF88EA8503B80CACC9A448712528C3CDA2F4C9E247471C68167F49ACC7D30C20A6BC1CDFA11273683A7B14DA95DB725B2E0BE9792B9A90AB6438C43897E4687D9C9256A8510B9F59005004567706F652C063D1296CF78A36979A5A6E310F6911B8470DC0CBF956BDA5CBF1C857BF1C44941FFC72A459F6FC11C1556DCD51810BF90EE21E6C655775F6A7B9FF5AD77440AF3B32DAE9A3D6D7F81D2E443EB791108E65DE2B627FC2A2564ECCACA6796A053E35DE4D0688C0CD95F5187A36F92C3C90D341192E5F6CC02AD9C228ED5B3B402B93A286C7C791C9383F9B2862386505012FF7A7B716C7A8A3942FF1C752BFFB4BA8064BC9B5FFE37DE74244C6A37F17F9EE3E2D3A14D271C9B93FDE69212C40BB198F5A4437FDCF715B6BEBA928EA3815C308CDCD6B2E3D4AB6CD94752AFA2E30AA7C809538F8B490405F5EEA94F5ED29B6C50E6264FCD5C1D9067B271F7A1955609AEEB0105F7A4CC6C75F82714060040A79E3067077D114E532AD439ECDAFD57B42C6C9FE0284BD2FB17650E9100B35A2D817B424ABDCC3FFE9EA5DFF1E2EF51E359DAC0A252C7EFB28F8897D5360939A56B7899E9D436B4666CF9522634862AF13C1B5479A9BCF30565C8B93652C08F80A8026BA4A9BD8A94B704CF217E33AA8A90513B6B71E7FB53BD934231F28CF4B65D522AFD1C4D478B6EF3D069C9459F27281A0987AA5F19E8ED9EFD5EE5938B60EC4A3479A1D6D2F7E4612E06A0C1C6D7E52D3699E0D20B8491D0F5702D7DA66A2220C10F09ECED5CE637312C87026EDAC0F21F00E2EEAEB9E620B081787399055101F30EEA9AABCA3AD64715EBA3E7358BFC9B624308DB73C20EBABED3154DD425C0C4F8C6E2BF4EC60CD6EB5AEB6AF1E71BE5059A8D085BAFE4332C02CA338E3514FD78FA686BFDA1005CD146CA57B63B4C19399137660FC4587D0FB4731E340B954D6DBA1805C93F373956AE20453A36F845EBE392CAEC3FA51E53644531A33AFF4EB65D2478230AE7E2EC345BA134AEFE66A41FB6A10EDCDEC38A55BA60757B6C9834B0978EDC7A82D19CFF3302A5D4D4B7D75E83CEF790CFD012FCBED5C81FA2D3EFA765CA307AF1CBEE2CD6F57E1FEBEE305818FBD905823889411D12B252078AFEC9DDBA33BDD94711982877CC8FD1B273303BDD7E617EA3A00E61174F14C9DA96EE9AAD562FEE34B882FEDE5CC47E77C7B8BDB650BD4DCCC55F9E18F6DFCA8EE7CDAC30B04EA75BE177C013EFC724A75AA45BB324CA49DFDF16046FAC2CB5388BC05DDE9FBDA62CA698612D12B06D65952E1F6CFED535582D1D9FF3757FAF644A35886FA3AA6918A53315BEE21B9B6EE355E307C9A6751558DCAA42F10C3E80B12111FEECF5418E787D93D759C6AC2D73192B0EED99CC9A1A341153D2DB5F347CD22AC638D23176B892802EBCE04C1C4F734F2782282BF384AF289D218103EBC4359BECD566623D719024150C3F6FC2B86573827A975FCC39AB6EEAEA4E44407E40E26C221D6F4442CFEEF7B2475C807F167A8B188BD4671E14CA4AB9144C5A3D549D537A85FA55CDC66664EC658935B98F74B02A184FAC84C5D5548BAE9AEC4DEE85DA9D0D5736CDAEB09D1697C0A361232A4EB0D0A6096256297156FA70C15CF42D9A2B8D4124F5F89974BC4CABC644240F96E15779072566EF88B840AB10EE2B2F5D7477B02D82A3B1C35C38E6A3A4B98FEF41D858D2D6FB2EA6009231D92F788A330D4860F2550AB0165FF410EE28D04508B6DA546720FDE4248E32C82FC778CF3398A5624F8BB4EC7AC26BFB6DA7492E88BDA4ABA793797887B476041E8593ABBB3519A37A7B482CC72DA982EAD92EE070075744AD0B5A4692C309AA49B201C7F9FC8A71B97CF2C4D4DF009DC055600975A629ED33CD4A297278FB3AE9836527ED8E269E6344F167A0C2A37021544FD9EDC4D31C8CB12F44C77DA6F84FD3BC47A849E5D7B4D821B795D9473DAE465B5A2903FCB2E193E28A251A6AE065A586C3CEC2FD6CB8EF819593FB250C47FFEED21067C085C3881CE8F35AAF391FEDF0C94F111A6F9EE05DB3BA384781E372CB9F761A27B9C0D1ACFFC61E4227CB7D5DE341A8AA6F02992CCE08150B83F6221B995300D78972A3D5E8638E50D3A1B5C86840F826DEC0639B103D0BBC405127FA866059457A4050336799BA02C73DD40A4402E5388C972A2466C80125FA9D18E72668BBE98F17C78351424A49D45DA119010E4FAC4F81808E32BB1A9DA92BE8EE8B4272A88C0C40E863A4FB8D46A5FC1407C66A8C8C0E4A6688D02960D863DA04EBF6D2C64F1515180B782415008DE8972C859CFDA494AAE07081C304D1C7BCF453BD755B803D194A06C43991EA9054D3B50F9DD492D56E82B9584D11B999212C7D70A801B2E28A61B042DD40438E27E99016A59E7FA0E1CFDE57613A0698B77145291CDEC0963B08949D18B9868094F22CE2F5652B1826784006E4CA9223B5C6498724AB8FF5874F7288AA7BC060EE8F00EA20A8DBD9E32F78B6C26FFD3C025CD4872562BCEDA4AF00A7214E15101AC86F6D1566994CD33DACC34BE5677D314BC2C3776E70337F74F0992AF4B589BF0CCD4A9ED309A5EE7CFFD247371D84C589B07A4E10DA4A47A56FFE35D1B849C3634D9724EE10FD06C52DF6F0D1D3F191F7DDDC4D5C9EC3A76FF740D8AB68D34040A2808B57AB83DDC894A1FCF0AE78B568269D1B7746054060A86E55FCAFB0985A91C0173B548FC50F398D94324A44F0DD7EAD74E8FB99E28E3F3C383F41FEE1214AC800E4DDD0809E7F2090B6A71683847C7EC00FFB9F257BE1773752AC8C234E8FC8E6E177F00D8BDEABB43CA02A000646D4D699E6370EE19D35098195BA85FE0AB9B29ECD98B32E740BF5A41D8A96D7814B430150AD5FA35C5E74C488F76740B15C9C0D7EA53855A8C66DF3072E6A3F2022C4A15FCB72B107841C21C04915655E67672978F7F1F5FE14E176790ADF55BBC63755A27720BF99B5E2762013A768F4B8AAA439F22A66C18F6B3AACC91BC7E85BFA9A7D373352CD2807E9751CF5C3C0CDA4C1A58ADF6548AD8D0084E2282EA8118253B1FFBC847674B5C45BA08CF4F0AFBC4C579A8D5415BC823E942CD0189DAEDFB54A73335B42288EF64473C455F4B5DFADB9DBAA2028317A8E25C1774304C94FEF5B5009623C6AE37EB41A624C6D0C7F64FE7BDD7B3CD83944BCF10899E7680ED1872307E857D432F278F79C6EE18ED2C7DF70431887B959E63E8F965DE676AA4261265EE4D901D40AB0A64FD2C95AC22F962AD096EEC69C2A3620047205887DA3CDDAA8B08454F510F03123E54991A91BF0DA31E402C12CE907DCDAB2DCBA7A8EA5ACDC8312D58869C922C563584AD08845BB29495D041F2512C55BAA7A58ACC8032F739BF35DF6782A9D180080EC48E166255370FD405766013086173AFAD1226D1D4049ADF32D8040BB7A4957B5E75D2D5E8E150835AD23FA6D987868CEBF9AA7B1E0FB48D127E8F526BAFDC944DC757F98252BD93AB870668B85BCE08102A4AA94480FABB1B7DBCD994AC05912AB6EECBE9EF23F87E639F0D8EA654ACDFE460E9AAF894DD42D0C0FB4DA3D763C7581F3CF7D50BA187D85E1B8C1D9F09B51B94D7435BAD2B06663B3E261A4CDE30C333A8C55D136F6AC816EFAB1197592113F6B2B51D01CAF0F19EB91B38D6E03CADF8903A64677680504A8838C1AE80DE5CFC72421259805A499BB3DBC2646B42698A125DC26502533F15DEB28DCDC68BF4D69AC1DC15CF25F13F6A4429949E82C1AC46B7D23EBDB5712E23B147E7139E83240E53DB06734F7DF57822C64B16F14A3C37845BD1BB673E82914DD8FAB759D4CF2AAF30DF290698D85FAF7BBEA2799EAB9A7B6435E61290BB404FCB037A9EF5C70D8C31BB91013509F2C620075DB91F166375C71AAA00AE680BCA0DF3AEC70E8829028E5F041177A98413546F2450A875DAB540A30046FA20816BE83BB2E6EF3BA2C47D0F6A7F5609B4556B83BA8AE0AFEC08E3C5CA740A1EF0DD5E1C4A9B3001A7483345DE1698A52A88ED88F3B401E34A19E4338E90DB9F0B98AC0D9077790837796B58FC7217C80A1ADBDDF98013F16D38A0A1AEF2A148D5EEE21B0FF374F8041D01E8678E46056907F3344943E7E7482E789EAC790A53AD0DD48826C1147B9B801063FF8BD3997A2CA5738EA7B60BD69ABDEAED0697C4D2584E42693FE7DA14659FF9953F5869139636981B6E58D6563834A7AC570B9985321C8F0F3BFA8BCE09C0434C881532DDBCBD77ED32D9D4EBE2A1AFEF48BBBD12824DE9D345E6B90FCA6604EEBF4714F33936D6F619E17A67DE8C0F41E176042AA4F85F04B20A9104FC7F0974D15A08EBBF96F6A10A9357C06DDB40A6EE932C7EB9D15C0703077FA855B02A308A1D0EA1321E421BACB594C9C4BDD389430EABB8C3CE4267B6984570EEB77E55718C92E06370BB55378DCE03A27E07EE31818E2D6C36D0B66D0C35871AE2FE365842ED66B2BC69A014054B9BC91AB096BEF5224E4D0CC4B7915F2BCDC3D28F7E904B941D4370CFA6770F9E9E896E29BDC3B088C3A754EA18A877EA4545C42359769F944632B55F5CCD30A942D9FBC74B682A03391F558754D55A24A070A1869B25C735A54B60577B28E9EE0772435528FE028F24B5B420585012EE09E6B979AD9BC2AC7C5C7A72EABEBACDAE7E9BA45B8551477838C31F727DDB750827F5EC5D0578C4AD86BDD879355B58B3C912A01EFE7EE4069B837CF5FCA16244672014445A0025A0B8DF91AA2CD5E9BBB1E39FCDB03CA95CE26D86EF201115B57DBDFE40673AAB62D336C78D526B2E2E8C45D6BEB7D404838982C3B0AF87862FFCB3DE5A314C8ADA198D86251CA50D5548F15EFA7B781BCC686FDB2C227FE4453C45DE232ADC09C0E89BCE92D824A8739B2943C65CAAC5F03AC0E75C00A4BC0B1F9044EC334BD50F0CEF3253AEA212D4582E66E9F1E526C548F31F8BD64A1EB12C38065D8A659F0ECEEA00CFD806875A590FCFBE6D998B9DC287492FEE59354D0C753899F2F982EEC813EAE3984C484D42DFC7EF3499F2ED72F5004A244418778F94C228589AC2A0A74E4AE181E7B445900B8303E34860CD3019DD0BA9AA255F2BDDABF9666127FC8BA7FF2E0A481731B0A3E2D1B73CD3595DA07E60CE0B83C0A575BECE22D0970ED2ED4A26D4C5FE2FDB106378E3B56C46ECFDB7FA8BCC9D2798E8AC29A1CC66E370AB71A3DF8A4DA965488BE00DC8EE826D30078D2D96F5E7635C2F9E5670A3DCC5CCC4EC9E30E06245DBB6E78A613A2ADC6BA7BEE7F48ABDFDF79051721910AE29D442F5F74A4178D82C50413958B111F4DD50458547FF3B34075101AE66777AF4F13AA45404E640685A9544FB46D331D70F795D04CFD2A14A6D6B7B0B8D60FB083A82AFA66E7BAB2B5B8A0EB7914F98F3F59208E84F14BD22680BAA09F973B8D86DDC3C7E58C0B49602A460BA6AC917CBA9C6433245A2B2EB4FA73C382FC779B9CEF934FF969016954A4707D2201634B3BEF8FFF79681AAA542F55C015CF4B60774DDB33A9A52DFECA0E143627EF64F12A7E7113C49803301F9AE5AE087AFFD9E8A241B881D62C1AB39B644F3C8A45FC367B17B6BE428FB80404AAE5E19EAF29B6CCB62A9EB0D579A7C06050CF2C5CD274E1589CEFF315B3D13B33D44A4AF4A05635905680DE679A35E0546D712D2F4C8A0F418C9ACA03F04ADAEA1A15552894D2ACB3F0F7BCB93988F79D8A1D0FDF75D5B14D4D1BE1B1AF83E509A61A04936175A6914E4D4B61BE1585B5901232CC71090667EAD9C88E599E6B806CF417BC2E5ED2BA2C14B21887E4BBA12E1F82CEE96045CE5D4CC6FC29CCE107505C7F758489E74C3F6E3E8F5D3FB0871B6F4B2E41FA602BAFE65C0C1FDFACA60E452C22B929CBCBF1608FBFA774E0B1BBCD91BAE5EEBD5A0A4AAF6E388C6137371C387951DBAFFFC14E0370996BC448E13AC8782B1242FFC0DBDBB12D126F2431E152BD7A95035006CAD7140AD15D72AF7907E3D353441008EE6E8231B900636D78DBB53DFB9C9B5D05835246C9FA0DA605BA7BA8077AD50E72FF75147D316ECD2F171B36473C0CEEF139CD232C192666B130181D0C11E118D81F2F0ABE7C6345A3EDDE76C0D9809E0140D8BF4D597B452C569EDC6BD928E5544063BB8CC3D3CCCBFF224666A0C701F8788BC864AC7A54F92BC2C0BE070EF4D138EDD050EFF911EE1D5CEDF336A8F9ACAACD75A76D0DD2741F887538BFB1DBE7BE77929ECFEB60567433A6E5BD3306DE5EFF117747B1DD477B356D2AE6B4282CF6F284564F598B0DE94CF7E85F54F2F65470A8879FFF4175B81D720CE8A07F1228425A6B9CCB4467A346704EFEB87F79A1BD55379882984542E685851AF8A9F890DFC03B95F9C05A3621EA54EC6528BE11EBC9B6BABC6F52F8B22978BC95B7FE4D21C9F66AD4031717089BDCF309C0F67CECFB6185E22416EA4AA50BAADB64F65A8FB73C4044EC7EA215703BE247B7046CE50F828EA1A50ACDB6C1A9D9FC512E4C337386E30BF21B02EFC95CF8C2F3BD87E2032795DC76B6C4638264C40957CDF1418757F6D3AC2EAE921CE190A975926C53ED2852FB210ED1C8C73B8A46F8BF6A81ED0A5B02AAADEC55F0E91FFF132143AB2634F1E33753C42B8274C31707E1BD1171A4E4AFCEA267A9015D455A09EEE1C1DEC453687C83EF60107536B4D59839574AE29ABD973A0B8A50EEC63C7BA7B115E57BE1EA767E6F04722C0667A2636BA19034A337A27ACBE45FF0533430DB4E7418BEA65C55652358222D93771517056EC45265CCDF657E060FF81CF2ED10735CA26DABB97D77BDE11996E1EEF61EA371A492C45DECEB0E4A830B056773703E9D7FE082AF112FC263C4109A3315AF4D7FD465B22CB84C93B9C1432036E928B9FC3BAC9CDC765DEFC526BB66E401F2021E4F32F085F75F35D0A3CE12C938D5256BBB5DD965A663D9EC46E20A7E9C40BF88A94DEBB48B17D5117C727817250A4A344A88D2FCE5A4AC2DB68253D42E912771552B84F7C6D924D050D3AC077828A439C73A1F086578A44DE6FB33531D62E5B5BBD9330DA37D9257E8B28705FA500B7FD0ED196F076ADB3C4DEDA1BF1A36687A3C52910800AA03D625410DDF43E365F22BEFCD0221D8C4BC059701BB9CDEB7914B28E986A0D9288079C3D52318CC744AEE7DAC48454EF145E84EB01996E4637FADDE074552C401565DFC0AC97F5CA37A6DE1198751CE51C715D4B65496FE43653E94F76EA027DEAA91B745B42726D8DEC7AA8C632639476480D7C39E564E624C273D571A3AE5A9FFCA03840D978F6F1C4EAA0C55647E255388FC233AF8B3609CFFA810A87BBAC9882E6E0377348B59C39D2F421BED5533BDCD6611C53DC859C5C50251F82B327E69DE0DEA87AA2379A5BA3636B3776C42DE6B0E938D297DDE60985987B3560665BB70A1C519E6000F5EDAF41D8CC6232E779A1D5FF40F576EA97F342B2D4FF936A4C746187443893A0ED72AFB913AE0DE88E70560FEA379EC3EA4E574E47FFD291DE012723519885B7586272D7E5E9BABB0D99541C865ACF7C8258B89151FC0645850BEAE37C742AF32B6D732F4C073D7D08118A534D702C9883DCE2AE1D8C52D6BDF0C3CB986E64C6968590007F7B09CE9C67E1C14F928095CC3B51D228D984C7D5FD7C2328B54CBC9A492D649D5440B554038982111019898A92FC1336245400E7E2111A7AB89E031911600E320D96220DD8BF320B19758ABAE0F57036A06DA3F5BC6BE310A90CB6B8A83A243350FFDADC81B3642FB1CBF028E5920ADCCA2050D216B05E5B640406D9BCF63647C7C6BF547E738902AB8BDE9C29C0F87260F24070413F6BFB3F8ED48AC161C898ED12E611D070B4ED8F59CEEEC196B5F13A0D84626D858A8A315C3BB11D545373692695923F6AF95A89C59E0579C4AEFF571AD0CA26922DEFA16FE140FE0510D39B74AB591A3CBB1CC212E9800C43D756DD310FCD60A08159845D48F193A8762055835AEE10A0104AE5FB4E1ADE143A5086CA947515172517DEB7DCACB6108D5672288914BF8BE2AA128C52D97E1CBF53E9C8F7569AB6CC80467F6E95C3874DB78CB2190A96F9481E1E1016D9C5A837C27116D947ED7062A1E562DEDA9CF33A647FC19D914672D148286FC2768C5589DA4D48EFB4E86136BE56CD6E2A89DFD716048E7C35ACD931244B661EB9F40AFE719996C134BDCC3816E9F27FEB20AD918DC4BCEA908EBF9E48503F44E02583E09BE0DF6B5DC57B32CDD7501A1CEE1FC4DBF17A2B6453A32D2A317ECAE039220B61CEAB09AEB8CF97CF9856F9AD3DCD1977888DA9F825F092C98C3AE0099114E10F45F180CA4D68BA8D0DFB82A3314B1EC57BBADC493498F43988169E1E8F8786BC5C48838C4665C1979696B741ABC0521080C4E20C0E926181E3113C293D75E58BC531816C648842C8AE42F246326135BECA35FF43D2FEDFC8CECABF59888985DEDB062FBF1C6E534413023007ED99DAE107446315BC18DCFCCA296ECB3B1269998578AAF3F9A524C7F67149B51428A0F5B81DD62E831937583C7A4EEBB6DFCA0DDB6B8C3B824BF272EF4401233E7C77586F0EFD0F4F98D552BB157E73066177471848DD864AA36180B9D63DC56F701F050EB786206B4DD646A39F37CDA8FF6D5AB514522FB4DE30F83963BB9228872CEF860C15D6B54B4616C78252D02A2AB3AD35C83148E25360F23D57EAAE80B0F002909ED0764CFCBB47008370D1B6BD8D294949FDE5021F24BCA0FFF809708701D818BBCEC1165DD4847994166FDA6E31D3A2F179D797827F1D03A5000CE43D75A34030907554F06F0DDE8C16EA85FB2B3C4E1791380AE8AB3C549FD4F7D0A81AF87A11FB8213600AB3D49D87BEFF42D5A1F94E4E4DEBBC1CDDCDD0AEA53CEDEA5A690DB0A391DA44C4EACD29ADA172DE2267791D6B34BA5D6C4605809A76039109F2953C4B7D9F56B28277CFA868EF62C25E48B1352E5FD12749E553FA89528D916824A9600F8DC595733BB71F8557CE1DE4B896C817F68580404A6F84F498F2E2AC60A21A6E70C34E3291D61E3DD38DB1E9726820CE6F11EEE2AD4E452EDB8A92CDE943E863AD9A9D20EBDC60CB076867BAC92AB0944B7E43905B388169965E20C6AB2DAAC39180C4DB2659965AF281F4088597C1982B7453C1F7CD34B64B3F5DB5A1E6F667FC4D45EFE668145AFFAEA36E479821F4302BFF8DA12B3741E3D6E3E0FAEA787060C247FA1FF69EB190D97EB2F6E8F0C060FCAF94204214685123FA1EF03A426A7317B700D6EBBF6D9A3610185CC595CE0D4B23C3B1D0DB193D6E9B95D18A0CA669A5EDEAF5BE316A55B2579E8B00171B2A635EB271EFAC65C954D65271364F5EEBF8E0D57786E2FC30AC9FA4CAAEDB7DD3AA6A3B2985FA146CE4790A1558EF7780B7D2A344CD388137A0631FA9B1B052FFC182E54820529FEC2A0E76877E0081C510621FBD5B0B80E7FD7931828241F369A846DEB6E7C27038D28982CF49D7D1A3E900B7931FBAC3A359361F332FEC8A129E32B2A8C5F95E25C22721383C86EFC8C30AEF374C4AA5C0A9B80025E71F09519D7B1483A37571EC188D71BE309D1DC9F888CB424B952B864474EEAC6BF32F395D312EB9911857D9A3F3EB28D628B2EC246E216D4B36779AF587C42F481AA36C16F9DD212C631064ADC8C9D49D119DD0781444FF30F7AFAE77CBBB59B8EC816178C00B441A90B6C2BF356E2DEC4601DE0BF0FBCDE1D874E22BBB288C0814980703C26BCBF0C7499589BB811E66E81C0F6D9BB07578533868F364E27F2AD951B0EBEBE28C627A6A65A798D7BB7D9540BD30EB01C7093026748182534F56F526B5C2BB635199C9D937916F7217D17E400011CFF8B79DAC73F1D248D8A2FF25F590EF61C92CC9C3C21249B67C813B0DBA64DEACB619A6D977EE6C21757E76F5E7C1A6C6A7013342128A553570D83CC7EEB4157D07EFBA437095516091B8BDA1FB6B1B329F3A87724FC7796AF9D294EEBB292BAB35AFF8064EA204709F3D5BE6E04780D917A64CD0FD3B9F362807B0F0BA44CE1B4CF7AE7592DF99BA0C583681B9C32D17FA84DBC2D298C336D4F184E320A32E15A08874E2FA94AB8B6FA723C5C41169D7153504F9263A5DE89B417B49F32051721BABD4421E027C0AAE7DA4293849D7C016B2AB1F94616526E29DBA55F30AC27EAF701ECA3540A8793B9DB78C3D91BE13B71AF6E3615BA8CDCD3F2685F8139BE8804FC6ADF883AC5CF39B7A6F4E14C1E05C1F1E515CD525912A153BB442A7FCA1CA88E52C1588D8826F95718D1A93A5DB93B573E9BB02E48D4502F15683DA21A45FFEF141FBB1D8C921D55CD8EC1CB13D81A5A165BB8BE1641CEB6509CEC2D4911620F2CD7E79532D6047F831CA48ABCC06DC2CD711FCB9C98172FD7C39C6DC885ACA74BE9982F5F8B4B813699224350CEE512EDCB82AC590ABEF89A4D6A4E4BB4661E7B5097310CD53F97ACC48A03C9CA65FA36687FC5F0CD7ADADC3326DBAE2346D3F3DC8E4217AACFFCD442D102FD7382B237096A2E2811C9D64FD6C69425FEEAC606044A7B4136FD2F858464DB394D38DC8A60DA0EC88766967A9A6D6876D8C46AE14C0D12EEA8690478CA8483512F5E4DA8672BBE10BBE02F937E904A7F14B9C776FC0932D9B3974224AD65910E590219440328AAE9820C67B8D3AAD40B65C9DE1D10F2695D123C0EB387AEE12AAF0EAD23063E752FAD5C588CB0A6B7776983A317AA95C2A0F4BEBA24C5B90A9920395C601FFD747CEE053F29E7FEA75625206D3EC236239AED012CC2A4273F606C25F3D56E6A16453A00FDE082CF91B357049697DBC800720AAEADD95AA238AFF881580A27611EDE7DE6081D3BBEAE2DCBEBBDBD812C64D8C8D37D07862F7227749E50CFE59AE39C944FC25500B314D067CB149111B35F8C08EEE365A260F3A6220F1C535E588D10C98E0292B87C83FCF0BE54A280E7DEE79E4C96E0CE6972CCCA404A0B1F16375CDC90F2E6B5A90317C8FF7E35D473DCB69164BB3900C87283BE8CA31F9CD3DDDEABBB9380EC30AE1C148540503E +smlen = 45641 +sm = 24B20000D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC8B0024202EE00E10281026D0206013700D700BB009A009B0048013D01010323021D03B4018B01D10072008A011002F000240169006C026201E7029602050194019D023201AB01F1012F0083022C00DA024602B501F60002028802A0006A0164000D02200321003100290003000B0003000500040015001F00170011000900080009002D0019002B001A00310022002F000C0010000500160032000300190014002700250033000A0006002D002900060012002900190022001100050018001F000700040008001800240C36882645E624DB471BFBB1CA6BD900F057079C4CB20AC5DF683AE40047FD5B5453D9FF0FC73A7BB7C5C32D2EA7ED3B180C59C0A897BD800391E10ACC37C499B290587CB7441AA37CF5C6C23DE23DABED82CB813DA01931DB59A610E3642CDF2F82210DEC433698AEF0D36C9B4170A68858CA774DE41C9118C7CDAEFF6A9EF0B8877FE232BE06E5D4C6D46893C519D251D7979391904A1D0521BCB4436EC5615EAEF9FE8FD5FC68377A2802E6BA3E55233CFD4A70D21AC786940244A88B148DB9E9529ADF5AF8100D9C2C9285E5DEC80969FF0B1D75032CC14AC1F89AB16E469D191ECD55A5E9A73EE983B075061F6C6EBCEE1FBB3205AEE5338D449CC43BA85B944C8CC8CA5195EB53F69821A021B002FE9EC14CD3A62DFC317C111C284A35797E0DC68476E51FB21CF2FDF896A795DA0829B9E3B96A7BF58C9ED7DAFEFF6332BE0FE13B26F78DACAF826B0A2E12A95724D2592112C8DF579EDE209BFBB64E7EB3B1655B848DD5DD970C72F5B7C67D7D23F5CB200873A72689F31A274B4A7A459BDBD88691EFC24926F0305C90758CEFC7CAD7724CCCB2DFE8109E947FA4FC55300E4D6CB9F96CDAB3E64144383452B2B4EEFA10B1A2BEE54979A83C760F06F5DBC00AD65B2B123973C84DE4D1BED2F3EAA29B219CA21F011BAF9CBFB0D7A40D0F477E2DFA7BCDD4F5123A5010D686EBA3B46C84080EADFC8B5C4875879E7CEEFBD4F482A66EA385347EE8B43729F45EF479536DB0CB2140E44D51AECEFED9C6C9654805BA5EF3537DF31D1F661EC27873EEDF95314FE38A51D29C3F4FDEB02C6DF4BEC7BC0A372B83DA1487605C9D8F513A3C3841C20F2127FEFE2B6824FA8857C3AC6E029A01CD3EEC72A06B458421CFE0706985A3214E4BB234B247D1E56850653E13FA1CE7B240C494BA33F9595DAE80FFFD6DED37506ABF797EDE64DC80190E10EE0590712E9AF387048A58BE20D71C9B4C6BE7F8729D9C278F24ED9ACA6F8B68AF26F1A4D72B7FE68C4E600A54979BC78293B92FFA09E8467BFDCF5625A59D45834114647077F60A0388A60BA75DD6A8A7252F2EDCB76CB8D1AE572642A1E3A222C7D56100E2BA9988BF35EAC139B9571A2564AEA3376529CC4B3119483758C97E737153CE084D4201576A8AD85075C75C9BC8B23EF2DB9C6FA68A88E76B72539F80C8EA935E6630403F610B3319D6C1CF3A8D97A19ED3AF9F20366C082719DC9E0610B6C55D0D5A6E16DA2AC9F0E022BC074C33312B21C53E28CDE2EFD6963BDD0E4468F58383667BD28C5C7801399F1ED88A04BE21F58A5B665B0B694DF3F25812C682A452BC1F58B42521B518DBC28A13CB814C0B1F05607A8CE4CEE0FF8F014EE6A494854DEF15F2C0DF246A7C8FB58AC8AE97B49ADEFB8DE3B46C71A91183880AD2E3A0A355B5EFAC0382BE47C111A0C1CF79D8F7800391C79DE826F89824E559F8EF5539970C7B4AD96EEC3C2F57AF1E2831C0A4FEEBED7D15E6D760E6C21FB00C2CF78B3DA2CA6EC46AACDB3801A363CB275ABEEAB9545621E5509FB4F9226E3CE06E3654E9D085AD2EACA7F8C111DA10A8C290ADB2661B7ED1F78E05A5BE629459623E164F1F4BBC9495EFCF510160876401325B1E46B0E325A6A9B68B5FFC22A12FF5BC8E19770F79E76FA8C15525B9286292AE9EC22A4F28C4B9DEEC9AAC97C05A4FD0E15FAC0321B356584D0730082621BE50E83FA52E3E308222AEBB6C4632E2BB99DD88567A979798ED0BC3FC204AEC111BF1E1CA90F6FCC0C0EDD946810F152CE56A3893A8DCC9CBB7B73ABB684D0FCD488193DED84E2861914B6FCCFFA64FC5F322DD4E687A85D899906E20FDCB29B58266215C77FA558D79D71F8DDB7AADB42CD3BA1B4832D2A36F2380615284F627D8C7399B41B5991EBFE1D07575993FE45DA719CF94D2D7F758F27878CD789BBE82163733815FABC9ED5E403979D708967D7B51D046FB23D9FB7844021D996CA9D16909E14FF08E3F3C4AA2CFF582F8BEAB6AB2FD23C3344873EE741B63FBBA3B0FF58EA79D59FB751DC6F4DD8BB650202F6E8A4698AD9CAF88C7F84D7D6F96F6C0F940B0AE8577DBC155E5BFEB0F39FBC1375A854018EDBF1CF827417655865F573B4D53394F65B11EFAF151A01F8E2E0D38D813004F7B47A47F4B13BC58102180F4AFA149F7AC26E83D3F102B353045417E614694A5C58F4218F7B23C1C494A55AF801DA6A8BC4591707D74B33D020C35C0AFABC73A3D24C4F69E6D169076878E484E795581E1ED38CD636945BE3FD98E3B765C256C10B27021BD22002277BADE683218DE6B090115598FC941CB078FA4154437B987F20A9DA733D3C3C21720D5219ABCA24EE0366DC23F096AABCA70B78A0A4E29378D0A9AF171A597146B73C7993E6C501561741F642AB57A475132C4094B881508908F813787202BD74C4B9FD139037D8BF2E4219D2499EF91838A62B02E02C722E7665DF47DDD74C2214321B4E5B787F504F181DA4B497151F7E5624822F366F3DD58E4E0506A69C85F5F4141F3B2557F39E8378A50E0B695F28B88BB6F43EFDFE9C3DB44E332708AE925A3F22F12E569E4EA73BD4A3D26C94EDA39E028F854518EF40132633E30AD95A910D8EA14CFA89BD5803B028ED8E19D8BC515E6F03961A0678757ABBFB09E5CF9E4D8D58938B6CA8C12FD7E503D7B917BC8851DB7B7F37895FA71E82584CCF945563207F7EDA43751D91FF27299705F4395559753D40030DAF89916F126A56A93BC49AE4FC98DAEDD763B010DD47A684B955FA42866EF4CF121A5C6DDE6DACB2E68BC305D8C8AB7E9BA6AB3141F7AACA966F1B973CB7FF5F0716856ADD7FB492F29686665A7A5679CB94D83B75BF7B12959372EA8683C280D5F1CD04EB270EEB93FC3DBDD74493824EC08DCED5229E0D265F421A0FB5905760E2F3A109D0A74B1D2AB5F4A11BF9D297FCA794ACBB6C7C952EB043BFCE11D07264A9749015F749A381915F42AD16B64BA3B4D66CCC82E44510A7F7A78DF22EC8C48E5A2EE49AA724CA66697B027D2319CF4C2B312280EC18100DCEF1BCE8B96774668788507802A42454831ED4F3CC341D5B3126196DB4B4A62C3892BE6BDDD17C97D909F2AF552169150EA39E12A657D8DEF67E04284B2FEFA8B915A0002384D7EEF35B1AC022833013014D1E9E8DB44663906752A2ADAA2FE2D68B36079A5ACFAAE7104CD1086829E936452F5450D6AF4362766B6333E7592528A0D9BE08EA60A14C5138362E852C9F042FC6044F5137B26E69AC58543693A34AE27E99B11EAC681D12B22C54A56478A8CD5277D195FD531A434ECF0B9B7698566937EFB935ED49A7B8E804C38A81A97D299E841E34737E5591FECEBE7ED77E506555DDE5113DB9D1E6FDF57828A654F156BB6D2AC55C74558E76F85F5629649C80AD0258D6FD4E52626C1C3427D0C38E12957BD18E09A7486BC0BEC881433DCDB75380F92FAE1C0BE744868A1E787E7B3963EE48D1A84767CF1C2147CB7EF6FE09157D772FE1E9E5833BDF63DE1EDF7177F4E70D9FFA60D5F5973840E680C9A7D3740B81CCCC4C21C1C0EF1E510D30D1DECA65681D94AA99E31109239BBEDF3C1C4230A94C55CB91A3A44F57B51ABC831CE83DECC45BC35BA9E7808E3B9C90C04683A5AC282E77E6CAFA56CC9B6648C4730F9E1BB5D0353C29CB5CC2C9C2C0C943C7058E6B9DC84480E6683A6DE47119CE416C68B201FA30A96D8AAC0C91575A21BEF2B3DFF5623E5A7CEE90F6ED1F39563EDB3709AB14965BAD09D75EC4D46BEA6B2E5FD527334DE59C0E09811F126821ADA0C58A3F52DB8835A7665517B3953F5C8E824596384BB9CC07B0253CE0A791AC4CBD6C53AD532AE68F4CA746C1FC941DD189DE1D7C8AE1CD26D4D703AFC7ED0645DD7813255622A01CA4C530CC0FA9F44A1F8E324EFC07729633CC5DDB61490685F5742AA7F94EBC3CFE053AC8FF9E3325AB3E4210C9B885C43C93F0E03C744273E9377A39A7F34FEF02311D2AAAD54BB8EDAA71C0697B8C028050D367FA69713573E2BF6432DECA424B3B15E4B6CF8729DD480137318F482134B06A85E4A64020615FCE57CD6C31E70B2F8EA98CDB62ED297794105BBFF72979CD3B2E0674D275B193AC1E331F498FE19280219EBDF52104F9308C61F449E94F16B3F3CA9D2CA077C2DAE0B03E4AB5DDFEF3CE73A95B9A1C17FBD71AC090E009111483630D9C5D400394A3C2DE3236F193CC568E74A7B02B89B1F485300FB139EEB817051EABA0D60E6F15835BADA4C59FEA5085E7BB4291E24A19442B07821014D474EC53432EFEA0DD70327477325D901ED73F38ED0A0D64CD64EF2574C5B1FB88F6C269B91D4632A529C21F5C36D94F87D97424BB94195DD4906AA0AE0B3944F4DC86A50D138CE20E1E46F543459C11F7C517B2E8BA886823E98463E284E9E4D2F28644AC7E4093D024935EA31945BA44CCF6A450AFDB9DE5BDE995C812CAEB14AFB78734456567CCB3E6CC0290D133D03B2B02607208237E4176766C22F01FE6F2816DA5DFA521D91A322C8364F57E58CCC5AE6699A68E27DD6C419F4C2B94A084893828032CC397CB2D028095CAE6FCFBC073F426B6C8C36013C918C3738F900F1D0F5F92D989B7E41A1D09BA62871D6445E56EF89FECC5563DB16D759C4C4D422EED94EB316ADAEE2DD9D1912EF70810E34A877279FEB5B971FC33FB6242EF1F79B7D79C7A2EA8197A93A061221FA3A7F2C36517D3487A18BCA33C55D16EE524BC0784EF28FAAF90E669F1B1A35C0FFB1B5B03523387140D658CF7E9688F308BCE9C8FFFA3C77283ED62CC7F9671DF1D88755DC5ACC9D6C124BD3699BA3061E18B8F0D3F0472B3AA253CBE52AD78431E012CA6976239F77D3072B1417BB0B5362C49F7469510740A1C1E7F68F20A31E6DA9AA6614515B939D10173040E1DD59DABC6DCFBEF992740EC800BCC66B49E82A16790D2C0A7169565F493B407979C9BDF46FB3618DC5962B7EC5D25DEA3B7D1683EED125DC97F0E8A6C3B8D31DCEAACCEAAC4CDAF16861E1FFD695623936EE88668F56ACCF392CAB3C6D7CB5907529718965B7D7109580EA955734AB3AFEF15B545757D31E52828100F2D4C6FC58893FA732E4FC42A15067D0C2725772E6BA37A234EBEAD9DD975F1B51F63113E0010ABB3ACBE2F6CB8362BD506333414220ED60218CEDC0331A151DB326D3E9CBC221CB6BD7A88B604BD92D45014CEDA42159B970CE71BF82C79C618C84FA6E64141583A8B234383929C160AB5C28F707C8108F971A93A98C71ED3C491394F166370F6B7743B8E5D2D3D41C1D451F15493C4806431EA6BB93E0B261FB2648560939374F0D0CB67A5AF029A06C7CC2B7CD075D9836FC6C3199FAFB5602DF24C5BE2EDDB99DAED9C01F8B167052446DEBE5F0C9E8381BE902A449BFEFFB750A3F217B842E6BAB6456CFB17F77C13D99249BEF5067BCD19A408805DF690913A651114810F31314F326D2A57CF76ABED223D3955C55DFF5D978A77111A3C4A9B6695B5C01776058B671712E8EF0A6134A67C9EF76995A7BA897E266DB687F358E74F81165BE9D3E5DE202B98F0FC44FF8BB74772A84263BB7AE84F430333AD333B7048EA7992CAF9F68264D5C51059BC283A788EE2180E809BE368A6292D060A0A90F0FDE5D5E7F5983E519003C668A16354E930206EFB14FD50791C60C09B4AF4A996E57E78F133B5F4D967186F3CB27729D175F2DE1EEDD81B2AC236BAE42160DE2D6A5F4997D37C4CD39530589B5FE311150919D82319B8EC81703D013FEC407EBD55867BEC5CBC95A0D4EDBF402D1B5CC8C7EE236E3B698603C590A5F904D685138C8B96C60876AA69BBDAC34B3D6A170D68448F3E5609AE0ABDED683F4CD421E225F1D4A294702855BBA7515B880DD6479D5ED14194DB9931CC28709EA735F89A061D6FB1A1E3703D8885FEABE4560E4F62889DA7B4A372F55E8D5E4FA0F728BE4782F08ECD07D2E88EF29AED519EC6B7AB943F54C8DA6B2AF4D87C777F9A2714020994F9188AEA83944E3733976DD9F368F0A0CD9278F0C6A4B9E5414C79D7F3DBA35231F8FE69B8F666C29492E3198DE45DD4DFEC341ADF6F85E79FFD83243019741BEB7A68992F1B9DC6BBC26EBFE0D63D568AA5EAD3F33D3306206B7881C0F2BC11167D6F890C39507893DD9491AA26B1D9CEFD86BDDC8015260630A1F94B10EED0D21FFBF1BD1032094AF4C6369D44F00622E94700E959B78D90A08E6831509F4DCB86A69A3D84BD7C1CB9D672E8D9EBB101A949C5D16462891D7E92CB9EF4B84A0B1CE4BC246E855C4B65CE8F02F59D7D2FA563AEE17EB2724CA8E0A5CD4D884A6DEFAEC7615282FE2E2BC8D3D204DB4E1E949BB7C9ED2E99C1861BCA85D5BC46F822FFD1D7E72F522293315CA303161EFCE0E1C0D295E856DBF593CEF015430304A9C791C5ADF66124A4724D09A0D4F162876C84D3DE0D004179BA322C7A9EC6F889A4421A57F8F74727CCFBD22C7387DE2C886B2F6545B282CBAC5E95C7FBBC3B15AAF5A605538B293FF14D54C76A44A55F71367274DAF70A0F0852499E2AE5146E4BDDBC469345AF72A2B0502DE62E21FB19C9797FFE2013E416D073BA0966795BC31646A6E45E4F4C6614E8F5F4A00374360DEA2EEFCB156925E68B44E1D0B64712B0503A68900BBB70D3C4D0CD810225C2ACBF2C9CE3F9C73CDDFB5F4A4505AB43A4F04F650078CFFEEC595149F558FC11BAE28EB80E7E65BDA238B8B74A003D275F0E77FF3936420296CAECD5D121604D1F5D78839B7C5492B1C0300E3B1D1BA9D061C6B628A710C3F555C6263E3A0BC86A364ABC912E6ADFC23E4A6829E40660E377A3070BE9DE93FD19C499A523D34DCF54CDA83D0E437D436D3853EF233CB112A30834C13595034E157436F04CBCCDDE295AEB9B0504A7CB6F987E95E48DFBDA287F2729D57D3EA8162B421EA5E7241849EAE903125CDCF35ADD495C17A893025B38185EECA23F2AD97CAC6A0CFCDE2B01CE8F3C819CCBA4915F1017D2D6064F4B947ED8A994E4F20BEB5C3682D298F08CBC4C2E8747B684D51968510CC6F8DC597A030B8FF605880C55E58CD8E67BD7B748A6BCF5DD5FC21EA31AC94AF2296AA998D3D7D96D1FABBE0C66B4332A3B0310DF1823F400E5BB9972CD578B83F6DA60CB2D1124F14AE071E165196C604A19F91D48CC2A5106CFD8F7CFE10B3BE8BFA26595684B685086ABE6A494C4E93965ED4CFFC268CD7BF6141441841EE87E95D7EB012D19C6306549C7967D62301D80E570D944346B8BFB4BE93CC3EB30FEE4A649E014DF518751553A8CC7DA072DF00D2D27234DB98A5142F528C090EB9B50036D775665FDD7AC847B12E9AF9870FC5A60FFAAF78C6E393EA08F8EF9C959C71BB4A270B44398A12733FABB6E69580A6F54A3BF8A938E1B30D90697A26E7BBA5D4A696611E16CF16DDF52B0FBAF604FB098C9FFAC9799CF1ADDD3207FBBA3A2962BBD4CE43DFCAB90FC7135C88D7C333E604466DF6B54B04A2E7A4D8C30C03E41CD1D1352857C2973CBFB9EE5B7A321F32EEBC7D8C5EE953E02164C3AA2E31C9B70DD99DEE48C81D04D8D5839E8E8383BEEDABF00EE30EA6DCB75D672AD771A1FF5C94A9826D9977086956DE1790126DEDAB0200D476FB7D4F3731A5DBE886E299314A5BE62C842174255C75E3588D204DD22F3CE2AAF4C898475155225BAC0FD27E901383C20CB62F1421338FB818DEB52DE96713A9491D1EFD5932670953439221FDA7079E8EDAFA3278CE7ED3881FCF24978B3C555BD56F53A8378C8C21B9FD03DA3E943A105E4A09C6C1D19F125D3EBA13F43A38509DD039028041674791080253EC123DFD9DEADA8DF7454610CCB4F0C60513FA09D598BAE9B0EF5DA450550B07CF7B12571E28DAAD3CFE09C5889719A2D6A588664EFABFEF8A8BE747FB78E468D941086345B7594C4F35E835C840D6B103E0B6CA9978077A85C60395B1567E22DBA6AD748A600D35C0333BBB1DA0F1C8B39580CA9F81441669A57EAAE4A09C3444E6624073F9150E3DBBBAD38D792A40F10F250968F445F96C8102E169899E09A42382DDBBCA7BE1CF27577AC6B44A55A75FCD0E79106952EC32084ACB6DFFA3ADD6FF0AD46B60AE67C55FA78C02B14CCABE7DE36D575E26D0834B0D7DB3DD9CAF7F7E1309A5A5FFED5F0B41C60C18443EECE35C32D31C6F03BEEC3239B95E64DE43436CEE3B670AE6E17460793BDBDFBC4975776F72CFD22E3F4CC29D3BA42ECA6B2425A026C3D5BB060D684203FD98D837C717E1137944ED41DDCD9B8858487439F9A3E4EAE23C2F7CD2A373B6990DE29A4F637A670BD2164E73D6E5E442C646867A664890AEB4F73257DA8CB85723530DB215BA1E5FC17CE950A8914BABBB2BDF4F447C1EEA8FEC09E4F6736FAE78414CC0F1825DD699DD35D77AA733F644E58730705A8E2ABD5DE26AAC434CD901BFF3B3F11A07A99B6900B28603DCE9F8C02BEDF7179C5D915B6D1E46D3F9E131A73C6DCAA64267438E09542CB3525EB81DA1CCF6189A33FB78E5069B5553ECB76E15BC11F3FA143707F18570F581111FFA5275C79AB131A9C489992B65A4C1880F3CB2440D1303A7C2D43B0E27B78A8F8C629F03FAA2E25A740488C2B698899A57188211FC8A6DC0F639C32B52249F8D42C5783A837CAD2189BF5FE099A00EE452FAD22C28A31D62BEACC6600D57E041D449DF8E21E352C752C44A1632D1C01D1DEE06207EC9AEAD02010EB52943A40660368F09C676DD9AB6EE3AFF34676317761D09DCFAD14320D50211725DA619B2B1B710ECC3DAC284879F6EEB77E2061BB56C0DEF06C9451A224CCD01376A24EDFAB9C1661C8423276F74ABCEECE66ECE6C6C302D8F89B9F22F5A0796F8C280E308E9B00C7C4CF7A0D35753494E60FA7CF4F2719AA1674A6809E5D281CA9BFAB82961226056F1267C7EC709B2AE91B9F3EC103D50EDBEB7D973E4D0C6F81B5493FD8F4A2920F5019EA1AF9B88A956F46E5520DD31234DBB4A7D5F5D425185293AFC39D0792044827AA943A4E5B5747E0CD4F0E90B4464ABE78614FB89CD30DD5004F49AB62CF9031185D90796DFC83123E82A221DD9CB33B84C050EE62EED317968753B6C4BD16A80FAE6E1388E63F64ADA47631DBF35F82E614A1C3DF6F667B2E0C44FB9EC7193661383C60EF476AC16A0555ABF7403957C8BE6F06122633BCCB40EDFE9391D3B02133DBA2A3C469C4AE681D7C75CC4293D1E0D84F6A2C5FEF7BF63E701802667A06CF39060165F377389C1B465549191F63E2A2627941D0D62FE875F429AA1A698E4BE9B61D9F36B4C576B192C83CE93F0AC9C1FCF9C6C44470665F10978C0A045BA2C38B2C08861A65F80A282598477C72B7CEBB483B6AB7D9FDC6C4A0E47F146573978B29DE437A6CA1E2D34870C35D64263CCC57FFCE173A73CB09F9856D0F588E29A4E6ABC1F862FCC737A5A134F0CCEFF0C116DBE169CBFDD5C3D47D2A58C4698DD06B29A3FA45B86BF870B8276A7CD3E1CAB783E296012F95382A68C27B7F39BDDD664811D531AD1D6649AAD861F45436311D05F428150365E26320B50FA974923A153DEDE975E33EBA32B86A455A58212A3B202FA6D5E2A4EAA55F2A4C677C5C9E3F606C547FD6D89C457FD76DD95B703C969512254E223104E75CB716EA513A0C7B7672B017CB8AF88D4B9AF3E2B22072D402BC220AB21B119840C5F80C364F6A131C2E169D5507A71E03A19A3C9C16EE3477AED085AA2E5F92EE8830CF4E24023D93D84A1C374903849D8EB007A9B863EBF394426B2948A50591A8DDD87DAF688B33F5C6D8EF873C17E0494AE90F33229D215A8544FE4DDBA82A5C413E775B21489CC27F45607A5E0FCC165DF998861098ED34B471A2DBA36B05814F5DDF71C23ACBB3C46638B1F9C2E589FA8C555FCCFCF926C655ED7723E5C7E4E496D6A1BB314BFFB680800882B92B875C02CDB57A2B0026D54AFFB42AFD31657E72CF34AD9441A27681782CB948574A9D1712E63FE71B71103EF504DB2AFFB8BBF81148128675B66D1B847B4845BB86DF0E60DEF03E5ADFDA0947453BD4608BE27F55D0F8542822E8576CDFE1F78474BC8983B63BB602D1BF369885B4E05B361C396F0EA43DBD4142492092B9E548887E6C1EA8A149982137BCFA73AF2FFBF8CF3651927AD2E18EAD4B6F4EB9206D71C951E49B852D5D463DC3CED03B58BE446CF70C1807FB21C0617C5FAA888238B93ABD0B971C5E28DCA5105ED07028F489FBDE98946CDB883B88C60218FE03EC7E4ED3A4B13AECD81D5FF1191AE1A9E5A53728D60C292A0D08E0C5AD29C2F254AF1F3538DED6008C7643BA33806400D6AB4FE7091B52A25E4D7C67583EA8058730ACEEA1AAA879ABCD44E9624FA09BF46746D562E44CAC3F9DF2E5AFF34E683F7460C70B2C1FA57D6BE74AF756EEAB4987E9B4A9526BE65A38BA2A791D68DCC9A41A33283E0E0A3C025C8AB40CB62C77F95BEABC3B3428814960AC2B8EBBBE40EB07C177B0A4F82D9A1DC263D522B68F5AF8DE0EB958A8EB5BA7ED6BFDF89765ACD10C40A315508BC8CABEA4859B2B0B15667C8EC8DAB9382D6D3DF7EFAB6819F045E923294D323476E1373F756E1DEA6FA51091ECE0A4C168E4C6ED93184F3CC2626AC5CB938BA3F866642A9FDE5F3E2BA5D764CFDDEFDDA00614CF2B2C444F29EAEE58B8C9DBA01D74EA405BB8DDC9BA42F4677018670FF331CF0F15E46450C973E170F61C110A8BCC2284ECD2D24F7CE60E94EBE1E659CA4D919CC949673F617B077BD3C1FD52460B6A5101DB7220D4E1D3DA4D95090DB6C9402B3D363EA498BB7B2F9E45530AD1DBA721227EC75605B763AE5FFAAA6D2DE2B5107C5EE613D16C62CDCC7E2F90E99E2355C5289163BF92717EC12347F1F813DCCB1FC7E9124A0B177113CE928D68B86BD87AC2D3E3C6D61CAB6445CDD67A594F1D2B9BDC54B3AB10521039EA2EB4745188A65A032B0E534412116EEFCD5B8E0B04CEC6A73AEED4E3BD1900C5F78BFE2910BD594B4B78A712A6648EB37EBD9C0142F91A1F567580ACE7DB0D9154086163A392D9CD197FD89801AE11323D25337CA9161ECA71DB83486B750A8161D99B30F6F126DB597583A76D42D73663A6DA261736A6E28FD6C661A3A6D5A2E8E30F39C4A853D6AE59C6D3FC138A70B9D9D6ED6C97E598B6F940866AAF1029E3E1E3C8E655F70EBAFDC40B742C785E2D043CB103D16E2DC69BA85CACCF3A501E97688FD021D4E45F6249F7E7B8698C74CE773B363161AB6B42AF5A16AA6A8A290161C79BCADF21959A51AC1E1E74AB93F4010EE13249CC86987F0910A5BC182E1D147727567D4AFDCB3E5E0157B1F05D7F440936CD12BA8FEDAC52E99C98A065680EAF5762C6F8B8B1D194DF2A6B00D6605B1CC21B158395303BCB1B96BE3A60762562F341E9D1DC3D16E7DC2483868E2F9159C4421A747C506027642BD54AF0E3D854684C3D6D3A8344F35CBEF4EB431BBFD9613C519A13EAB779F8EB640212B0C8CF0F68020AE639083BBF70C13F9474A6C77B071391A17CFE1C4E7905107B4AEB92AF7DB114607CC2779C6B285095A320F45357F5DC39D30D878EAE2879D103E4B9752313C593245467A94402E2873E7BD8D224D163DBB56E714A91C37401A7A5A8ABCA8C5E4BDC01CFF7B3BBBD7D7A648B725F87A055337D931A4E8181AB4C0F18C8934C7FCF5D687D9BBBBB563573D7C883CF553813AC47E73EC9ED65C711CC7465B8BB0FDA356FE865B04BEC85830AFB04825947DF053D39271E442CDE7E14CF28E93263819BF4310DDF8C09041E2398ED1D13889C089A3A0C910BEC0D94466E4ACAC55686B714B0ACFBE6D362EC091054DD86BD691F1642EBA6C747DBF8F7B6396DCD824DD064D87C000E5AAE97BB84E645BAA559A8EE990573F08ED1AEE34989F39513214739C88134CA2FAA527A1FC0ACE5ED4BFCD8CB277F6A2DBAAB1F56159304439D63E58C8FE61AB63E2F9F019D08B366248738164CEB709030340B199E1A18FA059E27F1D787D86FF32215234D516B23C7F9444A579D69271769066947F5966BDBAA8B6BCC43261738623C469D1F4ECEE67EE671502F9BAF747D613907272CAC654FB491799C3FE783A61587500081670EDE57B6687FE735BE19A28340DE66D54BC28371F1D223493088D776CE63558B77B8BD4F6D87C17D910B9F42392CAD90E4CF0D3D9BB61BD58EA24E916861B461627A8551F4BE229B84EC4D40A9E638A1E1051643EB905E0830927FA6BAFEAFF36454FC1BDE8AE1006A905289FEDCC81CB4FE11DA81BE2F7F1726E1C94C9C28C29EACE80E4F82196382EC04384C566B6BCD38EC4E13F1D75E84DDF1B359DF9B90950B01E7759BA4643D40C1351FA2580496771CD8403AA2BFC9FFCD8A290D3CC8991E33D2BC998D25AA3B248644F763D0C368149B7B854251AA9B6042065D209B538E2576545A206A9A64DB692ADA4E153FBA416A3454DEA0E8943E8AA3FC0A9EA09C8C1B9EC43CBA00E520EF9CFE0EF4651918689145BD3E0CBE0EEB8E2A173A0935E461E468F20FCAE22BC95F4EC09675A8518E58130D6CD865DA165CC0780F58927E1C95F48C1AD32834EBBE8AAB53C550C20AD817820CA3A8844DEFA8697B54185EF715201B555B73559D505F4ED253DE2703B4F466EE453A43175294480C307EC4A0CFC415E5D95CA201363F38421E19A3D43FA90CFCBF2301FF92CAABA45130AA5E4F9B362BD446A579CC14D8BE082138014280AC2ABAD2A0BCE7295475BCC6173A3CADF3F1718EAC9D4459D3819F8FFDD771534F0A8F75357DCD4C478D516D7099658498D6590F34ABF11D94FAA9CB734EA526A874C6CFAF396BA1BA4C8DDD5530CC6E2947D80DFAD3FCF523B150833823E5C58A0606B0F90C1D2C37C8A693DAC8F5D104B970800FE5B9F2D782D91389FF1D1989C1CF6ADDC83725908F7AF576BABACCFA6F4A4C6AAE9F8C4F88F46BAEB5C62BF9FB2E125BF320E2874228F82C601961F3FE79D0C161DAFF36EA55F36644FF7AB9AA20B19B04ADC459F52B2FFBF2B83BD5B1D7441CDF842DC4E390E2864C428F51F05C844C13C476154F69CAD5409436904F77C493F7926F3666526700EB0EC4EDF792958CC24F475263DAE2768999B0BB10ADABCB45CC0280E1178A9C8AD7001DA35BB5E0ED393397DACBAF4AF3A3B32ED105841E00C67003D3C947100B8CF3307214BD8C47135E5F87FA674D4C48C92C0D5894A274A01CE1A7635B3E94F1AF0BB3F0A917EE505DE3F55C8F34BD74C43C5E690448AEA0DCF226EF087659D0A82676D5B9AC5A6F305436CAED4A3F68A5B5131928D84787F85107677F9332296EB151EE563DA79D752EC35850828AEFD23DF6F3225E5928C5A43CE9D7637DF726580C582D3F0080A4D040C504773CF8193F8C3727633DF50A32C3ACF64B53C0538E8B3764406448B9EE6FDD863F357B4992BAD8161BC034C1B1D8EBDA113D15A0EE01B727A7C65582AE687FC61EA684F341852F2561AD34DEBE341705CE8F20BE78FD00D24A52B62BE0CA927AFDDC70AFEB4FBA7F51643D85C8403B6D0900C7C4DF8C0218DA075DA574C363CBC2D352C57B96B7C2DD8D713F0A586E1FE6C5200933BDD13F1D1211814DEE63A2AC3C0C4D4AB1AEB3E62DCD68D814D9158482168E7B75355F5683C3211C9B9F84B002B06E14A0C1DF62FC553AF60DBDD60CBE44E7076B40237FDD74FA2E02247F36B40692B93CB9A7604E57EFAB62F49C423CD8E2688D2957FFAF0035ACB345D9B8B2FFB95F7919626E7C7D8A986C99FA242E42D985429D2944361F60ED8932396489119A359500E33E364FBC51E2B49F95339A80104478C637192FA360823252C950BE5843162E5B553DBDA4179F7AA544CF3C112854F128A828EDA3B683386E276B0271C0F214F803331AE15105E6FC6F7F81F2AA1EC6ED6C619926A5577E1DE78C49B624C70298249EF6EB054693A976A6E5A56ECE6F9895710D7A0A97B6798EC69680D8E94CBEBA41CD3FC294A70616CCF90624EB08FEFCC3595D4A65DC8C0FCDB15E041E98A4A2EA127E779025CADF4ECD59A73A39A5B05131933EE991AB8C35C69B0434C3D7649B16DB55176B34AFC654AB3219A8C1D536B5FCB2DBF35A52C53D4F8DBB5C7D86A3586C4DB269465C7F419F771092389AA5FF9B2A4D9ADA7B3C7BD030D0EFDD142541B9B032034D9574F444704F603112523B8FA02F0F8AFEE75BDC9764D8F25F5BE4D5E50AC49971341338B0F2CBF731E7D20E3D7D3271C87B8E2ADBC883C094CEBD9BB97171D173F455933EB079FBE45880EF216F2A8495E8EA3FB495C605DCA7A2A677D7B03E890DA4712F4EDD5D8A013A33B96781AA2B948FFC41CE5DF319D83C695275CA19FCAF246AEC33ED1C57E2E96A00EB6BA847309FE0D55EAD1048260F55827730B221C32413E155D8BA63C9413A81A54249FA2DA7CAA2FFDB22C6A7FA9A8066F231813DFE807B522AD252115C781F338452D00F60936BCB0AFFA1865EEBD940CFE3F391D9BE182DA7B605544C18E148F0FA231391630171E6A2B20AD3091134845897E5B4BD34C4F0C43B07F19B19D4F1751CA20A43C1E2A61BE4AEC57F2888C1FFAF9C1C78BD87EEF9A883B9018B1BF05E31A8718191B96CAB5DCAE57D1AF96C5B58DEF9FE1C8025B5CEA6E386B9EDEA55F90383787FC44DD7A4A2CD9E495AD58CC2881139FE75F2C6C49FF01C2934E6487DCC59618EFDD1BFA715EF4E3E6424A68D8648E80584F68D2E7A66E9C47CE0EA660A535F458BE75083D878B641533C2A39A042D366E120F22D3694AC1C463D3EA3A14DDF0A83B2023F6F52A412E2D9BBFFF806463E135D78AEBB8992283275F214CB30184FD6BFAFA048C5601B3DC057D80284838576B89DA1589C5B1647896D7B1EFB12BD387BFB77FC6E5F3CC2A83E9075B9B0135B94CD23A2F8F52E5E4E6EDF3214143D50FD0EB68FCA58ADA064B276DC936FEBA8DDC6278CB9B0E9B658F76CD3660E031189B3F7193E6AB8D7DB325C5C2104DA8502BFC6E8052DDF141FCB4CEB79149624C982AEEF96CE43D235447B7A471259F2F45C9FBC2B35748D58014BBE66B98AC1BA1366D70E13E9EB6B8B6A475644542EACDAF9A677226FB953E6B5D23335BDCD2EB681547ADEC8BE8D8227067E2FFF707048F1401416AE0839E609F5638BFA775002D88155982B9BE3BB24EB1F2B8EEEB16DD9083C4566759D9A26930ACB073146BC4C3AA25747A649596EB88E789F2CBD576B56BFFDD5846B4D26AB03E57A3BB93D846769A1F170E5B1351DD33A1571BEA65A3C820ED3119E1264F808C71EC80F344E9EBB2B74033FF05B96BE92BF35F27362B117E204275D1D32CF7B93593448473B974E9FEA32C8956300A63E40E32F2E3FCAFBE74106F2FBCAB4345FAFE70932CE654F91C841FAADFAAE87D099665F13331E627219F9188FD37A387942EBC35F47460206C2819987ECC337E5FB441DC840310E1742560E9175AB3BC16E36012FABF3A6BC977E1E04885D43DB949C95E9DF256C57985E3DF5C5B60E835E5AAA38CE2276A7163C12BF8CBFE20BF6BA27D952060FE8F0944A3534FCD9DEF9619F6A39C09873BDCD1B5432586EE00AC2CC3552738D4D9FD9622D8BBCBA1B37498B29EE02AFC34A87432BBF08293064DAF0E49277C1EE6CAC288C56CABBBA77A794C3B457BFF8289A14A83A97A1CC1CBF139101427EB3D19DA9E06CCC69811DC12C5C0386FD230F314DBDD2FF996FA49892939D574E51F69BB469316971D0EB33579E453A948DF777CF1F07CD2C3C9F8D914C692716C831BB3BCA120B4E142D229DE623C6C335FE7ED5D3AE45049377A71EF3661CE4F8CA2631D513D1BB66D987FB1744A34F3C3E3F454265D6B74351976AF79013E640139B23520036F94A599092B9534EA6B632232DF81C81A7EB2ECDC2F6981EB432D7BB09B79040B1E555B048AA55528B7AA68A28EAC905C0BCC5364062CCD28D0950F70226F5677EBBB412572268048CE8387E917C37FF003E2C86B5011FA5B9C46FD852B52296029878766C834D18A64A5F6FB78429190ADD554C80ED565116ABD8E25C0C0A300380902F12239F626D8926BCE6DEE3DAF0F4F1E760807458CF704391BC77EE541228E4EA760E1C0E90AFAE2D80CF0BD6A36E9D51E21E91E48D1FA0375DDF942DA2AC43B30BD079863EF756EACF307AAEB6D16F67B00CC9CEE75C2102B9BBFA55A14C9C23BC6DD01C761446C9EB923E0535E67420F1BDDC4CC5C342B8D55E0335DE618D3F0410396191C04B3FB29B53B3DDB56F54AF487D9804F0AB237083CAFD1ACC3EE2086C4BBFAEB64D2315E3134BCD244133648E0103F7F46DD9DA45EB1C3A008870330A2D6952BCACD405F87947797F68716B0C77290DC5799CCE58A2B9F44A1BAFA86F531D97E4DD896E1790A5EAB4EB6DD44F0C21C0DB6C6F4ED9EDAF520015D5267E650B27508D0FC405DBA4D850696B6BD597A3B63CAD2907B7D29C4F723199F047DE8BFCE20986135AF06C46E3CB050E90CBD8919622C2FDE66D8E83E4F26B4CF8C313613227361780A4999E95E88BD7C2401F4F8A18D60FF69651253CBCEED746DDCA2EF85FF26BEFE62171386FF946E6B5B2A8E91D1920858EE940C6282E05974C1D444BC21D51D427B5DF8EAA5494373BE564C29533F992E451B0CFA6E44BA1DF6BC0C2682E5B4CD77765BEF49014EE35438DA3E25FB56C7C397CB8B323CD85F97CE2741DB1092C79AD8B5A4091186C667CDBD3FF23D99DB790CD33338BBCDE8E0DBA9C37AA45924544D7EF179CCB20EAFD982A345C2E815606DD7AE51459CEEB1FF75F9B13874C8428EE337A4BE9306C6F1D1C80463D5F3421BF2184C79536BFE547ADDD207EAC5750FDF33DA4FBCA479ADE277E7C12C6350FF1A2CD5C1ED623653A23048611D040082FB24977C200CEE39E4ABC1C9E65DEDBDB1B72425CC1A539A231D06098D7C1CE6FFB2DA65DB2D612D3A8D696672AD5CEDE89148B7EF64ECBA470C5EB1B0A1D5B59336A46ED2648AF2D2DA17E8B67C781622D8449008D3A1494625A283240220294A7EA59BF7B846AC0F2254C483BB09003C8593F01EAA53CF25D17406C70EEF367C17B19D8F70675BE168951FD86A160E33D65CA35E7E5689AB0B300012AE5C5CD9936F39BA217A4F7541C1F826281B24ABF828C7EAA772AEFCE58AAD42C8917726DE87B4120A89EB66CFF9BBDCE133499F98AF7E3709464A97AC4F0D27626BE5EA665C639705F65D1E23ED53E71EAFFE53E0B16D0252D8AA37BFACD6987258FD68BE912713E323FC2C28989D730F50649390FE522408E9A725BBB92420C00D81B44DD3425FEEB3708B6C0B8F2665D036DEFE414910C02567F84C00D5497FF87F8960C48979378F270152F5C90A18C3C9AD41FC84E7E5118209E8DD6BBB15B447F166113C69D34552644D271CA62C77A1CA759F9D414F3AFCBD3125C67D212AE32D517AD5D5B505F054380D4DE2EEF6E181150327883BBF9D4966655D1381F75CECE7DDD0220B8E60474D3C650DE7DF48F47C479E91020BB4DB43126ABED7327E0050914410410FD95C4B82FF3937D1AE4221A0C7D8E4B524FF389FFEF4693E1AF9475EB0E34A73E7BFDA48C5428F18AA4CA70E901C97FB734CBE89DC4B880FD2052611398DBEF7EBC55E93D4BC7AE77631170D7CE49E2145D86E1FA8C56140E407401FC1B5C69C85A01700718647787C7D8D1448D0A6782C0A56034A732608FCA0DBD9BA6660276F6EC1CD6EDCDC43443A3ECC4B5EABF3212D813BD60A0ECBAAF387DCB3EF3F5DDD237CDE553B832D5B98479A068DC249DAE2ED803BA1CC38BEB4CD5616DD5FE99DC648B1506B7724E419D76F791FED350DBE0A2AAA749EEB842868BF129EDC2BE70A9C17B24A2B01938180825BA812EEEB82BB932255423FD9B331004E1C460355C7A4AE403B468A4BB527F0E7CC4A80E031F85BBB9CC116FC6000FF7FF8EF35FC69FC253766CCD794872D838D5E557EFFD99EB5DF5611A566612D002C03B07CDD6E8B2AD97B495999E3C0F52AC73C4A30310EA23C8EC1FDDD8DB5D9AC2EC551A41C47CE4413FBAD3A482EE769878563B704031DEC3B046EF7DAFE5589652A3815FCC363255C8CF14BA13F5E63D1CF6D37C18C3BE76C095CF78AB17716E9F37211ABAE892C31C388D851D7411F6E759C81C6719CD537F54ADA458180553175249A175A117B1115C19350A4F94BCAE5087AED2B148E1C521822FE48C99C3D232667B763035215E9402F184D572A6BA2E494D5E3035631AB8979D0FBE6950BA8BDDC7B3F999D132457F8F5B0FB7BD290764D349C3A813B9C1B7E26CB077586E7284DAB9924FDE9F3957F0019EC7F24C41990293083071C60897E8EF76B99DF55343B87A9409195A0EAAEC7EEE44DA16CA837C9F4C9985D0C65B18F4CD84E2BEE44F2FBC6A4600451A89C01E098F9F1EE755D6BA32FF54BFFEA60C33A12732EB8991AF860C576B0C74B4F99CDF8286A2540A113ED669472F72F6F81071C5BE368E52AE23F87FE114B0FE1D9C361912929FEE72DA5BA2CB5EBF2337D312F06B933EAE020319922F09599DAA51ABFDFE83D9EB156E008D08083B549D5685F31A5D403FFEE86089808AEE7C6A1A0FF71D296FDA2F67A2FF549829A91050781C9EB8BB56A57932E7FA64745051CB0A03791EB094C3506FF3AF587D1D89C5A6845E314796877BC9F62339BE42960B1DD3D0BADCACDED28E319C22ADFE3E928BC06771C0825BE20A389F92B1AF32C0233ED19A151061ECFCADB788C3EF9B4A40BE559FBC4BEDBA620CC6888B22595B62A5ACB6A44BA0EBE08894961B2D0F17DF0B3BC5BD57DA60523FD56B01E52790F79954D24F356C043E61BDA3E751C0B057862350F7DBA5B364D40200AECB71D557361EB07C2232FD1C60429605A8FF9ACAE976185E7760444710C31787335AC02544D2AB02B3FF8DBFE3A2273E1DDEE361660CFFAECE17F566BDD112A93D2BDDF27A2C8C015D11E16945BFEFE219E72C422513D573B8508F6E433E75DBC71476406BFAA78B01C03A5FEB4E132013B5697BB0BA50879FFC21CDB1920DD7438A86F129045E872D0B864FAC77B32E01E7C2ECF55E532CD4623D596F28330DB637E368AF15252AB2E7F80F5AC43F745E9A42DE27592038DAB1BEF262A6272A01ECE3F3836F653E900EC6EA53B3E190855757A131F6320268347FFA8960429643CB971F75FA1B8C7810375A594809090FED37CB5E67DC8B6EA282365CD78AE63A2133AF0E28A2BECFDA8EBEB8073A1161BC1244414483D3E77A3E7C298CFC6AE8D2574502B2AA55981AD0A143AB79E3D73825AFDD10E8D516F372C459BF9B15ADBD922F00D5AF416F75669214CE4A765FB957CDEC0430B6BED0340DEF93D0292589086350BD9EFA4B8E539A1943B5FC9EFED10165399BED243FB4DF129FB8FACCB13E86C67D33BC313BF43B87F3F74D7ACAA0086A2916ECB78C9B3C208D37014D65E860FDBE489E36059B02B4265B9D4DCF555355B4FC842DBCC1B1AEFD65083CF24F7DB4B798293770D0291CD25C0A99C3A286E3616655FCE78CFC84AFBBB8EDE902C04C08EF58AE819F251D476FE26A4B6AC5718975E499C8864F3B210B24B1FA23E42FCA92E29511394A5622D5A595B80E8B3928EC4E43B1497B9A96D34C1E9E4C5834C6C048E56B66F26B117D8C0DF03FCF74EE3C275B7B1D80A607BAE120075CDF2C5E7B012A3AB61BDAD2792CB5DD718F79A8DF71D33343FF113D12333E8E8E180551F298C62B06018C16AD6DC30995D975633736A59A898BEF123056F4629351F41C8682FE12C199740F3E2C9E0F393DE3F7192B4DCFC0C36C5FD7360F80BBB707E4113ECC6CACD9438E72344867EFCECA0EE4CBB8629165C24EA7ADF68FBC0CEA0E83CD19C109FFF0017B8E30743F2EE77BB108735B30C03594DF0C7C78BAFF78CB92E22BEE3E71AA3BE12D2F20192D17D8B90E9F4F200D538C06F67F1B53ADCC7608C687A494AC3ACFDAC41F72A0589778D0CC8C9ABEF688538A20049DC9A0B11C440FAC7C3FDF2E1B81C26D3F947B6BE2807324BACCC15087C88725002432A9AE8FBAB580851932D38772D5C21633ACD4529D522DB627A99897D81BC509435190C1B6AB29C3A59E1DD2F76079A686110CE5CFF71831B91F035B266733A2F8950252BDE43C9FEB5F886262FDEB86752D8A9549C02030526AE349C16B02024EA65E2CBBDDA497EE4DE9B3B78D60CABC38EFF7808E069C8B5CE4375422115D34B34DD99740ACAECF7C161BC282E7C5CE1D0E46CC9C5432C76BEB382235F3D6E33E5C2668FDB5F20659FC4AF947F7BE8F9EB7710A92888D1D4B02FB74C54D6B273A4E92E610F6C9B7F1EF7CC049C51593A7C25E54AE40BB144A08D3C3080607C09CB29E3D05C5E1ABD57CBB3FD4C3158B9F7DAC43BF137A30EE528A1BAD4F4363BC24D65CCA477ECA49172469D2B2105D5BB3831B629A8E2C9923DFA520C0E6C7ADFE202A133280D4583FE196BF006FAE544DD2E9592611EF8B75E0D601F27DFE80010D012FFF2B7D512A5837E49221D90AC2ED5BD86B310856F28B3EEAA563955884D21470DE289621FE1E6B41BA65EDC18940C72EF352ADD33F20C583DC3145DCC275D23AAFF5C375F9598BF6C8526B162EFF30E05E8A605799F1C77A183FDF9A26DEEF3CDDE9184BB99277D08FEB200D111680F7BC0F0137FB1C7F4D498F240C6DED24A5A11D2FA714FC39AE61E9B188C04BB5673AAE4DFBC62C905B1A88498DBD1007DADF1A1CB7A6D7E2CE0A648A61843961B945610F996CF08C96E85E8FFB144179697489003CCF9AFECB3675D6BE22FC4BD0F7CBC1E5FD2D435160E98B18D5038AF5C8EDD9547D9E41950F786CE3C35944CE3DF3BD6E73E7D8BD0E8CA025C04B177271F22EA34359FE062B97840BAD5594C69257F95A68C1FCA4D49D0979A2FBA2F95DE4E2CEF907C7B120C2E18D90ACCC961BEC7E57F598233AC3D8CE6278E5C476254A7E75B56AA8196AD3261829D69F635F6B2E74C0CD8D9D6A276667FFD2D782AF5D7C1E7E4A0105688DB881EFF91700CD2B395F710275010CA6936E8D7851B7E7595F9D67FFF903EA29D85359D6FBC8CE6EA5615D20AEC0B938A123D9F5374A7DBFFFC028A7E7E86B7D19F7B0B04723FBBFD078D1714EA7D68C76471D68CAEECE8E6C7F5595C268A2F25A2E15A56D1200029D7E7AA4DC790F88DA627DEEE52E5BE1DB928FCC7DAE7856E8E9AAADA07D0B825518BD5E4747824523FD6679AFDD6DEE6C2C8CF8B2EF5A85069B1D1109771933C2EC95CB6AF3FFBE199721B26C60877D47D4E24D54B5EAE7A9297BB981CCCE2BEEB44DBC576C1353067CDD4D8D55E6743E8F0AC1F005F4B0B10C8CE050EFFC4B43193C0231DFFE1E5BF58B7D2EAFFCD4C1044672CC384FEC194205466712C0CE84C3DA6F1AE6741CA48EFA098B51BB57A48F4DE18A5910F7C90BC4C31392E1643C8B98F584E8454116954E16FCA6534AD2EFC2193E11C8DEF9F3EFC9B578CA11DE4723C76182E2CBA44CED26608D4B8B42E361C417E305F34CF757F44C3D59F415236D0521E5EC72C3599AAB91CD515F19A90326FDD3C8F2825B9C5E6A7653A0F81B0DD60623EC96D0E70A6FEC1B5B717EB9CBD2F40C2BBAAED1432ECB9CDFBF00BF9B0D4BD78D7B87D3F67E63812E6A6E81EFC6DC5F1E7F7A9E081A6B5FB13316E6B6ED551CD98774A5E894E49DBD53DA6A29F4DA6AE76163C638AFD7D1654E05338FF201476273D32EB3B3E5681BCC0D58770AAE98990B9E1FF122F08F2380460C67FBEEF66BB91A81F669A484CDE3B29027DF0A1E92360CD231130A29BAE7CE3CFFEA9B8EA03F06313D95EB2A30149791B4F800E8F3855FB9E78ADBE657A70CB89D37D1FD78242B770E27EA10E9786E9D1610CED6B44842A57B8E53F3FD424E14F60BF3DF0B155297CDEE0F01FCAAD38CC599F5CE4881554E8DEA634E1AB403D6CC81B77019CD535E41C54621986DBE5D39B34CEFA23B2113A34A1D6B775A839916F07E3B1BE22B47D63592F18BC3780E01EDE5316013FBD6BB86B7CB720731C697434E07219415E273A788FBBF6455256735B319D0A095FD904F539D77D9C4A40FA1121595E6A899E4366A420A58FDAF7918934FE13043AA6F3B37FD044B213AF808ADF2C430DD5484DD65B5607F6C8613EEEBBD17A63C65456388A9CADD5E971591A19234B133CB32789A2F266257CA737802D09561A8C379009CB6B9720198D2AE5EA803B6333A39B483414D64A4E9862138FFA03C7717AC38DB58269B42FC29527AB6CB1D088F9820CF4763BB9E7E17C6DB5BD1C49434E95B47CE79AC82828AD33DE153267DE57397108E3C111B5CC3B7E35E920DA0BA0693354DEAF6E7CBC8CA6724B072C9CC855DD48D6F459D92204BD871E33C56542F156140E555FAF1788DAF0603ED010601CDDBCB54C5706896917954A6E11CB361BBC44B27FBA1432390D6ACDBA35C33374B53C49562C54877968BC7CDDAC3C9C45881707BB8C11EF3BCFBC285EEAD9DB923DAB5F34806666204F004621477CFD388C2F18729118508E6D86C915C8AE31243B6E4BE35EA3B2A8D20D583F9CA1D115F4BD947BCE98D16039435679373943A30FC015BF970163691652096540694010DD860C8C48A2ACD2DCF9243BEF05685318D413197893780121EBB6353D39EF9F07501A98C5A9AAD89BF76D00FE0F670715DA42DA11E130C725A6C066AB7266F5CCFCDD67AA395EE93049418A254F81CBA5571701E3F4237761E536B3D7095DF341CA8858CE830E6A0566117CDB8DB3BECCCF9C7DCD798544AF136D763E78E62304DBBF9D19F8092F3979B06429FB9F2E248A06F8C929418AB0C68632E8F464FFAC6E8B1CA6E6A695A3430CBB721447D3F57DB20EC211BF9A4E5CB59F9E0BE544A98990368AFFF639B5D3AD8A6F8FBEAD4EE6557F9DB9CDE870726E5C3B4AFBFF5BC3A19EE9D4A1F35D9AF7AFB797212E8F651716B5C325404C943C47B0504F9EE0CAF1AFF0700F4D24164A064A0146A64E25F74897538388DE831343EE10FFBCDF7A75C82B4DC96167326FCF0AE0BDCA56A612EE351354D9B1D9896FF539BC7123ABBF338D0D659DA82384DE1A25A6375DCE1FD3E9947D7AB62831B7C3CFF9C32AF12F99501B7BA4A5B289A791EAB19CEDD1CDBC5D20235784E2613B16E6C0482DE13A18EFA9F89C34724BE435E8391115C66772AB11D73B45D300892B15140D5C206DD37BCF068B4D506BB8015E76BE416D7721B22E235F5FA24746F1A02B302B3931841E53CB71164B81876D588A617E3F72DBF50D47339F897A65532A620AC4280438E714924AF3EEA0EE87D407E69D41658AF998C13E141040C3EF9ED95674B6FB52FC11B4664FED6E9F8F9EBDFA3F1C7E9495004AA6917C2D914585B23EED8471C07ADD0B3F2373891E20C443C51B3774A6C40E71BA4A24D3C3D415F63ECE5B3C33056D5997B764CE5A1564B2AE315D95DB6B8E14B2FEDDD212B7BB0A50F4C03FC98A2943123A1FDAFF1BCEAAE1908EB152C78E7F28EF600BB684CC366A19FB8D73EA0FA0D8F8CDC709656D2F82C75B31AF60DA953B37AF0E2A2CE3703C042716EC69C4A6BAF84010E689C3A0989C8200D387751F2F80E8A4C26522B5097BF493C3E2DD5C044C70C76F5C54E4BC2483D161DA2C85A14DBFACA2787A0E9D38F1167077ED6C499E4ED731D587B9AE435FBF93B55E1A4710180C2CFE4AB324324CC9DD74C8762CB78B93385997469FE6D89004F67479541C5EAAF77D7A49150A83265A58CC0E4E32FB5C7A822497E176BA8C5A8E823E3BD8A5BEE48026A9DA43B1B04F3D82023601DBFA4C9383C9066477E0D7622E316A43985D15027809789AC4F9E0503FE326C4FE50BD2256E42861262FF47525EC4119918B05477CC8DE97F3F3066478975CD88DFB3F65B01C77ACABDCD2170FC0778C4D5AC9662F5E054B3424F48514E11560F567A699C89FE5566549198FC2B9E42EC8EA2251239A67F920AE7AC403B446D44B46E14A45024AEF93CD0C2CE1993FB293A192E07C7E2B5A532367AD08314FAAA35C6631C9B87FC25F5FCC2434381183E7831A2F65203D34BDCAC5466C310D0656BE5DEA3E8D9E224E8D432A1ED2021F1E02EB35BE4D5E8BA60508E44F1F57D590CE965FA93FD90C0D52835F1BFAEF4C619A493EAD610542D4D4D3C7D7EF87E505C321F2188409B15DAC3A84AB0B69B51F3F3AADB889157315EA43D5085B33A3C97EA62A3BAFD819A5F573BCEAF4BA6774B7477C379EFD595CDB011032AD5CDC3333443AE2FCAF2AD0CDF00C5F8AD65F9AF28D33B2A970024C9337A8BBC040FEE6230F389B78B0FA1ECDDF20239C300F02047307F51E2D20013491BF9F20BA5842AC763E964837963DF665D62D1844F515A61973BE856AE23EB37848593C8EF0DD065B1D7828C0E92640F4B3A8BA4F3C4855E2BF957CCE87A2F2CE19D215481BB4BAD295F078D0F492F70EA5ED523709406BDF8C369E73DEB351F36C0C23BFD787B8DB85B9EAB634224282B13FC616EA70D442CFF611E4325DAAA763F9BABD22593DA87B9D88E0D48DC3C6E9B10922A9C9390407941F8AE1EA74B2526C1EF6BAC274CBD54A65D56C9B25E6CDC3D69088FF8CAA8FD8443A4F9EF5CA3D084779F8D1611A820907968C66C1243D80501FC817532778AE95968C585F782211DB61FD9D2F6C0F7B365F2B778BD21333BD1815DD47DF8FF337F26EE0D46AD8D38DB60EEC9612E9B9FDF2A2EA719DE4753FD15C4C5A764DC45D441A1F3D05423D98D821E665341322E55E0461A2AF247FD1FDADD42ACA75D84327D875492124494F8C3D8D7527132526EA7E1E0A457CABE20A0B8CF6B2DD955DF71C8475D590989AECBBEED778FA5CAD6BA89D4BAF1239CD319811E8EA4EB798DE00D45EA3B4DFA4F8FE51820EB93071530BC1AC0D8DDFF147D93BA0202BBE23BA547D866044D8D6CC21E32EB93BC031403EA020CFBBACE43B82F97A68ADAB068509CB0ED52F0BDCE92022B33C2C811CA698E8716E050BB3F3B6DC16E2DDEDBF591FD34E15E073E0BCCEA2B01DAC781E5C5CC95D5C29DFC344F18F6C201C62C6B30F74A04BD81504C43DEEA78B8EA7E7CB2EAF1556D70ABF5E6F71BBDA1475E520D34F4F5FF71F46E9DAF734D3D9534876E850492B75C82755B3507E7ECE293314847B83ADD4D7FD7A53744E3BA52EE09028A2846E425C206CD2DC8FF7199F304D2ADE10A9E38E7BDB045DF7E72D36689EF4FB10039025417F9C4CF31546BC7D37D00064C12703FF1FC0F1C825E9F57F2C204A1E8A60BD0E8FEABB95070EDD5ED38A95725C965507FDAB9AD8123F25F1E825201DF7563DF7C7844DB45564F293356B283D60EC0A512CF47A9C8270F597DC0236C3B00FF9E7FA2195D0133DA9042D3090893021B9F60838CA1CB8BD57181B5DD7043ABD261B3EEA7DEA4BAB7809932176265BF9473ADCA9E0393602AC0CF20E09A980DBDBA1AA71BBBC9934CD6070AFE2B5F5A8433C0BD01E3ECA560DA61E0918A2C783AA5D7EE7F12CE4142E38A4B56D3BCAFACAF020CB43DC30C105F2B3631C118E88F7D234501F95B3707D2330B523FC8028F907435403C8634C1DF0F869F4EC1935F83657A9DCC59924259BCE33F2CCA336A71C840A4875A98CE9637C26DC761ADEC217C50FAA4194F4ECDAFEC23E3BA89C2FAA552256E33CBF34328EEAFB4D6F6A61EC80D7ECA8229298DF83FA826E85CB68C9F3FD8F6942836B2634E50470D2D3FD1EEC0DF0209DE929DECF79F9776D7F847BCED1D2BEC329CA38148B176243345756494288B1AE4A1A4E67450DC925DE6DC8F4F083D3007884617D3A61581F83A962E2D2FC2DD86D231C9E50FFF8E9D0071771F3F5AEA2D185448B500C084B49509AD7DE7779A1C7325CBD1AED9A135D34CF20CA8B4B94BAB782162A970C9743BFEDE5714591F80533ECB63E731CF1DF22012DABB0986C8F0F124776061EECE02E6E3FDD496CB757EAB674C6DB57579948D27EE2C2699C72339055A28F94ED6D6898D79D586962E8811A9B183E60BB6FEFCD6A551D878533BFC403A2F6E0C334ABDF8AB9D10A94083BE8D658644588E1EA42BAFDA45F2B47030444C6513E8D3863BF6839BE5FDC91FE5EBD210974404E6478BF7B1232B5436C605216E272CFB335E37504D112E71A4B690070A1B7E244A118519EBA9F4610F612C65C8D254FF311E2DAACCF5D8489F87C599FF79454BB335BD590B93D20B03781334C1C561015BB5A2A1809CAF7315E5A1CB920066138F0E3D1F9A721A7D003E0598D0FDB53FE0B4C720DA4260598650AA60D10700E4207269F745B63B706B06A18D86BE75B041B9CE17AA532BD102B57E15CD7379311B9E5BB8610785C5A8BBCEA77D9EAD3073DF657BE5CA732C3C174FAB4C031C7DA7F9DA9293AF5C91C99E688FE324B13C3C7FA9E9288CD9A7F30776DE8888051B63135C370044ACB484E7C56EA8AD298D4E846CEFCD4CD762B175E747B6F5375241CB75A1842338BFC77D2464B2313A78C9D2BF8E9D1673043620C4EB2B90D1E33D2436F272AD3927E55B80D14A10C91DDC036DC10E8AD5940A25C7CD796A73B4884F0B1CACB2EAC4636C9016F8657AD4BB8AD0AE4CD892B8560CE2149AE317C21B99BCF4CF1F4C8DE049B8DD6FB60D85EB14665BE5772924F9390EF98C511E8480D352B9E10A380E4E591A881EC6C874A9598BA56C6C396E1CA84F324C0D3E29F4142283433F0FBB89ABD752CBE1032DDA72F21596F6EED10A22FB4B78B6617DE5A4599BDEDE2C624B2230BD16627956FBC554971C2434020CBBD7AB913876189540ABFCB114A85E332DA21F6394B43D305F03CDBB46662078A230FE63080B9DC0FFA9A8430A25920514869B13D2C7E7DA6B3CFD9495B7464077C4BD37CA5D241EE7360286D6E1825F1CC6772B7D10A26E5629F7D0A8386C067C5DB1E2F7459B55EFC323A7437A189BEFA1773E2C8B52E4B52ADF4F504718271D3030DAD53AD90AB5705D575BDD4901A993FC6F06B2E2E0B56C65A5DAFBEBBA2AABC2E0CAEAEFF4258145FF17D641A567057D3A8FAAF6E5DA318E8A2DFBB7131E4F8EDC0D7321C3297055F5C74D5E5E6272EC34AF484CEC2D8130E5F3E601815A8A8AB8A1BCC54DB7D7431C256585286E9EEB0A18F8B7F56789BD9731B716FEE8A68121D77E997DD6029B60A88EB66CEEAB6AECFA0BCD04CDC713B22A89D9A865A222835B76BF8072C326E86B8434B2272F0DE01E110777AC580C4C4E0F2956C7493AF971FB0659F1248C9488C75D837E03DE7FDBE5A943F281DB0F25710147982AB944FCD5F5A65C7A0EAE3A95AFC0F62E5829DA8951ED6C9924467C600A589111A3CED5CC80B7FDA408BCBD8621A925F574EB06C2D2B44DBF1154EDA72122AC32A10854979692EA36DC1DE9A3A4BA2EBFB8B670C796C25F79107789D94DCA4A978F520A1C8A5563F8834F9C6B98F267D513ADA03858AE30484F9E4D8A5738A8DF8FF61B4C8584A9940CE498C22C0BAAA5C011524A53F970A981691299230D7064031BE9CC06A3D1F1A6EBBA4077E384403828B0DFB6798AB54F399E9C5B4CC25D688C358F8B030C855FAA1EB1531876A047C3F99380AC4C3648B46E8AD73066C783E34626F166D7877117E7BB0605A225284D21576BDE619B6EA5E1C677FDC1B0D6C3285FE359A966ABBF0AEAE69A782B475C94A78A85F80C805869FF204596B6A46D3B80E8AB984874A1B9828254258C0EF62C20A6AECE1848D914CDD76706A215C1809E11AA388EB0491F0E8D76EEF19056454C52D36858B9161435E742A3DFC7E84F06A40D35C856183CB217B6C63D9EE0A0ED9E9E1BAB52AE58583BD35C1F14038246C15C81DA2E9D40035445923E87CF33FBFC600CA20964F23D6764337A0546A2E6CC94E050CE8E7BF1980DF15170F6CA2AECC89555F6CB7C73B59CB0676F484E73A1CF692322CE792D1C9FD94F7E6CD2ED7941BEFDB112154583ED89787A9985EF12858CF665526BCCF2B8C4B4A2D0B9EEB54A86F5636B225D17D1887EF0ED96CCEF019D94F0AF39B5EFF8C01CC67A5EF8084E3FBB5F449236228249B6D02A529EEA373B07FE957956AD0244F30A5AAE7F5FFF250B37B1EE4A9D266EA25F58A24BC97E2C64EBEEC15F1B8A007A6137F7B6AB393D74A9FF04E83FD55C3B50107DC5845D25F73C7C009431770ABE8B919C5C04CFE18E21572C28E90D5B62AF0AFEAA6511A26D24489695E545E8CBE621C4E58ABAC8D23527EADF158FD56172C124C18A7B5126631DD58A6659260B9359FCE4D53ED85AAA3D6C58BB63CA946332B0C20E92139219B0E14F19EC1320B4635A88F97C3B0C176FB31A12B4010E1CAFAA15E433B629DD8FA4066D4263AC9995B28020C88712C7494B0451A68192D60FC192A50491D6B0DE9E7CB1E94E84CF6568846C927B17895C49E3F000883ED99C719ABA5011391080D4B3E0A87E9CF003D8DC8E825CBDD5C30D46E60D9241EC211BBCA56AFF19C58C2A19120DE7F8B98D2FAF787D6B9FD1C9D973F29970511EFCF2F373777DA383FE67CBC17D95408DFDC5D99E94A88A88C1618A3B951316175111346BB91528A99C43C2439D971C7B3115DA84D2B63C1D4C31355677DE1211D1DDB3F2D1CEC4C9F6E4D667AF613435E1F5B1DC0F907B67BAE2DD49775A6C97D77A1FE76E26A6AF5A7434639BC1B64F535B6B18F68CDEB3B0AE9D1299D70E3915DDE2B7387EB14B0EAFBC5854AC40D83E75005A2398D8574CED7BAFDC47A5947D73FB50F5B7123D221CE24525294DECD01586E2B5DF65293FBF3EE39C4B3E1780621E7957B5E1D96D604745D79DF225E720B010FE2161BB2661E3247E7F416F665E9E11E94D574A8E82D8D6C8F9F8A2659B0F2F570C5FCC694C91EA1BAA8117FB2F3616F3A85D133ABE3ED98BA16223F70DB032AB07167D92B458E069F47E58E13FDAF54C6AE3775AAAD6C9E616B9A225CD35D550BDF631B79B79CDA0174CF2A8655860848D0203D717150AD4ED8E8A3D806852C4B7ED0669B88E2F48A342EAEB819B28391C6FE66EC370584568AC6F67D7098ED167A1251D85F5557EF4EC4E6217C3F615D26A03564004D7FA3D6C6159665C011FBC5014C89A7A2C2CA3E89F1C03314B5AE7E5957AAFF472A1D51B5B70BACFF33F055F44483D610147AE11E5D31207A97617B850143941A9D47DC91C1A68F63957B09374D1D0BED17220E4B70EA1800E84CF9858FFBB023779359D85040654306E3A0A881B6E85F6B0A2EB9E729F26A50391C1467EF8B071DCC49D65831DFEA7BCCBC46A8E497C4825ABB61BD2C2F4CEE92C299724B723541F0C94F0252F244ED9C0497887816523C664ABAF881C599103A0719996E866A3ABA81D7D8AFFE0450099ABBC8FBAAC06D826F6F6984D0C7693D3BC9620B04BFC738958D9EABB17E3A796FC901A25AAE850F3CED6131F22E2231E52A7E39752DDDA82C0188807387EB67AEE225C23B7C71925D94507A6570F59313623AD33C323EA5B88C2B7588E2078006412157B24D60AFDC1E085A2A4B379F42BB6B9094ECB04261D580CF600DF39F1D1862E774F443F9C6505F0B38B2D739C01080608C151EBB11FF6901051E6F38302BC7F615B7A2F256F574EE5F9C7E2A5D02CBA31AEA918069991E68CB9D884B949CC2C40176B1DBA4492F7FFA2F790406BCF28D6901143DC1FFD578AF27BF62E9F2F81E52BBC3D9005E8E520352D1E9966C2CA956680A21AC7B21420864F37F229A935A280A6C3A6AA699C395423251E918C85A1A1ED466A779E0D9197D466DAD34D00F694A6C1D323A6F356024F609058D8759B733099E0552DB6A5AD20CECCA611B5BAFFBA9BC972E31AAF30251E87B252BD02637603D82004804E28F3AF0B269310F484EA3E0874C37EE0065031DB88CE965A642FF8151DC28FE2F7A247D370263E270C502742C868CD430F8D919674C64C8BF8B6EF6BD8E672A0E083C53B1DCCD1CBA2E57ABD46BEC866DB7C37356FC995FF98D54EC44BFF57E7475F57C2D18225ECDF68C48B6200D9A6D71EEA85A5B3744F641995587EC4D12AAC632C1B335F917658357AA207D540DE0D88E070FD4F10D6044BD3A5CF7272FC9D3170C4660594636E00872103720029A739C71A2FB683DCEBB9220EB6050A66487FB413C7018A296812BB2927793E4F2525A5F0AA2D4A84B7EE09580F1376A8B2E3CA75424758991646A41461DC9084DE21E8B00F221A3C6D98EE211FC8D533A0B17B7CA2C0C606F0DD0A0EAAE887F497E4F3D2B1893C26DD09B3B21E7923A32E35A102CEF9DE6BDCC2C22F7E13254B3AF684BB42A7655826DEAF8CF2096707B424A1EEEC27C80E1DD50AD31679841B439BD4EA889311BC7250B0AE77DB0FE6EA85316D15FD6886A9C19BAD2095ECFFE600A745897B8B1FC81A5D83FCC528FCF14D5312AE2A7464572DB36363E9782043900BD63BBADA02189BEA3487C18AE7F753B54728797BDB19E1EB44142B754C9FCC58A5E49AD0015E945B580FE8EDB0CCC2649463837A1EB24E4E9CEAB83CC5084DB64E0BA4B4846C2B6A4D97F66CBE225E5431C0130833857F3B8C77686DB4A9FAEADB5284A030E5AF85B83FF2F55F666AF7A79A4584D51DB330B9452C1B6CD18ECE45C93CB2109BD91C90314907B31CCC17FE74A2E7572D4634D33913D5D3E2E0E4BE6CA53AC6A1584BFBF6690CE7CFFBF5B14BA08D8551E2EB6512DB609B84BE0AE5DAE30701523766CB60AFEDBFC80B6B076C41B715EE2ED4950D821AC1021A0D2594DBE96AB78EF898EF1E58EE70F67D39E5BE5FD8B8A1EF182268812A213CC3281BDB25659BE52564DEFF39CD0E7B8D51EAD4472AD0DDA4B21BCCB7B3C73D1EDA5D4288A616C9D5225AA305AA7AF25194A465223A79E11B4CF9C01416B1D7614D521D08760468FBCED59EA6D89D442B5097489C38211AB7D22E0EABCD96C8686C86CFB64CD6CD3F1DE9312BACA2626A7D293F5BC953521D83DBD0DA51258E45CF87F6C5E80918BAAB68EC2283291031920DED0F16E1AFA4BF1BD80B34CA35EE765A9257C216FC787895765887D5AE8A4751BFF6F496AA6AB75FFC5C9C8359B918D3CB7309555A60FAF4DB47E141D0ACE7164654A299672E857B0AF0ECB7D8EF4359AB1AC3A5CABB17F17DCD822025FC843752D43995874C35D1852070AB546B7C5F332C2E40119F8090142886BCB788E1CBB1705F0BE9A221E585FB9D339C66438FDE78263AE33AD52F09F2E6B8F537B8624428185470162E7215B4A9C2A9CC79B5029AAF966EB45E555BDC95308674D6C8C25C8763BB78F33BA7845A0DB35E4533E2164F1085F350B94565C65B6FD9521918CAD2918326514DB1DAE5DDCB820AF3C6F6E1CC23330C59EBFF8EB147BE14279E9E71D376FD96C202B565F803D9820F3DBE4DA3FF538992FC2062AE9ADB0F152EC71319CE2D7305DCDE1A813786DAD5CA1757D84940FE867BD0C7C52665CAF7714B456046547A712EDDD5906BD4B1A3D8AB3109A8C8463849CEB3314463A2EA6340F90F5B53F681BEBCFBD321052CBD523AE2025F6E2AF8EEA65F0AEA478023A86CC9875FC35A0C55077E3C909D9724B118725E9EB5FAB9ED8F0B8308D06BE3C708E337D446141F67BBF3DA10B8F298D6F1F1FDE44B8FBBE5ACBC2AF89AA65D520A935A319E5FD21B6934252C5F6EBCE0DA323F5D18FB98CEAF4F98C8432B9196D59E9C27E1B360095794CE0A92511CE8D5C62332351A3070F748B85814761F97245EF78540C2983ACB74E8DCF9460A3DCDBE96FB521924ED237847A78CBE8897EAB4CB819B6CEC819C9D894D3147C271FBA9A68DE0C96920FBCDC21553B5D3271F2966641080B895F1B81820A7B6850463C5D8A6FB6ED80741EEAA7B7FF9770B7571F2DAE086BB8FB7729636942D335F51292DD4DEDC0181D3AB1310C4E979789622E2AB7BD19DD12639DD70FC75045642245E0642B79F498BC70B6E1485802D885D7FFAFEA339623C02CD7CBEF01E9437ECEF0E9E0CBE3D01619A6F23F1E0E9C541CA335D95F78E8B2BF1540330ADFCEEBF2C9732A5A219F24CBA55AD002D7ED2E3B234CF06F6EEEA0712DD22664BA9ABDD08361020166301985F9DE083AF4B1F2794B691D2FCACBDEE0D61F214301E7666A365802AF08858D2B5E67924BD4F21DEC0287CFD5D530CBE4C7E7B9699721331536DBD13DC58B17AFD94C285610C9AB42FD7FE4DC7083ED4D13CCFEB3C14CC6D763A7B5BFD70668A06E6E9A36529867FA89BF152E65E9A8280A9A3B6AEDD91F214EE4A77F5885CF7911CA3F65CF3AB251DA3B487CC3401194BBA7336587BCB11F58A372246E501E23B4F0C9A4CF87CB5D38880C63844AE84AEFE28B90AF6B5908B3C291FCA44B91ED87E352E5ED0DBBEF61D736A796956889907205B6B3A08A8F6105BFE44256A82F6216D322EEF0673F8D9436211D470CCAA10FCEA3096B28A65F24927F0013061C8C48D912780C2A8995B85B0890B0ACED6BF1C7A20D2DBB3E60313EDCCF5451D8797689D360A5E6CA2D9035CE37B94B080E31F3D4E6004D86EB09A5E2BC0F9B4C5970CD5CFD0106271501857B6F2D361E0B4F61A6803FDEA56E69330FC4F70810951DE80CF382C9185943BB71143E610C7FDB0DA6F1E1A9C84698A45E54BD64666A8E8878BE0854DF24BA9DD7A195D00F2B65EDA6E34E63F909023E4BC72E5865435E51850FE9388C775246A0E0E7BFE3F95AB59528FA0EC3C2E71D0F94701E46C9A0046F64305C67182705EEF3E6A75A31D70039946564FFFF7FF9BB1F5D6751D7F29D045D0BC1DF10F499B08E170F322059F3E54F713D19C45FFD902E8A0B1EFCF787CE168F00B7DEE52B6AD516E676961A2E8ECE1C0ECFC958C0FFFDB8BBF2CB6C93EA526F0A556BF427D59DD10AC633E56734A1079E01EC41327AEF61A5C0082080AEAD43C2AC8B7CD6C7B1338E52B33D0FD87619A9A9BF78F3268A3AA766B776515A345FD14757BEBA8E74A3A6DBD235937C986625F36827B671133A5330573DC6D69940B2027D5022F0BC8D65D82382CEFDBAF5DA25E125CECE481A5DE37ECF067463FE30249EADD5F44ECC2A08745ED85F612AAB3E2AEAC8CEBB96667A6ACEFFA2469BDB7AEC9E11A8A0315F2A49D4D30894C00C68E7ABC349CF1EB47C28B71D027C611B98E44A8E45DA1C80A8764275F7F9BCB3E44614B0283E56BD2540794D1596C2C2AE48A4734AB3A8DFD6A454E9E28DB2F3BCBFE9A29E5CB29D95FF49C3FBD0CA9877EE0A9074AB35AD1F2C888AD8C8292896D3DF35F73B87DA3259AA2181C82F42A09B77C1015D58A80AEBC7786980BD2DC22892B0D2600E383B58E55928389A67C163EEFF91D443B2F02F28F214B10CD7F6149E77A33B0B6F7208A585E91E1AD775360596E7A2FCFD7B32B64354E75A69EF679B74462779589603119A625B02AE231C9C99E56B8976C91404A1BC313A9EA76D95A4689A69E3C0146D4DF81C404807AF6CDABD7DC7A23B26F9EAA52D74256BD290FF3DC5411F7D5705C3A70C199D0F95FB66016C5AD1324A7FF8636BF45EE5CB35D54D4C8F8E70C305CAC1A53F0C3B3E8FA0A1279F77363376F9E8C72D61C76A8B8C5127F48C2F1916590CE1F74EBDD6CB2BDE91D6768B26B1DB39F00C275CF8DE56504EF5BB471273BBC90B0974DAC2B5CB05E8A3B2E05D27271C9118D9C747FA724AFFADFA20102B92C5D8D6B9972DC7E53B18BEC089632CC40F32E4FDCC20049A7469F7D1697EBD7DE16C3862409A0E9AEC3B5D74B308B490531C7D9DEDED661FE1CF59062F4095C406F2DC1AB26D8E743A8C96B1B156A8AB996DC151829909A8D1F720F4A0D2AF89CC2B4B30954760D654592EFE9E7B2C2AB7AAFA9F60F495D48974BCDF7E6E6875B4FA7FE9EAB6104A6FEFD0AF6BC39E939737557E96DF626D5FC155288172F54A00114271FEBDBE5F303C3BEDEB2DD382CB169315FAC1126541E0DA83D97DF11912D03D0209AD83F2607856B3A7F2726AC38072F7F8B32608A84055545C2E6062FFDD729179C4F2EBCC76986709C5986EFFB0CD05C9988B4A43CE33D6F8072C85413A670FE134A6D733BB20FA470723530A198C57D5E2F89B91F9A3734CB044154539FEB279F171A15235D91B320F68E76C760C4E08A636DBFE7267F6EDD3D5C58E77FB84048294CBB80EFB34A1644AC4A308CE163DA0295656A4F61BAEC2FC34C3A3F6927BD64297FB33CBF16C887A754CDA427DF7F7F7700C7C0A9A8805E95DC5C82750376F4B4C63CE5F251DC6B51DD19C9732CC1FF31DBEB4F9C06DC943FB83DE958048AE91857F35C7EFF1FB55F842331A52BBF0A7BCFA9142FABC91E936D7BABB07A47EA6F58B45503AB63E0646F3CF33D246FC2D4D512A479EA09148660937635E00E8BD8B5C0CC0FA265294E3A94702FAD7532E1D1F018CD888E40F9F45C64D0AF734246BB4EB811B54F875017C82DF068C72ED1874BA8BCDEF0C296409DE49C7C3BCF27050FF7A9E9A45264A10BABD8ED820CBFE010095A340F947C91CAD5336AAD59FE0B91030544389E9373FC6528A45E4D4F812DE2E34C23D25699D3291E2A61E966BDB07F07DFC6488B9412B8D7A88D6005E0B466B56629631F747054CB681BDC5D3E51BFD9600362EC528DAEB8F9A90854A848ED2962706A88BC1739C4419A90656B49BAEC4E2CAED84ECB955F41F5E45B8C18A9323750BB617823D8B20CB93EABEAEB836AE17B99DFA3CB1F4A666966ED507B150762F077872FAAC40EB706D5651BAEDC367F09ABFFEA778BA89F4BF99561AFFDF61E951C74AD1F49DB2F7118115425A43DA2BD3080631BECAAC702EE3C69CFB582C3FA8C953419567F3A79AE21F3F65E2C30612AC6801FE3DC08F305E15501AFC7A02567DE83A5248565B92E6E2B2320C82DA5305951457B56980B3E3EE4B49EE2AB5634CA40CE05A8795C7EB61C4D1AB21F50B492B7974175EA6178840BFC2D12C231922AB04D139AA5EE73ABF998B7D63D1C62829891D2741C4D1499CCF15D39F0C0704AD58B8F2B2849DD9EA661530E29A4450239460F9A09FC1A934174E5FDD4B2F14344F2C22134E16E47BF574E6ECD7469078E9B1D117A90422E962BF01871245015D3647BB0CAE2E2466D2827FE7AA6BFA9A4F23E0E784D626A514750BBF8EC7ED765E33DB81CE42AAA1E7CCE34401CE336CB94BC6728BF223E79CB154EF6565C14E9D748ADFF5DC3789CB37D808DB69E388F81FFBB54FEA44C84C40FAA70DFD83783949FFD5318D89029B400ED2E33297CC7AC28EE125092E94F6F87DFF16096BF7E0A48E02C003CBDEA3EDA022FBEC6BDF63AF766EA6EE3E500F4DEEAE002878F87DD653EFF19B0737627935EE73F74F079B481DFA23970E0B03F4BCF25A99EE5DDEE116F7146CF8CEE658FDAB119A47819E15FB8DDD806EFAC2450C72FAFA9D300BB3C38DEB05D74CF7BF7B685A008E725F0069006DBF1989C316BD704F8502DA3CA602276A90524D1B566B5305F7ED73DE7207B25696778AEA6B4B071C13A23F0DD207FDA3467157A80285AE6AB42AD6D9B74FE2E360162C942C46B259A1966093A207BA590565EFF149B8ECAE8A8CAA760024F0A52048E90A2F91CAA7492F9EB9D6B0765DC738A19CE4D454E785FEC8B8D0464F29C06D93892703E042617BABB636E24DA689AB1D0FD8C5DE8293D03BCDBE51A57706B3F0D67BFD3FE27E1ED8A82C26719E1828040D8D4834E307FD08E9C0C4CE7F2EDF0A9449133F1BCB2F6771E68597502540B644321A21ECFB98E9D5D5B963D0557C664A994054671788119BF2F28DFFDE99B59A027C66CEB989B84B4E220B3D0129ACF57101FF14160130A21795C73AACAF198C71C0353D1210F5A67A2F946461B6B300718095E5C9090B88B1898A61082DAABD2272C55619C415B8A0C7EAFA5D5F8BBD21611D7F5164ED95B2B6BBEE2A49F29EAA2CA3DA7C1E05E2346CA1DBBAC04B0165C2460EB745AC8F12A07A4007BD3709E0054D2083006D5EE208D81E48DABE5B987C704C0B7144F3F96F65CDBD0D2F82FEAED4845595696BAC5EA741C58D1A3398430E34C81C0250A19FAD2FA34A7B61038862753505B11B38D2D4FF31D321F7CF16965EA576F1985E66E88B28D931AF159F1BFF8A5BC7E40CA064F993E86A80B3E02FADD496C4B77416FFD4277059EBC33F72B44A2F73A9051B19A3D4B585CCB170D9DDC8BBDC340E1973570E3AEFE4694C3AE014A2FEA1B67B7E388308A842050DB47543975C25C1FDADD9BDAC77351818EAD1E92E4DF96102599CC6DB38BB7A832AE6940BA48DD008EB714E6E7C01125928ABA55264311B69A8538D2227ED605C9BDAE24E3AE993F2599E80D33BD66A86B06487DA5A1FE18A930F5D2CD292B93E0A4B34981DBD89249522205E07699AB88EFAE8E38BB9D6FCD96BC28FCFEEE872B0535851C4BB8EA6911C124493E213C093F990C839166FBFB87847639E6119C92218614BFA10C57670FF4DCE56A677C9751C0F05B6F43FB0B3E58EC97E80111C18F047B438774FDED7AC1394B3F9399C00A9D404DB7FDFD28BE9EFC12FBA205CFC7725CAACF2A30A2328BAF9649B97C11C86753F389F8D568783B95E38C8A7C6BE1E55EE552E0C1F746D8872C031586910089B194A5C6A95C03D9D0C8AFECD599DBF32B64526A41219BF5C25542EC4B887408BB4E30A1945373504CCCC8240250E42269EAED3F248D85B4F9197ED9F78190CFBADD100EE229422D355FC51FAD70A822A8529E15F151E3BC1C7F7C5942301168F7770A79C78E31F34C37AAB57710D2AE572EFC56FCAAE88D41F73D188327BB98F28D51383196951F89E0B4F35D23A6DE7D0071B41E26FF03B7627E05A805D51F448166CFD28A8DCD706182B65A236A7B7B3492848ED24B8EDD2F1D583413AB6EEACD233CE56501943393455EEDBCEE8F9B49CD85DBE3B4B65119C995739711F2139011BD93DE301C88628B9AFC632B4CB4F6963CF1BA17A015CB80CC110CA02E54B117C69901C34DED2C7D308B51F4EEA97AD45A224431D08E3C4DCE61F55CFE7955EB39E6918904E5C3CDEF57F633BF8966BBF56FD167D299BC8F30FE3011103194477CCC8DF9D3D792EA625F472E21E97EF6B8DA8BC73F04A36E548FB25B9AEE2EC60C87BDA8A552A793D92D69270C1B12874D17A5C2DFFAC58D76323F6ACBB8C2C33618E8EAE5347D473FE580515157F3001DC6F6083D1A353052FF6D92096E0E3609C6066B0719363AB7FABACD8F50E22460019BCEA48852E3A39C63A5892E559FBFEC7BAFE6E0DA68EC5969110E1CAFC4201149F3DBADDBA316A807EA0F8693DE796804E8774B79FEB76DE5B82F8201F2DB3F5731F69133ABCBDCB90F1DF360EF20D947BE1B0306622E35F2F635446531D879A2B7614C8C26279036870A669EE6C2A5EF40572066FBCE07FE628F926186E7ADCC052429CFABEC5F9707B7D415D63A189CF875BAAA5DB0F4D36574A2A20741FA8B3B0E282ABACC1941D02FBB127AD47BDF26FA3FD4C1C2C6B07DD583FE8E7335D2B136E14BF97AD1FA68950DE3BE0CED1ECAF360BFA9A23B6EA999FBA3E8E7DE41F5CF88C0655BFC2EA4FA7D2A2B6A512C9D322DD5099CC962447612D3F56D85A644ADA8421D814B3367BD0FAF1C027DF2C70D6D46DC3633B6BAFB2B5265FA15C8E0A1140C0A197AE340C519E9B724671E5E58B88A49E9B9A3F504F084CD9A3D5A87F4019D6540E0B2B72BE8068DAC0A7F61BF560446B878D03F31E7115330687C12A6DFAD3A4440EBC7CAAFE0CB05AB0C8888AE1A8CC1226DAFF7BD9F80CABC2120C2E41399D5811451065F1A0FCC3A8C90A34BFE6D25F947D1248A11869446B51DA0836E34EEA50863676C61739CEC33FA1400A3F9E3A16C2D05A5EDC49CC2C87134EC859187D31F10F58A00D1A3429CD75C4552A1A401B1B380981AA011FF24DF782D40B0016E2A64D1B9C7E264212D9C6A30C39C4E6804623B6A7A7AC32B7A71B4954B12642D63F4D52BB09812A39DD0D0F7C6AF0CBA291ABEAB3C53A3A66559FBFEC304E564E4741E1D4AAB76EBB407D2CE11F113903311C400CB1D311F91669639B9E4D7EC8A2FFC67440C88139862CE004519505347F4C147BFFAC13C7EA7BA3C21C5B6421FD04486D4300E39375C603C01014616352A44D0CD79B1C688578A75859D1D73F91D0637C1A5BC40B5ED8ABC6DB3CD7CCAC60B7BB39AB1F69FEB23DABF81B793583033A0C1C578C4AF1A4DD6CC09C5A4596814CF0EB73BAE076BD09137657FF9CC2DBE989C83BB3B7EE698DBB50BF109F8BC45A00B281203388DECE5D747D3E55327EA0B8A5054E9B7AD9B8A00C80AD61BC3C8B73135FD6D228219BFDBCCC72449AB126C2ADE5D007B127E78E100DCF550A6C5AABAF2DFCDBA1E618685FED54DA51DAAF1A0773D7D2284B4E6640E921529E16D79360A16CF480E789FF9D75DA5ECC9C264B2EBC7D30ACA4DB8EF44A788AD33613F2480EFDF310E0CF22447FB23A30748F1F72DFB6449B3BA63E9B0F2C3F8A5010598DC7E3A617683F002B7D9D845FEC63A30C9DB638C586B6BC99C9C84D3DC0BDCEDE837EAE92B5A432021429518F27C89001607B66C0B28798AE32E7627233EC438DDA8CAA6904A12B0DF9E0BE2B8D08CC744F384403838255F5D7B3F6C8BEE8AB489F3D3AC955A03405FDA51B6D1EAD4989357B78F6A0E8CA76D4265C8BEBD3A4A0D1213F043729479110E18E64DCFE6220B4BBAFE777B6F9427942C1148097F3DFBA26409CA7211E237C0AB6735E5887DEEADEA293B8621357A347A0E929738E87E0FBC37BF52145418080A38A60077973A99C58D6B0E8D6FDE2CE27746662CE3E4303F801AD9D4B8A1CBE4CEE4C6DC6F25E29B8A7FCBB22074236F946A24F8F79D0319CC6DDD6EA84C3CDB47EBF3634E93945E7B23D5FF397910015A16E92F2DE4303F5C0551EAE764E502AFDDFC3234007D5CB67692BC774DE1627A044C747BD9242B8EA800DAA9FBA7E3D385D0D79A0C4D3AF1F90D0024D7CC1DD9222ACF8293BFEC8FCA60DAD8C96493D7FF4D4A5C869EB49005AB1E5A2EF3B20DED3E6573CC4ECFF7D69A8716366417CCCB8E1937DD824513EADDAA8D5229E7F5D2C0F7979109E659C159EAF7D49D09AAB89C55CE96B3D8B0741DE57B9C6FFABC397084AD83EE699D4579F81681B127AE30E61A494F8E351CC315633AC13132E1277CC37F08C418299C1975DC84A7DB03910EA70B7B66A1EBB842D548503CE6653C61504B6F8CF1684400A50532B63C8F40037F8B9705C2A2BA45E4266682518711B8B22330A12EB4EA898E81D64E16CD232058F266549EE12AAC7D0BE6EF51C85CC4C9453D8B78F0D5F09CECA33208F1D8A7E98CB5922742E467BDAE8EB30E68313C6D352F81FEACD701BB53F4D9CF08DC46FB0553AABCF0336B0BC7E1B1E45EB98A1BD433DDDB96F622F4DF7F6C6F0BEE76510066EE31FCD4AF6BE5DE4706E3B96C71EBC5F3D30AEC8FF44C4C0578CF43E5C0462D5D0A23B6CD4477AA417720461CE8FCC23F4317B9681077D2EEEADDD151D8795C480C3A015FBD4BB4C466699C7B9164545F1A1D79AFB1F3462CB65C028070C7CD417469AAB9BCAE3761BABA89BCE3DF35B92715A5D23D06B0B286BE511555E71BFF86656A5433B0C00A56E0BE5EE4D7458EA03100B62D4A6135B9234DF6F61F53815ECC8F2022BC88403324A64B8BCF711F935A5FABDD170B65C3ADB6B6FB572DAD2A9839396AE6926FD49A6D4BAA4E478916FD358368E2147D9C7CF21394560B6B350EF2546699EE8E684B03F5F89D8D68665C777CF3B9DDF12776E7ABEF0CC2E34E5AC678100580A3AF22E8B89A31E589A66F151F670FB2BFBEA8AFEE2979FD682D5C6EFFD3522A80AC9B38D790638E56E4E329AADC41B1E6C7765DE5D9641D5871C7F602B41400088E1E23F21C519718094E6F173599138C7801F2589D216797B370B3B1FB2C0807C67A2D7F6BAC94803D162AFCA74010F05D843BC7B721DD76629E890ED2D280B20E427A9B383166AB1BDEC748C164C73DD6F42869B4F903D10E9D5AF9D543A37447531E1263A706FFF94B15E5892AC37B0B4B9E4B6FF8EAFE8E1479808B5A7D1435DD3330365CCE90E6C202AC6DBA6D1EB6A402EA28037B2D1EA5711119045B3807C4666B8016A2CCE76A24C439009863D7273DCE0C54DCD2D6E6F933C6CE97B83D8F36DBF8B914B46827A024373E06D8FE93AD4B319A36A459E679AAA1081B53D3BCE22F63C71347436FCE5519AFA78E690B27769CDF589D61C575C4015C03D76A02C12DCBB67033719EC6F7D7369E141E248C9EF8D37C1D35937B1EA140278E9BA0D7F8FA3E71CAF6A8B5BDDF97359386EE348F058DF3F87E8BDA778A491B8756E1B999CEFC3581EA58839DD9296D25ACAF9046994A71C55ABF74061D084C983F4E8DB900500C53CD594EDA0C21F03613FD68EFEB5F89BE42D9B90376A6F9482DF15141C83110CAD01A16B80F70A444A89DF5757DB5F2061DC4874AAB353AC6DF98ED61AD89BBC26D19C3F110C46EEB0CBD8CD9336512322DA6721945D7EA367A949C3C8D9AF147EFA9A35CACAE1AF3BED09100410323F8C04110FFAB2C9551AE6D1827C3FCE4E84370EF09DB323C56555A5C35BEB2CFCBC9B0BC08F70F3FC0A093F3B2721F832A1E43F2EF6CD42665DFE587B8DFCE9D192D14A633E3D64B05A070CE8EEF0D9148B0884E2884B6728D9D077DEC1B0774FD8B6D39500E4D9D2F1713D4D4E6897DD6BB1266D761771FFD42D10D2C4D75854D355C4867130B795A226604032F40889FC80E469101F3D2FE7D5D336860FBE4BDE9684D7D8873C961375C04CC320C94C7829A6C4069B1B9F00D808488C5A6C2997909CF4FB7AB6F0D841DD84A0B829ADA54999B427198569E1154E0DB61816595E21358FF10C3B71D3036F90554FE0B9B9B7F629E818DA196B50E356D877A447818E29CD6D7A95DE0CB6187E12C5B83C715DC60146ACCF81587591BCE7CE26412D3F5C9DAF3EA1B2560C625EE284013D226881CAEB967DBCD6C2E220F67EE894CA52EA24CF6CCA4FD6CE929CBF3F6241F6125867C03B60868E6155C742A941E0251444CB65D98927D0522D40F5176AD4279C46CD2DF97C4E7B8F8EE782601A5386BE951ADA0C816C93464BCBBEFF9888F39382821C504D7A89962D610C80952EA952985D8B7E9CADC4132F5B816929FCDAF89A80BBB1D0871DEBA205D8FC717B62D9DE2833AA81075EFA32F02091BE5511B9982B2AD83566A6C76CDCC0E39AB977390F61EE64FF68717213BA8DD485B8591B3C7933020B43AFEF9FC30062D09A9EA09420EF3620BCA3B638C03F610E5D1AE2E6B433F361D2D4E808E6DF16FDB733DDC556590F6260489428B486E7E833F30E1818C8A2170ACACCF52E3CD2BBAAB7465562300D966F72E9D441F9F0658C04095D8E7AB8706CA52CE8140D158CC18374932D16DEE220206C7554E9236EA325E4F1A0C4ADF734F439E8E62D5C369D88B0AE64A93E0E23817833E3BAA5D8C4819818B59F09B68837E868F82123E5DCD16D64E8A47BEBC1A558C9A1A63436F0F8396181C29AE4BB07AB2294191EFD015515815052B3ECA805B9D28F31ABEC240534A0607A280CD6811B859D8459C66154ABBBC08F0D6077FE9FEF32B1781700308AD0FE5A97D140A5F2C1B991760E06E0133048E5B965CD8B97E1E01CAFE388D753AAE16381BC343F73A4E36EAAB165DCCE9E2420E4E7C746EE0086E52F1F931E9191D937EE4A415CAEE9A6C1109DB9D4FB8941D43EB10424551DE64C4B22049BC14DAAEB2CA5258A90D1249769A8711B5254BEB388EDA4EDA43BB05843B0049C7FCADBC0557D6DB858BDDAA79078A0439DB828924CF461BB41C7D56AAD20D5141E40DC854F32CD6E8A80C3ED7C495580A3FFF8EB791054B8852B3E34B853B3BEEB80662384CFBFCD734528935F53574ED6497E09C7743F5BC8BA05B2B6836A2D3A63416D64BD71B1268773F97DC4E730EBD3A1AC792DA46F322346EDD80D4859933B1CA10328956D72002F14409836D628A1FAB264D081B8A97210DB951F44462C7D8C1F466990419BAAB43AF8F55F3B30AE6F06EBB4B8AC3551478F33F095D51BF655B861C2873AAC0D03D695B132215EB9DE7081CF2066CC9C01DAEF887ABF2CFD4D23BDC35E54508DC4D98F394E3A8824BD0A77CC36F23D345B52CDB7272632B6436A9E76835CBAB56753AF30FCCD9AF85A41B3EBF9A764AABDB0F8BA6190BAAADB1D474B0A373607E10F0CF4A436E01364087BA9096BBBC571869765F19F8439D3C59D145DEF1B3616E4738FA18806793E02C344B4930E3449BC7A793AFDA32B298146505108BB2D1B18AC8410F184C9BD35F23C5BAA61AA9A387677EDF86D88E6FE5A507D0E8F65B2AEB502FFE7988FE78BB4EA68C87791AB731AED0637C72CDA3FC69C6C3D65D79F68172D7F7396F377C744A235879D32B7DE5838335C1E4F699A95F56F9238F4D897705064F4E0B42A8E7273EB84FEF1E64A342195B8F0F8982BA2D4B544FAB1EF29A6B2297A58FE4ECE934ABED4881D5C160ACEA30ACBACADC7A83471B2E7ED8EB9EA5A0A3FBB4A748C6B70A5CDFDEE87A54826E1455EA27F406C683733A873F28557B713E6BBE3DD8F2BA5C411D70524B4B067B14B57BA1ED2C580CFC8C8724DD094526376D640C6F9F094A37CA43D765B087EE9C3149CBD148C30544F08979FCAC3B6F923A04B396D2C183C1E05BFFB4FE9879EA44A1684B36064DCC4A4F98892AE6537316E253722A2F2FA051EACBA9AD6803AA0DE3EB1B90DCD2AEEBCA50E51EFF6DC5ED2FF9FD8793882011CDC7C7F242431350E5F1AAF307AF09A4A08FA67AFC0748F2D7071AE804455441818780D03A92A99A6E307DEC685FCD8AB77F5E1DC802DA1EC88384BAC44EC647732BA0827EC13A5C28EB13CAA81CAE938CF33D65F82C2F82C06F114B63F494E7640AC2E3F702AF5E12076178FBFABE9A105B6D5CBAE82F9D074B0851AC5E2B062A499862F30E1BCBEEB2EC10F39F4B5943496AF67514764EB4CDF59A3453D03D2B09B8350C91D9804D4D836CCD1E8A95966415CCB9AD19859C5A1EBF5D60C5A434B3AAE3CD64182AE73ACC323A80FD20297B230AC2F5425F2977F70D7423A2261111C25D266A97FD2E404F30ADB80E8851CD3E20E3763CBD2306348247E6F709389DAFFC870E6A852E1B904C09A04F2E697F2CF128A1C237F8EEF2D1FA259125F46A69713F284D87CCF78164D218293FAFA4CFA7917884CCFC3228B87A7D468B342C67E4718EF13DA9F43199DDB441723B71EC62302CD50A425D7D6269E12E7690006150509855977B87A00A8A909E5A8264F3CD1A840521277FA45B53F10F626832CE350B46C6B1D6464FC8FFF7770C97378BDB65C9652AA937D25356FB33A965BD9F22F7092279164683EB5E45B6494362FAE98D1F68882E531F6E34F56DB4BED698D5F5EF1F6E23DAEC806E69235C54010CF5CB0B1C3596240742BBE9D9DA57CDDE134F18E8CD9BADC5F50ADC50F2A22384CBD7D6EE126F3D46609312F20694FEB458F2625BE1F85766089857E208DBF57B9E4C93A20FA4ADF312458CFCD4FBA97A4B360E335FCADD1499114CAD094C0011BE3ED5897318EFC2E63F466943B8F69E381D0DB193D78407BABF100071718824354E2F57016AA6149E65660D40145EEE59F94EC0FB84B4D31E2614CC134D1F8557656D4847DE8E086616AB2302DD0EDBCA404C3718DF3E732E4D9697A9E5CBD88DA5C02BD657B31833608C0C4587036D06B71312D687139A5ABF0BE4CD67BC4D0A10FE2A60E2DEE4FD26AB0933081B33BF35E62BCB376370A24FE2F1060AEFF91FEA1501FA1C44606FC1D0781607B5E484003B548E79EC87CA186F883ED87FFE3B939106980AE28143CCB8DE81340D4498536A36ECA80724083B3BC54AFF025CCFBB5323A35EBE2513414D41C6C7DDFD4529FE814654FEA7CA8B87CD41614EF3E0589E02B449D831E2B6674CEF59797A56C9019BDA600CC4817328E42525E31915C3AB4E757179A9646333BBC570EDB09CE0035E4046C5733A700534EF638968CE0054EE60ED31508A311C985E115AEB34EE8D6231E96BABE707E797E1FEB8B4DB03F982DF57CE8F309685748CDF23A4341BD2FE912A8E5CF9C4BD42F0038BD753AA16F4FAB6F20572F466081E313F733DD6A8AC08F9E5FF54AD5E0942FA56D25F0DB33CBBBE4344429E0171545F81444BFADE34E9C6B8676922B5F0F10670352709882125D2B89E324BED47C28815025F3E0FC2AA4C59F0EC515A3CA3F17EEDE84382F034B301F6A21C361C16D450F87D7CC43690E78826F610042BF5BFD4C67E07259001C0645B99CC1A13F17466A14F14812E72EA3880274C233AA3AD921697EB0FAF9E8C9AAB7DCCD328B0BC4D6126A59F3FED7E7B8B000DFFC2A248868D24127E1380CBDA24FF84B4F97C22989D60D15499893DE927454D08436EB9BE36F3C5EBEAEF23555BC259E2FC8A3448FF0543E9EE7601A02F53DC3205AFDB3B1EF8433FE9B736707F6723116F3E23693ED4D7CB3443234DA118D7A7CB1F8832C40695016AC3E47B74F4C2E1B4DB4CDA6579008FE2E61CCF8E782071D497D979CCF33EA9A0A696EBF198B7FE14C811D882AE9B23A66601FE4A4B946D5E8EE7B02DB6A77D2AD07F7D5A20522C3CAC7DCEC2B701A3FD8D3D13966BAF2C7F4E304AF8A1390EC693676160EC1B37FC317737956B755E26287087E508786FD60ABE544BB9CA8409378DE2CA77A1C309DAC99E2077D0CE0461A9B6054241AB3299A26E3D39B15D863E23542CC37BD06CD9FF99BE2F13C629D884EB5DFDC26E03CDB92AEB47BD1B88B6DB8CD9C9F33A66CCA4088E7A2BE30F5EF824059BE231EE26589AA0563671A5CE3CB279885BD5143F53F086D8427B6EB8D28964F855B94F4F29BA2831E3D6DB11EE8BC841ACB16EEBF82AB76A3C4E1F1853B95836478DD0FD6FF6089A8541B44D9E35611124EC9FA8133B78805B3A4FD4AF8D2025CCFAB2E665E61860874429225415D4167A11CE418C008CD7B6530A413ED04BD04CADEB6BC68D00071A3FD0B13C1898E7143FDBFBF661EEFD93089AC5F3A75F89C72E5D7CB3B2A6FC3E5D16BB3E21E338A685D263691D9DED60709B20F1D477BD64ECBEC6B3479B98ADE7743B5C3E56ECED9FE939BC2870A22895CC47AA62523C1E3F8831091EF646E1864596F088FD9EAB22E8B0B551E793648BAF27C056C4FF5E42B49AF52353BAAD585CDDBA24FEF989F5AB165A930BABDA70E9D3B23D80FBF3B4436AC957F5E04F00EBE4A590474481B1BC45F21A8B785A5618AAE135C32984EAFC155384577AA030885D3F3BF5A4F939B212D20B17B2E4B4DA9079E3C70D618059D50528114A098679597C568A29A0558C3BF0EE8E8A639232A1FEA0243C6EA99EE819439D9A48767128E7ADE74EC6BB74E6DCC032A37DAECED30097900408C84420BD56DFC8460C6E918366690D04A0BC8F69553DBDBEB6AF2EC5328EA22E5DA2A915C75502877FC7E7246F4C522CE695E2AD96BCC718238C8AD3240A39EBC7D56E0529B311740712EAF1B35990894A20E5F9AF2D49485728CB22C69F3F18AFB4BBB0C2C1315E07F22B1B0A9A731E627D5F2AEA83969A86A874008641D94A9F0689DEEDF61B1E85788126F1170AF48881D906CDFFB184B0C5A01912E68A906D54FF47820D2F0BB5A010EFB80266EEDFA6258727A7F0643C1BCBB2F190C68941F56A3CA4D103A66BBD27BFCC6B2E6B97855E9B33B2A120CF06C0AA3DB63842877409DF636B744D29292F166E8226376E5D8765E8BBDDDB0961406899406F4E02251DD194A77D6059BC536443F04E9B64C483D7A79DF700A9C9BB7B40E9F7282A7F08137B2F1F0F2BFD2C6E5846E65330A098BDC33D08BED03B78ACFE1F58A0CCF52907559C5270FDAE25407D65FF18B260784EAEED7FBCC3093FB36441D78C01C51A9BD0AF614FD80A7113ADABCB31E3A0678AE62732ECFF47B6360C76FD070CBFC67CF4CDFE919A03560E951CE09B24F75D9D6195FFACD86F534AF912377B0B752F78869337CD4BEB1BCD594BFCE2456771053F441C3B7CD44A5831DC811DA434348682278A527C828BABB9D9037D14538BECB8C7E6C726238B94E7DDA435366116ED4B810EC4A63548B1AFC469B8506ED03CD4BB0A6CB994A470F0BEDBF42CD583566116A4E0288DA56720117424A1940AEDA14E88E8A99B2280B0A083B050A6270D8AFF8319B11EB7687C8F176E9C9815151F0BB5F4D00C3A9418A2AC422C741EE836E983D66F37901646B603F0477D4E5AF1DAF11D06F4598FE5C8EAFCA62B93FDFCDE8193B3249782045F7158B626F15960A6C587F5555C0D26B4D9844C12CE51B9B715E4E6E1B8D0E138CAD9EA71A5C182EBB7FFAC67F181FFAA25E0EB9BFA1C279249C007FDC39C7DC5411554BFDFB7DB4ED327275A94FC1F501B749C51D67FC14E2FC07386BEF27D2357403108A590A2459FDDC33748933EA35A0FB900DC8E908405ABB3574EA9DA68ABDE17984226FB31AC9DA1DE5513F3176571170BD1FB007BEB68ECD78D790CB0D0EE00C4A694BDE2ED9178C308A2F598F7EB43E4100F9CFF468A1236D7C5D980BCD69BF91B06533CC264C6DD7CD33649C696848B1ED46DECC5A681832E5932010A41663E52BE18154BDA520BDA3978D3223CD1F0707A1692DA6C5493B421A11DCBFC579529945B9BE12D9F5825A2D21BB748C5B1D6EAD293D775FA323380CC51D27483525795729267010D04595915B63DC61C0B7B082E06DB34C22EFF7A2FEA240AA834B2B16FDEDC5EF2912E3EB42649419689521CFD160FC919178ACBF401E20CBE35A0A3CCC4D25A25B5766C546650A788C506B59CDAEE6CEAFF9BE626CB264309141125D69EB6E8773DEBE9EE8FAEDC3A8FB234415B549F373DC7EA986EB1250B6537E917C1D4D704D10A512BF44B9700299A1CBE36447BA54FEA317AEF7BEEF7353D55739DB47CAA70D8E3554565A97D427E02DE08FB88B0786BDD94961B578224AFDE745629F3E372D163839FA79E3A2F6F2429E8E72D36AD48FF250F8D2B0DEF12C7DD545563136BDF27F21CC837F8C277C750A217A97431659AB2D8EE9D11D39715FF865A0D467F0524DBDB272ECAB9B9C350AA2BE57DDA7C488A116F38A91D292D1C2E199B7EEDE9215B3DEA5358296F1ABA3C8F8CA40FE128A0CAB9DB1B5CA2D97BFAD26468AF63EF3B981A54648AF8E00271EF5FB5DCBD27D14C11826AB044B741C9B8E2D80CB70BD5155EF4A67A21E88C9257E5497A7F6F69ACFF9C9003CC156633871CD1F3B5DF103FF392D2160CD1AB0EE5047D9A2BE2E1E5DB2B9A716C43283B54B09C629C74BA4F6565CE004C66D1AFF84229EFC778DDE3B3A666680762E80C8F9218900FC53619A0C349B0CB5F32B46F68E87F8DE151DA7AA5C67B3B5107F4CA02EED2504335A54640BB931BEA6768F2486AD463B814B4671D7675BE2F681B44D1AEBD2F98770A3235D59B2390F668479B3E53E969B9EA7D801EAD0F53933A177B8238DB077F7AF360755AC7EB2051096DCB7D7D61EA61943103A71E123AB038F0019151083F409C17DCBDAD9B697F3E916838E16E72BD1F55DC1FE29DF151B5650A70EAC531C5240C45558DD16D72715EEAFA63512903C0D288DEF10F04AC8F70ED8C12417691C1E8D227FBA61C6D8771FCA95337BF063CF070E459C0009246F4619D41B64E3C77CA865E707974780FF922C79FDCC6734645F844FD911DD8687839A1BF2FE6F99F1BF43C7C5C80430A27E80AB9F627E0BD2254DB538C3346515AC2B96BF073EC6D949F704475A0BC2ABF3F6446CC0038D6CE8245DA4FAC955A75D04F45A2AFA0A8CB5F67C5EBB0E25430EA59EA5996E985C4E03C1E8DD9ADBAEE1B6F7E7009000E253DFCC019E36CDF6F91AD120D8015058EFB5B79B91DE1019EE67CE60A4704C33E9F95AAF777EC04DCEF8C5EF5D5C554851DCCBD665B30E41F105FC17776F554B26744E3E967B05D17A9C5E25BA5265829DD990E47E4E4ED39878913C94C848370868207EF7C785B8E6593E373E454C336BC3DAB012B41F5195AEF0245164DF061089670F66A415D409459D3490EB4C464AA78B2882A45642EDEB7457FFBC45D1A1BD8CBD595488551D4267E74CCE372D7E76AAC179881E2D22910E0C43B8B60CDED26D80565F3B18245B9DD4E46C5B2B47B41F207E5D72AE458F625CF9C480924EB9D5875CD1AEB29861DA8FDE6E9A47A176E55664C41F5C036C3BE8CD7EF7D03E5AB79CE1A6A093C5DCCEB88F2442DA3ADAD2BD72E3D377A8CA8A23B4AD2C1C8860A8F03214AA870FF5B3615A5B4E89875F897990E411E15019B4C2FEBD9941184791D047F28914ED5E5C398ADED0D4FBB30CE8F0AE00D286205864CE6714830341BCD9B3F95FDB50A774FB9201751CA13C87CB7BD882C4925BFB56E54E15AF8531ED4391695AD9135E4EF7DBC3A1636D21B27782B5EAA7BB39B1FC26D0A084B53999443F8CC4495E467F6CF044CAF836989BA4E2AA751DC78BDE8B4E8F644CA9F28144BF7FB05D476192B642B631FFBA58E141069F4A7AAC18EFEDAF2B01847D0F52A955E59BCB38A663D3EF87A1C79C72F18924EB4226F25209737ACFB5398C7ECF173BFF8CB71D8F993F41794A1268D4C1B0764E3A3BE1F8399F0E7E2786BE4C01F9954BC33ABAAE738B690671F1D38461777C24056A2712A91A346F34D014EFDDD7C3A97AD5104AD8E1C3C7F8FEF960E85691FFCD00E68375F8D7A4AEB23ACACDFD1AE96768DD2121D320F33A81C7E7307B57350E8B34B58FB900340D1E85EEFD347D1B4A63532E5E98B7D2297F4F7D2498055F022EDCB5ACAE9B574FC5576CC2E147F6BDACEB54957B94E7B5C5BCC1935A91789EC104511417653CF188242EA84E5DA3EF2CC5229860C09C8024D1A3018ABB342421E0B420EC788215A6DD0A22546332972CDE413A6BAB911BAF1DC13B9392DFE75DA2FAC1EB7BD00FEBE18961FE090963840F7DB381FCC83DD2930ACFBA61D5348CFC6704D0EC8A9DC98BF7F5221B9299AF1E57E932A376548F4177F1695BC16CEAE804FCC46441E0C3A360BC5D3130A80939A36D985F75CC20F8A0631029413C12689F85055102B5B9B65FB99A893A24146CE7146F958ED705EA6B44D2E1548C27A623E69C5026FAD6180B2E7BF9FE2CD3E4958E2E81E0A7ACA33C2CE0531E2C0E3C20FEB51C30633B22BDB173FEDE56072AF7F860536EE9A65E844F2CBD706C88B4A9FB0DC62513F6DF3A045A173767D3BF6BF70CF8891CED27DA4DC53C0362BFDF0C8A110D6A750BFBD7568A37387C2896F86AD9B2D789B04FE08EBED45A3473788BA3301AC4DBBFB5FB34D9A3942E25D95793FF42AA793ED210F5FECF1170EC8297FDC1B695D8DB00A78F051499653263ACD9A7FAE12017E738BA9A521DF83DBFE91C376508CC01BFC3A5B0F412867621DFD34C075A4F6DA09F5B9D607A471FDD882D135079D9F73C7494C14E53A6E435FE6728F0099313A15FDFC047DEC7764928F0B913E1622B479C1043387967E799E5921F2092EAD595A8CD869F116A321C60DB79A40E377FDA3D5AB66D94C03B613710E1A62EEF3DCEF29AF99CF6886AAF9E54D1DD931BBB29179AAD78C54B73C926A06393603D591AB4199A43ABE748815080EB5BCFEF56D65A741135B7F734719386463EE7E08D28BECDF61788DDB12FA51340272C0EAB77B5531FCE97A3361895D0DEAFE73FDC953CAE0E9048692C6E3217D358A97075D929C908B44557F02E76560FDE82BF47B3A9CC64936656D63F585A2C128EB25B62F542EF748BF4C6670FE2C60CEF2F18C39B3CCF8D00ADB00B323DBC2AC6E1FF8F1DB37D7ADD881C6415B16CF6FB9D48DA4C40EF045BA60AFEEDE0AEE7A65FCF4AF7D81A582F96D28CEAB468646466A5E443886BF88E90C2822A181DC5AE29F34E343263DB11EDDEC787B838A973A61B4CA5FDA853B88599656A56BFEC83CE0A64B2E6F6399F12E8C84B070E8EEADC7884DE6A0AD146C6105C6A48318F80E9937303410EC9544C97284C36D40E40AB4E9C999BC7D26E528D364D9C6CC42DC50E394BE67E9BE42CD42205972BE72F9E55E6454D03E1B6D6DDED025A889CF693259FDB0F5D28527E9350D73EE46EBE258635AF57B74715533FD215FB95658E8495D286139EA11CC4729DC72362E73BCDC66257E56ADAA3EB3C4BF056B120ED277B15907D520D57EEFDFD9D9D2B8DC45D0E401FFFB27E81F1F0B836D2C0508E9D1F4F02BF4F40C450BAFBEEC2D6ED10DBF556F2092BC0C204309B25804B16669392C848D8C505ACCFEB61B2A1B9081EFB486C0D23C4ED581D939DDFAD362B04216633207096B65352575909D93520B9B5437FB019D6F85891A5C2D7C5D03A491C6F3FD0CC2C1AB4E86BDE2CDFC9541A16DA5D485BAFDDE3D16375D2103DEC947916C3C365E068BB585DB67A758B746452D80F0024CA24990ACD577E752DE2B23DACB74F770EEFC9215DF0F3298BD3CA5351888423CDCDB6CBCA8E8DEF0B36F2A7C562D72AC9634E511FEF907E8F6A70BF81585975FD4D7264CB4CF97A1C9CC00BA4108840F03C70F5A748FBD854F7BB98C1CE66F2F83BA478302C48C4DE7CED4BA2E211F2CC42F33DBAF4570D3459B540B878FF2C1CAC1E8891BE157988F39168445A399C563568BB2A0DFCCFCA7D3A58D096589D3C66F59C5B5823A394692AA7FBDAC4F855502088CFBDAD208A6CDE830F47B0CA77ED7990B0DE50D5B8B140A9F650A9EAAA0A85062E4792573EA68BAA2F19F1506A4527448A92400288FCB0BAAD79F6CE73733CB39D3025219A409E3A229240A53CF6552CCC13C85F76C1D9C69CB7FF87A5DE33A523314C152718C9E3BD1864FF4669AC6E094DBE5DC861BA40B34A4703B82526F743E8ADB94C2D5CA4A579CC794EE7FF1E0FEC7438263A0B106C9435DD9909D1E5C26378981B5EC28E1428DC238A0CBBE2D22F000AE87E88938B492BE3800FF138AB952B18586493608AE83BC40CA2AD2211003284368D3AD131067842E23413DFC9C7C88162F44064F240F66508F5560C100F928160B52BD309A29369ED4AB21BA285C145546D4DF3498BA079BC2519EFFBA43EED64A926642588F3773EF64B0A3E214EF4C673D144743AE67737681797C28019373FEEFE6473A108EFB37B6E0586E92758AB8F37180BADEA45797652CF1669207402400019F2F990B990B6D31EDDFE19A2566CC74AD2CC164A9DA22469666C27FED767E2092C02E70D4BB94F4AD73E3C8CF685F2FC48887FD24021C82A17F1CD405E093B6955BA71798B1254423AE0B10A880D1040F8DF3777440F0557B5D3C5C0F88B5F8AD8BE2DABD22092D0C5886E47DC05A449552DE917C9D9152BB000123FF74959E77B827E1E9CAF5DDDDFFB0AA5716DECBD46DCD697DC8B037E4100FF152DAAF066CA7BE38491F73AA063E002A334E2F42F6B0E111ED73DF7944F382E5BC703183137114E6C2F7BC01F42B249B05CCE0FE5AAC329484672763094E4C9AD26523A90FBF381265F178D391C8DEA06AFA154A61655C300549BBCCDB592D0264C62DF25BEA0D4A17C52AB2936D67CD5A871595C83C67E4D63A8DF63CC6911B958CFC27F4127E5A7EB385E18FC093D34C8FF73E27475965D97D82CC313915E4FA1EE1CF451F44230D12FD7AA8644B83A73E8FAE01D1F8A74BB20E482B302DBB620AE8ABED521011F7173454452B56D1E251FAEECBBE1DE6A4CC9A3AC31825CC228D63F30EA9D99F0D1D53153D2B704A3EBE242DDC192EC87FCB231679564D76EBCEC103C2429BC5B6C57830E7018954FB3DA018A4BD063A5E20B05B9F486D4F3FD64AAB7C225185D6A47934DE75E1328C38910A23CF745F0962F468C834B84FCF8667A0FCF4C99D07C22C3D55C780F3674FA4F76055D9524608CA0CE789CC5CE2CBE00BB5A2F25138FF81787B2C42287C386A37B271F539C8B0B00D3CBAAAFD95FA2E3AC7C17CA798E061AE1BD5C92B49EA9C5901B25246107E6975F22C3DBC7924CB1E983A9FD93359B21CC9A6D7BFDA62B5B202DF58CEA853DD41B5815A92381590FA7237A93777D9C944022C424369DC96AF9C5FA60C406A9640A4F13822456FF2935B95BC99DF5412838064D3F1F6A8698512877DFEE1EDCEDA6F2256CED6AF0D52AEA26A58C1BCE59FCB20EDAC327E4F393646A8D4914E6C254590FF5E5FF49DB1F6359B2898FA07596F4C7AE0817E036862F5A7C5538F9B79C87296CAB652B9F9AA780C29F06011A05C499128B7408615ACCCF1561DFC2709D1AA52014CF48406D4E2BC498CF1D010C0322B1DE27393475054C6EEFF89672C4FB15293492A89A754F78595F84E95DDF05A1456F70588EBF74EA2068D92D533AF364A81E029A58EE81B4DE03B871311CCA39A78F38DCC2AD5994BBA81FE2BE3D761A41F60755105FBE1C689941E43D82C058CAB1FB04B32EBEECB83FC4A21F3677E9BB73C01B21A7FB4A4C3B3DA3122A6DBF09610EE41A7B3C22AB91B0CB0347CC5CEAA964EEBA7C99F022DF4F3734DBC3E66E200056AE8238B2BE08DEE112D090BD072F6B6C57CD01C614EDF92F5D87952BB7112811B72B235827BEA759D1ED922DE4A61DC36ADFA676A2CEB80D7919FD836698EDC3AFC96E3BF3CADAE4CF73043047857974564C06586C1C1CA71C115B9B0F0824F886D1E795CE26908DDBD4493478EE44DC53DCAB0F9F43FB749489272A87551B20491E9B69B763401473F09C1A539C82AA051A39F331876E281FF2DC45455139D67BF61D7E9A74807C7FABC840926B5D75D6D6CE6B63F0D71479C02E40F7AED63E9242457B82737FC89A10F18BBC63E5DA3147DE202C75D0F3FC596B530778C52D60CDD5599B6FF9778420F80615BA09F69692C937809CBAC64F703132AD6263DB57B4FBA220305CD2FAFB38F472CC0B10BE0CFC2E0E49B7766F5988A5EC784C999A4B4D8ED5FA770F8DC2902038C869E409313ABCA3F96D5F57DF87E637D8D896BCFA38FB853B3FF6290AF4C656181CCB7A16F782B504F489A9D647411755BA2316DE82DB33EC3D24E90D3C1D436947EEB79CDC95CDF0C84A294892F0ACF96FA809B1107B2A103354382300A720303D7248030DE0A37FAF8FBF91D3BCC9E77A59FB62B222F085363934BDE8404CA1A2071D01CDB2DFDDB2B43684966E501F25E9B9D8CC3F1530B00E3E13EE0E615885FA5D7DDC4C9CED1CE84D1784A43B3035DCDC31E383698F55DD1D55A72152F71E8A0D084283024FC2768EB68212C86128C1186C24E8DB5F766E808D174262B1CDF27707230FD1313DB244E2E36B034992E474FB93B23606C0690949A340E3C707EA1DDF0B25A4458DA130746403987B41054CEC515AEFE1CC2551EE84ADB3D69BFE8638651180B23562251C108D3E8112DB5151F48E8273556DE6C08CAF98DBFA33AB2C121B91619A6B6C58BC7B6609BA4B2F23170C428E67C123F8673234BB6AE2871405E3F264A38F9EB8E4BE8611CC43A4CFD39BD029582FFA702BA472BCAD8EDED763551A3EE99F470ED0B75856FD2DF1B07AB97618B7B4470A37F4D78CB13B894185299648048D5CFD5207E9B7D8E51ADA0E7B0A2FDCBAE2AC6E92DC74CD4D24C3DEF074A04264F2C0F707474FE48B51C1B82EA0700916F8A6737E6F1869FBB1B57E7B41338782CFD54968281905658857CF526B669CA2573091C1C9F3F24A9C8DACE9CF8F30EF7EF2012AE144A11FD994E6E7F49C2A1FD4C85C0586C16E425030D0CA12DD2DC53652B0D46802A6BC44E844E8C7795BD39B3D7C717789B49485050B291E4A47F947794B58B16A621721A202F4F10D425499C26F4CAF99EA0BE1B69C3A12618D1FD2765F6D69D472021DBF8241B9F3E83BACD6E70940B5C3E9414DF1D1C2C039B29E63B27996F4260F181BEC1CF279040BA71CFF8EB687216A47804D10425C435121A31585280A80320EC74B361E6141940C23C68D325685D4B884CA06578884F254CB76233C3FB129D80299C65B538F614F7B4E633B61846E08795C5D168AC952F73577E0C45386E7CC2C056B9123568E2704555C58185B94A174445D2E4755A77217FA57403A363E63186D1D925BE9F78BA710EE289AFC7D1120155D708055032973998A6203A589390C034B99730B1D95844B64AD01FFC0EEED31BC147F766265724AF46C26CAB015B307169E1AA2BE69A25745ED1B81CB8FF9945F0F41B68AA33DB0B2649CA40497C34F3D1F8F4256E40FC12F71F22DD46EC3E9A22FC0917A6C0649CE36AE90372B7C3AC000BFD1F9FEF03ACCED0E13D25695D5EAD28783F97029AB6F9BAB7E8B4730EB68715DBE841A124323262022934C1CBAB9C40FC44DFCA71F795308F4BBE14951FA18D2CA2AF1583EA6E3DA2D4A07D9DEFFC5E573B28A062B8428B9DA9AC3955623014E5A34AAF5E3695318986E944379CEED0BDBAEE7B3B46973D183D904CE0CE9DFDA7FB90FB075BE9BA597324BFCE0B6193481CDC88C1292B8B7C70E798D7024367CDFEB26BD43940E7A4A890B78C82612D8D0E6CA8ADB483A4F814FC44586E5B412DF03D4761D6F28D06C7F91507A5309C75E65A63AB826969EBABAE20EA1942B37999FFB85745D25B6B56C4832A914E844A96FE8E197219303602AD56C92AE944FF4323D3EEF5787E756EE1E7D318B02F7E5A870D07B6BAD3AC83AB4C06752338E23408769222B45DC1D9871E3E8F7DBC0FCA669F54A0F8576708871A55910795B9A466A532591FB79788AE82B710D15CD43FB4E87ADB457537121EB1BC6B3BA98E8E892043E34A6841082017030B0FDC7A30E6822349217CA8BC2923B46CB1BDD6A6E03BFA814C54E09A6B0668D6DC9DFC668CE610F1F32FF2F7EDF6F449AF8861C8659B82783870B4232F31E004BA0DE356ADC0E37A0337ED41CF3D3D08FE762B1AD59FB9E5A5128E80C61AC9C999C823804737EEBCACA20896A17A738EFC9A96F1F9710BF790AF163E14EDAF0E751D9602E88FAFDE59AE27CC5F0FA708CD4955444F7F5A7FFBAF49477D0956EF707C187201128D3AC1A047976531CB57DADBB533570D835F7F46F1DD1D422BEE9620EC67B3B4171AB3A6E548AA5376B42129E7DA755F263E84CFD334D7461ADFB63DF9A8DFD0DB165C2401421DE41CBEA0BC389807A3EF0607B01B5F00228CD97EFB4CBBBC2C8A3A1069D67317EFCF9057A2A617A86023D844AADA2881AA51CA3F3F5466D4F19085102260CE6B65BF86509AFE3850297E5308D29817140A3C1A2EA351E44F1B993AA9BA68F2247792D17A57353C02DF631BC1DFB5A5405F4154C1958EDF503B8664F8A805D453292067C3C6E4B0456EAFB845EE0C78134A97885376AAF8E3A4797543A6497385009755BF7872B1E992DCF9DB8B5C731322FE92C3B8A2588A23A812BD289A7212909F6D17723E860297212AFE956C0AE4662817AE5C194C514E9F83B9398EB841891ECCB7A77DB89DCAA37FB5B6813C6E8F7D6051B05B9E38659E09223A5C6ED4D5452DBE9183955BD5C388AFD933F91FF268C55AD72D462F084DAE7252243056B7A9E774B45055D99B992EE8D0F27F059A3A9ACD1BC3D42DF7BE0F2C86AD9F9D5E2C77B7356F51A27A462662C05D83FD3F2C4D61349BA23320C4FD0C958577A795ED4A8632DFF18E9D881692CD12870634B6869A7C5E61888E0FBBF1D87A61EA1738ABC69ACF304000423D0B4235BECF3F25B27AD7B9E24370699BF28303453728CC1F6EC410896CA186ACCC57858E107ADE40EDEF3245F73A4406F30010BFA0C68A8CE236A2E25ADD40A9456998F7AB88056B77AE4A82DDE614755131C055233B9FB06B8FB0209ABC3D62609B273DF0B11B1862531FAFC81BB53B4C6BF7B5D0B098DD0A48C87138997DA1DE8089A10EDC71058B2CC9C7A82A58E20494BE0FDE6AAFC4CD3B00737C1B946D826AED4FB006EC1BC09786665DD1FC64027E2EAD8F51AEA203DDF1ADFF5BBFA35C0EB9FC81F3F6F5F754EC26292A9A5E7244B08CA584B91462FF2B62F8A266CC3BED6BC58A761508A58B1A61C0D06209F7A3172553EDA20EABD48F6F93FC3F7E92CC95836F2B500393A9BF250A5AD69B30F0F62FD9F62046CB00A06DFD9D3566822A98138F1939AADAD5224E37D20C55C1BE67A3B7B212D321A199F8B6FC5C9D087DFABF00133098256689D3A5ACDB7BB9EA0F4FFF33A80933F7C6A730732A13C84A78EDCE314627BD6837D78906BB19173DE50E616EBE0997ADFA408776C2F8B4C9846818FD671A85ABAE1EDCEFD4F2ABA9831063AEF5109DA0747C06B6929A36739B07707323BBFB76EC148D53F8AE954F76444C5BC030CA3BD39083A9AF39EACC4397356D287F2209833ED8E7269B9A120012698337803878608BDA0A569ABA5739A5CB4F5058E70A1BAE8FF14BCBEFD81C99FA5CC60537FFC7BCD8B6A428E8261F4604FA2AF7FFF9F9EB10571AF75701AC27C659782E8BC8EF4CA77C6D08610B24C41ECAB5F1B794FE5A66EE865614F60776CBA442DBF96155D9D9F72C83FA9B0D04D43AC6DE80AFA1F34C1CBB6A85F3E015E8B522DD091886FF00FF72254AD04E4B262706059EFC154CE97427710EC1A332FD943D13119D5AB5AC88E77836D6CF2C709489BB2926A2E2B7CC1AD1ABD8F14C612687E1F1855EC8A2B79EC6D0DFDC57D2E0D8BB29C9863CA58B1330059A7781B1B82637B6A90C83571769F1AAF34DC68C963798CE4AE77FAB072041C3EA1D30D4F7F06AAF3309FFE7A7FE599166AFD5150DD6C6DA4B780DD1994EFCC3DE851E66672C1CD052BE0D9A28541B999502D4FC25E4FB498C4BE79CC37DB0A5BB6637C5D2784CAAE9DABF6B533F74872CB8B9B66DFFDD9A2DDB6F802E58F40E6B4FDC978D287CB42185D70D728DF79097AC05394B702D13DC1979FDB9C6B179931715DF493F430E0BBFF32D0E3B8BF47E3137EB004DB452D1C7ECC2FA87A126FF49CC13328DD2C26FA9970D1C356A986394DC270D8348349E257D317ACB75B06E22D819093D106869963319AA1AF74AA624D14348197BDB12BFF90DA4148FF9F73C9C49DE102FDA54B470C4B37AEBD57E1FF8CB7BA3762C3D7BC7025A28779906F6239865AA172DB3DF8C88558AB49D36A41C00FE18F94BB14A984308FCB5C1FF9C42A24E3D1B82CED255C07D8C47AB93C6CAD27A3B9C83E5323B401FB737E536CEE9C225AB0CC43D75E066A3A43C82BEB21A7E01066ADB544FA23429285992F66285EE49DF5327094E2F3C8EBD7D4FAD0F6F18EDD8C6E509DE6F7137B8DCA796A1AFAD6F3C059E39CA217811536B9DA646E4C41118E74660A44EE566E415D806770169C2532C4632552AEE8F851B590DDD7B1EA469E52A7FC6165F0D01BC03622B89463480FDF776A6B0B874694703453C4B8999DF2CA9EE632ACF7BE902EE7D17AEE962FE7DC16D9A3687820429494CE43E8353B35DEF4BAFD072750183CB8600B104F00C50B53AF6523D6B3457F6843DB650F9AA25358C74C4E20F52BE34D2C9D8481FEC312B7D660DEF1106022B3123A49B1C91A0BB5749659682DC0EC81690FEFD2F902A9570C00453EE732B567A6A200DBE8C373C7D95B106F256A60D667C741946DB814EEA6DDD152F53B4FA7E0D029C606E3834393080D03B1AB67859283A0A9E925FF7B143920723FC71F51DDBA36421003F3B0CAB773BF64BEDC206E0ADEF2D17EEC8A3B4215EA9179A454FF632FA0FA4ACC7864F200E23AACAF7D45CD878DC5F56C52A857874C87866A4CFC01EA949D16796D4FA9F99E1B8191E5C6FD04058AAC5B316FE346CB800B7FB68890C5854D966C1AD6ACFF6D64F964BE1B3262CA11FED83E1E1DC69E710C6F88C5DDAFDED238C169648DB8C445AF3E2DAEB1009AC2F120CC83FB701810505055489678ED9DD1F51E7193B725498AB6221D226D3664815C1F6886DE24733A40D3B6E0C55C21C00E008918058C40F01DE915F022DF5D86A1549A87DB36B583C2A70EBF7BC393289202C3304064A5AF2A0DB131D7C85BB18FE2313B2263BCCB4F5A4EC30B3B00F084FA859730D66A67F101BA0086B50FCF56A4D1C9D04C3E3A7D137EFDD79ADE320F97FF65EF51738D6B3A99677E2EDA62B238EF1F81FECA78EBD081575E020D5AF4742C5B5DE3AA3479C9CED43929222DC3CBD0813E783440F0EEA3869C825851BD80D08275D6C1A803A62D25EFDFDB3D07D19E931D5224BFF2E73592D706DB43AE9DB49C02A43E4ADC5B416CB229AE79D5E6A4CF7462D0B987AAFF2BB854A0A7649BE237F1DB852B92C0E8C7B6351FEE97EB1E45AAB7F4F9971BA649E522F72EC8938006ED8CB6830CCB0E3E3C85A244AE082DA16C9143ACF33AE674AA24BCB1ADDE2CBFEA175895D3135AC07CCFF4C5F82219B2D4EEE8953D06B93C4D0BBC1376D19D9CBE377EDD17C1161E33088C796BEC56F9FE4196F35EA54CDB4B3DFB3FE2DE1D5FF66C8D847108B5D26EB5EC382A1465CAD385BB26E67F43818C60040C0ACCD47EBE30C717CE278AD00010FE7EEFA420FF909B0D25590C09E38BB5C2CE1D46A26D555F849E3DBB4F75B1947D19D863AB15B05363E5E8533AC00EF59D743C76CCEF0E6FF0D9A5F95CDF6DC104F467841A51CB92F10CD9BB0607049B3EA21031ECC2D5C3D18EA7198CE7796386FDC2C213A207694B0C5819163BCC1E854B6CB6013E366535DA21C1120A87335CD396924AEDDA8B25536FEA7BC2AD5B7F582377F7E33479AFF388027DACDC98416FBAB3324679EED27083E0D8973188995093F86257561BC08AEFBF0D9F381C1FB3D574F0F7E8C19013C224D4EE23C4F0C17A6B32DC1830854E8ABADA50753CFECB46F19EB6956AD74CAE33FEE9883E074A0EB34B8175C10F7F44BD9B28C91772694F69F617B6CCA65CBD983ED2FEBA4E0708CF09A155096686254BB1CBFD9AB4B73625862AE4B9FB5C395F2353A0136B03840943405A5A60B983CFA83F5DDF232CA6CBD354EB0FEA01905EF304419AD6BAF58BF90459C2F117D62AF763FA5CBF8B19D66D5110BFD9701313E63AF0A26329191DFB658C59B38CAA19ECA77DF6A624E406DC8E0F328E2A4AACCAD3D05B6C1E35F4C20991CC2756D1FD161079C56B951A00DA54D01B0B60E1E0FBEF70DAB49852CB25705E0EED5B2FC292F3CEE1D4555F35DAF4B069EC2A8ADF2DEE0581446E8A077CD127943B295D3C08D3C6C2EF42EBB91B4BA9CC6CB24515379368E7342E227582CFA390AA75F6336441495F59343AFCFC28176558BCFBA2BD0553C732059076B04CEC36D81D076AB44BFC53955A87B023421D5A97749145296615BE158C162B4500B363B27012B3403F78436EE96B0544CAFE005D99C6FACE343D42674A3C06CD6C16D04C32E8A3047F16950D01E810C46F666A6469CDACBD40DCFD5C16A601050046D8BB8631650D040763D7D3471337D52CB8020536D7325AE07B35CD7EC13BFB666564B5BBD5D81528E0FA7542365C185F079B7DF8D2AFED0D4CBE343E731A56EFB2BA4BDF8B72166CE5523DE9EA6B75FD9AD8C43519C3B0250B8507DAB7B36938AE0D47EE71C4936B065D0A20EF684FE5EB7B14E3E4FA214CD6D3AF8B73C1253233DB1201234CFB4D22BD726B0B4A64F81F31D361A9DA7E113B3BF213D0B4E15BF679FC237048488DC48B926B5C1A1CE7811720046D2F65B6329AF3E96525D0478B371F27095C36D57D7293DD9A6D7E78C77B1359EB680F99D485D37BEFA38E917C78B047F3A7714EE46AB8FD0078B9DC3F7634173655410D20F1ED14B6FBFD310D879FCF2411104E3068582C296B5F070396E785B0CC6E5B6C596BEF8B07AD21297E950FF9071B940E9822125D46E25910C274DDCB7DDF0062A8BD17DD7EF977BAB539A9E79C2504F037BB65CBEEA845B948F652D21CA32C0BE90082A66E496EE6198B3D9B34B27AB75EB58D06D21D49E4C71074A4AD6614E2C4931D3E82FE48117848B1F004CB375D73E32492905CAB3CC384F06ECDD886B40B71A54F2E16A2154A2B87EB217FD11B88030BEF5D1A3BEE4F174CB1B33B1999F6B844BAAE20A4AAB42DA07A8D1334160E8D148BDAFDFB5C088EF6E21992A76E1667CFEA2D407C6C7CA9B57E25A45E8B737757EA3B276B8A98A746F4ECE4262754EC6DB5FE8510E43C7FBD7922BDCCBDD94551790115020A9755F35BA6028B818F486034AB20DE47A6C46050D783D8A71C3FB795BE1BF3812243158E1B3139DB43D969ADB49CF924B2F7FC9FB551D3C2A38793B89C5573D0169F499244563E0C71037821FE97F84463E16DA985AB073C4BE6EF88EC5031F6719EF06632B595F67A00CC94EB7A453B2E3D44322D5CD39E6ED1FECB40A5926C6A0CC7908135AA4CC930062E48D569C9CB2F850A50AC7CFA5BC21FE642DAFC8871A889544326C554357C2145CCA4A5585552FFBAEF88DA90AF6C4AB5D4EFA27197805F7BBAC9AC651915EADAE2A6BC876153E2B0013B585EFCB68CB889FAF8DCF0861750C034E357DDAECAAC3919DDA456DA643E94D27659C0EA946935E1B01B498D6C2F9BA2653AD124763035D306AA2B25F415A599176D4CDA447BEF832E80A0586A442CAB3C1EEF3335D152853C2D423E6CD34F5EE9BA80BFD02141F329FAC1A45F3886F4BEEC55581CD691264ECE0AD0A1CED84B916204386F923F99CB152269497C230DBD30C6B84F6B904043BBEA225A36EB26765FE38A7B45DEEBBBCE1C0DA422C7D6C940CD5BF2C844187388B3FDA30A263DA573884EF112438785011420D0D2707F4886C3E06D55A410444EB0AEB6EF2383B346DCF44D392E0FBB1262CB23952FDD112B31118D1E6171F813AFF4619AF0C22DB26E67E09AD3D089A4BEA67E30F3F0436269FB2B8877E2A621D3891123052BF2909092092D9B3C3E9963C6441C5C646CC36CAEAD62C12367BD5035BC8EE9EA41D188C7BD0206E6C44248B8709080D8D9AAD77FF7C14078504F7A6BBF48156653EBAA328B0A68B64FD6CB7D12661D48B9335C55CB98A2D39713441FB4D6DFA56F9679E9D5F72B11FE7771018F47BC97B8BCBFE3F5E9EC119EB3EABB034D1FBF3020B2A467C8EA88BC44946EA560451D9A486F9BC13798517980D6993DA7F937CAB49CA937A51B4E5C11A2B6C0537834311B491C04BC3FB8D555F913FDA8080DFAB458AAFA7C735021A3F2B39FFF2D41E0B30040AE3C7824C15272285E7A149734B50A43C165C117BB95138E00828A82728AC4199FBAFD63CCADCB61452B46A103B49B6CCC83B12A5B4A818E6BA638DB74116F3145F2AEA9568DF424D0BC68FAA23AEA46DE598A6348B031D717813D4DBCFEFB579AD883B5D0D6B750616D2EF0A6E6F778D7CDDD9E780FC3FD550D853B8F81578B7E4B5C44BFA3414B27E0209A750DBF884203934E073C15E43283548A8C3AB790251C8F365E1CD0E8C323F740D8ADCBA2D0CEEAD6D24B82D1151500A53465CC078A8F2E4942DDA340232635220631B7157FCBC7172C6984C80D3DCD2E02429AA7AC4F8423FC120AF10586C79323C2DC0A0D26B9EDED32AA7E9CB04405E9B549E07EB3B2C4A2936B612BD711852E7A318C0EEA5BC51F5415D9822AA4F7D306806E5A0327AD843C95703EE03FEF902596197240F94E702E7FCF1FEA8DC3FC35C7E95075342E36B806DEFAFF3C7F7D2EEA52E0AFDC905247630AABF0F4E5CC0B057932FBDE627A0AE9BEE6B27E74F4EBD08249FEBA91ED94ACBED24619EFE6AC1F95A58873C3E9D289968BC0C416AB5AF9102CFA05CABD4673F0E0A1C63E442CC66B2CD424D3F4EAC528EF39F05179FD88E1C489FB161E793232CA5ACCB978D4F133596E95B083A2D55B444ED8A82410DB281DAF08EA75049EDC02A04E10DD2964115468E024E7E508DCC4EA859C7749C66A9A7D66B692BBCB04F75E42E415C95E8DF3338AAFA05BB2723EEE7B822958BA48FD8DB62623B2F904DABE885CD0B5C5EB9498CF1631410BD16CBCE4BEFEFE8AF188BA359FBB99A427D8DA7554DF06BEEC5EAE80BC5042FFF18098760555C796492925D84946323BAF3A46D3A88C902BBD8E5DB67AB268FC53C5712DA72690FD72EE765E5D9C6BAF162C6BE2B9840960658D1C75FD6F820693B6DA18FCFB9AE7FC4B1F49661CE6404EE789B6721B389657D8078A625258B7AA7A19753339B4E0B3B07D710C128BA1D686576265D1A7743AEC8146F0CEC398D9B981FFC71C478514DBFE7E8207D76098D5DE1A7B4DBC760284A0E00A77BCD1DEA1D1CAF2D456A4F4CEF6C509EA6D148B0F8252B44E700E852A1B3F7719F5A694C4BFC5F7C7522BDA28297258C6A208E08ED2812B6CF4F2C6C394A1AFC4BEB53FF7E06E30BB198419C041F95ABBD8905DDF395BEC27432D0DAD4C861ECAE6FC1B77CC00B853917A2119EFB56928622B8FEA20EC473AC2AF05C6B0332E88DF9F0FA3F669C0D5D82256F077165AC416A0E6368CBDC75B1C74C31E97C0FA3E63B199417667FD93252640B21E3A098813F0C4ED7B3C198F0AF67917148CECE85B85BB65A521E2E30972D78D98E900DA10FE34076BA13844C8942FB107A20283F5E99F1B225734F06F7F01B88D43C2B337AD77C0B1E20927F15286183C5364976CB38FB13402554090E0762F099209E51D8E047A15A71ACB1779F15050E56A4B245546F08CDB23AAE44AF2BA01737FCEB9B09A69B86F8F7D35ABD5576450B6841FE96C93A4F98F3CD99535D24C9AA99087CA4C04773366F82886C9FF31E64EF5F7DEE486872BEA6AFEEEDD40EAE1C0BFF42A0A85E4DF8021D2AA89AF8E3633E8B543886D0FEAA3DBFF300D4555BA0A224A71DC8BF9B72CFAE6A8FD81A144C1A43A749482DF1065F3E902BF26A0167EA88105C242C4750AC7CFDB90F0B0BABB4F24ABE108667A6D5586BB7CDB55114F21CA67E2FFC8E2266DC575929561A7FEC3F1CA9FA1BC3927DE24B755BB553D694D9B718AE1CBCC81208A05C02771D8C48E73AD4C2378CD10DD6AE123D476296B41D6E931095F30359547B1399B8E445E106066261E798BD5A909F502E1A82852ED7B54ABAF07011997B19C3A44F6D02F790B66EA6FD80E029CB10FC28D7DF5FC63EBDAA9912207C8A8C635A45DE0115085452F70E0CB63026F3DF6AA3A99DEA90B4CC5A765D5C850E4B87352AF62372BC91605A9FFAA4A62EA09319B07E85FB0DF617A9B42F352DC0D39646CBFE547F0E3CE2CD9D746A86198F48EA0E3F1442C8D62310AA03E134B5D5F78CFE5C2B2DB16EFF82EFCE7195ABA3A91707573B017B618ED0B46F72381AAB3CE28515322CD4D9D3701E491665F792C3EC75AD78E76D9C288C44F34E5634031C37BEB0E7F3D07AA0C1D8DB60E683D5893689EBE9A93EAC4269CFC43760F35356271922EDC7A2A595DE12351543603279C5B59D0EAA03496034340223E222E7CC6C0547FB165D6E04013AF57B0C2B6F9F21F1C3F5B96C9F0EB90392454A231D6F6C173EB36591DC77E21A4D992AB5DD6BE5830EAAC6C7DFFA213DBD6439FB753E75B52D50DAE2F18F632CA6FF0E2CE7D7D5BA26228A3108A18C61B32C944B3F4AD5DEF808696E0AC2A47491CF82CECF53EE0FEC4CF1A2DCBB724BB82C1E8B600CD989868752D9F71688D5D622473D079CF77AE4937AB1CF8FF30BE06C84D88BA3CD1A3870E7A33C7B9F2DC11D8BA8AAFF945BB58DE2663A8F0DF466278822E9F627025B6F5C3BD9ECF2E657447C25FFE5FE611C750D7C54CF769CAD49FA7E403BD6704A12A9841E74A295108DBA1D1001249B21CBB2D38AD228B55D2D3ED49BF93B660A331A0980DF0EDAD7492C3BA6D1454CBE4BE2A73C80BF8F58963BC54D1408307662F5D763F44AB505D49C948611B459C9BBC21C34694378AABE0DB5A5ECC4404B0E6670BB3D1A810C615D0CF15AB059BCBCB6C38EEB572E5B66B430C220215B389D234EAEE0152CCEEE2DD8E51D66247494CC8F1A308DDB797B0B76C9C9CC503ADDB5A1BCED4CC7AABE4E785188794959DA5F5D6EE143DF7706E136F2B5D82C33F713292350DAE8532ACED66E845DB95AF04D4024F1652CEEFEDC53E2EA29CEDD5C576F4DE5827762A014D5817B90B54E192C6ECBAE2B39F4AC76FB392E5FBB1705C4EDF29A0EFB40A97EC4EB7A7E4BE959643CA880C0C2DEE7C055A5D2361E0FE241102CD82DC39E275B7BE4068E5F68CD17FA24D4C76F4C632FBC1CFC7F471E00D0053D7B4C615C55A4D831A648EA2885BCFB5DE6D3CCFD407B44C668AE2975632AF078AD3D95DA895C1BCD66C5FA2DC1F0DBE623CA6D11A3DD0E304C4923D9DA1EFF40ECFF840B077247795CCD2B1FFB549E6C0F6E73EDDB9259A774FEB45E8959B879DFF10517AF5B87233D272B81938489CC77E617C832E9926A992FCD0C93B6A5ECE04C8B1